1 /*
2  * An XaoS thread API implementation
3  * Many functions are implemented as macros that maps simple
4  * XaoS thread API into architecture depended API.
5  * I tried avoid functions because of speed issues
6  * So this header will be quite messy soon :)
7  *
8  * Supported API for now:
9  * pthread (POSIX) enabled using USE_PTHREAD
10  * nothread (my own) enabled by default
11  */
12 #ifndef THREAD_H
13 #define THREAD_H 1
14 #include "config.h"
15 #define MAXTHREADS 32
16 /*You might increase this constant if needed
17    (xaos on connection machine? :) */
18 
19 #define NSEMAPHORS 2
20 #define MAXSEMAPHORS 2
21 #define NSLEEPS 2
22 #define MAXCONDS 2
23 
24 #ifdef USE_PTHREAD
25 #include <pthread.h>
26 #endif
27 
28 struct taskinfo {
29     int n;
30 #ifdef USE_PTHREAD
31     pthread_t id;
32 #endif
33 };
34 
35 extern struct taskinfo definfo;
36 extern int ethreads; /*Is threading enabled? */
37 extern int nthreads; /*Number of threads */
38 typedef void (*xfunction)(void *, struct taskinfo *, int, int);
39 
40 /*No-thread API implementation version */
41 #define nothread                                                               \
42     {                                                                          \
43     }
44 #define nothread_init(nthreads) nothread
45 #define nothread_uninit() nothread
46 #define nothread_function(f, data, range) f(data, &definfo, 0, range)
47 #define nothread_bgjob(f, d) f(d, &definfo, 0, 0)
48 #define nothread_lock(n) nothread
49 #define nothread_unlock(n) nothread
50 #define nothread_sync() nothread
51 #define nothread_sleep(n, l) nothread
52 #define nothread_wakeup(n) nothread
53 #define nothread_wakefirst(n) nothread
54 
55 #define xth_wrap(f1, f2)                                                       \
56     if (nthreads != 1)                                                         \
57         f1();                                                                  \
58     else                                                                       \
59         f2();
60 
61 #ifdef USE_PTHREAD
62 /* A posix thread API maps */
63 void pth_init(int nthreads);
64 void pth_uninit(void);
65 void pth_function(xfunction f, void *d, int r);
66 void pth_synchronize(void);
67 void pth_bgjob(xfunction f, void *d);
68 extern pthread_mutex_t semaphors[MAXSEMAPHORS];
69 extern pthread_cond_t conds[MAXCONDS];
70 
71 /*Map pthread API to XaoS thread API */
72 
73 #define xth_init(nthreads) pth_init(nthreads)
74 #define xth_uninit() pth_uninit()
75 #define xth_lock(n)                                                            \
76     if (ethreads)                                                              \
77     pthread_mutex_lock(semaphors + (n))
78 #define xth_unlock(n)                                                          \
79     if (ethreads)                                                              \
80     pthread_mutex_unlock(semaphors + (n))
81 #define xth_function(f, d, r)                                                  \
82     if (ethreads)                                                              \
83         pth_function(f, d, r);                                                 \
84     else                                                                       \
85         nothread_function(f, d, r)
86 #define xth_nthread(ts) (ethreads ? ts->n : 0)
87 #define xth_sync()                                                             \
88     if (ethreads)                                                              \
89         pth_synchronize();
90 #define xth_bgjob(f, d)                                                        \
91     if (ethreads)                                                              \
92         pth_bgjob(f, d);                                                       \
93     else                                                                       \
94         f(d, &definfo, 0, 0);
95 #define xth_sleep(n, l)                                                        \
96     if (ethreads)                                                              \
97     pthread_cond_wait(conds + (n), semaphors + (l))
98 #define xth_wakeup(n)                                                          \
99     if (ethreads)                                                              \
100     pthread_cond_broadcast(conds + (n))
101 #define xth_wakefirst(n)                                                       \
102     if (ethreads)                                                              \
103     pthread_cond_signal(conds + (n))
104 #define API_MAPPED
105 #endif /*USE_PTHREAD */
106 
107 #ifndef API_MAPPED
108 /*
109  * No thread support is compiled - do just wrappers
110  * to nothread implementation
111  */
112 #define nthreads 1
113 #define ethreads 0
114 #define xth_init(n) nothread_init(n)
115 #define xth_uninit() nothread_uninit()
116 #define xth_function(f, d, r) nothread_function(f, d, r)
117 #define xth_lock(n) nothread_lock(n)
118 #define xth_unlock(n) nothread_unlock(n)
119 #define xth_sync() nothread_sync()
120 #define xth_bgjob(f, d) nothread_bgjob(f, d)
121 #define xth_nthread(ts) 0
122 #define xth_wakeup(n) nothreads_wakeup(n)
123 #define xth_wakefirst(n) nothreads_wakefirst(n)
124 #define xth_sleep(n, l) nothreads_sleep(n, l)
125 #endif
126 #endif
127