1 /* thread.h
2  * - Thread Abstraction Function Headers
3  *
4  * Copyright (c) 1999, 2000 the icecast team <team@icecast.org>
5  *
6  *  This library is free software; you can redistribute it and/or
7  *  modify it under the terms of the GNU Library General Public
8  *  License as published by the Free Software Foundation; either
9  *  version 2 of the License, or (at your option) any later version.
10  *
11  *  This library is distributed in the hope that it will be useful,
12  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
13  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14  *  Library General Public License for more details.
15  *
16  *  You should have received a copy of the GNU Library General Public
17  *  License along with this library; if not, write to the Free
18  *  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
19  */
20 
21 #ifndef __THREAD_H__
22 #define __THREAD_H__
23 
24 #include <pthread.h>
25 
26 /* renamed from thread_t due to conflict on OS X */
27 
28 typedef struct {
29     /* the local id for the thread, and it's name */
30     long thread_id;
31     char *name;
32 
33     /* the time the thread was created */
34     time_t create_time;
35 
36     /* the file and line which created this thread */
37     const char *file;
38     int line;
39 
40     /* is the thread running detached? */
41     int detached;
42 
43 #ifdef __OpenBSD__
44     int running;
45 #endif
46 
47     /* the system specific thread */
48     pthread_t sys_thread;
49 } thread_type;
50 
51 typedef struct {
52 #ifdef THREAD_DEBUG
53     /* the local id and name of the mutex */
54     long mutex_id;
55     char *name;
56 
57     /* the thread which is currently locking this mutex */
58     long thread_id;
59 
60     /* time the lock was taken */
61     unsigned long long lock_start;
62 
63 #endif
64     /* the file and line where the mutex was locked */
65     const char *file;
66     int line;
67 
68     /* the system specific mutex */
69     pthread_mutex_t sys_mutex;
70 } mutex_t;
71 
72 typedef struct {
73 #ifdef THREAD_DEBUG
74     long cond_id;
75     char *name;
76 #endif
77 
78     int set;
79     pthread_cond_t sys_cond;
80 } cond_t;
81 
82 typedef struct {
83 #ifdef THREAD_DEBUG
84     long rwlock_id;
85     char *name;
86 
87     /* information on which thread and where in the code
88     ** this rwlock was write locked
89     */
90     long thread_id;
91     const char *file;
92     int line;
93 
94     /* time the lock was taken */
95     unsigned long long lock_start;
96 #endif
97 
98     pthread_rwlock_t sys_rwlock;
99 } rwlock_t;
100 
101 #ifdef HAVE_PTHREAD_SPIN_LOCK
102 typedef struct
103 {
104     pthread_spinlock_t lock;
105 } spin_t;
106 
107 void thread_spin_create (spin_t *spin);
108 void thread_spin_destroy (spin_t *spin);
109 void thread_spin_lock (spin_t *spin);
110 void thread_spin_unlock (spin_t *spin);
111 #else
112 typedef mutex_t spin_t;
113 #define thread_spin_create(x)  thread_mutex_create(x)
114 #define thread_spin_destroy(x)   thread_mutex_destroy(x)
115 #define thread_spin_lock(x)      thread_mutex_lock(x)
116 #define thread_spin_unlock(x)    thread_mutex_unlock(x)
117 #endif
118 
119 typedef int (*thread_mx_create_func)(void**m, int create);
120 typedef int (*thread_mx_lock_func)(void**m, int create);
121 
122 int thread_mtx_create_callback(void**m, int create);
123 int thread_mtx_lock_callback(void**m, int lock);
124 
125 #define thread_create(n,x,y,z) thread_create_c(n,x,y,z,__LINE__,__FILE__)
126 #define thread_mutex_create(x) thread_mutex_create_c(x,__LINE__,__FILE__)
127 #define thread_mutex_destroy(x) thread_mutex_destroy_c(x,__LINE__,__FILE__)
128 #define thread_mutex_lock(x) thread_mutex_lock_c(x,__LINE__,__FILE__)
129 #define thread_mutex_unlock(x) thread_mutex_unlock_c(x,__LINE__,__FILE__)
130 #define thread_cond_create(x) thread_cond_create_c(x,__LINE__,__FILE__)
131 #define thread_cond_signal(x) thread_cond_signal_c(x,__LINE__,__FILE__)
132 #define thread_cond_broadcast(x) thread_cond_broadcast_c(x,__LINE__,__FILE__)
133 #define thread_cond_wait(x) thread_cond_wait_c(x,__LINE__,__FILE__)
134 #define thread_cond_timedwait(x,m,t) thread_cond_timedwait_c(x,m,t,__LINE__,__FILE__)
135 #define thread_rwlock_create(x) thread_rwlock_create_c(__FILE__,(x),__LINE__,__FILE__)
136 #define thread_rwlock_rlock(x) thread_rwlock_rlock_c(x,__LINE__,__FILE__)
137 #define thread_rwlock_tryrlock(x) thread_rwlock_tryrlock_c(x,__LINE__,__FILE__)
138 #define thread_rwlock_wlock(x) thread_rwlock_wlock_c(x,__LINE__,__FILE__)
139 #define thread_rwlock_trywlock(x) thread_rwlock_trywlock_c(x,__LINE__,__FILE__)
140 #define thread_rwlock_unlock(x) thread_rwlock_unlock_c(x,__LINE__,__FILE__)
141 #define thread_exit(x) thread_exit_c(x,__LINE__,__FILE__)
142 
143 #define MUTEX_STATE_NOTLOCKED -1
144 #define MUTEX_STATE_NEVERLOCKED -2
145 #define MUTEX_STATE_UNINIT -3
146 #define THREAD_DETACHED 1
147 #define THREAD_ATTACHED 0
148 
149 #ifdef _mangle
150 # define thread_initialize _mangle(thread_initialize)
151 # define thread_use_log_id _mangle(thread_use_log_id)
152 # define thread_shutdown _mangle(thread_shutdown)
153 # define thread_create_c _mangle(thread_create_c)
154 # define thread_mutex_create_c _mangle(thread_mutex_create)
155 # define thread_mutex_lock_c _mangle(thread_mutex_lock_c)
156 # define thread_mutex_unlock_c _mangle(thread_mutex_unlock_c)
157 # define thread_mutex_destroy _mangle(thread_mutex_destroy_c)
158 # define thread_cond_create_c _mangle(thread_cond_create_c)
159 # define thread_cond_signal_c _mangle(thread_cond_signal_c)
160 # define thread_cond_broadcast_c _mangle(thread_cond_broadcast_c)
161 # define thread_cond_wait_c _mangle(thread_cond_wait_c)
162 # define thread_cond_timedwait_c _mangle(thread_cond_timedwait_c)
163 # define thread_cond_destroy _mangle(thread_cond_destroy)
164 # define thread_rwlock_create_c _mangle(thread_rwlock_create_c)
165 # define thread_rwlock_rlock_c _mangle(thread_rwlock_rlock_c)
166 # define thread_rwlock_wlock_c _mangle(thread_rwlock_wlock_c)
167 # define thread_rwlock_unlock_c _mangle(thread_rwlock_unlock_c)
168 # define thread_rwlock_destroy _mangle(thread_rwlock_destroy)
169 # define thread_exit_c _mangle(thread_exit_c)
170 # define thread_sleep _mangle(thread_sleep)
171 # define thread_library_lock _mangle(thread_library_lock)
172 # define thread_library_unlock _mangle(thread_library_unlock)
173 # define thread_self _mangle(thread_self)
174 # define thread_rename _mangle(thread_rename)
175 # define thread_join _mangle(thread_join)
176 #endif
177 
178 /* init/shutdown of the library */
179 void thread_initialize(void);
180 void thread_shutdown(void);
181 void thread_use_log_id(int log_id);
182 
183 /* creation, destruction, locking, unlocking, signalling and waiting */
184 thread_type *thread_create_c(char *name, void *(*start_routine)(void *),
185         void *arg, int detached, int line, const char *file);
186 void thread_mutex_create_c(mutex_t *mutex, int line, const char *file);
187 void thread_mutex_lock_c(mutex_t *mutex, int line, const char *file);
188 void thread_mutex_unlock_c(mutex_t *mutex, int line, const char *file);
189 void thread_mutex_destroy_c (mutex_t *mutex, int line, const char *file);
190 void thread_cond_create_c(cond_t *cond, int line, char *file);
191 void thread_cond_signal_c(cond_t *cond, int line, char *file);
192 void thread_cond_broadcast_c(cond_t *cond, int line, char *file);
193 void thread_cond_wait_c(cond_t *cond, mutex_t *mutex, int line, char *file);
194 void thread_cond_timedwait_c(cond_t *cond, mutex_t *mutex, struct timespec *ts, int line, char *file);
195 void thread_cond_destroy(cond_t *cond);
196 void thread_rwlock_create_c(const char *name, rwlock_t *rwlock, int line, const char *file);
197 void thread_rwlock_rlock_c(rwlock_t *rwlock, int line, const char *file);
198 int  thread_rwlock_tryrlock_c(rwlock_t *rwlock, int line, const char *file);
199 void thread_rwlock_wlock_c(rwlock_t *rwlock, int line, const char *file);
200 int  thread_rwlock_trywlock_c(rwlock_t *rwlock, int line, const char *file);
201 void thread_rwlock_unlock_c(rwlock_t *rwlock, int line, const char *file);
202 void thread_rwlock_destroy(rwlock_t *rwlock);
203 void thread_exit_c(long val, int line, char *file);
204 
205 /* sleeping */
206 void thread_sleep(unsigned long len);
207 
208 /* for using library functions which aren't threadsafe */
209 void thread_library_lock(void);
210 void thread_library_unlock(void);
211 #define PROTECT_CODE(code) { thread_library_lock(); code; thread_library_unlock(); }
212 
213 /* thread information functions */
214 thread_type *thread_self(void);
215 
216 /* renames current thread */
217 void thread_rename(const char *name);
218 
219 /* waits until thread_exit is called for another thread */
220 void thread_join(thread_type *thread);
221 
222 void thread_get_timespec (struct timespec *now);
223 void thread_time_add_ms (struct timespec *now, unsigned long value);
224 
225 #define THREAD_TIME_MS(X) ((X)->tv_sec*(uint64_t)1000+(X)->tv_nsec/1000000)
226 #define THREAD_TIME_SEC(X) ((X)->tv_sec)
227 
228 #endif  /* __THREAD_H__ */
229