diff options
Diffstat (limited to 'C/Threads.c')
-rw-r--r-- | C/Threads.c | 53 |
1 files changed, 36 insertions, 17 deletions
diff --git a/C/Threads.c b/C/Threads.c index cf52bd3..464efec 100644 --- a/C/Threads.c +++ b/C/Threads.c | |||
@@ -1,5 +1,5 @@ | |||
1 | /* Threads.c -- multithreading library | 1 | /* Threads.c -- multithreading library |
2 | 2023-03-04 : Igor Pavlov : Public domain */ | 2 | 2024-03-28 : Igor Pavlov : Public domain */ |
3 | 3 | ||
4 | #include "Precomp.h" | 4 | #include "Precomp.h" |
5 | 5 | ||
@@ -195,20 +195,19 @@ WRes CriticalSection_Init(CCriticalSection *p) | |||
195 | 195 | ||
196 | // ---------- POSIX ---------- | 196 | // ---------- POSIX ---------- |
197 | 197 | ||
198 | #ifndef __APPLE__ | 198 | #if defined(__linux__) && !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__) |
199 | #ifndef Z7_AFFINITY_DISABLE | 199 | #ifndef Z7_AFFINITY_DISABLE |
200 | // _GNU_SOURCE can be required for pthread_setaffinity_np() / CPU_ZERO / CPU_SET | 200 | // _GNU_SOURCE can be required for pthread_setaffinity_np() / CPU_ZERO / CPU_SET |
201 | // clang < 3.6 : unknown warning group '-Wreserved-id-macro' | 201 | // clang < 3.6 : unknown warning group '-Wreserved-id-macro' |
202 | // clang 3.6 - 12.01 : gives warning "macro name is a reserved identifier" | 202 | // clang 3.6 - 12.01 : gives warning "macro name is a reserved identifier" |
203 | // clang >= 13 : do not give warning | 203 | // clang >= 13 : do not give warning |
204 | #if !defined(_GNU_SOURCE) | 204 | #if !defined(_GNU_SOURCE) |
205 | #if defined(__clang__) && (__clang_major__ >= 4) && (__clang_major__ <= 12) | 205 | Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER |
206 | #pragma GCC diagnostic ignored "-Wreserved-id-macro" | 206 | // #define _GNU_SOURCE |
207 | #endif | 207 | Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER |
208 | #define _GNU_SOURCE | ||
209 | #endif // !defined(_GNU_SOURCE) | 208 | #endif // !defined(_GNU_SOURCE) |
210 | #endif // Z7_AFFINITY_DISABLE | 209 | #endif // Z7_AFFINITY_DISABLE |
211 | #endif // __APPLE__ | 210 | #endif // __linux__ |
212 | 211 | ||
213 | #include "Threads.h" | 212 | #include "Threads.h" |
214 | 213 | ||
@@ -244,8 +243,9 @@ WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, | |||
244 | { | 243 | { |
245 | if (cpuSet) | 244 | if (cpuSet) |
246 | { | 245 | { |
247 | #ifdef Z7_AFFINITY_SUPPORTED | 246 | // pthread_attr_setaffinity_np() is not supported for MUSL compile. |
248 | 247 | // so we check for __GLIBC__ here | |
248 | #if defined(Z7_AFFINITY_SUPPORTED) && defined( __GLIBC__) | ||
249 | /* | 249 | /* |
250 | printf("\n affinity :"); | 250 | printf("\n affinity :"); |
251 | unsigned i; | 251 | unsigned i; |
@@ -267,7 +267,7 @@ WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, | |||
267 | // ret2 = | 267 | // ret2 = |
268 | pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet); | 268 | pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet); |
269 | // if (ret2) ret = ret2; | 269 | // if (ret2) ret = ret2; |
270 | #endif | 270 | #endif |
271 | } | 271 | } |
272 | 272 | ||
273 | ret = pthread_create(&p->_tid, &attr, func, param); | 273 | ret = pthread_create(&p->_tid, &attr, func, param); |
@@ -369,13 +369,20 @@ WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) | |||
369 | { return AutoResetEvent_Create(p, 0); } | 369 | { return AutoResetEvent_Create(p, 0); } |
370 | 370 | ||
371 | 371 | ||
372 | #if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13) | ||
373 | // freebsd: | ||
374 | #pragma GCC diagnostic ignored "-Wthread-safety-analysis" | ||
375 | #endif | ||
376 | |||
372 | WRes Event_Set(CEvent *p) | 377 | WRes Event_Set(CEvent *p) |
373 | { | 378 | { |
374 | RINOK(pthread_mutex_lock(&p->_mutex)) | 379 | RINOK(pthread_mutex_lock(&p->_mutex)) |
375 | p->_state = True; | 380 | p->_state = True; |
376 | int res1 = pthread_cond_broadcast(&p->_cond); | 381 | { |
377 | int res2 = pthread_mutex_unlock(&p->_mutex); | 382 | const int res1 = pthread_cond_broadcast(&p->_cond); |
378 | return (res2 ? res2 : res1); | 383 | const int res2 = pthread_mutex_unlock(&p->_mutex); |
384 | return (res2 ? res2 : res1); | ||
385 | } | ||
379 | } | 386 | } |
380 | 387 | ||
381 | WRes Event_Reset(CEvent *p) | 388 | WRes Event_Reset(CEvent *p) |
@@ -408,8 +415,8 @@ WRes Event_Close(CEvent *p) | |||
408 | return 0; | 415 | return 0; |
409 | p->_created = 0; | 416 | p->_created = 0; |
410 | { | 417 | { |
411 | int res1 = pthread_mutex_destroy(&p->_mutex); | 418 | const int res1 = pthread_mutex_destroy(&p->_mutex); |
412 | int res2 = pthread_cond_destroy(&p->_cond); | 419 | const int res2 = pthread_cond_destroy(&p->_cond); |
413 | return (res1 ? res1 : res2); | 420 | return (res1 ? res1 : res2); |
414 | } | 421 | } |
415 | } | 422 | } |
@@ -487,8 +494,8 @@ WRes Semaphore_Close(CSemaphore *p) | |||
487 | return 0; | 494 | return 0; |
488 | p->_created = 0; | 495 | p->_created = 0; |
489 | { | 496 | { |
490 | int res1 = pthread_mutex_destroy(&p->_mutex); | 497 | const int res1 = pthread_mutex_destroy(&p->_mutex); |
491 | int res2 = pthread_cond_destroy(&p->_cond); | 498 | const int res2 = pthread_cond_destroy(&p->_cond); |
492 | return (res1 ? res1 : res2); | 499 | return (res1 ? res1 : res2); |
493 | } | 500 | } |
494 | } | 501 | } |
@@ -549,6 +556,18 @@ LONG InterlockedIncrement(LONG volatile *addend) | |||
549 | #endif | 556 | #endif |
550 | } | 557 | } |
551 | 558 | ||
559 | LONG InterlockedDecrement(LONG volatile *addend) | ||
560 | { | ||
561 | // Print("InterlockedDecrement") | ||
562 | #ifdef USE_HACK_UNSAFE_ATOMIC | ||
563 | LONG val = *addend - 1; | ||
564 | *addend = val; | ||
565 | return val; | ||
566 | #else | ||
567 | return __sync_sub_and_fetch(addend, 1); | ||
568 | #endif | ||
569 | } | ||
570 | |||
552 | #endif // _WIN32 | 571 | #endif // _WIN32 |
553 | 572 | ||
554 | WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p) | 573 | WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p) |