]> mj.ucw.cz Git - libucw.git/blob - ucw/threads.c
make Sherlock compilable on Darwin without hacks due to missing direct IO
[libucw.git] / ucw / threads.c
1 /*
2  *      The UCW Library -- Threading Helpers
3  *
4  *      (c) 2006 Martin Mares <mj@ucw.cz>
5  *
6  *      This software may be freely distributed and used according to the terms
7  *      of the GNU Lesser General Public License.
8  */
9
10 #include "ucw/lib.h"
11 #include "ucw/threads.h"
12
13 #ifdef CONFIG_UCW_THREADS
14
15 #include <pthread.h>
16
17 #ifdef CONFIG_LINUX
18 #include <sys/types.h>
19 #include <sys/syscall.h>
20 #include <unistd.h>
21 #ifdef __NR_gettid
22 static pid_t
23 gettid(void)
24 {
25   return syscall(__NR_gettid);
26 }
27 #define CONFIG_USE_GETTID
28 #endif
29 #endif
30
31 static pthread_key_t ucwlib_context_key;
32 static pthread_mutex_t ucwlib_master_mutex;
33
34 static void
35 ucwlib_free_thread_context(void *p)
36 {
37   xfree(p);
38 }
39
40 static void CONSTRUCTOR
41 ucwlib_threads_init(void)
42 {
43   if (pthread_key_create(&ucwlib_context_key, ucwlib_free_thread_context) < 0)
44     die("Cannot create pthread_key: %m");
45   pthread_mutex_init(&ucwlib_master_mutex, NULL);
46 }
47
48 static int
49 ucwlib_tid(void)
50 {
51   static int tid_counter;
52   int tid;
53
54 #ifdef CONFIG_USE_GETTID
55   tid = gettid();
56   if (tid > 0)
57     return tid;
58   /* The syscall might be unimplemented */
59 #endif
60
61   ucwlib_lock();
62   tid = ++tid_counter;
63   ucwlib_unlock();
64   return tid;
65 }
66
67 struct ucwlib_context *
68 ucwlib_thread_context(void)
69 {
70   struct ucwlib_context *c = pthread_getspecific(ucwlib_context_key);
71   if (!c)
72     {
73       c = xmalloc_zero(sizeof(*c));
74       c->thread_id = ucwlib_tid();
75       pthread_setspecific(ucwlib_context_key, c);
76     }
77   return c;
78 }
79
80 void
81 ucwlib_lock(void)
82 {
83   pthread_mutex_lock(&ucwlib_master_mutex);
84 }
85
86 void
87 ucwlib_unlock(void)
88 {
89   pthread_mutex_unlock(&ucwlib_master_mutex);
90 }
91
92 #else
93
94 struct ucwlib_context *
95 ucwlib_thread_context(void)
96 {
97   static struct ucwlib_context ucwlib_context;
98   return &ucwlib_context;
99 }
100
101 void
102 ucwlib_lock(void)
103 {
104 }
105
106 void
107 ucwlib_unlock(void)
108 {
109 }
110
111 #endif
112
113 #ifdef TEST
114
115 int main(void)
116 {
117   ucwlib_lock();
118   ucwlib_unlock();
119   msg(L_INFO, "tid=%d", ucwlib_thread_context()->thread_id);
120   return 0;
121 }
122
123 #endif