00001
00002
00003
00004
00005
00006
00007
00008 #include "ibrcommon/config.h"
00009 #include "ibrcommon/thread/Thread.h"
00010 #include <pthread.h>
00011 #include <sys/times.h>
00012 #include <stdio.h>
00013 #include <unistd.h>
00014
00015
00016 namespace ibrcommon
00017 {
00018 static void *exec_thread(void *obj)
00019 {
00020 if (obj == NULL) return NULL;
00021
00022 Thread *th = static_cast<Thread *>(obj);
00023 th->setPriority();
00024 th->run();
00025 th->exit();
00026 return NULL;
00027 }
00028
00029 Thread::Thread(size_t size)
00030 {
00031 stack = size;
00032 priority = 0;
00033 }
00034
00035 void Thread::setPriority(void)
00036 {};
00037
00038 void Thread::yield(void)
00039 {
00040 #if defined(HAVE_PTHREAD_YIELD_NP)
00041 pthread_yield_np();
00042 #elif defined(HAVE_PTHREAD_YIELD)
00043 pthread_yield();
00044 #else
00045 sched_yield();
00046 #endif
00047 }
00048
00049 void Thread::concurrency(int level)
00050 {
00051 #if defined(HAVE_PTHREAD_SETCONCURRENCY)
00052 pthread_setconcurrency(level);
00053 #endif
00054 }
00055
00056 void Thread::sleep(size_t timeout)
00057 {
00058 timespec ts;
00059 ts.tv_sec = timeout / 1000l;
00060 ts.tv_nsec = (timeout % 1000l) * 1000000l;
00061 #if defined(HAVE_PTHREAD_DELAY)
00062 pthread_delay(&ts);
00063 #elif defined(HAVE_PTHREAD_DELAY_NP)
00064 pthread_delay_np(&ts);
00065 #else
00066 usleep(timeout * 1000);
00067 #endif
00068 }
00069
00070 Thread::~Thread()
00071 {
00072 }
00073
00074 void Thread::exit(void)
00075 {
00076 pthread_exit(NULL);
00077 }
00078
00079 bool Thread::equal(pthread_t t1, pthread_t t2)
00080 {
00081 return (pthread_equal(t1, t2) != 0);
00082 }
00083
00084 JoinableThread::JoinableThread(size_t size)
00085 {
00086 running = false;
00087 stack = size;
00088 }
00089
00090 JoinableThread::~JoinableThread()
00091 {
00092 join();
00093 }
00094
00095 void JoinableThread::start(int adj)
00096 {
00097 int result;
00098
00099 if(running)
00100 return;
00101
00102 priority = adj;
00103
00104 pthread_attr_t attr;
00105 pthread_attr_init(&attr);
00106 pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
00107 pthread_attr_setinheritsched(&attr, PTHREAD_INHERIT_SCHED);
00108
00109
00110 #ifdef PTHREAD_STACK_MIN
00111 if(stack && stack < PTHREAD_STACK_MIN)
00112 stack = PTHREAD_STACK_MIN;
00113 #else
00114 if(stack && stack < 2)
00115 stack = 0;
00116 #endif
00117
00118 if(stack)
00119 pthread_attr_setstacksize(&attr, stack);
00120 result = pthread_create(&tid, &attr, &exec_thread, this);
00121 pthread_attr_destroy(&attr);
00122
00123
00124
00125 if(!result)
00126 running = true;
00127 }
00128
00129 void JoinableThread::join(void)
00130 {
00131 pthread_t self = pthread_self();
00132
00133 if(running && equal(tid, self))
00134 Thread::exit();
00135
00136
00137 if(!running)
00138 return;
00139
00140 if(!pthread_join(tid, NULL))
00141 running = false;
00142 }
00143
00144 void JoinableThread::waitFor()
00145 {
00146 join();
00147 }
00148 }