diff options
author | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-08 16:57:53 +0200 |
---|---|---|
committer | Benoit Germain <benoit.germain@ubisoft.com> | 2024-04-08 17:00:56 +0200 |
commit | 96daea993eeea17f0c64325491943e48795ff751 (patch) | |
tree | 653072dc81d0360382576b520e19619b0e06d085 /src/threading.h | |
parent | 63b930ebc5060efecea0ec3acf7e5c93e4047864 (diff) | |
download | lanes-96daea993eeea17f0c64325491943e48795ff751.tar.gz lanes-96daea993eeea17f0c64325491943e48795ff751.tar.bz2 lanes-96daea993eeea17f0c64325491943e48795ff751.zip |
C++ migration: use std::jthread, std::condition_variable, std::chrono.
win32 pthread support is gone
new setting configure.shutdown_mode for cancellation of free-running threads at shutdown.
no more hard thread termination! If a thread doesn't cooperate, an error is raised.
lane.status "killed" is gone
lane:cancel can't force-kill.
Diffstat (limited to '')
-rw-r--r-- | src/threading.h | 58 |
1 files changed, 4 insertions, 54 deletions
diff --git a/src/threading.h b/src/threading.h index 38a021f..e9f302a 100644 --- a/src/threading.h +++ b/src/threading.h | |||
@@ -1,13 +1,9 @@ | |||
1 | #pragma once | 1 | #pragma once |
2 | 2 | ||
3 | /* | ||
4 | * win32-pthread: | ||
5 | * define HAVE_WIN32_PTHREAD and PTW32_INCLUDE_WINDOWS_H in your project configuration when building for win32-pthread. | ||
6 | * link against pthreadVC2.lib, and of course have pthreadVC2.dll somewhere in your path. | ||
7 | */ | ||
8 | #include "platform.h" | 3 | #include "platform.h" |
9 | 4 | ||
10 | #include <time.h> | 5 | #include <time.h> |
6 | #include <thread> | ||
11 | 7 | ||
12 | /* Note: ERROR is a defined entity on Win32 | 8 | /* Note: ERROR is a defined entity on Win32 |
13 | PENDING: The Lua VM hasn't done anything yet. | 9 | PENDING: The Lua VM hasn't done anything yet. |
@@ -19,7 +15,7 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
19 | #define THREADAPI_WINDOWS 1 | 15 | #define THREADAPI_WINDOWS 1 |
20 | #define THREADAPI_PTHREAD 2 | 16 | #define THREADAPI_PTHREAD 2 |
21 | 17 | ||
22 | #if( defined( PLATFORM_XBOX) || defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) && !defined( HAVE_WIN32_PTHREAD) | 18 | #if( defined( PLATFORM_XBOX) || defined( PLATFORM_WIN32) || defined( PLATFORM_POCKETPC)) |
23 | //#pragma message ( "THREADAPI_WINDOWS" ) | 19 | //#pragma message ( "THREADAPI_WINDOWS" ) |
24 | #define THREADAPI THREADAPI_WINDOWS | 20 | #define THREADAPI THREADAPI_WINDOWS |
25 | #else // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) | 21 | #else // (defined PLATFORM_WIN32) || (defined PLATFORM_POCKETPC) |
@@ -68,16 +64,9 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
68 | }; | 64 | }; |
69 | 65 | ||
70 | 66 | ||
71 | #define MUTEX_T HANDLE | ||
72 | void MUTEX_INIT( MUTEX_T* ref); | ||
73 | void MUTEX_FREE( MUTEX_T* ref); | ||
74 | void MUTEX_LOCK( MUTEX_T* ref); | ||
75 | void MUTEX_UNLOCK( MUTEX_T* ref); | ||
76 | |||
77 | #else // CONDITION_VARIABLE are available, use them | 67 | #else // CONDITION_VARIABLE are available, use them |
78 | 68 | ||
79 | #define SIGNAL_T CONDITION_VARIABLE | 69 | #define SIGNAL_T CONDITION_VARIABLE |
80 | #define MUTEX_T CRITICAL_SECTION | ||
81 | #define MUTEX_INIT( ref) InitializeCriticalSection( ref) | 70 | #define MUTEX_INIT( ref) InitializeCriticalSection( ref) |
82 | #define MUTEX_FREE( ref) DeleteCriticalSection( ref) | 71 | #define MUTEX_FREE( ref) DeleteCriticalSection( ref) |
83 | #define MUTEX_LOCK( ref) EnterCriticalSection( ref) | 72 | #define MUTEX_LOCK( ref) EnterCriticalSection( ref) |
@@ -111,7 +100,6 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
111 | # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE | 100 | # define _MUTEX_RECURSIVE PTHREAD_MUTEX_RECURSIVE |
112 | #endif | 101 | #endif |
113 | 102 | ||
114 | #define MUTEX_T pthread_mutex_t | ||
115 | #define MUTEX_INIT(ref) pthread_mutex_init(ref, nullptr) | 103 | #define MUTEX_INIT(ref) pthread_mutex_init(ref, nullptr) |
116 | #define MUTEX_RECURSIVE_INIT(ref) \ | 104 | #define MUTEX_RECURSIVE_INIT(ref) \ |
117 | { pthread_mutexattr_t a; pthread_mutexattr_init( &a ); \ | 105 | { pthread_mutexattr_t a; pthread_mutexattr_init( &a ); \ |
@@ -126,8 +114,6 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
126 | 114 | ||
127 | using SIGNAL_T = pthread_cond_t; | 115 | using SIGNAL_T = pthread_cond_t; |
128 | 116 | ||
129 | void SIGNAL_ONE( SIGNAL_T *ref ); | ||
130 | |||
131 | // Yield is non-portable: | 117 | // Yield is non-portable: |
132 | // | 118 | // |
133 | // OS X 10.4.8/9 has pthread_yield_np() | 119 | // OS X 10.4.8/9 has pthread_yield_np() |
@@ -143,10 +129,6 @@ enum e_status { PENDING, RUNNING, WAITING, DONE, ERROR_ST, CANCELLED }; | |||
143 | #define THREAD_CALLCONV | 129 | #define THREAD_CALLCONV |
144 | #endif //THREADAPI == THREADAPI_PTHREAD | 130 | #endif //THREADAPI == THREADAPI_PTHREAD |
145 | 131 | ||
146 | void SIGNAL_INIT( SIGNAL_T *ref ); | ||
147 | void SIGNAL_FREE( SIGNAL_T *ref ); | ||
148 | void SIGNAL_ALL( SIGNAL_T *ref ); | ||
149 | |||
150 | /* | 132 | /* |
151 | * 'time_d': <0.0 for no timeout | 133 | * 'time_d': <0.0 for no timeout |
152 | * 0.0 for instant check | 134 | * 0.0 for instant check |
@@ -155,11 +137,6 @@ void SIGNAL_ALL( SIGNAL_T *ref ); | |||
155 | using time_d = double; | 137 | using time_d = double; |
156 | time_d now_secs(void); | 138 | time_d now_secs(void); |
157 | 139 | ||
158 | time_d SIGNAL_TIMEOUT_PREPARE( double rel_secs ); | ||
159 | |||
160 | bool SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | ||
161 | |||
162 | |||
163 | /*---=== Threading ===--- | 140 | /*---=== Threading ===--- |
164 | */ | 141 | */ |
165 | 142 | ||
@@ -167,16 +144,9 @@ bool SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | |||
167 | 144 | ||
168 | #if THREADAPI == THREADAPI_WINDOWS | 145 | #if THREADAPI == THREADAPI_WINDOWS |
169 | 146 | ||
170 | using THREAD_T = HANDLE; | ||
171 | # define THREAD_ISNULL( _h) (_h == 0) | ||
172 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (__stdcall *func)( void*), void* data, int prio /* -3..+3 */); | ||
173 | |||
174 | # define THREAD_PRIO_MIN (-3) | 147 | # define THREAD_PRIO_MIN (-3) |
175 | # define THREAD_PRIO_MAX (+3) | 148 | # define THREAD_PRIO_MAX (+3) |
176 | 149 | ||
177 | # define THREAD_CLEANUP_PUSH( cb_, val_) | ||
178 | # define THREAD_CLEANUP_POP( execute_) | ||
179 | |||
180 | #else // THREADAPI == THREADAPI_PTHREAD | 150 | #else // THREADAPI == THREADAPI_PTHREAD |
181 | 151 | ||
182 | /* Platforms that have a timed 'pthread_join()' can get away with a simpler | 152 | /* Platforms that have a timed 'pthread_join()' can get away with a simpler |
@@ -195,11 +165,6 @@ bool SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | |||
195 | # endif | 165 | # endif |
196 | # endif | 166 | # endif |
197 | 167 | ||
198 | using THREAD_T = pthread_t; | ||
199 | # define THREAD_ISNULL( _h) 0 // pthread_t may be a structure: never 'null' by itself | ||
200 | |||
201 | void THREAD_CREATE( THREAD_T* ref, THREAD_RETURN_T (*func)( void*), void* data, int prio /* -3..+3 */); | ||
202 | |||
203 | # if defined(PLATFORM_LINUX) | 168 | # if defined(PLATFORM_LINUX) |
204 | extern volatile bool sudo; | 169 | extern volatile bool sudo; |
205 | # ifdef LINUX_SCHED_RR | 170 | # ifdef LINUX_SCHED_RR |
@@ -213,13 +178,6 @@ bool SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | |||
213 | # define THREAD_PRIO_MAX (+3) | 178 | # define THREAD_PRIO_MAX (+3) |
214 | # endif | 179 | # endif |
215 | 180 | ||
216 | # if THREADWAIT_METHOD == THREADWAIT_CONDVAR | ||
217 | # define THREAD_CLEANUP_PUSH( cb_, val_) pthread_cleanup_push( cb_, val_) | ||
218 | # define THREAD_CLEANUP_POP( execute_) pthread_cleanup_pop( execute_) | ||
219 | # else | ||
220 | # define THREAD_CLEANUP_PUSH( cb_, val_) { | ||
221 | # define THREAD_CLEANUP_POP( execute_) } | ||
222 | # endif // THREADWAIT_METHOD == THREADWAIT_CONDVAR | ||
223 | #endif // THREADAPI == THREADAPI_WINDOWS | 181 | #endif // THREADAPI == THREADAPI_WINDOWS |
224 | 182 | ||
225 | /* | 183 | /* |
@@ -236,16 +194,8 @@ bool SIGNAL_WAIT( SIGNAL_T *ref, MUTEX_T *mu, time_d timeout ); | |||
236 | #endif // THREADAPI == THREADAPI_WINDOWS || (defined PTHREAD_TIMEDJOIN) | 194 | #endif // THREADAPI == THREADAPI_WINDOWS || (defined PTHREAD_TIMEDJOIN) |
237 | 195 | ||
238 | 196 | ||
239 | #if THREADWAIT_METHOD == THREADWAIT_TIMEOUT | ||
240 | bool THREAD_WAIT_IMPL( THREAD_T *ref, double secs); | ||
241 | #define THREAD_WAIT( a, b, c, d, e) THREAD_WAIT_IMPL( a, b) | ||
242 | #else // THREADWAIT_METHOD == THREADWAIT_CONDVAR | ||
243 | bool THREAD_WAIT_IMPL( THREAD_T *ref, double secs, SIGNAL_T *signal_ref, MUTEX_T *mu_ref, volatile enum e_status *st_ref); | ||
244 | #define THREAD_WAIT THREAD_WAIT_IMPL | ||
245 | #endif // // THREADWAIT_METHOD == THREADWAIT_CONDVAR | ||
246 | |||
247 | void THREAD_KILL( THREAD_T* ref); | ||
248 | void THREAD_SETNAME( char const* _name); | 197 | void THREAD_SETNAME( char const* _name); |
249 | void THREAD_MAKE_ASYNCH_CANCELLABLE(); | ||
250 | void THREAD_SET_PRIORITY( int prio); | 198 | void THREAD_SET_PRIORITY( int prio); |
251 | void THREAD_SET_AFFINITY( unsigned int aff); | 199 | void THREAD_SET_AFFINITY( unsigned int aff); |
200 | |||
201 | void JTHREAD_SET_PRIORITY(std::jthread& thread_, int prio_); | ||