| |
| |
| #include "tthread.h" |
| #include <pthread.h> |
| |
| |
| |
| |
| |
| class TMutexImp |
| { |
| pthread_mutex_t id; |
| |
| public: |
| TMutexImp(); |
| ~TMutexImp(); |
| void lock(); |
| void unlock(); |
| }; |
| |
| |
| TMutex lockForTheList; |
| |
| class TThreadGroupImp |
| { |
| list<TThread *> threads; |
| |
| public: |
| TThreadGroupImp(); |
| ~TThreadGroupImp(); |
| void add(TThread *); |
| void remove(TThread *); |
| void wait(); |
| }; |
| |
| |
| |
| TMutexImp::TMutexImp() |
| { |
| pthread_mutex_init(&id, 0); |
| } |
| |
| |
| |
| TMutexImp::~TMutexImp() |
| { |
| pthread_mutex_destroy(&id); |
| } |
| |
| |
| |
| void TMutexImp::lock() |
| { |
| pthread_mutex_lock(&id); |
| } |
| |
| |
| |
| void TMutexImp::unlock() |
| { |
| pthread_mutex_unlock(&id); |
| } |
| |
| |
| |
| TMutex::TMutex() |
| : m_imp(new TMutexImp) |
| { |
| } |
| |
| |
| |
| TMutex::~TMutex() |
| { |
| delete m_imp; |
| } |
| |
| |
| |
| void TMutex::lock() |
| { |
| m_imp->lock(); |
| } |
| |
| |
| |
| void TMutex::unlock() |
| { |
| m_imp->unlock(); |
| } |
| |
| |
| |
| |
| |
| |
| class TThreadImp |
| { |
| pthread_t threadId; |
| |
| public: |
| TThreadImp(); |
| ~TThreadImp(); |
| |
| TThread *thread; |
| |
| void start(); |
| |
| bool setThreadPriority(TThread::TThreadPriority p); |
| bool setPreferredProcessor(int processorId); |
| |
| TMutex secureLock; |
| bool isRunning; |
| |
| static void incNThreads() |
| { |
| mutex.lock(); |
| nThreads++; |
| mutex.unlock(); |
| } |
| static void decNThreads() |
| { |
| mutex.lock(); |
| nThreads--; |
| mutex.unlock(); |
| } |
| |
| |
| static TUINT32 nThreads; |
| static TMutex mutex; |
| |
| friend class TThreadGroupImp; |
| void setOwner(TThreadGroupImp *_owner) { owner = _owner; } |
| TThreadGroupImp *owner; |
| }; |
| |
| TUINT32 TThreadImp::nThreads = 0; |
| TMutex TThreadImp::mutex = TMutex(); |
| |
| |
| TThreadImp::TThreadImp() |
| : isRunning(false), owner(0), thread(0) |
| { |
| } |
| |
| |
| |
| TThreadImp::~TThreadImp() |
| { |
| |
| } |
| |
| |
| static void * fun(void *data) |
| { |
| TThreadImp *t = (TThreadImp *)data; |
| |
| t->secureLock.lock(); |
| if (t->isRunning) { |
| t->secureLock.unlock(); |
| assert(!"thread is already running"); |
| return 0; |
| } |
| t->isRunning = true; |
| |
| t->secureLock.unlock(); |
| |
| t->thread->run(); |
| |
| t->decNThreads(); |
| if (t->owner) |
| t->owner->remove(t->thread); |
| |
| return 0; |
| } |
| |
| |
| |
| void TThreadImp::start() |
| { |
| incNThreads(); |
| pthread_create(&threadId, 0, fun, (void *)this); |
| } |
| |
| |
| |
| bool TThreadImp::setThreadPriority(TThread::TThreadPriority) |
| { |
| assert(!"not implemented"); |
| return false; |
| } |
| |
| |
| |
| bool TThreadImp::setPreferredProcessor(int processorId) |
| { |
| #ifdef __sgi |
| #if (OP_RELEASE == rel_2) |
| assert(!"Not implemented"); |
| return false; |
| #else |
| int rc = pthread_setrunon_np(processorId); |
| return (rc != -1); |
| #endif |
| #else |
| assert(0); |
| return false; |
| #endif |
| } |
| |
| |
| |
| TThread::TThread() |
| : m_imp(new TThreadImp()) |
| { |
| m_imp->thread = this; |
| } |
| |
| |
| |
| TThread::~TThread() |
| { |
| delete m_imp; |
| } |
| |
| |
| |
| void TThread::start() |
| { |
| m_imp->start(); |
| } |
| |
| |
| |
| bool TThread::setPreferredProcessor(int processorId) |
| { |
| return m_imp->setPreferredProcessor(processorId); |
| } |
| |
| |
| |
| bool TThread::setThreadPriority(TThread::TThreadPriority p) |
| { |
| return m_imp->setThreadPriority(p); |
| } |
| |
| |
| |
| |
| TThreadGroupImp::TThreadGroupImp() |
| { |
| } |
| |
| |
| |
| TThreadGroupImp::~TThreadGroupImp() |
| { |
| } |
| |
| |
| |
| void TThreadGroupImp::add(TThread *t) |
| { |
| lockForTheList.lock(); |
| threads.push_back(t); |
| lockForTheList.unlock(); |
| t->m_imp->setOwner(this); |
| } |
| |
| |
| void TThreadGroupImp::remove(TThread *t) |
| { |
| lockForTheList.lock(); |
| threads.remove(t); |
| lockForTheList.unlock(); |
| t->m_imp->setOwner(0); |
| } |
| |
| |
| static void * mainFun(void *data) |
| { |
| |
| list<TThread *> *threads = (list<TThread *> *)data; |
| |
| ULONG s = threads->size(); |
| |
| |
| |
| while (s != 0) { |
| lockForTheList.lock(); |
| s = threads->size(); |
| lockForTheList.unlock(); |
| } |
| return 0; |
| } |
| |
| |
| void TThreadGroupImp::wait() |
| { |
| |
| lockForTheList.lock(); |
| ULONG count = threads.size(); |
| |
| for (list<TThread *>::iterator it = threads.begin(); it != threads.end(); it++) { |
| TThread *t = *it; |
| t->start(); |
| } |
| lockForTheList.unlock(); |
| |
| if (count == 0) |
| return; |
| void *mainRet = 0; |
| pthread_t mainThread; |
| |
| pthread_create(&mainThread, 0, mainFun, &threads); |
| |
| pthread_join(mainThread, &mainRet); |
| } |
| |
| |
| |
| TThreadGroup::TThreadGroup() |
| : m_imp(new TThreadGroupImp()) |
| |
| { |
| } |
| |
| |
| |
| TThreadGroup::~TThreadGroup() |
| { |
| delete m_imp; |
| } |
| |
| |
| |
| void TThreadGroup::add(TThread *t) |
| { |
| m_imp->add(t); |
| } |
| |
| |
| |
| void TThreadGroup::wait() |
| { |
| m_imp->wait(); |
| } |
| |