00001 00014 #ifndef NXS_HEADERS_THREAD 00015 #define NXS_HEADERS_THREAD 00016 00017 #ifdef HAVE_CONFIG_H 00018 #include "config.h" 00019 #endif 00020 00021 #include <stdbool.h> 00022 00023 /* MACROS */ 00036 #define NXS_THREAD_USABLE 00037 00051 #define NXS_THREAD_HAS_TLS 00052 00053 #if defined(HAVE_PTHREAD_H) 00054 #include <pthread.h> 00055 #elif defined(HAVE_WINDOWS_H) 00056 #include <windows.h> 00057 #else 00058 #undef NXS_THREAD_USABLE 00059 #undef NXS_THREAD_HAS_TLS 00060 #endif 00061 00085 #define nxs_thread_semaphore(_type) \ 00086 struct { \ 00087 nxs_thread_mutex _mutex; \ 00088 _type value; \ 00089 } 00090 00091 /* TYPES */ 00095 typedef struct { 00096 #if defined(HAVE_PTHREAD_H) 00097 pthread_t _id; 00098 #elif defined(HAVE_WINDOWS_H) 00099 HANDLE _id; 00100 #endif 00101 00102 void (*_entry)(void *); 00103 void * _data; 00104 } nxs_thread; 00105 00113 #if defined(HAVE_PTHREAD_H) 00114 typedef pthread_mutex_t nxs_thread_mutex[1]; 00115 #elif defined(HAVE_WINDOWS_H) 00116 typedef HANDLE nxs_thread_mutex; 00117 #else 00118 typedef int nxs_thread_mutex; 00119 #endif 00120 00128 typedef 00129 #if defined(HAVE_PTHREAD_H) 00130 pthread_key_t 00131 #elif defined(HAVE_WINDOWS_H) 00132 DWORD 00133 #else 00134 int 00135 #endif 00136 nxs_thread_tls; 00137 00138 /* PUBLIC FUNCTION PROTOTYPES */ 00143 bool nxs_thread_create (nxs_thread *thread, void (*entry)(void *), void *data); 00144 00148 void nxs_thread_exit (void); 00149 00154 bool nxs_thread_kill (nxs_thread *thread); 00155 00162 bool nxs_thread_mutex_alloc (nxs_thread_mutex *mutex); 00163 00168 bool nxs_thread_mutex_free (nxs_thread_mutex mutex); 00169 00176 bool nxs_thread_mutex_lock (nxs_thread_mutex mutex); 00177 00184 bool nxs_thread_mutex_tryLock (nxs_thread_mutex mutex); 00185 00192 bool nxs_thread_mutex_unlock (nxs_thread_mutex mutex); 00193 00200 static inline 00201 bool nxs_thread_sem_init (void *semaphore); 00202 00207 static inline 00208 bool nxs_thread_sem_release (void *semaphore); 00209 00217 static inline 00218 bool nxs_thread_sem_lock (void *semaphore); 00219 00226 static inline 00227 bool nxs_thread_sem_tryLock (void *semaphore); 00228 00237 static inline 00238 bool nxs_thread_sem_unlock (void *semaphore); 00239 00243 void nxs_thread_sleep (unsigned long ms); 00244 00254 bool nxs_thread_tls_alloc (nxs_thread_tls *tls); 00255 00262 bool nxs_thread_tls_free (nxs_thread_tls tls); 00263 00271 void * nxs_thread_tls_get (nxs_thread_tls tls); 00272 00277 bool nxs_thread_tls_set (nxs_thread_tls tls, const void *data); 00278 00283 bool nxs_thread_wait (nxs_thread *thread); 00284 00286 /* IMPLEMENTATION DETAILS BELOW */ 00287 typedef struct { 00288 nxs_thread_mutex mutex; 00289 } nxs_thread_semaphore_; 00290 00291 /* INLINE FUNCTION DEFINITIONS */ 00292 static inline 00293 bool nxs_thread_sem_init (void *semaphore) { 00294 nxs_thread_semaphore_ * const sem = semaphore; 00295 00296 return nxs_thread_mutex_alloc (&sem->mutex); 00297 } 00298 00299 static inline 00300 bool nxs_thread_sem_release (void *semaphore) { 00301 nxs_thread_semaphore_ * const sem = semaphore; 00302 00303 return nxs_thread_mutex_free ( sem->mutex); 00304 } 00305 00306 static inline 00307 bool nxs_thread_sem_lock (void *semaphore) { 00308 nxs_thread_semaphore_ * const sem = semaphore; 00309 00310 return nxs_thread_mutex_lock ( sem->mutex); 00311 } 00312 00313 static inline 00314 bool nxs_thread_sem_tryLock (void *semaphore) { 00315 nxs_thread_semaphore_ * const sem = semaphore; 00316 00317 return nxs_thread_mutex_tryLock ( sem->mutex); 00318 } 00319 00320 static inline 00321 bool nxs_thread_sem_unlock (void *semaphore) { 00322 nxs_thread_semaphore_ * const sem = semaphore; 00323 00324 return nxs_thread_mutex_unlock ( sem->mutex); 00325 } 00326 #endif