]> mj.ucw.cz Git - libucw.git/blob - lib/threads.c
Remember size of the input file.
[libucw.git] / lib / 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 "lib/lib.h"
11 #include "lib/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 <linux/unistd.h>
20 #ifdef __NR_gettid
21 static _syscall0(pid_t, gettid)
22 #define CONFIG_USE_GETTID
23 #endif
24 #endif
25
26 static pthread_key_t ucwlib_context_key;
27 static pthread_mutex_t ucwlib_master_mutex;
28
29 static void
30 ucwlib_free_thread_context(void *p)
31 {
32   xfree(p);
33 }
34
35 static void CONSTRUCTOR
36 ucwlib_threads_init(void)
37 {
38   if (pthread_key_create(&ucwlib_context_key, ucwlib_free_thread_context) < 0)
39     die("Cannot create pthread_key: %m");
40   pthread_mutex_init(&ucwlib_master_mutex, NULL);
41 }
42
43 static int
44 ucwlib_tid(void)
45 {
46   static int tid_counter;
47   int tid;
48
49 #ifdef CONFIG_USE_GETTID
50   tid = gettid();
51   if (tid > 0)
52     return tid;
53   /* The syscall might be unimplemented */
54 #endif
55
56   ucwlib_lock();
57   tid = ++tid_counter;
58   ucwlib_unlock();
59   return tid;
60 }
61
62 struct ucwlib_context *
63 ucwlib_thread_context(void)
64 {
65   struct ucwlib_context *c = pthread_getspecific(ucwlib_context_key);
66   if (!c)
67     {
68       c = xmalloc_zero(sizeof(*c));
69       c->thread_id = ucwlib_tid();
70       pthread_setspecific(ucwlib_context_key, c);
71     }
72   return c;
73 }
74
75 void
76 ucwlib_lock(void)
77 {
78   pthread_mutex_lock(&ucwlib_master_mutex);
79 }
80
81 void
82 ucwlib_unlock(void)
83 {
84   pthread_mutex_unlock(&ucwlib_master_mutex);
85 }
86
87 #else
88
89 struct ucwlib_context *
90 ucwlib_thread_context(void)
91 {
92   static struct ucwlib_context ucwlib_context;
93   return &ucwlib_context;
94 }
95
96 void
97 ucwlib_lock(void)
98 {
99 }
100
101 void
102 ucwlib_unlock(void)
103 {
104 }
105
106 #endif
107
108 #ifdef TEST
109
110 int main(void)
111 {
112   ucwlib_lock();
113   ucwlib_unlock();
114   log(L_INFO, "tid=%d", ucwlib_thread_context()->thread_id);
115   return 0;
116 }
117
118 #endif