threads_posix.cpp

Go to the documentation of this file.
00001 #include <math.h>
00002 #include <unistd.h>
00003 #include <pthread.h>
00004 #include <sys/time.h>
00005 #include "threads.h"
00006 #include "utility.h"
00007 
00008 
00009 namespace audiere {
00010 
00011   struct ThreadInternal {
00012     AI_ThreadRoutine routine;
00013     void* opaque;
00014   };
00015 
00016 
00017   void* ThreadRoutine(void* arg) {
00018     ThreadInternal* ti = (ThreadInternal*)arg;
00019     ti->routine(ti->opaque);
00020     delete ti;
00021     return NULL;
00022   }
00023 
00024 
00025   bool AI_CreateThread(AI_ThreadRoutine routine, void* opaque, int priority) {
00026     ThreadInternal* ti = new ThreadInternal;
00027     ti->routine = routine;
00028     ti->opaque  = opaque;
00029 
00030     pthread_attr_t attr;
00031     if (pthread_attr_init(&attr)) {
00032       delete ti;
00033       return false;
00034     }
00035 
00036     // get default scheduling policy
00037     int policy;
00038     if (pthread_attr_getschedpolicy(&attr, &policy)) {
00039       pthread_attr_destroy(&attr);
00040       delete ti;
00041       return false;
00042     }
00043 
00044     int min_prio = sched_get_priority_min(policy);
00045     int max_prio = sched_get_priority_max(policy);
00046 
00047     // get default scheduling parameters
00048     sched_param sched;
00049     if (pthread_attr_getschedparam(&attr, &sched)) {
00050         pthread_attr_destroy(&attr);
00051         delete ti;
00052         return false;
00053     }
00054 
00055     // treat the specified priority as an offset from the default one
00056     sched.sched_priority = clamp(
00057         min_prio,
00058         sched.sched_priority + priority,
00059         max_prio);
00060 
00061     if (pthread_attr_setschedparam(&attr, &sched)) {
00062         pthread_attr_destroy(&attr);
00063         delete ti;
00064         return false;
00065     }
00066 
00067     pthread_t thread;
00068     int result = pthread_create(&thread, &attr, ThreadRoutine, ti);
00069     if (result != 0) {
00070       pthread_attr_destroy(&attr);
00071       delete ti;
00072       return false;
00073     }
00074 
00075     pthread_attr_destroy(&attr);
00076     return true;
00077   }
00078 
00079 
00080   void AI_Sleep(unsigned milliseconds) {
00081     int seconds = milliseconds / 1000;
00082     int useconds = (milliseconds % 1000) * 1000;
00083 
00084     sleep(seconds);
00085     usleep(useconds);
00086   }
00087 
00088 
00089   struct Mutex::Impl {
00090     pthread_mutex_t mutex;
00091   };
00092 
00093   Mutex::Mutex() {
00094     m_impl = new Impl;
00095     int result = pthread_mutex_init(&m_impl->mutex, 0);
00096     if (result != 0) {
00097       delete m_impl;
00098       m_impl = 0;
00099       ADR_LOG("pthread_mutex_init() failed in Mutex::Mutex()");
00100       abort();
00101     }
00102   }
00103 
00104   Mutex::~Mutex() {
00105     pthread_mutex_destroy(&m_impl->mutex);
00106     delete m_impl;
00107   }
00108 
00109   void Mutex::lock() {
00110     pthread_mutex_lock(&m_impl->mutex);
00111   }
00112 
00113   void Mutex::unlock() {
00114     pthread_mutex_unlock(&m_impl->mutex);
00115   }
00116 
00117 
00118   struct CondVar::Impl {
00119     pthread_cond_t cond;
00120   };
00121 
00122   CondVar::CondVar() {
00123     m_impl = new Impl;
00124     int result = pthread_cond_init(&m_impl->cond, 0);
00125     if (result != 0) {
00126         delete m_impl;
00127         m_impl = 0;
00128         ADR_LOG("pthread_cond_init() failed in CondVar::CondVar()");
00129         abort();
00130     }
00131   }
00132 
00133   CondVar::~CondVar() {
00134     pthread_cond_destroy(&m_impl->cond);
00135     delete m_impl;
00136   }
00137 
00138   void CondVar::wait(Mutex& mutex, float seconds) {
00139     double ds = seconds;  // May need greater than float precision.
00140     
00141     timeval tv;
00142     gettimeofday(&tv, 0);
00143     ds += tv.tv_sec + tv.tv_usec / 1000000000.0;
00144     
00145     timespec ts;
00146     ts.tv_sec  = int(ds);
00147     ts.tv_nsec = int((ds - floor(ds)) * 1000000000);
00148     pthread_cond_timedwait(&m_impl->cond, &mutex.m_impl->mutex, &ts);
00149   }
00150 
00151   void CondVar::notify() {
00152     pthread_cond_signal(&m_impl->cond);
00153   }
00154 
00155 }

Generated on Mon Feb 13 23:07:47 2006 for audiere by  doxygen 1.4.6