#ifndef _TTHERAD_H_ #define _TTHREAD_H_ #include "sysenv.h" #include #include #if _OS_WIN #include //#include //#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 int tprintf(MUTEX* mutex, const char* format, ...); static inline int tfprintf(MUTEX* mutex, FILE* const stream, const char* format, ...); static inline int tsprintf(MUTEX* mutex, char* const buffer, const char* format, ...); static inline int tsnprintf(MUTEX* mutex, char* const buffer, const size_t buffer_count, const char* format, ...); static inline int tvprintf(MUTEX* mutex, const char* format, va_list arglist); static inline int tvfprintf(MUTEX* mutex, FILE* const stream, const char* format, va_list arglist); static inline int tvsprintf(MUTEX* mutex, char* const buffer, const char* format, va_list arglist); static inline int 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, (void*(*)(void*))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) { 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(); #endif } // mutex part static inline int thread_mutex_init(MUTEX* mutex) { #if _OS_WIN InitializeCriticalSection(mutex); #elif _OS_LINUX if (pthread_mutex_init(mutex, NULL) != 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, NULL) != 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 if (SleepConditionVariableCS(cond, mutex, INFINITE) != 0) { return -ERR_THREAD_COND_WAIT; } #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 int tprintf(MUTEX* mutex, const char* format, ...) { va_list var; va_start(var, format); int res = tvprintf(mutex, format, var); va_end(var); return res; } static inline int tvprintf(MUTEX* mutex, const char* format, va_list arglist) { thread_mutex_lock(mutex); int res = vprintf(format, arglist); thread_mutex_unlock(mutex); return res; } static inline int tfprintf(MUTEX* mutex, FILE *const stream, const char* format, ...) { va_list var; va_start(var, format); int res = tvfprintf(mutex, stream, format, var); va_end(var); return res; } static inline int tvfprintf(MUTEX* mutex, FILE* const stream, const char* format, va_list arglist) { thread_mutex_lock(mutex); int res = vfprintf(stream, format, arglist); thread_mutex_unlock(mutex); return res; } static inline int tsprintf(MUTEX* mutex, char* const buffer, const char* format, ...) { va_list var; va_start(var, format); int res = tvsprintf(mutex, buffer, format, var); va_end(var); return res; } static inline int tvsprintf(MUTEX* mutex, char* const buffer, const char* format, va_list arglist) { thread_mutex_lock(mutex); int res = vsprintf(buffer, format, arglist); thread_mutex_unlock(mutex); return res; } static inline int tsnprintf(MUTEX* mutex, char* const buffer, const size_t buffer_count, const char* format, ...) { va_list var; va_start(var, format); int res = tvsnprintf(mutex, buffer, buffer_count, format, var); va_end(var); return res; } static inline int tvsnprintf(MUTEX* mutex, char* const buffer, const size_t buffer_count, const char* format, va_list arglist) { thread_mutex_lock(mutex); int res = vsnprintf(buffer,buffer_count, format, arglist); thread_mutex_unlock(mutex); return res; } #ifdef __cplusplus } #endif #endif // _TTHREAD_H_