added mutex support on linux
This commit is contained in:
parent
bb6f3f967c
commit
4cc2159793
3 changed files with 840 additions and 814 deletions
368
cthreads.c
368
cthreads.c
|
|
@ -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
|
||||||
82
cthreads.h
82
cthreads.h
|
|
@ -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
|
||||||
Loading…
Add table
Add a link
Reference in a new issue