diff options
| author | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
|---|---|---|
| committer | sumuel <samuel@yakubos.org> | 2026-08-17 20:44:55 +0000 |
| commit | 76424950e373d3b04ac3dd13019151bfba3e8423 (patch) | |
| tree | 4c3cfdbda039e592b9186be3e28f8d7cfd439e8a /src/common/thread.h | |
Add the files
Diffstat (limited to 'src/common/thread.h')
| -rw-r--r-- | src/common/thread.h | 115 |
1 files changed, 115 insertions, 0 deletions
diff --git a/src/common/thread.h b/src/common/thread.h new file mode 100644 index 0000000..64d8478 --- /dev/null +++ b/src/common/thread.h @@ -0,0 +1,115 @@ +#pragma once + +#include "fastfetch.h" + +#ifdef FF_HAVE_THREADS + #if defined(_WIN32) + #include <winternl.h> + #include <synchapi.h> + #include <process.h> + #include <processthreadsapi.h> + #define FF_THREAD_MUTEX_INITIALIZER SRWLOCK_INIT +typedef SRWLOCK FFThreadMutex; +typedef HANDLE FFThreadType; +static inline void ffThreadMutexLock(FFThreadMutex* mutex) { + AcquireSRWLockExclusive(mutex); +} +static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { + ReleaseSRWLockExclusive(mutex); +} +static inline FFThreadType ffThreadCreate(unsigned(__stdcall* func)(void*), void* data) { + return (FFThreadType) _beginthreadex(NULL, 0, func, data, 0, NULL); +} + #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) \ + static __stdcall unsigned fn##ThreadMain(void* data) { \ + fn((paramType) data); \ + return 0; \ + } + #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) \ + static __stdcall unsigned fn##ThreadMain() { \ + fn(); \ + return 0; \ + } +static inline void ffThreadDetach(FFThreadType thread) { + NtClose(thread); +} +static inline bool ffThreadJoin(FFThreadType thread, uint32_t timeout) { + if (NtWaitForSingleObject(thread, FALSE, timeout == 0 ? NULL : &(LARGE_INTEGER) { .QuadPart = (int64_t) timeout * -10000 }) != STATUS_WAIT_0) { + TerminateThread(thread, (DWORD) -1); + NtClose(thread); + return false; + } + NtClose(thread); + return true; +} + #else + #include <pthread.h> + #include <signal.h> + #if FF_HAVE_PTHREAD_NP + #include <pthread_np.h> + #endif +typedef pthread_t FFThreadType; + #if __APPLE__ + #include <os/lock.h> + #define FF_THREAD_MUTEX_INITIALIZER OS_UNFAIR_LOCK_INIT +typedef os_unfair_lock FFThreadMutex; +static inline void ffThreadMutexLock(os_unfair_lock* mutex) { + os_unfair_lock_lock(mutex); +} +static inline void ffThreadMutexUnlock(os_unfair_lock* mutex) { + os_unfair_lock_unlock(mutex); +} + #else + #define FF_THREAD_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER +typedef pthread_mutex_t FFThreadMutex; +static inline void ffThreadMutexLock(FFThreadMutex* mutex) { + pthread_mutex_lock(mutex); +} +static inline void ffThreadMutexUnlock(FFThreadMutex* mutex) { + pthread_mutex_unlock(mutex); +} + #endif +static inline FFThreadType ffThreadCreate(void* (*func)(void*), void* data) { + FFThreadType newThread = 0; + pthread_create(&newThread, NULL, func, data); + return newThread; +} + #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) \ + static void* fn##ThreadMain(void* data) { \ + fn((paramType) data); \ + return NULL; \ + } + #define FF_THREAD_ENTRY_DECL_WRAPPER_NOPARAM(fn) \ + static void* fn##ThreadMain() { \ + fn(); \ + return NULL; \ + } +static inline void ffThreadDetach(FFThreadType thread) { + pthread_detach(thread); +} +static inline bool ffThreadJoin(FFThreadType thread, FF_A_UNUSED uint32_t timeout) { + #if HAVE_TIMEDJOIN_NP + if (timeout > 0) { + struct timespec ts; + if (clock_gettime(CLOCK_REALTIME, &ts) == 0) { + ts.tv_sec += timeout / 1000; + ts.tv_nsec += (timeout % 1000) * 1000000; + if (pthread_timedjoin_np(thread, NULL, &ts) != 0) { + pthread_kill(thread, SIGTERM); + return false; + } + return true; + } + } + #endif + pthread_join(thread, NULL); + return true; +} + #endif +#else // FF_HAVE_THREADS + #define FF_THREAD_MUTEX_INITIALIZER 0 +typedef char FFThreadMutex; +static inline void ffThreadMutexLock(FF_A_UNUSED FFThreadMutex* mutex) {} +static inline void ffThreadMutexUnlock(FF_A_UNUSED FFThreadMutex* mutex) {} + #define FF_THREAD_ENTRY_DECL_WRAPPER(fn, paramType) +#endif // FF_HAVE_THREADS |