added mutex support on linux

This commit is contained in:
alessandrobason 2021-10-27 12:32:22 +01:00
parent bb6f3f967c
commit 4cc2159793
3 changed files with 840 additions and 814 deletions

View file

@ -1,172 +1,198 @@
#include "cthreads.h" #include "cthreads.h"
typedef struct { typedef struct {
cthread_func_t func; cthread_func_t func;
void *arg; void *arg;
} _thr_internal_t; } _thr_internal_t;
#ifdef _WIN32 #ifdef _WIN32
#define VC_EXTRALEAN #define VC_EXTRALEAN
#include <windows.h> #include <windows.h>
// == THREAD =========================================== // == THREAD ===========================================
static DWORD _thrFuncInternal(void *arg) { static DWORD _thrFuncInternal(void *arg) {
_thr_internal_t *params = (_thr_internal_t *)arg; _thr_internal_t *params = (_thr_internal_t *)arg;
cthread_func_t func = params->func; cthread_func_t func = params->func;
void *argument = params->arg; void *argument = params->arg;
free(params); free(params);
return (DWORD)func(argument); return (DWORD)func(argument);
} }
cthread_t thrCreate(cthread_func_t func, void *arg) { cthread_t thrCreate(cthread_func_t func, void *arg) {
HANDLE thread = INVALID_HANDLE_VALUE; HANDLE thread = INVALID_HANDLE_VALUE;
_thr_internal_t *params = malloc(sizeof(_thr_internal_t)); _thr_internal_t *params = malloc(sizeof(_thr_internal_t));
if(params) { if(params) {
params->func = func; params->func = func;
params->arg = arg; params->arg = arg;
thread = CreateThread(NULL, 0, _thrFuncInternal, params, 0, NULL); thread = CreateThread(NULL, 0, _thrFuncInternal, params, 0, NULL);
} }
return (cthread_t)thread; return (cthread_t)thread;
} }
bool thrValid(cthread_t ctx) { bool thrValid(cthread_t ctx) {
return (HANDLE)ctx != INVALID_HANDLE_VALUE; return (HANDLE)ctx != INVALID_HANDLE_VALUE;
} }
bool thrDetach(cthread_t ctx) { bool thrDetach(cthread_t ctx) {
return CloseHandle((HANDLE)ctx); return CloseHandle((HANDLE)ctx);
} }
cthread_t thrCurrent(void) { cthread_t thrCurrent(void) {
return (cthread_t)GetCurrentThread(); return (cthread_t)GetCurrentThread();
} }
int thrCurrentId(void) { int thrCurrentId(void) {
return GetCurrentThreadId(); return GetCurrentThreadId();
} }
int thrGetId(cthread_t ctx) { int thrGetId(cthread_t ctx) {
return GetThreadId((HANDLE)ctx); return GetThreadId((HANDLE)ctx);
} }
void thrExit(int code) { void thrExit(int code) {
ExitThread(code); ExitThread(code);
} }
bool thrJoin(cthread_t ctx, int *code) { bool thrJoin(cthread_t ctx, int *code) {
if(!ctx) return false; if(!ctx) return false;
int return_code = WaitForSingleObject((HANDLE)ctx, INFINITE); int return_code = WaitForSingleObject((HANDLE)ctx, INFINITE);
if(code) *code = return_code; if(code) *code = return_code;
BOOL success = CloseHandle((HANDLE)ctx); BOOL success = CloseHandle((HANDLE)ctx);
return return_code != WAIT_FAILED && success; return return_code != WAIT_FAILED && success;
} }
// == MUTEX ============================================ // == MUTEX ============================================
cmutex_t mtxInit(void) { cmutex_t mtxInit(void) {
CRITICAL_SECTION *crit_sec = malloc(sizeof(CRITICAL_SECTION)); CRITICAL_SECTION *crit_sec = malloc(sizeof(CRITICAL_SECTION));
if(crit_sec) { if(crit_sec) {
InitializeCriticalSection(crit_sec); InitializeCriticalSection(crit_sec);
} }
return (cmutex_t)crit_sec; return (cmutex_t)crit_sec;
// return (cmutex_t)CreateMutexW(NULL, false, NULL); }
}
void mtxDestroy(cmutex_t ctx) {
void mtxDestroy(cmutex_t ctx) { DeleteCriticalSection((CRITICAL_SECTION *)ctx);
DeleteCriticalSection((CRITICAL_SECTION *)ctx); }
// CloseHandle((HANDLE)ctx);
} bool mtxValid(cmutex_t ctx) {
return (void *)ctx != NULL;
bool mtxValid(cmutex_t ctx) { }
return (void *)ctx != NULL;
} bool mtxLock(cmutex_t ctx) {
EnterCriticalSection((CRITICAL_SECTION *)ctx);
bool mtxLock(cmutex_t ctx) { return true;
EnterCriticalSection((CRITICAL_SECTION *)ctx); }
return true;
// DWORD result = WaitForSingleObject((HANDLE)ctx, INFINITE); bool mtxTryLock(cmutex_t ctx) {
// // TODO maybe remove abandoned? or return a enum? it'll hurt usability tho return TryEnterCriticalSection((CRITICAL_SECTION *)ctx);
// return result == WAIT_OBJECT_0 || result == WAIT_ABANDONED; }
}
bool mtxUnlock(cmutex_t ctx) {
bool mtxTryLock(cmutex_t ctx) { LeaveCriticalSection((CRITICAL_SECTION *)ctx);
return TryEnterCriticalSection((CRITICAL_SECTION *)ctx); return true;
// int result = mtxTimedLock(ctx, 0); }
// if(result == CMTX_TIMEDOUT) return CMTX_BUSY;
// return result;
} #else
#include <pthread.h>
bool mtxUnlock(cmutex_t ctx) { #include <stdlib.h>
LeaveCriticalSection((CRITICAL_SECTION *)ctx); #include <unistd.h>
return true; #include <sys/syscall.h>
// return ReleaseMutex((HANDLE)ctx); #include <sys/types.h>
}
// == THREAD ===========================================
#else #define INT_TO_VOIDP(a) ((void *)((uintptr_t)(a)))
#include <pthread.h>
#include <stdlib.h> static void *_thrFuncInternal(void *arg) {
#include <unistd.h> _thr_internal_t *params = (_thr_internal_t *)arg;
#include <sys/syscall.h> cthread_func_t func = params->func;
#include <sys/types.h> void *argument = params->arg;
free(params);
#define INT_TO_VOIDP(a) ((void *)((uintptr_t)(a))) return INT_TO_VOIDP(func(argument));
}
static void *_thrFuncInternal(void *arg) {
_thr_internal_t *params = (_thr_internal_t *)arg; cthread_t thrCreate(cthread_func_t func, void *arg) {
cthread_func_t func = params->func; pthread_t handle = (pthread_t)NULL;
void *argument = params->arg;
free(params); _thr_internal_t *params = malloc(sizeof(_thr_internal_t));
return INT_TO_VOIDP(func(argument));
} if(params) {
params->func = func;
cthread_t thrCreate(cthread_func_t func, void *arg) { params->arg = arg;
pthread_t handle = (pthread_t)NULL;
int result = pthread_create(&handle, NULL, _thrFuncInternal, params);
_thr_internal_t *params = malloc(sizeof(_thr_internal_t)); if(result) handle = (pthread_t)NULL;
}
if(params) {
params->func = func; return (cthread_t)handle;
params->arg = arg; }
int result = pthread_create(&handle, NULL, _thrFuncInternal, params); bool thrValid(cthread_t ctx) {
if(result) handle = (pthread_t)NULL; return (void *)ctx != NULL;
} }
return (cthread_t)handle; bool thrDetach(cthread_t ctx) {
} return pthread_detach((pthread_t)ctx) == 0;
}
bool thrValid(cthread_t ctx) {
return (void *)ctx != NULL; cthread_t thrCurrent(void) {
} return (cthread_t)pthread_self();
}
bool thrDetach(cthread_t ctx) {
return pthread_detach((pthread_t)ctx) == 0; int thrCurrentId(void) {
} return (int)pthread_self();
}
cthread_t thrCurrent(void) {
return (cthread_t)pthread_self(); int thrGetId(cthread_t ctx) {
} return (int)ctx;
}
int thrCurrentId(void) {
return (int)pthread_self(); void thrExit(int code) {
} pthread_exit(INT_TO_VOIDP(code));
}
int thrGetId(cthread_t ctx) {
return (int)ctx; bool thrJoin(cthread_t ctx, int *code) {
} void *result = code;
return pthread_join((pthread_t)ctx, &result) != 0;
void thrExit(int code) { }
pthread_exit(INT_TO_VOIDP(code));
} // == MUTEX ============================================
bool thrJoin(cthread_t ctx, int *code) { cmutex_t mtxInit(void) {
void *result = code; pthread_mutex_t *mutex = malloc(sizeof(pthread_mutex_t));
return pthread_join((pthread_t)ctx, &result) != 0;
} if(mutex) {
int res = pthread_mutex_init(mutex, NULL);
if(res != 0) mutex = NULL;
}
return (cmutex_t)mutex;
}
void mtxDestroy(cmutex_t ctx) {
pthread_mutex_destroy((pthread_mutex_t *)ctx);
}
bool mtxValid(cmutex_t ctx) {
return (void *)ctx != NULL;
}
bool mtxLock(cmutex_t ctx) {
return pthread_mutex_lock((pthread_mutex_t *)ctx) == 0;
}
bool mtxTryLock(cmutex_t ctx) {
return pthread_mutex_trylock((pthread_mutex_t *)ctx) == 0;
}
bool mtxUnlock(cmutex_t ctx) {
return pthread_mutex_unlock((pthread_mutex_t *)ctx) == 0;
}
#endif #endif

View file

@ -1,42 +1,42 @@
#pragma once #pragma once
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
#include <stdint.h> #include <stdint.h>
#include <stdbool.h> #include <stdbool.h>
// == THREAD =========================================== // == THREAD ===========================================
typedef uintptr_t cthread_t; typedef uintptr_t cthread_t;
typedef int (*cthread_func_t)(void *); typedef int (*cthread_func_t)(void *);
cthread_t thrCreate(cthread_func_t func, void *arg); cthread_t thrCreate(cthread_func_t func, void *arg);
bool thrValid(cthread_t ctx); bool thrValid(cthread_t ctx);
bool thrDetach(cthread_t ctx); bool thrDetach(cthread_t ctx);
cthread_t thrCurrent(void); cthread_t thrCurrent(void);
int thrCurrentId(void); int thrCurrentId(void);
int thrGetId(cthread_t ctx); int thrGetId(cthread_t ctx);
void thrExit(int code); void thrExit(int code);
bool thrJoin(cthread_t ctx, int *code); bool thrJoin(cthread_t ctx, int *code);
// == MUTEX ============================================ // == MUTEX ============================================
typedef uintptr_t cmutex_t; typedef uintptr_t cmutex_t;
cmutex_t mtxInit(void); cmutex_t mtxInit(void);
void mtxDestroy(cmutex_t ctx); void mtxDestroy(cmutex_t ctx);
bool mtxValid(cmutex_t ctx); bool mtxValid(cmutex_t ctx);
bool mtxLock(cmutex_t ctx); bool mtxLock(cmutex_t ctx);
bool mtxTryLock(cmutex_t ctx); bool mtxTryLock(cmutex_t ctx);
bool mtxUnlock(cmutex_t ctx); bool mtxUnlock(cmutex_t ctx);
#ifdef __cplusplus #ifdef __cplusplus
} // extern "C" } // extern "C"
#endif #endif

1204
vec.h

File diff suppressed because it is too large Load diff