📄 athread.hh
字号:
} ~Semaphore(){ errnumber=pthread_cond_destroy(&condition); errnumber=pthread_mutex_destroy(&mlock); } int P(){ errnumber=pthread_mutex_unlock(&mlock); count--; while (count<0) errnumber=pthread_cond_wait(&condition, &mlock); return errnumber=pthread_mutex_unlock(&mlock); } int V(){ errnumber=pthread_mutex_unlock(&mlock); count++; errnumber=pthread_cond_signal(&condition); return errnumber=pthread_mutex_unlock(&mlock); }};class Condition : public Errors { pthread_cond_t condition; public: Condition(){ errnumber=pthread_cond_init(&condition, 0); } ~Condition(){ errnumber=pthread_cond_destroy(&condition); } int signal(){ return errnumber=pthread_cond_signal(&condition); } int broadcast(){ return errnumber=pthread_cond_broadcast(&condition); } int wait(MutexLock* l){ return errnumber=pthread_cond_wait(&condition, &l->mlock); } int timedwait(MutexLock* l, const timespec* time){ return errnumber=pthread_cond_timedwait(&condition, &l->mlock, time); }};inline int athr_create(void* (*function)(void*), void* arg, athr_t* thread){ return pthread_create(thread, 0, function, arg);}inline int athr_join(athr_t id){ return pthread_join(id, 0); }inline void athr_yield(){ pthread_yield(); }inline void athr_exit(void* code){ pthread_exit(code); }inline int athr_suspend(athr_t& id){ return -1; } // return pthread_suspend(id); }inline int athr_continue(athr_t& id){ return -1; } // return pthread_continue(id); }inline athr_t athr_self(){ return pthread_self(); }inline int athr_detach(athr_t thread){ return pthread_detach(thread); }inline int athr_kill(athr_t thread, int signal){ return pthread_kill(thread, signal); }inline int athr_equal(athr_t thread1, athr_t thread2){ return pthread_equal(thread1, thread2); }inline int athr_setschedparam(athr_t t, int p, sched_param* param){ return pthread_setschedparam(t, p, param); }inline int athr_getschedparam(athr_t t, int* p, sched_param* param){ return pthread_getschedparam(t, p, param); }#endif // IRIX_PTHREAD#ifdef IRIX#ifndef _SGI_MP_SOURCE#define _SGI_MP_SOURCE#endif#ifndef _REENTRANT#define _REENTRANT#endif#include <sys/time.h>#include <sys/types.h>#include <sys/prctl.h>#include <sys/schedctl.h>#include <signal.h>#include <wait.h>#include <unistd.h>#include <errno.h>#include <ulocks.h>#include <iostream.h>struct sched_param { // copied from pthread in order to stay compatible int prio; void* no_data; sched_param() : prio(0) { no_data=0; }};class SharedArena { friend class MutexLock; friend class Semaphore; friend class Condition; friend class athr_t; friend class _Thread_library; protected: char filename[50]; // filename of shared arena usptr_t* handle; public: SharedArena(); ~SharedArena();};class SA : public Errors { protected: static SharedArena _sa;};class MutexLock : public SA { friend class Condition; ulock_t mlock; public: MutexLock(){ mlock=usnewlock(_sa.handle); errnumber=usinitlock(mlock); } ~MutexLock(){ usfreelock(mlock, _sa.handle); } int lock(){ return errnumber=ussetlock(mlock); } int unlock(){ return errnumber=usunsetlock(mlock); }};class Semaphore : public SA { usema_t* sema; public: Semaphore(int value=0){ sema=usnewsema(_sa.handle, value); errnumber=usinitsema(sema, value); } ~Semaphore(){ usfreesema(sema, _sa.handle); } int P(){ return errnumber=uspsema(sema); } int V(){ return errnumber=usvsema(sema); }};class Condition : public SA { usema_t* sema; public: Condition(){ sema=usnewsema(_sa.handle, 0); errnumber=usinitsema(sema, 0); } ~Condition(){ usfreesema(sema, _sa.handle); } int signal(){ return (ustestsema(sema)<0) ? errnumber=usvsema(sema) : errnumber; } int broadcast(){ int count=ustestsema(sema); while (count++<0) errnumber=usvsema(sema); return errnumber; } int wait(MutexLock* l){ errnumber=usunsetlock(l->mlock); errnumber=uspsema(sema); // this should be atomic return errnumber=ussetlock(l->mlock); } int timedwait(MutexLock* l, const timespec* time){ errnumber=usunsetlock(l->mlock); int gotit=0; if (!(gotit=uscpsema(sema))){ timeval timevalue; timevalue.tv_sec=time->tv_sec; timevalue.tv_usec=time->tv_nsec * 1000; select(0, 0, 0, 0, &timevalue); // primitive solution gotit=uscpsema(sema); } errnumber=ussetlock(l->mlock); return gotit; }};class athr_t : public SA { friend class _Thread_library; protected: usema_t* done; int terminated; int id; int exit(){ terminated=1; while (ustestsema(done)<0) errnumber=usvsema(done); // cerr << "athr - thread "<< id << " terminated\n"; return errnumber; } int wait(){// cerr << "athr - waiting for thread " << id << " to terminate ... "; return (terminated) ? 0 : uspsema(done); } public: athr_t(int pid=0) : terminated(0), id(pid){ done=usnewsema(_sa.handle, 0); usinitsema(done, 0); } ~athr_t(){ /* usfreesema(done, _sa.handle); */ }};// Globals for conversion of standard void return argument of sproc for void* for threadsconst int _thread_list_max=20; // Maximum number of threadsclass _Thread_library : public SA { static athr_t** _thread_list; static ulock_t mlock; static usema_t* funct_sema; static void* (*function_call)(void*); static void sproc_function_call(void* arg){/* if (prctl(PR_SETEXITSIG)<0) cerr << "could not set PR_SETEXITSIG after sproc\n";*/ void* (*call)(void*)=function_call; usvsema(funct_sema); // done with using function_call if (call) call(arg); athr_exit(0); } public: static int init(); static int athr_create(void* (*function)(void*), void* arg, athr_t* thread){ uspsema(funct_sema); // we are using function_call here function_call=function; ussetlock(mlock); for (int i=0; _thread_list[i]!=0 && i<_thread_list_max; i++); if (i>=_thread_list_max){ cerr << "thread overflow!\n"; return -1; } // add entry to thread list in order to do proper clean-up _thread_list[i]=thread; usunsetlock(mlock); return (thread->id=sproc(sproc_function_call, PR_SFDS | PR_SADDR, arg)); // PR_SALL } static int athr_join(athr_t& thread){ return thread.wait(); } static void athr_yield(){ schedctl(getpid(), DL_BLOCK); } static athr_t athr_self(){ return getpid(); } static int athr_detach(athr_t /* thread */ ){ return 0; } static int athr_suspend(athr_t& /* id */ ){ return -1; } // return ; } static int athr_continue(athr_t& /* id */ ){ return -1; } // ; } static int athr_kill(athr_t& thread, int signal){ return kill(thread.id, signal); } static void athr_exit(void* /* code */){ ussetlock(mlock); for (int i=0; i<_thread_list_max; i++) if (_thread_list[i] && _thread_list[i]->id==getpid()){ _thread_list[i]->exit(); // remove entry from thread list _thread_list[i]=0; break; } usunsetlock(mlock); ::exit(0); } static int athr_equal(athr_t& thread1, athr_t& thread2){ return (thread1.id==thread2.id); } static int athr_setschedparam(athr_t& /* t */, int /* p */ , sched_param* /* param */ ){ /* I really don't know how to use this stuff properly if (schedctl(GETNDPRI, t.id)<param->prio) return schedctl(NDPRI, t.id, NDPNORMMAX); if (schedctl(GETNDPRI, t.id)>param->prio) return schedctl(NDPRI, t.id, NDPNORMMIN); if (schedctl(GETNDPRI, t.id)==param->prio) return -1;*/ return 0; } static int athr_getschedparam(athr_t& t, int* /* p */, sched_param* param){ return (param->prio=schedctl(GETNDPRI, t.id)); }};#define athr_create _Thread_library::athr_create#define athr_join _Thread_library::athr_join#define athr_suspend _Thread_library::athr_suspend#define athr_continue _Thread_library::athr_continue#define athr_yield _Thread_library::athr_yield#define athr_self _Thread_library::athr_self#define athr_detach _Thread_library::athr_detach#define athr_kill _Thread_library::athr_kill#define athr_exit _Thread_library::athr_exit#define athr_equal _Thread_library::athr_equal#define athr_setschedparam _Thread_library::athr_setschedparam#define athr_getschedparam _Thread_library::athr_getschedparam#endif // IRIX#endif // __athread_hh
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -