Web   ·   Wiki   ·   Activities   ·   Blog   ·   Lists   ·   Chat   ·   Meeting   ·   Bugs   ·   Git   ·   Translate   ·   Archive   ·   People   ·   Donate
summaryrefslogtreecommitdiffstats
path: root/src/include/xthread.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/include/xthread.h')
-rw-r--r--src/include/xthread.h208
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