Add a compile option to choose between thread implementations
This commit is contained in:
parent
707acadd36
commit
7df9e2a454
@ -64,6 +64,7 @@ option(MUNT "MUNT" ON)
|
|||||||
option(VRAMDUMP "Video RAM dumping" OFF)
|
option(VRAMDUMP "Video RAM dumping" OFF)
|
||||||
option(DINPUT "DirectInput" OFF)
|
option(DINPUT "DirectInput" OFF)
|
||||||
option(DISCORD "Discord integration" ON)
|
option(DISCORD "Discord integration" ON)
|
||||||
|
option(CPPTHRAD "C++11 threads" ON)
|
||||||
|
|
||||||
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
|
option(NEW_DYNAREC "Use the PCem v15 (\"new\") dynamic recompiler" OFF)
|
||||||
|
|
||||||
|
@ -34,10 +34,14 @@ endif()
|
|||||||
|
|
||||||
# WIN32 marks us as a GUI app on Windows
|
# WIN32 marks us as a GUI app on Windows
|
||||||
# MACOSX_BUNDLE prepares a macOS application bundle including with the app icon
|
# MACOSX_BUNDLE prepares a macOS application bundle including with the app icon
|
||||||
add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c cpp11_thread.cpp log.c random.c timer.c io.c acpi.c apm.c
|
add_executable(86Box WIN32 MACOSX_BUNDLE 86box.c config.c log.c random.c timer.c io.c acpi.c apm.c
|
||||||
dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c
|
dma.c ddma.c nmi.c pic.c pit.c port_6x.c port_92.c ppi.c pci.c mca.c usb.c
|
||||||
device.c nvr.c nvr_at.c nvr_ps2.c rtmidi_midi.cpp ${APP_ICON_MACOSX})
|
device.c nvr.c nvr_at.c nvr_ps2.c rtmidi_midi.cpp ${APP_ICON_MACOSX})
|
||||||
|
|
||||||
|
if(CPPTHREADS)
|
||||||
|
target_sources(plat PRIVATE cpp11_thread.cpp)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(APPLE)
|
if(APPLE)
|
||||||
target_link_libraries(86Box "-framework AppKit")
|
target_link_libraries(86Box "-framework AppKit")
|
||||||
endif()
|
endif()
|
||||||
|
@ -8,7 +8,7 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux")
|
|||||||
else()
|
else()
|
||||||
set(PLAT_SOURCES unix_midi.c)
|
set(PLAT_SOURCES unix_midi.c)
|
||||||
endif()
|
endif()
|
||||||
add_library(plat STATIC ${PLAT_SOURCES} unix_thread.c)
|
add_library(plat STATIC ${PLAT_SOURCES})
|
||||||
add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c)
|
add_library(ui STATIC unix.c unix_sdl.c unix_cdrom.c)
|
||||||
target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64)
|
target_compile_definitions(ui PUBLIC _FILE_OFFSET_BITS=64)
|
||||||
target_link_libraries(ui dl)
|
target_link_libraries(ui dl)
|
||||||
@ -28,6 +28,10 @@ if (ALSA_FOUND)
|
|||||||
target_link_libraries(plat ALSA::ALSA)
|
target_link_libraries(plat ALSA::ALSA)
|
||||||
endif()
|
endif()
|
||||||
|
|
||||||
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
if (NOT CPPTHREADS)
|
||||||
find_package(Threads REQUIRED)
|
target_sources(plat PRIVATE unix_thread.c)
|
||||||
target_link_libraries(86Box Threads::Threads)
|
|
||||||
|
set(THREADS_PREFER_PTHREAD_FLAG TRUE)
|
||||||
|
find_package(Threads REQUIRED)
|
||||||
|
target_link_libraries(86Box Threads::Threads)
|
||||||
|
endif()
|
||||||
|
@ -23,6 +23,10 @@ add_library(ui OBJECT win_ui.c win_icon.c win_stbar.c win_sdl.c win_dialog.c win
|
|||||||
win_jsconf.c win_media_menu.c win_preferences.c win_discord.c glad.c win_opengl.c
|
win_jsconf.c win_media_menu.c win_preferences.c win_discord.c glad.c win_opengl.c
|
||||||
win_opengl_glslp.c 86Box.rc)
|
win_opengl_glslp.c 86Box.rc)
|
||||||
|
|
||||||
|
if(NOT CPPTHREADS)
|
||||||
|
target_sources(plat PRIVATE win_thread.c)
|
||||||
|
endif()
|
||||||
|
|
||||||
if(MSVC)
|
if(MSVC)
|
||||||
# MSVC complains when we include the manifest from 86Box.rc...
|
# MSVC complains when we include the manifest from 86Box.rc...
|
||||||
# On the bright side, CMake supports passing the manifest as a source
|
# On the bright side, CMake supports passing the manifest as a source
|
||||||
|
@ -163,6 +163,9 @@ endif
|
|||||||
ifndef DYNAREC
|
ifndef DYNAREC
|
||||||
DYNAREC := y
|
DYNAREC := y
|
||||||
endif
|
endif
|
||||||
|
ifndef CPPTHREADS
|
||||||
|
CPPTHREADS := cpp11
|
||||||
|
endif
|
||||||
ifeq ($(DYNAREC), y)
|
ifeq ($(DYNAREC), y)
|
||||||
ifeq ($(ARM), y)
|
ifeq ($(ARM), y)
|
||||||
ifeq ($(NEW_DYNAREC), n)
|
ifeq ($(NEW_DYNAREC), n)
|
||||||
@ -370,6 +373,12 @@ MUNTOBJ := midi_mt32.o \
|
|||||||
Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o
|
Synth.o Tables.o TVA.o TVF.o TVP.o sha1.o c_interface.o
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(CPPTHREADS), y)
|
||||||
|
THREADOBJ := cpp11_thread.o
|
||||||
|
else
|
||||||
|
THREADOBJ := win_thread.o
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(VNC), y)
|
ifeq ($(VNC), y)
|
||||||
OPTS += -DUSE_VNC
|
OPTS += -DUSE_VNC
|
||||||
RFLAGS += -DUSE_VNC
|
RFLAGS += -DUSE_VNC
|
||||||
@ -464,7 +473,7 @@ CXXFLAGS := $(CFLAGS)
|
|||||||
#########################################################################
|
#########################################################################
|
||||||
# Create the (final) list of objects to build. #
|
# Create the (final) list of objects to build. #
|
||||||
#########################################################################
|
#########################################################################
|
||||||
MAINOBJ := 86box.o config.o cpp11_thread.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \
|
MAINOBJ := 86box.o config.o log.o random.o timer.o io.o acpi.o apm.o dma.o ddma.o \
|
||||||
nmi.o pic.o pit.o port_6x.o port_92.o ppi.o pci.o mca.o \
|
nmi.o pic.o pit.o port_6x.o port_92.o ppi.o pci.o mca.o \
|
||||||
usb.o device.o nvr.o nvr_at.o nvr_ps2.o rtmidi_midi.o \
|
usb.o device.o nvr.o nvr_at.o nvr_ps2.o rtmidi_midi.o \
|
||||||
$(VNCOBJ)
|
$(VNCOBJ)
|
||||||
@ -693,7 +702,7 @@ endif
|
|||||||
OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \
|
OBJ := $(MAINOBJ) $(CPUOBJ) $(CHIPSETOBJ) $(MCHOBJ) $(DEVOBJ) $(MEMOBJ) \
|
||||||
$(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \
|
$(FDDOBJ) $(GAMEOBJ) $(CDROMOBJ) $(ZIPOBJ) $(MOOBJ) $(HDDOBJ) $(MINIVHDOBJ) \
|
||||||
$(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \
|
$(NETOBJ) $(PRINTOBJ) $(SCSIOBJ) $(SIOOBJ) $(SNDOBJ) $(VIDOBJ) $(VOODOOOBJ) \
|
||||||
$(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ)
|
$(PLATOBJ) $(UIOBJ) $(FSYNTHOBJ) $(MUNTOBJ) $(DEVBROBJ) $(MINITRACEOBJ) $(THREADOBJ)
|
||||||
ifdef EXOBJ
|
ifdef EXOBJ
|
||||||
OBJ += $(EXOBJ)
|
OBJ += $(EXOBJ)
|
||||||
endif
|
endif
|
||||||
|
183
src/win/win_thread.c
Normal file
183
src/win/win_thread.c
Normal file
@ -0,0 +1,183 @@
|
|||||||
|
/*
|
||||||
|
* 86Box A hypervisor and IBM PC system emulator that specializes in
|
||||||
|
* running old operating systems and software designed for IBM
|
||||||
|
* PC systems and compatibles from 1981 through fairly recent
|
||||||
|
* system designs based on the PCI bus.
|
||||||
|
*
|
||||||
|
* This file is part of the 86Box distribution.
|
||||||
|
*
|
||||||
|
* Implement threads and mutexes for the Win32 platform.
|
||||||
|
*
|
||||||
|
*
|
||||||
|
*
|
||||||
|
* Authors: Sarah Walker, <http://pcem-emulator.co.uk/>
|
||||||
|
* Fred N. van Kempen, <decwiz@yahoo.com>
|
||||||
|
*
|
||||||
|
* Copyright 2008-2018 Sarah Walker.
|
||||||
|
* Copyright 2017,2018 Fred N. van Kempen.
|
||||||
|
*/
|
||||||
|
#define UNICODE
|
||||||
|
#define BITMAP WINDOWS_BITMAP
|
||||||
|
#include <windows.h>
|
||||||
|
#include <windowsx.h>
|
||||||
|
#include <process.h>
|
||||||
|
#undef BITMAP
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <wchar.h>
|
||||||
|
#include <86box/86box.h>
|
||||||
|
#include <86box/plat.h>
|
||||||
|
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
HANDLE handle;
|
||||||
|
} win_event_t;
|
||||||
|
|
||||||
|
|
||||||
|
thread_t *
|
||||||
|
thread_create(void (*func)(void *param), void *param)
|
||||||
|
{
|
||||||
|
uintptr_t bt = _beginthread(func, 0, param);
|
||||||
|
return((thread_t *)bt);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
thread_wait(thread_t *arg, int timeout)
|
||||||
|
{
|
||||||
|
if (arg == NULL) return(0);
|
||||||
|
|
||||||
|
if (timeout == -1)
|
||||||
|
timeout = INFINITE;
|
||||||
|
|
||||||
|
if (WaitForSingleObject(arg, timeout)) return(1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
event_t *
|
||||||
|
thread_create_event(void)
|
||||||
|
{
|
||||||
|
win_event_t *ev = malloc(sizeof(win_event_t));
|
||||||
|
|
||||||
|
ev->handle = CreateEvent(NULL, FALSE, FALSE, NULL);
|
||||||
|
|
||||||
|
return((event_t *)ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
thread_set_event(event_t *arg)
|
||||||
|
{
|
||||||
|
win_event_t *ev = (win_event_t *)arg;
|
||||||
|
|
||||||
|
if (arg == NULL) return;
|
||||||
|
|
||||||
|
SetEvent(ev->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
thread_reset_event(event_t *arg)
|
||||||
|
{
|
||||||
|
win_event_t *ev = (win_event_t *)arg;
|
||||||
|
|
||||||
|
if (arg == NULL) return;
|
||||||
|
|
||||||
|
ResetEvent(ev->handle);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
thread_wait_event(event_t *arg, int timeout)
|
||||||
|
{
|
||||||
|
win_event_t *ev = (win_event_t *)arg;
|
||||||
|
|
||||||
|
if (arg == NULL) return(0);
|
||||||
|
|
||||||
|
if (ev->handle == NULL) return(0);
|
||||||
|
|
||||||
|
if (timeout == -1)
|
||||||
|
timeout = INFINITE;
|
||||||
|
|
||||||
|
if (WaitForSingleObject(ev->handle, timeout)) return(1);
|
||||||
|
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
thread_destroy_event(event_t *arg)
|
||||||
|
{
|
||||||
|
win_event_t *ev = (win_event_t *)arg;
|
||||||
|
|
||||||
|
if (arg == NULL) return;
|
||||||
|
|
||||||
|
CloseHandle(ev->handle);
|
||||||
|
|
||||||
|
free(ev);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mutex_t *
|
||||||
|
thread_create_mutex(void)
|
||||||
|
{
|
||||||
|
mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION));
|
||||||
|
|
||||||
|
InitializeCriticalSection(mutex);
|
||||||
|
|
||||||
|
return mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
mutex_t *
|
||||||
|
thread_create_mutex_with_spin_count(unsigned int spin_count)
|
||||||
|
{
|
||||||
|
mutex_t *mutex = malloc(sizeof(CRITICAL_SECTION));
|
||||||
|
|
||||||
|
InitializeCriticalSectionAndSpinCount(mutex, spin_count);
|
||||||
|
|
||||||
|
return mutex;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
thread_wait_mutex(mutex_t *mutex)
|
||||||
|
{
|
||||||
|
if (mutex == NULL) return(0);
|
||||||
|
|
||||||
|
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
|
||||||
|
|
||||||
|
EnterCriticalSection(critsec);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
thread_release_mutex(mutex_t *mutex)
|
||||||
|
{
|
||||||
|
if (mutex == NULL) return(0);
|
||||||
|
|
||||||
|
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
|
||||||
|
|
||||||
|
LeaveCriticalSection(critsec);
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void
|
||||||
|
thread_close_mutex(mutex_t *mutex)
|
||||||
|
{
|
||||||
|
if (mutex == NULL) return;
|
||||||
|
|
||||||
|
LPCRITICAL_SECTION critsec = (LPCRITICAL_SECTION)mutex;
|
||||||
|
|
||||||
|
DeleteCriticalSection(critsec);
|
||||||
|
|
||||||
|
free(critsec);
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user