Main Page   Namespace List   Compound List   File List   Namespace Members   Compound Members   Related Pages  

threadsPAL.hpp

Go to the documentation of this file.
00001 #ifndef __THREADS_POSIX_PAL_HPP__
00002 #define __THREADS_POSIX_PAL_HPP__
00003 
00004 #include <pthread.h>
00005 #include <semaphore.h>
00006 #include <string.h>
00007 #include <assert.h>
00008 
00009 namespace lfc
00010 {
00011 namespace posixPAL
00012 {
00013 
00015 
00019 namespace threads
00020 {
00021 
00022 const int MAX_ERROR_CODE = 1;
00023 
00024 enum ErrorCodes
00025 {
00026     errOk,
00027     errGeneric,
00028 };
00029 
00030 
00031 extern const char *messagesTable[MAX_ERROR_CODE + 1];
00032 
00034 void* __threadProc(void *);
00035 
00037 struct __StartThreadInfo
00038 {
00039     void (*proc)(void *);
00040     void *pData;
00041 };
00042 
00044 struct ThreadHandle
00045 {
00046     ::pthread_t handle;
00047     bool valid;
00048 
00049     ThreadHandle() : valid(false) {}
00050     bool isNull() const { return !valid; }
00051     
00052 private:
00053     void operator==(const ThreadHandle &) const;    // disabled, no implementation
00054 };
00055 
00057 struct MutexHandle
00058 {
00059     ::pthread_mutex_t handle;
00060     bool valid;
00061 
00062     MutexHandle() : valid(false) {}
00063     bool isNull() const { return !valid; }
00064     
00065 private:
00066     void operator==(const MutexHandle &) const; // disabled, no implementation
00067 };
00068 
00070 
00071 struct SemHandle
00072 {
00073     ::sem_t handle;
00074     bool valid;
00075 
00076     SemHandle() : valid(false) {}
00077     bool isNull() const { return !valid; }
00078     
00079 private:
00080     void operator==(const SemHandle &) const;   // disabled, no implementation
00081 };
00082 
00084 typedef ::pthread_key_t TLSKey;
00085 
00086 
00088 const ThreadHandle NULL_THREAD_HANDLE = ThreadHandle();
00089 
00091 const MutexHandle NULL_MUTEX_HANDLE = MutexHandle();
00092 
00094 const SemHandle NULL_SEM_HANDLE = SemHandle();
00095 
00097 const int
00098     priorityMin = -1,
00099     priorityNormal = 0,
00100     priorityMax = 1;
00101     
00102 
00104 
00107 inline int init()
00108 {
00109     return errOk;
00110 }
00111 
00112 
00114 
00117 inline int cleanup()
00118 {
00119     return errOk;
00120 }
00121 
00122 
00124 
00132 inline int createThread(ThreadHandle &handle, void (*proc)(void *), void *pData)
00133 {
00134     assert(handle.valid == false);
00135 
00136     __StartThreadInfo *pInfo = new __StartThreadInfo;
00137     pInfo->proc = proc;
00138     pInfo->pData = pData;
00139     
00140     ThreadHandle h;
00141     if( ::pthread_create(&h.handle, NULL, &__threadProc, pInfo) != 0 )
00142         return errGeneric;
00143 
00144     h.valid = true;
00145     handle = h;
00146 
00147     return errOk;
00148 }
00149 
00150 
00152 
00157 inline int closeThread(ThreadHandle &handle)
00158 {
00159     assert(handle.valid == true);
00160     
00161     if(::pthread_detach(handle.handle) == 0)
00162     {
00163         handle.valid = false;
00164         return errOk;
00165     }
00166     else
00167         return errGeneric;
00168 }
00169 
00171 
00180 inline int getCurrentThread(ThreadHandle &handle)
00181 {
00182     // my man page doesn't say anything about errs.
00183     // it just says pthread_self returns the calling thread's handle
00184     handle.handle = ::pthread_self();    
00185     handle.valid = true;
00186     return errOk;
00187 }
00188 
00189 
00191 
00196 inline int destroyThread(const ThreadHandle &handle)
00197 {
00198     assert(handle.valid == true);
00199     return ::pthread_cancel(handle.handle) == 0 ? errOk : errGeneric;
00200 }
00201 
00203 
00208 inline int joinThread(const ThreadHandle &handle)
00209 {
00210     assert(handle.valid == true);
00211 
00212     if( ::pthread_join(handle.handle, NULL) == 0 )
00213         return errOk;
00214     else
00215         return errGeneric;
00216 }
00217 
00218 
00220 
00226 inline int setThreadPriority(const ThreadHandle &handle, int priority)
00227 {
00228     assert(handle.valid == true);
00229 
00230     sched_param param;
00231     
00232     ::memset(&param, 0, sizeof(param));
00233 
00234     switch(priority)
00235     {
00236     case priorityMin:
00237         param.sched_priority = ::sched_get_priority_min(SCHED_OTHER);
00238         break;
00239         
00240     case priorityNormal:
00241         param.sched_priority =
00242             (::sched_get_priority_min(SCHED_OTHER) +
00243             ::sched_get_priority_max(SCHED_OTHER)) / 2;
00244         break;
00245         
00246     case priorityMax:
00247         param.sched_priority = ::sched_get_priority_max(SCHED_OTHER);
00248         break;
00249         
00250     default:
00251         return errGeneric;
00252     }
00253 
00254     if(::pthread_setschedparam(handle.handle, SCHED_OTHER, &param) != 0)
00255         return errGeneric;
00256 
00257     return errOk;
00258 }
00259 
00260 
00262 
00266 inline int yield()
00267 {
00268     if( ::sched_yield() == 0)
00269         return errOk;
00270 
00271     return errGeneric;
00272 }
00273 
00275 
00280 inline int sleep(long miliseconds)
00281 {
00282     timespec ts;
00283     ts.tv_sec = miliseconds / 1000;
00284     ts.tv_nsec = (miliseconds % 1000) * 1000000;
00285     ::nanosleep(&ts, NULL);
00286 
00287     return errOk;
00288 }
00289 
00290 
00292 
00297 inline int allocTLS(TLSKey &key)
00298 {
00299     TLSKey k;
00300     
00301     if( ::pthread_key_create(&k, NULL) != 0)
00302         return errGeneric;
00303 
00304     key = k;
00305     return errOk;
00306 }
00307 
00309 
00315 inline int freeTLS(TLSKey key)
00316 {
00317     return ::pthread_key_delete(key) == 0 ? errOk : errGeneric;
00318 }
00319 
00320 
00322 
00328 inline int setTLS(TLSKey key, void *value)
00329 {
00330     return  ::pthread_setspecific(key, value) == 0 ? errOk : errGeneric;
00331 }
00332 
00333 
00335 
00341 inline int getTLS(TLSKey key, void *&value)
00342 {
00343     void *v = ::pthread_getspecific(key);
00344     if( v == NULL)
00345         return errGeneric;
00346 
00347     value = v;
00348     return errOk;
00349 }
00350 
00351 
00353 
00362 // 
00363 int createMutex(MutexHandle &handle);
00364 
00366 
00371 inline int closeMutex(MutexHandle &handle)
00372 {
00373     assert(handle.valid == true);
00374 
00375     if(::pthread_mutex_destroy(&handle.handle) == 0)
00376     {
00377         handle.valid = false;
00378         return errOk;
00379     }
00380     else
00381         return errGeneric;
00382 }
00383 
00384 
00386 
00392 inline int lockMutex(MutexHandle &handle)
00393 {
00394     assert(handle.valid == true);
00395     return ( ::pthread_mutex_lock(&handle.handle) == 0) ? errOk : errGeneric;
00396 }
00397 
00398 
00400 
00406 inline int tryLockMutex(MutexHandle &handle, bool &bLocked)
00407 {
00408     assert(handle.valid == true);
00409     bLocked = ::pthread_mutex_trylock(&handle.handle) == 0;
00410     return errOk;
00411 }
00412 
00414 
00418 inline int unlockMutex(MutexHandle &handle)
00419 {
00420     assert(handle.valid == true);
00421     return ::pthread_mutex_unlock(&handle.handle) == 0 ? errOk : errGeneric;
00422 }
00423 
00424 
00426 
00433 inline int createSemaphore(SemHandle &handle, long count)
00434 {    
00435     assert(handle.valid == false);
00436     
00437     if( ::sem_init(&handle.handle, 0, count) == -1)
00438         return errGeneric;
00439 
00440     handle.valid = true;
00441     return errOk;
00442 }
00443 
00444 
00446 
00451 inline int closeSemaphore(SemHandle &handle)
00452 {
00453     assert(handle.valid == true);
00454 
00455     if(::sem_destroy(&handle.handle) == 0)
00456     {
00457         handle.valid = false;
00458         return errOk;
00459     }
00460     else
00461         return errGeneric;
00462 }
00463 
00464 
00466 
00471 inline int waitSemaphore(SemHandle &handle)
00472 {
00473     assert(handle.valid == true);
00474     return ( ::sem_wait(&handle.handle) == 0 ) ? errOk : errGeneric;
00475 }
00476 
00478 
00484 inline int tryWaitSemaphore(SemHandle &handle, bool &bLocked)
00485 {
00486     assert(handle.valid == true);
00487     bLocked = (::sem_trywait(&handle.handle) == 0);
00488     return errOk;
00489 }
00490 
00492 
00497 inline int postSemaphore(SemHandle &handle)
00498 {
00499     return (::sem_post(&handle.handle) == 0) ? errOk : errGeneric;
00500 }
00501 
00502 
00504 
00507 inline const char *message(int index)
00508 {
00509     assert(index >= 0 && index <= MAX_ERROR_CODE);
00510     return messagesTable[index];
00511 }
00512 
00513 
00514 } // namespace posixPAL::threads
00515 } // namespace posixPAL
00516 
00517 namespace pal = posixPAL;
00518 
00519 } // namespace lfc
00520 
00521 
00522 #endif  // __THREADS_POSIX_PAL_HPP__

Generated on Sat Jan 26 00:35:00 2002 for LFC2 PAL by doxygen1.2.11.1 written by Dimitri van Heesch, © 1997-2001