diff options
author | Bernie Innocenti <bernie@codewiz.org> | 2010-05-03 21:53:47 (GMT) |
---|---|---|
committer | Bernie Innocenti <bernie@codewiz.org> | 2010-05-03 21:53:47 (GMT) |
commit | 1030dc837b10a03a02a85d5504cbeec168ce49e2 (patch) | |
tree | 698eefa87ac437deaf36a4141b326f8ce7986692 /src/include/xthread.h |
Import XaoS r489 (trunk after version 3.5)
Diffstat (limited to 'src/include/xthread.h')
-rw-r--r-- | src/include/xthread.h | 208 |
1 files changed, 208 insertions, 0 deletions
diff --git a/src/include/xthread.h b/src/include/xthread.h new file mode 100644 index 0000000..01f210c --- /dev/null +++ b/src/include/xthread.h @@ -0,0 +1,208 @@ +/* + * An XaoS thread API implementation + * Many functions are implemented as macros that maps simple + * XaoS thread API into architecture depended API. + * I tried avoid functions because of speed issues + * So this header will be quite messy soon :) + * + * Supported API for now: + * pthread (POSIX) enabled using USE_PTHREAD + * nothread (my own) enabled by default + */ +#ifndef THREAD_H +#define THREAD_H 1 +#include <fconfig.h> +#ifdef __cplusplus +extern "C" { +#endif +#define MAXTHREADS 32 + /*You might increase this constant if needed + (xaos on connection machine? :) */ + +#define NSEMAPHORS 2 +#define MAXSEMAPHORS 2 +#define NSLEEPS 2 +#define MAXCONDS 2 + +#ifdef USE_PTHREAD +#include <pthread.h> +#endif +#ifdef __BEOS__ +#include <OS.h> +#endif + + struct taskinfo { + int n; +#ifdef USE_PTHREAD + pthread_t id; +#endif +#ifdef _plan9_ + int id; +#endif +#ifdef __BEOS__ + thread_id id; +#endif + }; + + extern struct taskinfo definfo; + extern int ethreads; /*Is threading enabled? */ + extern int nthreads; /*Number of threads */ + typedef void (*xfunction) (void *, struct taskinfo *, int, int); + +/*No-thread API implementation version */ +#define nothread { } +#define nothread_init(nthreads) nothread +#define nothread_uninit() nothread +#define nothread_function(f,data,range) f(data,&definfo,0,range) +#define nothread_bgjob(f,d) f(d,&definfo,0,0) +#define nothread_lock(n) nothread +#define nothread_unlock(n) nothread +#define nothread_sync() nothread +#define nothread_sleep(n,l) nothread +#define nothread_wakeup(n) nothread +#define nothread_wakefirst(n) nothread + +#define xth_wrap(f1,f2) if(nthreads!=1) f1(); else f2(); + +#ifdef USE_PTHREAD +/* A posix thread API maps */ + void pth_init(int nthreads); + void pth_uninit(void); + void pth_function(xfunction f, void *d, int r); + void pth_synchronize(void); + void pth_bgjob(xfunction f, void *d); + extern pthread_mutex_t semaphors[MAXSEMAPHORS]; + extern pthread_cond_t conds[MAXCONDS]; + +/*Map pthread API to XaoS thread API */ + +#define xth_init(nthreads) pth_init(nthreads) +#define xth_uninit() pth_uninit() +#define xth_lock(n) if(ethreads) pthread_mutex_lock(semaphors+(n)) +#define xth_unlock(n) if(ethreads) pthread_mutex_unlock(semaphors+(n)) +#define xth_function(f,d,r) if(ethreads) pth_function(f,d,r); else nothread_function(f,d,r) +#define xth_nthread(ts) (ethreads?ts->n:0) +#define xth_sync() if(ethreads) pth_synchronize(); +#define xth_bgjob(f,d) if(ethreads) pth_bgjob(f,d); else f(d,&definfo,0,0); +#define xth_sleep(n,l) if(ethreads) pthread_cond_wait(conds+(n),semaphors+(l)) +#define xth_wakeup(n) if(ethreads) pthread_cond_broadcast(conds+(n)) +#define xth_wakefirst(n) if(ethreads) pthread_cond_signal(conds+(n)) +#define API_MAPPED +#endif /*USE_PTHREAD */ + +#ifdef _plan9_ + + struct Stack { + int nwaiting; + int tags[MAXTHREADS]; + }; +#ifdef _plan9v2_ +#include <lock.h> /* in plan9v3 part of libc */ +#endif +/* A plan9 thread API maps */ + void p9wait(struct Stack *s, Lock * l); + void p9wakeup(struct Stack *s); + void p9wakeall(struct Stack *s); + void p9init(int nthreads); + void p9uninit(void); + void p9function(xfunction f, void *d, int r); + void p9synchronize(void); + void p9bgjob(xfunction f, void *d); + extern Lock semaphors[MAXSEMAPHORS]; + extern struct Stack conds[MAXCONDS]; + +/*Map pthread API to XaoS thread API */ + +#define xth_init(nthreads) p9init(nthreads) +#define xth_uninit() p9uninit() +#define xth_lock(n) if(ethreads) lock(semaphors+(n)) +#define xth_unlock(n) if(ethreads) unlock(semaphors+(n)) +#define xth_function(f,d,r) if(ethreads) p9function(f,d,r); else nothread_function(f,d,r) +#define xth_nthread(ts) (ethreads?ts->n:0) +#define xth_sync() if(ethreads) p9synchronize(); +#define xth_bgjob(f,d) if(ethreads) p9bgjob(f,d); else f(d,&definfo,0,0); +#define xth_sleep(n,l) if(ethreads) p9wait(conds+(n), semaphors+(l)) +#define xth_wakeup(n) if(ethreads) p9wakeall(conds+(n)) +#define xth_wakefirst(n) if(ethreads) p9wakeup(conds+(n)) +#define API_MAPPED +#endif /*USE_PTHREAD */ + +#ifdef __BEOS__ + typedef struct { + int32 cnt; + sem_id sem; + } benaphore; + + void acquire_benaphore(benaphore * p); + void release_benaphore(benaphore * p); +#ifdef __GNUC__ + extern +#endif + inline void acquire_benaphore(benaphore * p) { + if (atomic_add(&(p->cnt), 1) >= 1) { + /* Someone was faster. */ + while (acquire_sem(p->sem) == B_INTERRUPTED); + } + } +#ifdef __GNUC__ + extern +#endif + inline void release_benaphore(benaphore * p) { + if (atomic_add(&(p->cnt), -1) > 1) { + /* Someone was slower. */ + release_sem(p->sem); + } + } + + extern benaphore mutexes[MAXSEMAPHORS]; + extern benaphore condvars[MAXCONDS]; + + void be_thread_init(int num_threads); + void be_thread_uninit(void); + void be_thread_function(xfunction f, void *d, int r); + void be_thread_synchronize(void); + void be_thread_bgjob(xfunction f, void *d); + void be_thread_sleep(benaphore * pCondition, benaphore * pMutex); + void be_thread_wakeup(benaphore * pCondition); + void be_thread_wakefirst(benaphore * pCondition); + +/* Map BeOS API to XaoS thread API. */ + +#define xth_init(nthreads) be_thread_init(nthreads) +#define xth_uninit() be_thread_uninit() +#define xth_function(f,d,r) if(ethreads) be_thread_function(f,d,r); else nothread_function(f,d,r) +#define xth_nthread(ts) (ethreads?ts->n:0) +#define xth_sync() if(ethreads) be_thread_synchronize(); +#define xth_bgjob(f,d) if(ethreads) be_thread_bgjob(f,d); else f(d,&definfo,0,0); +#define xth_lock(n) if(ethreads) acquire_benaphore(mutexes+(n)) +#define xth_unlock(n) if(ethreads) release_benaphore(mutexes+(n)) +#define xth_sleep(n,l) if(ethreads) be_thread_sleep(condvars+(n),mutexes+(l)) +#define xth_wakeup(n) if(ethreads) be_thread_wakeup(condvars+(n)) +#define xth_wakefirst(n) if(ethreads) be_thread_wakefirst(condvars+(n)) +#define API_MAPPED +#endif /* __BEOS__ */ + +#ifndef API_MAPPED +/* + * No thread support is compiled - do just wrappers + * to nothread implementation + */ +#define nthreads 1 +#define ethreads 0 +#define xth_init(n) nothread_init(n) +#define xth_uninit() nothread_uninit() +#define xth_function(f,d,r) nothread_function(f,d,r) +#define xth_lock(n) nothread_lock(n) +#define xth_unlock(n) nothread_unlock(n) +#define xth_sync() nothread_sync() +#define xth_bgjob(f,d) nothread_bgjob(f,d) +#define xth_nthread(ts) 0 +#define xth_wakeup(n) nothreads_wakeup(n) +#define xth_wakefirst(n) nothreads_wakefirst(n) +#define xth_sleep(n,l) nothreads_sleep(n,l) +#endif + +#ifdef __cplusplus +} +#endif +#endif |