aboutsummaryrefslogtreecommitdiff
path: root/src/threading.h
diff options
context:
space:
mode:
Diffstat (limited to 'src/threading.h')
-rw-r--r--src/threading.h196
1 files changed, 196 insertions, 0 deletions
diff --git a/src/threading.h b/src/threading.h
new file mode 100644
index 0000000..4a83229
--- /dev/null
+++ b/src/threading.h
@@ -0,0 +1,196 @@
1/*
2* THREADING.H
3*/
4#ifndef THREADING_H
5#define THREADING_H
6
7/* Platform detection
8*/
9#ifdef _WIN32_WCE
10 #define PLATFORM_POCKETPC
11#elif (defined _WIN32)
12 #define PLATFORM_WIN32
13#elif (defined __linux__)
14 #define PLATFORM_LINUX
15#elif (defined __APPLE__) && (defined __MACH__)
16 #define PLATFORM_OSX
17#elif (defined __NetBSD__) || (defined __FreeBSD__) || (defined BSD)
18 #define PLATFORM_BSD
19#elif (defined __QNX__)
20 #define PLATFORM_QNX
21#elif (defined __CYGWIN__)
22 #define PLATFORM_CYGWIN
23#else
24 #error "Unknown platform!"
25#endif
26
27typedef int bool_t;
28#ifndef FALSE
29# define FALSE 0
30# define TRUE 1
31#endif
32
33typedef unsigned int uint_t;
34
35#if defined(PLATFORM_WIN32) && defined(__GNUC__)
36/* MinGW with MSVCR80.DLL */
37/* Do this BEFORE including time.h so that it is declaring _mktime32()
38 * as it would have declared mktime().
39 */
40# define mktime _mktime32
41#endif
42#include <time.h>
43
44/* Note: ERROR is a defined entity on Win32
45*/
46enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED };
47
48
49/*---=== Locks & Signals ===---
50*/
51
52#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
53 #define WIN32_LEAN_AND_MEAN
54 // 'SignalObjectAndWait' needs this (targets Windows 2000 and above)
55 #define _WIN32_WINNT 0x0400
56 #include <windows.h>
57 #include <process.h>
58
59 // MSDN: http://msdn2.microsoft.com/en-us/library/ms684254.aspx
60 //
61 // CRITICAL_SECTION can be used for simple code protection. Mutexes are
62 // needed for use with the SIGNAL system.
63 //
64 #define MUTEX_T HANDLE
65 void MUTEX_INIT( MUTEX_T *ref );
66 #define MUTEX_RECURSIVE_INIT(ref) MUTEX_INIT(ref) /* always recursive in Win32 */
67 void MUTEX_FREE( MUTEX_T *ref );
68 void MUTEX_LOCK( MUTEX_T *ref );
69 void MUTEX_UNLOCK( MUTEX_T *ref );
70
71 typedef unsigned THREAD_RETURN_T;
72
73 #define SIGNAL_T HANDLE
74
75 #define YIELD() Sleep(0)
76#else
77 // PThread (Linux, OS X, ...)
78 //
79 #include <pthread.h>
80
81 #ifdef PLATFORM_LINUX
82 # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE_NP
83 #else
84 /* OS X, ... */
85 # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE
86 #endif
87
88 #define MUTEX_T pthread_mutex_t
89 #define MUTEX_INIT(ref) pthread_mutex_init(ref,NULL)
90 #define MUTEX_RECURSIVE_INIT(ref) \
91 { pthread_mutexattr_t a; pthread_mutexattr_init( &a ); \
92 pthread_mutexattr_settype( &a, _MUTEX_RECURSIVE ); \
93 pthread_mutex_init(ref,&a); pthread_mutexattr_destroy( &a ); \
94 }
95 #define MUTEX_FREE(ref) pthread_mutex_destroy(ref)
96 #define MUTEX_LOCK(ref) pthread_mutex_lock(ref)
97 #define MUTEX_UNLOCK(ref) pthread_mutex_unlock(ref)
98
99 typedef void * THREAD_RETURN_T;
100
101 typedef pthread_cond_t SIGNAL_T;
102
103 void SIGNAL_ONE( SIGNAL_T *ref );
104
105 // Yield is non-portable:
106 //
107 // OS X 10.4.8/9 has pthread_yield_np()
108 // Linux 2.4 has pthread_yield() if _GNU_SOURCE is #defined
109 // FreeBSD 6.2 has pthread_yield()
110 // ...
111 //
112 #ifdef PLATFORM_OSX
113 #define YIELD() pthread_yield_np()
114 #else
115 #define YIELD() pthread_yield()
116 #endif
117#endif
118
119void SIGNAL_INIT( SIGNAL_T *ref );
120void SIGNAL_FREE( SIGNAL_T *ref );
121void SIGNAL_ALL( SIGNAL_T *ref );
122
123/*
124* 'time_d': <0.0 for no timeout
125* 0.0 for instant check
126* >0.0 absolute timeout in secs + ms
127*/
128typedef double time_d;
129time_d now_secs(void);
130
131time_d SIGNAL_TIMEOUT_PREPARE( double rel_secs );
132
133bool_t SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout );
134
135
136/*---=== Threading ===---
137*/
138
139#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC)
140
141 typedef HANDLE THREAD_T;
142 //
143 void THREAD_CREATE( THREAD_T *ref,
144 THREAD_RETURN_T (__stdcall *func)( void * ),
145 void *data, int prio /* -3..+3 */ );
146
147# define THREAD_PRIO_MIN (-3)
148# define THREAD_PRIO_MAX (+3)
149
150#else
151 /* Platforms that have a timed 'pthread_join()' can get away with a simpler
152 * implementation. Others will use a condition variable.
153 */
154# ifdef USE_PTHREAD_TIMEDJOIN
155# ifdef PLATFORM_OSX
156# error "No 'pthread_timedjoin()' on this system"
157# else
158 /* Linux, ... */
159# define PTHREAD_TIMEDJOIN pthread_timedjoin_np
160# endif
161# endif
162
163 typedef pthread_t THREAD_T;
164
165 void THREAD_CREATE( THREAD_T *ref,
166 THREAD_RETURN_T (*func)( void * ),
167 void *data, int prio /* -2..+2 */ );
168
169# if defined(PLATFORM_LINUX)
170 volatile bool_t sudo;
171# ifdef LINUX_SCHED_RR
172# define THREAD_PRIO_MIN (sudo ? -2 : 0)
173# else
174# define THREAD_PRIO_MIN (0)
175# endif
176# define THREAD_PRIO_MAX (sudo ? +2 : 0)
177# else
178# define THREAD_PRIO_MIN (-2)
179# define THREAD_PRIO_MAX (+2)
180# endif
181#endif
182
183/*
184* Win32 and PTHREAD_TIMEDJOIN allow waiting for a thread with a timeout.
185* Posix without PTHREAD_TIMEDJOIN needs to use a condition variable approach.
186*/
187#if (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) || (defined PTHREAD_TIMEDJOIN)
188 bool_t THREAD_WAIT( THREAD_T *ref, double secs );
189#else
190 bool_t THREAD_WAIT( THREAD_T *ref, SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref, double secs );
191#endif
192
193void THREAD_KILL( THREAD_T *ref );
194
195#endif
196 // THREADING_H