00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022 #include <iostream>
00023 #include <OpenSdkThread.h>
00024 #include <Platform.h>
00025
00026 using namespace std;
00027
00028 static void* threadFunc(void*arg);
00029
00030
00031 std::vector<OpenSdkThread*> *OpenSdkThread::threadVector;
00032 static pthread_mutex_t mutex = PTHREAD_MUTEX_INITIALIZER;
00033
00034 #define LOCK() pthread_mutex_lock(&mutex);
00035 #define UNLOCK() pthread_mutex_unlock(&mutex);
00036
00037
00038 int OpenSdkThread::runFunction(FuncPointer func, void *arg)
00039 {
00040 std::vector<OpenSdkThread*>::iterator it = threadVector->begin();
00041
00042 do {
00043 OpenSdkThread *ost = *it;
00044
00045 pthread_mutex_lock(&ost->stateMutex);
00046
00047 if (ost->state == Idle) {
00048 ost->state = Running;
00049 pthread_mutex_unlock(&ost->stateMutex);
00050
00051 ost->func = func;
00052 ost->arg = arg;
00053 pthread_mutex_unlock(&ost->runMutex);
00054 return 0;
00055 }
00056
00057 pthread_mutex_unlock(&ost->stateMutex);
00058
00059 if(++it == threadVector->end()) {
00060
00061 cerr << "****************** OpenSdkThread::runFunction: no thread available ******************" << endl;
00062 return -1;
00063 }
00064
00065 } while (true);
00066 }
00067
00068
00069 void OpenSdkThread::initThreadPool()
00070 {
00071 cout << "Initializing thread pool ..." << endl;
00072
00073 threadVector = new std::vector<OpenSdkThread*>;
00074
00075 for(int i = 0; i<THREAD_POOL_SIZE; i++) {
00076 OpenSdkThread *ost = new OpenSdkThread();
00077 threadVector->push_back(ost);
00078 }
00079
00080 cout << "thread pool created with " << THREAD_POOL_SIZE << " threads." << endl;
00081 }
00082
00083 void OpenSdkThread::cleanThreadPool()
00084 {
00085 LOCK();
00086 for (std::vector<OpenSdkThread*>::iterator it = OpenSdkThread::threadVector->begin();
00087 it != OpenSdkThread::threadVector->end(); ++it) {
00088 (*it)->state = Dead;
00089 pthread_mutex_unlock(&((*it)->runMutex));
00090 }
00091 UNLOCK();
00092
00093 int guard = 42;
00094 while (--guard) {
00095 opensdk_yield();
00096
00097 LOCK();
00098 if (threadVector->empty()) {
00099 UNLOCK();
00100 delete threadVector;
00101 return;
00102 }
00103 UNLOCK();
00104 }
00105 }
00106
00107
00108 OpenSdkThread::OpenSdkThread()
00109 {
00110 pthread_mutex_init(&(this->runMutex), NULL);
00111 pthread_mutex_init(&(this->stateMutex), NULL);
00112
00113 pthread_mutex_lock(&(this->runMutex));
00114
00115 pthread_t threadId;
00116 int threadRet = pthread_create(&threadId, NULL, threadFunc, this);
00117
00118 if (threadRet == 0) {
00119
00120 this->state = Idle;
00121 pthread_detach(threadId);
00122 } else {
00123
00124 cerr << "ERROR: failed to create thread" << endl;
00125 exit(0xdead);
00126 }
00127 }
00128
00129
00130 OpenSdkThread::~OpenSdkThread()
00131 {
00132 pthread_mutex_destroy(&(this->runMutex));
00133 pthread_mutex_destroy(&(this->stateMutex));
00134 }
00135
00136
00137 void OpenSdkThread::deleteThread(void)
00138 {
00139 LOCK();
00140
00141 for (std::vector<OpenSdkThread*>::iterator it = OpenSdkThread::threadVector->begin();
00142 it != OpenSdkThread::threadVector->end(); ++it) {
00143 if (*it == this) {
00144 threadVector->erase(it);
00145 UNLOCK();
00146 return;
00147 }
00148 }
00149
00150 UNLOCK();
00151 cerr << "[OpenSdkThread::deleteThread] the impossible happened: thread not found in the list" << endl;
00152 }
00153
00154
00155 static void* threadFunc(void *arg)
00156 {
00157 OpenSdkThread *ost = (OpenSdkThread*)arg;
00158
00159 while (true) {
00160 pthread_mutex_lock(&(ost->runMutex));
00161
00162 if (ost->state == Dead) {
00163 ost->deleteThread();
00164
00165
00166
00167 pthread_mutex_unlock(&(ost->runMutex));
00168 delete ost;
00169 return NULL;
00170 }
00171
00172 ost->func(ost->arg);
00173
00174 pthread_mutex_lock(&(ost->stateMutex));
00175 ost->state = Idle;
00176 pthread_mutex_unlock(&(ost->stateMutex));
00177 }
00178 }