From 76424950e373d3b04ac3dd13019151bfba3e8423 Mon Sep 17 00:00:00 2001 From: sumuel Date: Mon, 17 Aug 2026 20:44:55 +0000 Subject: Add the files --- src/common/thread.h | 115 ++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 src/common/thread.h (limited to 'src/common/thread.h') 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 + #include + #include + #include + #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 + #include + #if FF_HAVE_PTHREAD_NP + #include + #endif +typedef pthread_t FFThreadType; + #if __APPLE__ + #include + #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 -- cgit v1.2.3