From b4f674bc0628c300f5a3bb4dc1365ddb629acf39 Mon Sep 17 00:00:00 2001 From: ThePedroo Date: Fri, 26 Jan 2024 18:53:33 -0300 Subject: [PATCH] update(cthreads): update CThreads library This commit updates CThreads library with latest fixes. --- core/cthreads.c | 319 ++++++++++++++++++++++++++---------------------- core/cthreads.h | 137 ++++++++++++--------- 2 files changed, 250 insertions(+), 206 deletions(-) diff --git a/core/cthreads.c b/core/cthreads.c index ff7eea1e..1af2ef70 100644 --- a/core/cthreads.c +++ b/core/cthreads.c @@ -3,191 +3,203 @@ #include "cthreads.h" -#if _WIN32 +#ifdef _WIN32 #include -DWORD WINAPI __cthreads_win_thread_create_wrapper(void *data) { - struct cthreads_args *args = data; - args->func(args->data); +DWORD WINAPI __cthreads_winthreads_function_wrapper(void *data) { + struct cthreads_args *args = data; + args->func(args->data); - return TRUE; + return TRUE; } #else #include #endif int cthreads_thread_create(struct cthreads_thread *thread, struct cthreads_thread_attr *attr, void *(*func)(void *data), void *data, struct cthreads_args *args) { - #ifdef _WIN32 - args->func = func; - args->data = data; - - if (attr) thread->wThread = CreateThread(NULL, attr->stacksize ? attr->stacksize : 0, - __cthreads_win_thread_create_wrapper, args, - attr->dwCreationFlags ? (DWORD)attr->dwCreationFlags : 0, NULL); - else thread->wThread = CreateThread(NULL, 0, __cthreads_win_thread_create_wrapper, args, 0, NULL); - - return thread->wThread ? 0 : 1; - #else - pthread_attr_t pAttr; - - if (attr) { - if (pthread_attr_init(&pAttr)) return 1; - if (attr->detachstate) pthread_attr_setdetachstate(&pAttr, attr->detachstate); - if (attr->guardsize) pthread_attr_setguardsize(&pAttr, attr->guardsize); - #if !defined __ANDROID__ - if (attr->inheritsched) pthread_attr_setinheritsched(&pAttr, attr->inheritsched); - #endif - if (attr->schedpolicy) pthread_attr_setschedpolicy(&pAttr, attr->schedpolicy); - if (attr->scope) pthread_attr_setscope(&pAttr, attr->scope); - if (attr->stack) pthread_attr_setstack(&pAttr, attr->stackaddr, attr->stack); - if (attr->stacksize) pthread_attr_setstacksize(&pAttr, attr->stacksize); - } - - return pthread_create(&thread->pThread, attr ? &pAttr : NULL, func, data); - #endif + #ifdef _WIN32 + args->func = func; + args->data = data; + + if (attr) thread->wThread = CreateThread(NULL, attr->stacksize ? attr->stacksize : 0, + __cthreads_winthreads_function_wrapper, args, + attr->dwCreationFlags ? (DWORD)attr->dwCreationFlags : 0, NULL); + else thread->wThread = CreateThread(NULL, 0, __cthreads_winthreads_function_wrapper, args, 0, NULL); + + return thread->wThread ? 0 : 1; + #else + pthread_attr_t pAttr; + + (void) args; + + if (attr) { + if (pthread_attr_init(&pAttr)) return 1; + if (attr->detachstate) pthread_attr_setdetachstate(&pAttr, attr->detachstate); + if (attr->guardsize) pthread_attr_setguardsize(&pAttr, attr->guardsize); + #if !defined __ANDROID__ + if (attr->inheritsched) pthread_attr_setinheritsched(&pAttr, attr->inheritsched); + #endif + if (attr->schedpolicy) pthread_attr_setschedpolicy(&pAttr, attr->schedpolicy); + if (attr->scope) pthread_attr_setscope(&pAttr, attr->scope); + #if _POSIX_C_SOURCE >= 200112L + if (attr->stack) pthread_attr_setstack(&pAttr, attr->stackaddr, attr->stack); + #endif + if (attr->stacksize) pthread_attr_setstacksize(&pAttr, attr->stacksize); + } + + return pthread_create(&thread->pThread, attr ? &pAttr : NULL, func, data); + #endif } -int cthreads_thread_detach(struct cthreads_thread *thread) { - #ifdef _WIN32 - return CloseHandle(thread->wThread); - #else - return pthread_detach(thread->pThread); - #endif +int cthreads_thread_detach(struct cthreads_thread thread) { + #ifdef _WIN32 + return CloseHandle(thread.wThread); + #else + return pthread_detach(thread.pThread); + #endif } void cthreads_thread_close(void *code) { - #ifdef _WIN32 - #ifdef __WATCOMC__ - ExitThread((DWORD)code); - #else - ExitThread((DWORD)(uintptr_t)code); - #endif + #ifdef _WIN32 + #ifdef __WATCOMC__ + ExitThread((DWORD)code); #else - pthread_exit(code); + ExitThread((DWORD)(uintptr_t)code); #endif + #else + pthread_exit(code); + #endif } int cthreads_mutex_init(struct cthreads_mutex *mutex, struct cthreads_mutex_attr *attr) { - #ifdef _WIN32 - return (attr ? mutex->wMutex = CreateMutex(NULL, attr->bInitialOwner ? TRUE : FALSE, - attr->lpName ? (LPCSTR)attr->lpName : NULL); - : CreateMutex(NULL, FALSE, NULL)) ? 0 : 1; - #else - pthread_mutexattr_t pAttr; - if (attr) { - if (pthread_mutexattr_init(&pAttr)) return 1; - if (attr->pshared) pthread_mutexattr_setpshared(&pAttr, attr->pshared); - if (attr->type) pthread_mutexattr_settype(&pAttr, attr->type); - #if (defined __linux__ || defined __FreeBSD__) && !defined __ANDROID__ - if (attr->robust) pthread_mutexattr_setrobust(&pAttr, attr->robust); - #endif - #if !defined __ANDROID__ - if (attr->protocol) pthread_mutexattr_setprotocol(&pAttr, attr->protocol); - if (attr->prioceiling) pthread_mutexattr_setprioceiling(&pAttr, attr->prioceiling); - #endif - } - - return pthread_mutex_init(&mutex->pMutex, attr ? &pAttr : NULL); - #endif + #ifdef _WIN32 + if (attr) mutex->wMutex = CreateMutex(NULL, attr->bInitialOwner ? TRUE : FALSE, + attr->lpName ? (LPCSTR)attr->lpName : NULL); + else mutex->wMutex = CreateMutex(NULL, FALSE, NULL); + + return mutex->wMutex == NULL ? 1 : 0; + #else + pthread_mutexattr_t pAttr; + if (attr) { + if (pthread_mutexattr_init(&pAttr)) return 1; + if (attr->pshared) pthread_mutexattr_setpshared(&pAttr, attr->pshared); + #if _POSIX_C_SOURCE >= 200809L + if (attr->type) pthread_mutexattr_settype(&pAttr, attr->type); + #endif + #if _POSIX_C_SOURCE >= 200112L + #if (defined __linux__ || defined __FreeBSD__) && !defined __ANDROID__ + if (attr->robust) pthread_mutexattr_setrobust(&pAttr, attr->robust); + #endif + #endif + #if !defined __ANDROID__ + if (attr->protocol) pthread_mutexattr_setprotocol(&pAttr, attr->protocol); + if (attr->prioceiling) pthread_mutexattr_setprioceiling(&pAttr, attr->prioceiling); + #endif + } + + return pthread_mutex_init(&mutex->pMutex, attr ? &pAttr : NULL); + #endif } int cthreads_mutex_lock(struct cthreads_mutex *mutex) { - #ifdef _WIN32 - return WaitForSingleObject(mutex->wMutex, INFINITE) == WAIT_OBJECT_0 ? 0 : 1; // Needs to re-see - #else - return pthread_mutex_lock(&mutex->pMutex); - #endif + #ifdef _WIN32 + return WaitForSingleObject(mutex->wMutex, INFINITE) == WAIT_OBJECT_0 ? 0 : 1; + #else + return pthread_mutex_lock(&mutex->pMutex); + #endif } int cthreads_mutex_trylock(struct cthreads_mutex *mutex) { - #ifdef _WIN32 - return WaitForSingleObject(mutex->wMutex, 0) == WAIT_OBJECT_0 ? 0 : 1; // Needs to re-see - #else - return pthread_mutex_trylock(&mutex->pMutex); - #endif + #ifdef _WIN32 + return WaitForSingleObject(mutex->wMutex, 0) == WAIT_OBJECT_0 ? 0 : 1; + #else + return pthread_mutex_trylock(&mutex->pMutex); + #endif } int cthreads_mutex_unlock(struct cthreads_mutex *mutex) { - #ifdef _WIN32 - return ReleaseMutex(mutex->wMutex) == 0 ? 1 : 0; // Needs to re-see - #else - return pthread_mutex_unlock(&mutex->pMutex); - #endif + #ifdef _WIN32 + return ReleaseMutex(mutex->wMutex) == 0 ? 1 : 0; + #else + return pthread_mutex_unlock(&mutex->pMutex); + #endif } int cthreads_mutex_destroy(struct cthreads_mutex *mutex) { - #ifdef _WIN32 - return CloseHandle(mutex->wMutex) == 0 ? 1 : 0; // Needs to re-see - #else - return pthread_mutex_destroy(&mutex->pMutex); - #endif + #ifdef _WIN32 + return CloseHandle(mutex->wMutex) == 0 ? 1 : 0; + #else + return pthread_mutex_destroy(&mutex->pMutex); + #endif } int cthreads_cond_init(struct cthreads_cond *cond, struct cthreads_cond_attr *attr) { - #ifdef _WIN32 - if (attr) cond->wCond = CreateEvent(NULL, attr->bManualReset ? TRUE : FALSE, - attr->bInitialState ? TRUE : FALSE, - attr->lpName ? (LPTSTR)attr->lpName : NULL); - else cond->wCond = CreateEvent(NULL, FALSE, FALSE, NULL); - - if (cond->wCond == NULL) return 1; - return 0; - #else - pthread_condattr_t pAttr; - if (attr) { - if (pthread_condattr_init(&pAttr) != 0) return 1; - if (attr->pshared) pthread_condattr_setpshared(&pAttr, attr->pshared); - if (attr->clock) pthread_condattr_setclock(&pAttr, attr->clock); - } - - return pthread_cond_init(&cond->pCond, attr ? &pAttr : NULL); - #endif + #ifdef _WIN32 + if (attr) cond->wCond = CreateEvent(NULL, attr->bManualReset ? TRUE : FALSE, + attr->bInitialState ? TRUE : FALSE, + attr->lpName ? (LPTSTR)attr->lpName : NULL); + else cond->wCond = CreateEvent(NULL, FALSE, FALSE, NULL); + + return cond->wCond == NULL ? 1 : 0; + #else + pthread_condattr_t pAttr; + if (attr) { + if (pthread_condattr_init(&pAttr) != 0) return 1; + if (attr->pshared) pthread_condattr_setpshared(&pAttr, attr->pshared); + #if _POSIX_C_SOURCE >= 200112L + if (attr->clock) pthread_condattr_setclock(&pAttr, attr->clock); + #endif + } + + return pthread_cond_init(&cond->pCond, attr ? &pAttr : NULL); + #endif } int cthreads_cond_signal(struct cthreads_cond *cond) { - #ifdef _WIN32 - return SetEvent(cond->wCond) == 0 ? 1 : 0; // Needs to re-see - #else - return pthread_cond_signal(&cond->pCond); - #endif + #ifdef _WIN32 + return SetEvent(cond->wCond) == 0 ? 1 : 0; + #else + return pthread_cond_signal(&cond->pCond); + #endif } int cthreads_cond_broadcast(struct cthreads_cond *cond) { - #ifdef _WIN32 - return SetEvent(cond->wCond) == 0 ? 1 : 0; // Needs to re-see - #else - return pthread_cond_broadcast(&cond->pCond); - #endif + #ifdef _WIN32 + return SetEvent(cond->wCond) == 0 ? 1 : 0; + #else + return pthread_cond_broadcast(&cond->pCond); + #endif } int cthreads_cond_destroy(struct cthreads_cond *cond) { - #ifdef _WIN32 - return CloseHandle(cond->wCond) == 0 ? 1 : 0; // Needs to re-see - #else - return pthread_cond_destroy(&cond->pCond); - #endif + #ifdef _WIN32 + return CloseHandle(cond->wCond) == 0 ? 1 : 0; + #else + return pthread_cond_destroy(&cond->pCond); + #endif } int cthreads_cond_wait(struct cthreads_cond *cond, struct cthreads_mutex *mutex) { - #ifdef _WIN32 - return SleepConditionVariableCS(&cond->wCond, &mutex->wMutex, INFINITE) == 0 ? 1 : 0; - #else - return pthread_cond_wait(&cond->pCond, &mutex->pMutex); - #endif + #ifdef _WIN32 + return SleepConditionVariableCS(&cond->wCond, &mutex->wMutex, INFINITE) == 0 ? 1 : 0; + #else + return pthread_cond_wait(&cond->pCond, &mutex->pMutex); + #endif } int cthreads_join(struct cthreads_thread *thread, void *code) { - #ifdef _WIN32 - if (WaitForSingleObject(thread->wThread, INFINITE) == WAIT_FAILED) return 1; + #ifdef _WIN32 + if (WaitForSingleObject(thread->wThread, INFINITE) == WAIT_FAILED) return 0; - return GetExitCodeThread(thread->wThread, (LPDWORD)&code) == 0 ? 1 : 0; - #else - return pthread_join(thread->pThread, code ? &code : NULL); - #endif + return GetExitCodeThread(thread->wThread, (LPDWORD)&code) == 0 ? 1 : 0; + #else + return pthread_join(thread->pThread, code ? &code : NULL); + #endif } +#if _POSIX_C_SOURCE >= 200112L || _WIN32 int cthreads_rwlock_init(struct cthreads_rwlock *rwlock) { #ifdef _WIN32 - return (rwlock->wRWLock = CreateMutex(NULL, FALSE, NULL)) == NULL ? 1 : 0; // Needs to re-see + return (rwlock->wRWLock = CreateMutex(NULL, FALSE, NULL)) == NULL ? 1 : 0; #else return pthread_rwlock_init(&rwlock->pRWLock, NULL); #endif @@ -195,7 +207,7 @@ int cthreads_rwlock_init(struct cthreads_rwlock *rwlock) { int cthreads_rwlock_rdlock(struct cthreads_rwlock *rwlock) { #ifdef _WIN32 - return WaitForSingleObject(rwlock->wRWLock, INFINITE) == WAIT_FAILED ? 1 : 0; // Needs to re-see + return WaitForSingleObject(rwlock->wRWLock, INFINITE) == WAIT_FAILED ? 1 : 0; #else return pthread_rwlock_rdlock(&rwlock->pRWLock); #endif @@ -203,7 +215,7 @@ int cthreads_rwlock_rdlock(struct cthreads_rwlock *rwlock) { int cthreads_rwlock_unlock(struct cthreads_rwlock *rwlock) { #ifdef _WIN32 - return ReleaseMutex(rwlock->wRWLock) == 0 ? 1 : 0; // Needs to re-see + return ReleaseMutex(rwlock->wRWLock) == 0 ? 1 : 0; #else return pthread_rwlock_unlock(&rwlock->pRWLock); #endif @@ -211,7 +223,7 @@ int cthreads_rwlock_unlock(struct cthreads_rwlock *rwlock) { int cthreads_rwlock_wrlock(struct cthreads_rwlock *rwlock) { #ifdef _WIN32 - return WaitForSingleObject(rwlock->wRWLock, INFINITE) == WAIT_FAILED ? 1 : 0; // Needs to re-see + return WaitForSingleObject(rwlock->wRWLock, INFINITE) == WAIT_FAILED ? 1 : 0; #else return pthread_rwlock_wrlock(&rwlock->pRWLock); #endif @@ -219,28 +231,37 @@ int cthreads_rwlock_wrlock(struct cthreads_rwlock *rwlock) { int cthreads_rwlock_destroy(struct cthreads_rwlock *rwlock) { #ifdef _WIN32 - return CloseHandle(rwlock->wRWLock) == 0 ? 1 : 0; // Needs to re-see + return CloseHandle(rwlock->wRWLock) == 0 ? 1 : 0; #else return pthread_rwlock_destroy(&rwlock->pRWLock); #endif } +#endif int cthreads_equal(struct cthreads_thread thread1, struct cthreads_thread thread2) { - #ifdef _WIN32 - return GetThreadId(thread1.wThread) == GetThreadId(thread2.wThread); - #else - return pthread_equal(thread1.pThread, thread2.pThread); - #endif + #ifdef _WIN32 + return thread1.wThread == thread2.wThread; + #else + return pthread_equal(thread1.pThread, thread2.pThread); + #endif } -struct cthreads_thread cthreads_self() { - struct cthreads_thread t; +struct cthreads_thread cthreads_self(void) { + struct cthreads_thread t; - #ifdef _WIN32 - t.wThread = GetCurrentThread(); - #else - t.pThread = pthread_self(); - #endif + #ifdef _WIN32 + t.wThread = GetCurrentThread(); + #else + t.pThread = pthread_self(); + #endif + + return t; +} - return t; +unsigned long cthreads_thread_id(struct cthreads_thread thread) { + #ifdef _WIN32 + return GetThreadId(thread.wThread); + #else + return (unsigned long)thread.pThread; + #endif } diff --git a/core/cthreads.h b/core/cthreads.h index 514e9db3..784c0384 100644 --- a/core/cthreads.h +++ b/core/cthreads.h @@ -7,85 +7,95 @@ struct cthreads_args { }; #if _WIN32 - #include + #include #else - #include + #include #endif struct cthreads_thread { - #ifdef _WIN32 - HANDLE wThread; - #else - pthread_t pThread; - #endif + #ifdef _WIN32 + HANDLE wThread; + #else + pthread_t pThread; + #endif }; struct cthreads_thread_attr { - size_t stacksize; - #ifdef _WIN32 - int dwCreationFlags; - #else - void *stackaddr; - int detachstate; - size_t guardsize; - int inheritsched; - int schedpolicy; - int scope; - size_t stack; + size_t stacksize; + #ifdef _WIN32 + int dwCreationFlags; + #else + void *stackaddr; + int detachstate; + size_t guardsize; + int inheritsched; + int schedpolicy; + int scope; + #if _POSIX_C_SOURCE >= 200112L + size_t stack; #endif + #endif }; struct cthreads_mutex { - #ifdef _WIN32 - HANDLE wMutex; - #else - pthread_mutex_t pMutex; - #endif + #ifdef _WIN32 + HANDLE wMutex; + #else + pthread_mutex_t pMutex; + #endif }; struct cthreads_mutex_attr { - #ifdef _WIN32 - int bInitialOwner; - char *lpName; - #else - int pshared; - int type; - #if (defined __linux__ || defined __FreeBSD__) && !defined __ANDROID__ - int robust; - #endif - #if !defined __ANDROID__ - int protocol; - int prioceiling; - #endif + #ifdef _WIN32 + int bInitialOwner; + char *lpName; + #else + int pshared; + #if _POSIX_C_SOURCE >= 200809L + int type; + #endif + #if _POSIX_C_SOURCE >= 200112L + #if (defined __linux__ || defined __FreeBSD__) && !defined __ANDROID__ + int robust; + #endif #endif + #ifndef __ANDROID__ + int protocol; + int prioceiling; + #endif + #endif }; struct cthreads_cond { - #ifdef _WIN32 - HANDLE wCond; - #else - pthread_cond_t pCond; - #endif + #ifdef _WIN32 + HANDLE wCond; + #else + pthread_cond_t pCond; + #endif }; struct cthreads_cond_attr { - #ifdef _WIN32 - int bManualReset; - int bInitialState; - char *lpName; - #else - int pshared; - int clock; + #ifdef _WIN32 + int bManualReset; + int bInitialState; + char *lpName; + #else + int pshared; + #if _POSIX_C_SOURCE >= 200112L + int clock; #endif + #endif }; +#if _POSIX_C_SOURCE >= 200112L || _WIN32 struct cthreads_rwlock { - #ifdef _WIN32 - HANDLE wRWLock; - #else - pthread_rwlock_t pRWLock; - #endif + #ifdef _WIN32 + HANDLE wRWLock; + #else + pthread_rwlock_t pRWLock; + #endif }; +#endif /** * Creates a new thread. @@ -108,10 +118,10 @@ int cthreads_thread_create(struct cthreads_thread *thread, struct cthreads_threa * - pthread: pthread_detach * - windows threads: CloseHandle * - * @param thread Pointer to the thread structure to be detached. + * @param thread Thread structure to be detached. * @return 0 on success, non-zero error code on failure. */ -int cthreads_thread_detach(struct cthreads_thread *thread); +int cthreads_thread_detach(struct cthreads_thread thread); /** * Closes a thread. @@ -240,7 +250,7 @@ int cthreads_cond_wait(struct cthreads_cond *cond, struct cthreads_mutex *mutex) * Joins a thread. * * - pthread: pthread_join - * - windows threads: WaitForSingleObject + * - windows threads: WaitForSingleObject & GetExitCodeThread * * @param thread Pointer to the thread structure to be joined. * @param code Pointer to store the exit code of the joined thread. @@ -248,6 +258,7 @@ int cthreads_cond_wait(struct cthreads_cond *cond, struct cthreads_mutex *mutex) */ int cthreads_join(struct cthreads_thread *thread, void *code); +#if _POSIX_C_SOURCE >= 200112L || _WIN32 /** * Initializes a read-write lock. * @@ -302,6 +313,7 @@ int cthreads_rwlock_wrlock(struct cthreads_rwlock *rwlock); * @return 0 on success, non-zero error code on failure. */ int cthreads_rwlock_destroy(struct cthreads_rwlock *rwlock); +#endif /** * Compares two thread structures for equality. @@ -323,6 +335,17 @@ int cthreads_equal(struct cthreads_thread thread1, struct cthreads_thread thread * * @return Thread identifier of the current thread. */ -struct cthreads_thread cthreads_self(); +struct cthreads_thread cthreads_self(void); + +/** + * Retrieves the thread identifier of the specified thread. + * + * - pthread: pthread_self + * - windows threads: GetCurrentThreadId + * + * @param thread Thread structure to retrieve the identifier from. + * @return Thread identifier of the specified thread. +*/ +unsigned long cthreads_thread_id(struct cthreads_thread thread); #endif /* CTHREADS_H */