#ifndef _TTHERAD_H_ #define _TTHREAD_H_ #include "sysenv.h" #include #if _OS_WIN //#include //#include //#include //#define INFINITE 0xFFFFFFFF // Infinite timeout //#define WAIT_FAILED ((DWORD)0xFFFFFFFF) //#include #include typedef DWORD TID; typedef CRITICAL_SECTION MUTEX; typedef CONDITION_VARIABLE COND; #elif _OS_LINUX #include typedef pthread_t TID; typedef pthread_mutex_t MUTEX; typedef pthread_cond_t COND; #else #error "Not Supported Operator System" #endif #ifdef __cplusplus extern "C" { #endif enum { ERR_THREAD_SUCCESS, ERR_THREAD_CREATE, ERR_THREAD_JOIN, ERR_THREAD_WIN_CLOSE_HANDLE, //ERR_THREAD_WIN_OPEN_THREAD, ERR_THREAD_MUTEX_INIT, ERR_THREAD_MUTEX_DESTROY, ERR_THREAD_MUTEX_LOCK, ERR_THREAD_MUTEX_UNLOCK, ERR_THREAD_COND_INIT, ERR_THREAD_COND_DESTROY, ERR_THREAD_COND_SINGAL, ERR_THREAD_COND_BROADCAST, ERR_THREAD_COND_WAIT, ERR_THREAD_COND_TIMEDWAIT, ERR_THREAD_ENUM_END }; static inline int thread_create(TID* tid, void(*start_routine)(void*), void* arg); static inline void thread_exit(void); static inline int thread_join(TID tid); static inline TID thread_self(void); static inline int thread_mutex_init(MUTEX* mutex); static inline int thread_mutex_destroy(MUTEX* mutex); static inline int thread_mutex_lock(MUTEX* mutex); static inline int thread_mutex_unlock(MUTEX* mutex); static inline int thread_cond_init(COND* cond); static inline int thread_cond_destroy(COND* cond); static inline int thread_cond_singal(COND* cond); static inline int thread_cond_broadcast(COND* cond); static inline int thread_cond_wait(COND* cond, MUTEX* mutex); static inline int thread_cond_timedwait(COND* cond, MUTEX* mutex); static inline tprintf(MUTEX* mutex, const char* format, ...); static inline tfprintf(MUTEX* mutex, FILE* const stream, const char* format, ...); static inline tsprintf(MUTEX* mutex, char* const buffer, const char* format, ...); static inline tsnprintf(MUTEX* mutex, char* const buffer, const size_t buffer_count, const char* format, ...); static inline tvprintf(MUTEX* mutex, const char* format, va_list arglist); static inline tvfprintf(MUTEX* mutex, FILE* const stream, const char* format, va_list arglist); static inline tvsprintf(MUTEX* mutex, char* const buffer, const char* format, va_list arglist); static inline tvsnprintf(MUTEX* mutex, char* const buffer, const size_t buffer_count, const char* format, va_list arglist); static inline int thread_create(TID* tid, void(*start_routine)(void*), void* arg) { #if _OS_WIN HANDLE h = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)start_routine, arg, 0, (LPDWORD)tid); if (h == NULL) { return ERR_THREAD_CREATE; } if (!CloseHandle(h)) { return ERR_THREAD_WIN_CLOSE_HANDLE; } #elif _OS_LINUX if (pthread_create(tid, NULL, start_routine, arg) != 0) { return ERR_THREAD_CREATE; } #endif return ERR_THREAD_SUCCESS; } static inline void thread_exit(void) { #if _OS_WIN ThreadExit(0); #elif _OS_LINUX pthread_exit(NULL); #endif } static inline int thread_join(TID tid) { #if _OS_WIN HANDLE h = OpenThread(THREAD_ALL_ACCESS, 0, tid); //if (h == NULL) { return ERR_THREAD_WIN_OPEN_THREAD; } if (WaitForSingleObject(h, INFINITE) == WAIT_FAILED) { return ERR_THREAD_JOIN; } if (!CloseHandle(h)) { return ERR_THREAD_WIN_CLOSE_HANDLE; } #elif _OS_LINUX if (pthread_join(tid, NULL) != 0) { return ERR_THREAD_JOIN; } #endif return ERR_THREAD_SUCCESS; } static inline TID thread_self(void) { #if _OS_WIN return GetCurrentThreadId(); #elif _OS_LINUX return pthread_self(void); #endif } // mutex part static inline int thread_mutex_init(MUTEX* mutex) { #if _OS_WIN InitializeCriticalSection(mutex); #elif _OS_LINUX if (pthread_mutex_init() != 0) { return ERR_THREAD_MUTEX_INIT; } #endif return ERR_THREAD_SUCCESS; } static inline int thread_mutex_destroy(MUTEX* mutex) { #if _OS_WIN #elif _OS_LINUX if (pthread_mutex_destroy(mutex) != 0) { return ERR_THREAD_MUTEX_DESTROY; } #endif return ERR_THREAD_SUCCESS; } static inline int thread_mutex_lock(MUTEX* mutex) { #if _OS_WIN EnterCriticalSection(mutex); #elif _OS_LINUX if (pthread_mutex_lock(mutex) != 0) { return ERR_THREAD_MUTEX_LOCK; } #endif return ERR_THREAD_SUCCESS; } static inline int thread_mutex_unlock(MUTEX* mutex) { #if _OS_WIN LeaveCriticalSection(mutex); #elif _OS_LINUX if (pthread_mutex_unlock(mutex) != 0) { return ERR_THREAD_MUTEX_UNLOCK; } #endif return ERR_THREAD_SUCCESS; } //cond part static inline int thread_cond_init(COND* cond) { #if _OS_WIN InitializeConditionVariable(cond); if (cond == NULL) { return ERR_THREAD_COND_INIT; } #elif _OS_LINUX if (pthread_cond_init(cond) != 0) { return ERR_THREAD_COND_INIT; } #endif return ERR_THREAD_SUCCESS; } static inline int thread_cond_destroy(COND* cond) { #if _OS_WIN #elif _OS_LINUX if (pthread_cond_destroy(cond) != 0) { return ERR_THREAD_COND_DESTROY; } #endif return ERR_THREAD_SUCCESS; } static inline int thread_cond_singal(COND* cond) { #if _OS_WIN WakeConditionVariable(cond); #elif _OS_LINUX if (pthread_cond_signal(cond) != 0) { return ERR_THREAD_COND_SINGAL; } #endif return ERR_THREAD_SUCCESS; } static inline int thread_cond_broadcast(COND* cond) { #if _OS_WIN WakeAllConditionVariable(cond); #elif _OS_LINUX if (pthread_cond_broadcast(cond) != 0) { return ERR_THREAD_COND_BROADCAST; } #endif return ERR_THREAD_SUCCESS; } static inline int thread_cond_wait(COND* cond, MUTEX* mutex) { #if _OS_WIN int res = SleepConditionVariableCS(cond, mutex, INFINITE); #elif _OS_LINUX if (pthread_cond_wait(cond, mutex) != 0) { return ERR_THREAD_COND_WAIT; } #endif return ERR_THREAD_SUCCESS; } //static inline int thread_cond_timedwait(COND cond, MUTEX mutex, ) { //#if _OS_WIN // if (SignalObjectAndWait(cond, mutex, INFINITE, 0) == WAIT_FAILED) { return ERR_THREAD_COND_TIMEDWAIT; } // WAIT_TIMEOUT //#elif _OS_LINUX // if (pthread_cond_timedwait(cond, mutex, ) != 0) { return ERR_THREAD_COND_TIMEDWAIT; } // ETIMEDOUT //#endif // return ERR_THREAD_SUCCESS; //} // thread safety stdio static inline tprintf(MUTEX* mutex, const char* format, ...) { va_list var; va_start(var, format); tvprintf(mutex, format, var); va_end(var); } static inline tvprintf(MUTEX* mutex, const char* format, va_list arglist) { thread_mutex_lock(mutex); vprintf(format, arglist); thread_mutex_unlock(mutex); } static inline tfprintf(MUTEX* mutex, FILE *const stream, const char* format, ...) { va_list var; va_start(var, format); tvfprintf(mutex, stream, format, var); va_end(var); } static inline tvfprintf(MUTEX* mutex, FILE* const stream, const char* format, va_list arglist) { thread_mutex_lock(mutex); vfprintf(stream, format, arglist); thread_mutex_unlock(mutex); } static inline tsprintf(MUTEX* mutex, char* const buffer, const char* format, ...) { va_list var; va_start(var, format); tvsprintf(mutex, buffer, format, var); va_end(var); } static inline tvsprintf(MUTEX* mutex, char* const buffer, const char* format, va_list arglist) { thread_mutex_lock(mutex); vsprintf(buffer, format, arglist); thread_mutex_unlock(mutex); } static inline tsnprintf(MUTEX* mutex, char* const buffer, const size_t buffer_count, const char* format, ...) { va_list var; va_start(var, format); tvsnprintf(mutex, buffer, buffer_count, format, var); va_end(var); } static inline tvsnprintf(MUTEX* mutex, char* const buffer, const size_t buffer_count, const char* format, va_list arglist) { thread_mutex_lock(mutex); vsnprintf(buffer,buffer_count, format, arglist); thread_mutex_unlock(mutex); } #ifdef __cplusplus } #endif #endif //_TTHREAD_H_