moved threading wrappers into headers
This commit is contained in:
parent
39bd02e79c
commit
023447aef7
|
@ -66,6 +66,8 @@ typedef double f64;
|
||||||
#define Max(a,b) (((a)>(b))?(a):(b))
|
#define Max(a,b) (((a)>(b))?(a):(b))
|
||||||
#define Min(a,b) (((a)<(b))?(a):(b))
|
#define Min(a,b) (((a)<(b))?(a):(b))
|
||||||
|
|
||||||
|
#define FixSize(s) struct{ u8 __size_fixer__[s]; }
|
||||||
|
|
||||||
inline i32 ceil32(f32 v){
|
inline i32 ceil32(f32 v){
|
||||||
return(((v)>0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)+1.f)) ):( ((i32)(v)) ));
|
return(((v)>0)?( (v == (i32)(v))?((i32)(v)):((i32)((v)+1.f)) ):( ((i32)(v)) ));
|
||||||
}
|
}
|
||||||
|
|
|
@ -327,22 +327,6 @@ build(u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, c
|
||||||
# error gcc options not set for this platform
|
# error gcc options not set for this platform
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
internal i32
|
|
||||||
get_freetype_include(char *out, u32 max){
|
|
||||||
i32 size = 0;
|
|
||||||
#if defined(IS_LINUX)
|
|
||||||
char freetype_include[512];
|
|
||||||
FILE *file = popen("pkg-config --cflags freetype2", "r");
|
|
||||||
if (file != 0){
|
|
||||||
fgets(freetype_include, sizeof(freetype_include), file);
|
|
||||||
size = strlen(freetype_include);
|
|
||||||
freetype_include[size-1] = 0;
|
|
||||||
pclose(file);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
return(size);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
build(u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){
|
build(u32 flags, u32 arch, char *code_path, char **code_files, char *out_path, char *out_file, char **defines, char **exports, char **inc_folders){
|
||||||
Build_Line line;
|
Build_Line line;
|
||||||
|
@ -507,6 +491,22 @@ do_buildsuper(char *cdir, char *file, u32 arch){
|
||||||
END_TIME_SECTION("build custom");
|
END_TIME_SECTION("build custom");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
internal i32
|
||||||
|
get_freetype_include(char *out, u32 max){
|
||||||
|
i32 size = 0;
|
||||||
|
#if defined(IS_LINUX)
|
||||||
|
char freetype_include[512];
|
||||||
|
FILE *file = popen("pkg-config --cflags freetype2", "r");
|
||||||
|
if (file != 0){
|
||||||
|
fgets(freetype_include, sizeof(freetype_include), file);
|
||||||
|
size = strlen(freetype_include);
|
||||||
|
freetype_include[size-1] = 0;
|
||||||
|
pclose(file);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return(size);
|
||||||
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
build_main(char *cdir, b32 update_local_theme, u32 flags, u32 arch){
|
build_main(char *cdir, b32 update_local_theme, u32 flags, u32 arch){
|
||||||
char *dir = fm_str(BUILD_DIR);
|
char *dir = fm_str(BUILD_DIR);
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 17.07.2017
|
||||||
|
*
|
||||||
|
* Cross platform threading constants
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
#if !defined(FRED_SHARED_THREADING_CONSTANTS_H)
|
||||||
|
#define FRED_SHARED_THREADING_CONSTANTS_H
|
||||||
|
|
||||||
|
#define CORE_COUNT 8
|
||||||
|
|
||||||
|
#define THREAD_TYPE_SIZE 32
|
||||||
|
#define MUTEX_TYPE_SIZE 40
|
||||||
|
#define CONDITION_VARIABLE_TYPE_SIZE 32
|
||||||
|
#define SEMAPHORE_TYPE_SIZE 32
|
||||||
|
|
||||||
|
#define AssertThreadSizes() \
|
||||||
|
Assert( sizeof(Thread) == THREAD_TYPE_SIZE ); \
|
||||||
|
Assert( sizeof(Mutex) == MUTEX_TYPE_SIZE ); \
|
||||||
|
Assert(sizeof(Condition_Variable) == CONDITION_VARIABLE_TYPE_SIZE); \
|
||||||
|
Assert( sizeof(Semaphore) == SEMAPHORE_TYPE_SIZE )
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
|
@ -9,10 +9,6 @@
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
#if !defined(CORE_COUNT)
|
|
||||||
#define CORE_COUNT 8
|
|
||||||
#endif
|
|
||||||
|
|
||||||
enum CV_ID{
|
enum CV_ID{
|
||||||
CANCEL_CV0,
|
CANCEL_CV0,
|
||||||
CANCEL_CV1,
|
CANCEL_CV1,
|
||||||
|
@ -374,6 +370,8 @@ INTERNAL_Sys_Get_Thread_States_Sig(system_internal_get_thread_states){
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
system_init_threaded_work_system(){
|
system_init_threaded_work_system(){
|
||||||
|
AssertThreadSizes();
|
||||||
|
|
||||||
u32 core_count = CORE_COUNT;
|
u32 core_count = CORE_COUNT;
|
||||||
i32 thread_system_memory_size = core_count*(sizeof(Thread_Context) + sizeof(Thread_Memory));
|
i32 thread_system_memory_size = core_count*(sizeof(Thread_Context) + sizeof(Thread_Memory));
|
||||||
void *thread_system_memory = system_memory_allocate(thread_system_memory_size);
|
void *thread_system_memory = system_memory_allocate(thread_system_memory_size);
|
||||||
|
|
|
@ -76,6 +76,9 @@
|
||||||
#include <linux/fs.h>
|
#include <linux/fs.h>
|
||||||
#include <linux/input.h>
|
#include <linux/input.h>
|
||||||
|
|
||||||
|
#include "4ed_shared_thread_constants.h"
|
||||||
|
#include "linux_threading_wrapper.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Linux macros
|
// Linux macros
|
||||||
//
|
//
|
||||||
|
@ -234,77 +237,6 @@ system_schedule_step(){
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
#define PLAT_THREAD_SIG(n) void* n(void *ptr)
|
|
||||||
typedef PLAT_THREAD_SIG(Thread_Function);
|
|
||||||
|
|
||||||
struct Thread{
|
|
||||||
pthread_t t;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Mutex{
|
|
||||||
pthread_mutex_t crit;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Condition_Variable{
|
|
||||||
pthread_cond_t cv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Semaphore{
|
|
||||||
sem_t s;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_and_launch_thread(Thread *t, Thread_Function *proc, void *ptr){
|
|
||||||
pthread_create(&t->t, 0, proc, ptr);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_lock(Mutex *m){
|
|
||||||
pthread_mutex_init(&m->crit, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_acquire_lock(Mutex *m){
|
|
||||||
pthread_mutex_lock(&m->crit);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_release_lock(Mutex *m){
|
|
||||||
pthread_mutex_unlock(&m->crit);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_cv(Condition_Variable *cv){
|
|
||||||
pthread_cond_init(&cv->cv, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_wait_cv(Condition_Variable *cv, Mutex *m){
|
|
||||||
pthread_cond_wait(&cv->cv, &m->crit);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_signal_cv(Condition_Variable *cv, Mutex *m){
|
|
||||||
pthread_cond_signal(&cv->cv);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_semaphore(Semaphore *s, u32 count){
|
|
||||||
sem_init(&s->s, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_wait_on_semaphore(Semaphore *s){
|
|
||||||
sem_wait(&s->s);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_release_semaphore(Semaphore *s){
|
|
||||||
sem_post(&s->s);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
internal
|
internal
|
||||||
Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
|
Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
|
||||||
linuxvars.hide_cursor = !show;
|
linuxvars.hide_cursor = !show;
|
||||||
|
@ -314,7 +246,7 @@ Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
|
||||||
internal
|
internal
|
||||||
Sys_Toggle_Fullscreen_Sig(system_toggle_fullscreen){
|
Sys_Toggle_Fullscreen_Sig(system_toggle_fullscreen){
|
||||||
b32 success = true;
|
b32 success = true;
|
||||||
LinuxToggleFullscreen(linuxvars.XDisplay, linuxvars.XWindow);
|
LinuxSetWMState(linuxvars.XDisplay, linuxvars.XWindow, linuxvars.atom__NET_WM_STATE_FULLSCREEN, 0, 2);
|
||||||
return(success);
|
return(success);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1146,12 +1078,6 @@ LinuxMaximizeWindow(Display* d, Window w, b32 maximize)
|
||||||
LinuxSetWMState(d, w, linuxvars.atom__NET_WM_STATE_MAXIMIZED_HORZ, linuxvars.atom__NET_WM_STATE_MAXIMIZED_VERT, maximize != 0);
|
LinuxSetWMState(d, w, linuxvars.atom__NET_WM_STATE_MAXIMIZED_HORZ, linuxvars.atom__NET_WM_STATE_MAXIMIZED_VERT, maximize != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
|
||||||
LinuxToggleFullscreen(Display* d, Window w)
|
|
||||||
{
|
|
||||||
LinuxSetWMState(d, w, linuxvars.atom__NET_WM_STATE_FULLSCREEN, 0, 2);
|
|
||||||
}
|
|
||||||
|
|
||||||
#include "linux_icon.h"
|
#include "linux_icon.h"
|
||||||
internal void
|
internal void
|
||||||
LinuxSetIcon(Display* d, Window w)
|
LinuxSetIcon(Display* d, Window w)
|
||||||
|
@ -1585,7 +1511,7 @@ LinuxX11WindowInit(int argc, char** argv, int* window_width, int* window_height)
|
||||||
LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1);
|
LinuxMaximizeWindow(linuxvars.XDisplay, linuxvars.XWindow, 1);
|
||||||
}
|
}
|
||||||
else if (linuxvars.settings.fullscreen_window){
|
else if (linuxvars.settings.fullscreen_window){
|
||||||
LinuxToggleFullscreen(linuxvars.XDisplay, linuxvars.XWindow);
|
system_toggle_fullscreen();
|
||||||
}
|
}
|
||||||
|
|
||||||
XSync(linuxvars.XDisplay, False);
|
XSync(linuxvars.XDisplay, False);
|
||||||
|
|
|
@ -0,0 +1,94 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 17.07.2017
|
||||||
|
*
|
||||||
|
* Linux threading wrapper
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TODO(allen): Can this just be placed in UNIX? If so do that.
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
#if !defined(LINUX_THREADING_WRAPPER)
|
||||||
|
#define LINUX_THREADING_WRAPPER
|
||||||
|
|
||||||
|
#define PLAT_THREAD_SIG(n) void* n(void *ptr)
|
||||||
|
typedef PLAT_THREAD_SIG(Thread_Function);
|
||||||
|
|
||||||
|
union Thread{
|
||||||
|
pthread_t t;
|
||||||
|
FixSize(THREAD_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
union Mutex{
|
||||||
|
pthread_mutex_t crit;
|
||||||
|
FixSize(MUTEX_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
union Condition_Variable{
|
||||||
|
pthread_cond_t cv;
|
||||||
|
FixSize(CONDITION_VARIABLE_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
union Semaphore{
|
||||||
|
sem_t s;
|
||||||
|
FixSize(SEMAPHORE_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_and_launch_thread(Thread *t, Thread_Function *proc, void *ptr){
|
||||||
|
pthread_create(&t->t, 0, proc, ptr);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_lock(Mutex *m){
|
||||||
|
pthread_mutex_init(&m->crit, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_acquire_lock(Mutex *m){
|
||||||
|
pthread_mutex_lock(&m->crit);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_release_lock(Mutex *m){
|
||||||
|
pthread_mutex_unlock(&m->crit);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_cv(Condition_Variable *cv){
|
||||||
|
pthread_cond_init(&cv->cv, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_wait_cv(Condition_Variable *cv, Mutex *m){
|
||||||
|
pthread_cond_wait(&cv->cv, &m->crit);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_signal_cv(Condition_Variable *cv, Mutex *m){
|
||||||
|
pthread_cond_signal(&cv->cv);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_semaphore(Semaphore *s, u32 count){
|
||||||
|
sem_init(&s->s, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_wait_on_semaphore(Semaphore *s){
|
||||||
|
sem_wait(&s->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_release_semaphore(Semaphore *s){
|
||||||
|
sem_post(&s->s);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
|
@ -80,6 +80,9 @@
|
||||||
#include "4ed_font_interface_to_os.h"
|
#include "4ed_font_interface_to_os.h"
|
||||||
#include "4ed_system_shared.h"
|
#include "4ed_system_shared.h"
|
||||||
|
|
||||||
|
#include "4ed_shared_thread_constants.h"
|
||||||
|
#include "win32_threading_wrapper.h"
|
||||||
|
|
||||||
//
|
//
|
||||||
// Win32_Vars structs
|
// Win32_Vars structs
|
||||||
//
|
//
|
||||||
|
@ -194,79 +197,6 @@ system_schedule_step(){
|
||||||
PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0);
|
PostMessage(win32vars.window_handle, WM_4coder_ANIMATE, 0, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
#define PLAT_THREAD_SIG(n) DWORD CALL_CONVENTION n(LPVOID ptr)
|
|
||||||
typedef PLAT_THREAD_SIG(Thread_Function);
|
|
||||||
|
|
||||||
struct Thread{
|
|
||||||
HANDLE t;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Mutex{
|
|
||||||
CRITICAL_SECTION crit;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Condition_Variable{
|
|
||||||
CONDITION_VARIABLE cv;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Semaphore{
|
|
||||||
HANDLE s;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_and_launch_thread(Thread *t, Thread_Function *proc, void *ptr){
|
|
||||||
t->t = CreateThread(0, 0, proc, ptr, 0, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_lock(Mutex *m){
|
|
||||||
InitializeCriticalSection(&m->crit);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_acquire_lock(Mutex *m){
|
|
||||||
EnterCriticalSection(&m->crit);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_release_lock(Mutex *m){
|
|
||||||
LeaveCriticalSection(&m->crit);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_cv(Condition_Variable *cv){
|
|
||||||
InitializeConditionVariable(&cv->cv);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_wait_cv(Condition_Variable *cv, Mutex *lock){
|
|
||||||
SleepConditionVariableCS(&cv->cv, &lock->crit, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_signal_cv(Condition_Variable *cv, Mutex *lock){
|
|
||||||
WakeConditionVariable(&cv->cv);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_init_semaphore(Semaphore *s, u32 max){
|
|
||||||
s->s = CreateSemaphore(0, 0, max, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_wait_on_semaphore(Semaphore *s){
|
|
||||||
WaitForSingleObject(s->s, INFINITE);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
system_release_semaphore(Semaphore *s){
|
|
||||||
ReleaseSemaphore(s->s, 1, 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
//
|
//
|
||||||
// 4ed path
|
// 4ed path
|
||||||
//
|
//
|
||||||
|
|
|
@ -0,0 +1,92 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 17.07.2017
|
||||||
|
*
|
||||||
|
* Win32 threading wrapper
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
#if !defined(WIN32_THREADING_WRAPPER)
|
||||||
|
#define WIN32_THREADING_WRAPPER
|
||||||
|
|
||||||
|
#define PLAT_THREAD_SIG(n) DWORD CALL_CONVENTION n(LPVOID ptr)
|
||||||
|
typedef PLAT_THREAD_SIG(Thread_Function);
|
||||||
|
|
||||||
|
union Thread{
|
||||||
|
HANDLE t;
|
||||||
|
FixSize(THREAD_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
union Mutex{
|
||||||
|
CRITICAL_SECTION crit;
|
||||||
|
FixSize(MUTEX_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
union Condition_Variable{
|
||||||
|
CONDITION_VARIABLE cv;
|
||||||
|
FixSize(CONDITION_VARIABLE_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
union Semaphore{
|
||||||
|
HANDLE s;
|
||||||
|
FixSize(SEMAPHORE_TYPE_SIZE);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_and_launch_thread(Thread *t, Thread_Function *proc, void *ptr){
|
||||||
|
t->t = CreateThread(0, 0, proc, ptr, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_lock(Mutex *m){
|
||||||
|
InitializeCriticalSection(&m->crit);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_acquire_lock(Mutex *m){
|
||||||
|
EnterCriticalSection(&m->crit);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_release_lock(Mutex *m){
|
||||||
|
LeaveCriticalSection(&m->crit);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_cv(Condition_Variable *cv){
|
||||||
|
InitializeConditionVariable(&cv->cv);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_wait_cv(Condition_Variable *cv, Mutex *lock){
|
||||||
|
SleepConditionVariableCS(&cv->cv, &lock->crit, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_signal_cv(Condition_Variable *cv, Mutex *lock){
|
||||||
|
WakeConditionVariable(&cv->cv);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_init_semaphore(Semaphore *s, u32 max){
|
||||||
|
s->s = CreateSemaphore(0, 0, max, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_wait_on_semaphore(Semaphore *s){
|
||||||
|
WaitForSingleObject(s->s, INFINITE);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
system_release_semaphore(Semaphore *s){
|
||||||
|
ReleaseSemaphore(s->s, 1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
Loading…
Reference in New Issue