1*f6dc9357SAndroid Build Coastguard Worker /* Threads.c -- multithreading library
2*f6dc9357SAndroid Build Coastguard Worker 2024-03-28 : Igor Pavlov : Public domain */
3*f6dc9357SAndroid Build Coastguard Worker
4*f6dc9357SAndroid Build Coastguard Worker #include "Precomp.h"
5*f6dc9357SAndroid Build Coastguard Worker
6*f6dc9357SAndroid Build Coastguard Worker #ifdef _WIN32
7*f6dc9357SAndroid Build Coastguard Worker
8*f6dc9357SAndroid Build Coastguard Worker #ifndef USE_THREADS_CreateThread
9*f6dc9357SAndroid Build Coastguard Worker #include <process.h>
10*f6dc9357SAndroid Build Coastguard Worker #endif
11*f6dc9357SAndroid Build Coastguard Worker
12*f6dc9357SAndroid Build Coastguard Worker #include "Threads.h"
13*f6dc9357SAndroid Build Coastguard Worker
GetError(void)14*f6dc9357SAndroid Build Coastguard Worker static WRes GetError(void)
15*f6dc9357SAndroid Build Coastguard Worker {
16*f6dc9357SAndroid Build Coastguard Worker const DWORD res = GetLastError();
17*f6dc9357SAndroid Build Coastguard Worker return res ? (WRes)res : 1;
18*f6dc9357SAndroid Build Coastguard Worker }
19*f6dc9357SAndroid Build Coastguard Worker
HandleToWRes(HANDLE h)20*f6dc9357SAndroid Build Coastguard Worker static WRes HandleToWRes(HANDLE h) { return (h != NULL) ? 0 : GetError(); }
BOOLToWRes(BOOL v)21*f6dc9357SAndroid Build Coastguard Worker static WRes BOOLToWRes(BOOL v) { return v ? 0 : GetError(); }
22*f6dc9357SAndroid Build Coastguard Worker
HandlePtr_Close(HANDLE * p)23*f6dc9357SAndroid Build Coastguard Worker WRes HandlePtr_Close(HANDLE *p)
24*f6dc9357SAndroid Build Coastguard Worker {
25*f6dc9357SAndroid Build Coastguard Worker if (*p != NULL)
26*f6dc9357SAndroid Build Coastguard Worker {
27*f6dc9357SAndroid Build Coastguard Worker if (!CloseHandle(*p))
28*f6dc9357SAndroid Build Coastguard Worker return GetError();
29*f6dc9357SAndroid Build Coastguard Worker *p = NULL;
30*f6dc9357SAndroid Build Coastguard Worker }
31*f6dc9357SAndroid Build Coastguard Worker return 0;
32*f6dc9357SAndroid Build Coastguard Worker }
33*f6dc9357SAndroid Build Coastguard Worker
Handle_WaitObject(HANDLE h)34*f6dc9357SAndroid Build Coastguard Worker WRes Handle_WaitObject(HANDLE h)
35*f6dc9357SAndroid Build Coastguard Worker {
36*f6dc9357SAndroid Build Coastguard Worker DWORD dw = WaitForSingleObject(h, INFINITE);
37*f6dc9357SAndroid Build Coastguard Worker /*
38*f6dc9357SAndroid Build Coastguard Worker (dw) result:
39*f6dc9357SAndroid Build Coastguard Worker WAIT_OBJECT_0 // 0
40*f6dc9357SAndroid Build Coastguard Worker WAIT_ABANDONED // 0x00000080 : is not compatible with Win32 Error space
41*f6dc9357SAndroid Build Coastguard Worker WAIT_TIMEOUT // 0x00000102 : is compatible with Win32 Error space
42*f6dc9357SAndroid Build Coastguard Worker WAIT_FAILED // 0xFFFFFFFF
43*f6dc9357SAndroid Build Coastguard Worker */
44*f6dc9357SAndroid Build Coastguard Worker if (dw == WAIT_FAILED)
45*f6dc9357SAndroid Build Coastguard Worker {
46*f6dc9357SAndroid Build Coastguard Worker dw = GetLastError();
47*f6dc9357SAndroid Build Coastguard Worker if (dw == 0)
48*f6dc9357SAndroid Build Coastguard Worker return WAIT_FAILED;
49*f6dc9357SAndroid Build Coastguard Worker }
50*f6dc9357SAndroid Build Coastguard Worker return (WRes)dw;
51*f6dc9357SAndroid Build Coastguard Worker }
52*f6dc9357SAndroid Build Coastguard Worker
53*f6dc9357SAndroid Build Coastguard Worker #define Thread_Wait(p) Handle_WaitObject(*(p))
54*f6dc9357SAndroid Build Coastguard Worker
Thread_Wait_Close(CThread * p)55*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Wait_Close(CThread *p)
56*f6dc9357SAndroid Build Coastguard Worker {
57*f6dc9357SAndroid Build Coastguard Worker WRes res = Thread_Wait(p);
58*f6dc9357SAndroid Build Coastguard Worker WRes res2 = Thread_Close(p);
59*f6dc9357SAndroid Build Coastguard Worker return (res != 0 ? res : res2);
60*f6dc9357SAndroid Build Coastguard Worker }
61*f6dc9357SAndroid Build Coastguard Worker
Thread_Create(CThread * p,THREAD_FUNC_TYPE func,LPVOID param)62*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
63*f6dc9357SAndroid Build Coastguard Worker {
64*f6dc9357SAndroid Build Coastguard Worker /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
65*f6dc9357SAndroid Build Coastguard Worker
66*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_THREADS_CreateThread
67*f6dc9357SAndroid Build Coastguard Worker
68*f6dc9357SAndroid Build Coastguard Worker DWORD threadId;
69*f6dc9357SAndroid Build Coastguard Worker *p = CreateThread(NULL, 0, func, param, 0, &threadId);
70*f6dc9357SAndroid Build Coastguard Worker
71*f6dc9357SAndroid Build Coastguard Worker #else
72*f6dc9357SAndroid Build Coastguard Worker
73*f6dc9357SAndroid Build Coastguard Worker unsigned threadId;
74*f6dc9357SAndroid Build Coastguard Worker *p = (HANDLE)(_beginthreadex(NULL, 0, func, param, 0, &threadId));
75*f6dc9357SAndroid Build Coastguard Worker
76*f6dc9357SAndroid Build Coastguard Worker #endif
77*f6dc9357SAndroid Build Coastguard Worker
78*f6dc9357SAndroid Build Coastguard Worker /* maybe we must use errno here, but probably GetLastError() is also OK. */
79*f6dc9357SAndroid Build Coastguard Worker return HandleToWRes(*p);
80*f6dc9357SAndroid Build Coastguard Worker }
81*f6dc9357SAndroid Build Coastguard Worker
82*f6dc9357SAndroid Build Coastguard Worker
Thread_Create_With_Affinity(CThread * p,THREAD_FUNC_TYPE func,LPVOID param,CAffinityMask affinity)83*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity)
84*f6dc9357SAndroid Build Coastguard Worker {
85*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_THREADS_CreateThread
86*f6dc9357SAndroid Build Coastguard Worker
87*f6dc9357SAndroid Build Coastguard Worker UNUSED_VAR(affinity)
88*f6dc9357SAndroid Build Coastguard Worker return Thread_Create(p, func, param);
89*f6dc9357SAndroid Build Coastguard Worker
90*f6dc9357SAndroid Build Coastguard Worker #else
91*f6dc9357SAndroid Build Coastguard Worker
92*f6dc9357SAndroid Build Coastguard Worker /* Windows Me/98/95: threadId parameter may not be NULL in _beginthreadex/CreateThread functions */
93*f6dc9357SAndroid Build Coastguard Worker HANDLE h;
94*f6dc9357SAndroid Build Coastguard Worker WRes wres;
95*f6dc9357SAndroid Build Coastguard Worker unsigned threadId;
96*f6dc9357SAndroid Build Coastguard Worker h = (HANDLE)(_beginthreadex(NULL, 0, func, param, CREATE_SUSPENDED, &threadId));
97*f6dc9357SAndroid Build Coastguard Worker *p = h;
98*f6dc9357SAndroid Build Coastguard Worker wres = HandleToWRes(h);
99*f6dc9357SAndroid Build Coastguard Worker if (h)
100*f6dc9357SAndroid Build Coastguard Worker {
101*f6dc9357SAndroid Build Coastguard Worker {
102*f6dc9357SAndroid Build Coastguard Worker // DWORD_PTR prevMask =
103*f6dc9357SAndroid Build Coastguard Worker SetThreadAffinityMask(h, (DWORD_PTR)affinity);
104*f6dc9357SAndroid Build Coastguard Worker /*
105*f6dc9357SAndroid Build Coastguard Worker if (prevMask == 0)
106*f6dc9357SAndroid Build Coastguard Worker {
107*f6dc9357SAndroid Build Coastguard Worker // affinity change is non-critical error, so we can ignore it
108*f6dc9357SAndroid Build Coastguard Worker // wres = GetError();
109*f6dc9357SAndroid Build Coastguard Worker }
110*f6dc9357SAndroid Build Coastguard Worker */
111*f6dc9357SAndroid Build Coastguard Worker }
112*f6dc9357SAndroid Build Coastguard Worker {
113*f6dc9357SAndroid Build Coastguard Worker DWORD prevSuspendCount = ResumeThread(h);
114*f6dc9357SAndroid Build Coastguard Worker /* ResumeThread() returns:
115*f6dc9357SAndroid Build Coastguard Worker 0 : was_not_suspended
116*f6dc9357SAndroid Build Coastguard Worker 1 : was_resumed
117*f6dc9357SAndroid Build Coastguard Worker -1 : error
118*f6dc9357SAndroid Build Coastguard Worker */
119*f6dc9357SAndroid Build Coastguard Worker if (prevSuspendCount == (DWORD)-1)
120*f6dc9357SAndroid Build Coastguard Worker wres = GetError();
121*f6dc9357SAndroid Build Coastguard Worker }
122*f6dc9357SAndroid Build Coastguard Worker }
123*f6dc9357SAndroid Build Coastguard Worker
124*f6dc9357SAndroid Build Coastguard Worker /* maybe we must use errno here, but probably GetLastError() is also OK. */
125*f6dc9357SAndroid Build Coastguard Worker return wres;
126*f6dc9357SAndroid Build Coastguard Worker
127*f6dc9357SAndroid Build Coastguard Worker #endif
128*f6dc9357SAndroid Build Coastguard Worker }
129*f6dc9357SAndroid Build Coastguard Worker
130*f6dc9357SAndroid Build Coastguard Worker
Event_Create(CEvent * p,BOOL manualReset,int signaled)131*f6dc9357SAndroid Build Coastguard Worker static WRes Event_Create(CEvent *p, BOOL manualReset, int signaled)
132*f6dc9357SAndroid Build Coastguard Worker {
133*f6dc9357SAndroid Build Coastguard Worker *p = CreateEvent(NULL, manualReset, (signaled ? TRUE : FALSE), NULL);
134*f6dc9357SAndroid Build Coastguard Worker return HandleToWRes(*p);
135*f6dc9357SAndroid Build Coastguard Worker }
136*f6dc9357SAndroid Build Coastguard Worker
Event_Set(CEvent * p)137*f6dc9357SAndroid Build Coastguard Worker WRes Event_Set(CEvent *p) { return BOOLToWRes(SetEvent(*p)); }
Event_Reset(CEvent * p)138*f6dc9357SAndroid Build Coastguard Worker WRes Event_Reset(CEvent *p) { return BOOLToWRes(ResetEvent(*p)); }
139*f6dc9357SAndroid Build Coastguard Worker
ManualResetEvent_Create(CManualResetEvent * p,int signaled)140*f6dc9357SAndroid Build Coastguard Worker WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled) { return Event_Create(p, TRUE, signaled); }
AutoResetEvent_Create(CAutoResetEvent * p,int signaled)141*f6dc9357SAndroid Build Coastguard Worker WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled) { return Event_Create(p, FALSE, signaled); }
ManualResetEvent_CreateNotSignaled(CManualResetEvent * p)142*f6dc9357SAndroid Build Coastguard Worker WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p) { return ManualResetEvent_Create(p, 0); }
AutoResetEvent_CreateNotSignaled(CAutoResetEvent * p)143*f6dc9357SAndroid Build Coastguard Worker WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p) { return AutoResetEvent_Create(p, 0); }
144*f6dc9357SAndroid Build Coastguard Worker
145*f6dc9357SAndroid Build Coastguard Worker
Semaphore_Create(CSemaphore * p,UInt32 initCount,UInt32 maxCount)146*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
147*f6dc9357SAndroid Build Coastguard Worker {
148*f6dc9357SAndroid Build Coastguard Worker // negative ((LONG)maxCount) is not supported in WIN32::CreateSemaphore()
149*f6dc9357SAndroid Build Coastguard Worker *p = CreateSemaphore(NULL, (LONG)initCount, (LONG)maxCount, NULL);
150*f6dc9357SAndroid Build Coastguard Worker return HandleToWRes(*p);
151*f6dc9357SAndroid Build Coastguard Worker }
152*f6dc9357SAndroid Build Coastguard Worker
Semaphore_OptCreateInit(CSemaphore * p,UInt32 initCount,UInt32 maxCount)153*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
154*f6dc9357SAndroid Build Coastguard Worker {
155*f6dc9357SAndroid Build Coastguard Worker // if (Semaphore_IsCreated(p))
156*f6dc9357SAndroid Build Coastguard Worker {
157*f6dc9357SAndroid Build Coastguard Worker WRes wres = Semaphore_Close(p);
158*f6dc9357SAndroid Build Coastguard Worker if (wres != 0)
159*f6dc9357SAndroid Build Coastguard Worker return wres;
160*f6dc9357SAndroid Build Coastguard Worker }
161*f6dc9357SAndroid Build Coastguard Worker return Semaphore_Create(p, initCount, maxCount);
162*f6dc9357SAndroid Build Coastguard Worker }
163*f6dc9357SAndroid Build Coastguard Worker
Semaphore_Release(CSemaphore * p,LONG releaseCount,LONG * previousCount)164*f6dc9357SAndroid Build Coastguard Worker static WRes Semaphore_Release(CSemaphore *p, LONG releaseCount, LONG *previousCount)
165*f6dc9357SAndroid Build Coastguard Worker { return BOOLToWRes(ReleaseSemaphore(*p, releaseCount, previousCount)); }
Semaphore_ReleaseN(CSemaphore * p,UInt32 num)166*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num)
167*f6dc9357SAndroid Build Coastguard Worker { return Semaphore_Release(p, (LONG)num, NULL); }
Semaphore_Release1(CSemaphore * p)168*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_Release1(CSemaphore *p) { return Semaphore_ReleaseN(p, 1); }
169*f6dc9357SAndroid Build Coastguard Worker
CriticalSection_Init(CCriticalSection * p)170*f6dc9357SAndroid Build Coastguard Worker WRes CriticalSection_Init(CCriticalSection *p)
171*f6dc9357SAndroid Build Coastguard Worker {
172*f6dc9357SAndroid Build Coastguard Worker /* InitializeCriticalSection() can raise exception:
173*f6dc9357SAndroid Build Coastguard Worker Windows XP, 2003 : can raise a STATUS_NO_MEMORY exception
174*f6dc9357SAndroid Build Coastguard Worker Windows Vista+ : no exceptions */
175*f6dc9357SAndroid Build Coastguard Worker #ifdef _MSC_VER
176*f6dc9357SAndroid Build Coastguard Worker #ifdef __clang__
177*f6dc9357SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wlanguage-extension-token"
178*f6dc9357SAndroid Build Coastguard Worker #endif
179*f6dc9357SAndroid Build Coastguard Worker __try
180*f6dc9357SAndroid Build Coastguard Worker #endif
181*f6dc9357SAndroid Build Coastguard Worker {
182*f6dc9357SAndroid Build Coastguard Worker InitializeCriticalSection(p);
183*f6dc9357SAndroid Build Coastguard Worker /* InitializeCriticalSectionAndSpinCount(p, 0); */
184*f6dc9357SAndroid Build Coastguard Worker }
185*f6dc9357SAndroid Build Coastguard Worker #ifdef _MSC_VER
186*f6dc9357SAndroid Build Coastguard Worker __except (EXCEPTION_EXECUTE_HANDLER) { return ERROR_NOT_ENOUGH_MEMORY; }
187*f6dc9357SAndroid Build Coastguard Worker #endif
188*f6dc9357SAndroid Build Coastguard Worker return 0;
189*f6dc9357SAndroid Build Coastguard Worker }
190*f6dc9357SAndroid Build Coastguard Worker
191*f6dc9357SAndroid Build Coastguard Worker
192*f6dc9357SAndroid Build Coastguard Worker
193*f6dc9357SAndroid Build Coastguard Worker
194*f6dc9357SAndroid Build Coastguard Worker #else // _WIN32
195*f6dc9357SAndroid Build Coastguard Worker
196*f6dc9357SAndroid Build Coastguard Worker // ---------- POSIX ----------
197*f6dc9357SAndroid Build Coastguard Worker
198*f6dc9357SAndroid Build Coastguard Worker #if defined(__linux__) && !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__)
199*f6dc9357SAndroid Build Coastguard Worker #ifndef Z7_AFFINITY_DISABLE
200*f6dc9357SAndroid Build Coastguard Worker // _GNU_SOURCE can be required for pthread_setaffinity_np() / CPU_ZERO / CPU_SET
201*f6dc9357SAndroid Build Coastguard Worker // clang < 3.6 : unknown warning group '-Wreserved-id-macro'
202*f6dc9357SAndroid Build Coastguard Worker // clang 3.6 - 12.01 : gives warning "macro name is a reserved identifier"
203*f6dc9357SAndroid Build Coastguard Worker // clang >= 13 : do not give warning
204*f6dc9357SAndroid Build Coastguard Worker #if !defined(_GNU_SOURCE)
205*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_BEGIN_RESERVED_MACRO_IDENTIFIER
206*f6dc9357SAndroid Build Coastguard Worker // #define _GNU_SOURCE
207*f6dc9357SAndroid Build Coastguard Worker Z7_DIAGNOSTIC_IGNORE_END_RESERVED_MACRO_IDENTIFIER
208*f6dc9357SAndroid Build Coastguard Worker #endif // !defined(_GNU_SOURCE)
209*f6dc9357SAndroid Build Coastguard Worker #endif // Z7_AFFINITY_DISABLE
210*f6dc9357SAndroid Build Coastguard Worker #endif // __linux__
211*f6dc9357SAndroid Build Coastguard Worker
212*f6dc9357SAndroid Build Coastguard Worker #include "Threads.h"
213*f6dc9357SAndroid Build Coastguard Worker
214*f6dc9357SAndroid Build Coastguard Worker #include <errno.h>
215*f6dc9357SAndroid Build Coastguard Worker #include <stdlib.h>
216*f6dc9357SAndroid Build Coastguard Worker #include <string.h>
217*f6dc9357SAndroid Build Coastguard Worker #ifdef Z7_AFFINITY_SUPPORTED
218*f6dc9357SAndroid Build Coastguard Worker // #include <sched.h>
219*f6dc9357SAndroid Build Coastguard Worker #endif
220*f6dc9357SAndroid Build Coastguard Worker
221*f6dc9357SAndroid Build Coastguard Worker
222*f6dc9357SAndroid Build Coastguard Worker // #include <stdio.h>
223*f6dc9357SAndroid Build Coastguard Worker // #define PRF(p) p
224*f6dc9357SAndroid Build Coastguard Worker #define PRF(p)
225*f6dc9357SAndroid Build Coastguard Worker #define Print(s) PRF(printf("\n%s\n", s);)
226*f6dc9357SAndroid Build Coastguard Worker
Thread_Create_With_CpuSet(CThread * p,THREAD_FUNC_TYPE func,LPVOID param,const CCpuSet * cpuSet)227*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet)
228*f6dc9357SAndroid Build Coastguard Worker {
229*f6dc9357SAndroid Build Coastguard Worker // new thread in Posix probably inherits affinity from parrent thread
230*f6dc9357SAndroid Build Coastguard Worker Print("Thread_Create_With_CpuSet")
231*f6dc9357SAndroid Build Coastguard Worker
232*f6dc9357SAndroid Build Coastguard Worker pthread_attr_t attr;
233*f6dc9357SAndroid Build Coastguard Worker int ret;
234*f6dc9357SAndroid Build Coastguard Worker // int ret2;
235*f6dc9357SAndroid Build Coastguard Worker
236*f6dc9357SAndroid Build Coastguard Worker p->_created = 0;
237*f6dc9357SAndroid Build Coastguard Worker
238*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_attr_init(&attr))
239*f6dc9357SAndroid Build Coastguard Worker
240*f6dc9357SAndroid Build Coastguard Worker ret = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE);
241*f6dc9357SAndroid Build Coastguard Worker
242*f6dc9357SAndroid Build Coastguard Worker if (!ret)
243*f6dc9357SAndroid Build Coastguard Worker {
244*f6dc9357SAndroid Build Coastguard Worker if (cpuSet)
245*f6dc9357SAndroid Build Coastguard Worker {
246*f6dc9357SAndroid Build Coastguard Worker // pthread_attr_setaffinity_np() is not supported for MUSL compile.
247*f6dc9357SAndroid Build Coastguard Worker // so we check for __GLIBC__ here
248*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_AFFINITY_SUPPORTED) && defined( __GLIBC__)
249*f6dc9357SAndroid Build Coastguard Worker /*
250*f6dc9357SAndroid Build Coastguard Worker printf("\n affinity :");
251*f6dc9357SAndroid Build Coastguard Worker unsigned i;
252*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < sizeof(*cpuSet) && i < 8; i++)
253*f6dc9357SAndroid Build Coastguard Worker {
254*f6dc9357SAndroid Build Coastguard Worker Byte b = *((const Byte *)cpuSet + i);
255*f6dc9357SAndroid Build Coastguard Worker char temp[32];
256*f6dc9357SAndroid Build Coastguard Worker #define GET_HEX_CHAR(t) ((char)(((t < 10) ? ('0' + t) : ('A' + (t - 10)))))
257*f6dc9357SAndroid Build Coastguard Worker temp[0] = GET_HEX_CHAR((b & 0xF));
258*f6dc9357SAndroid Build Coastguard Worker temp[1] = GET_HEX_CHAR((b >> 4));
259*f6dc9357SAndroid Build Coastguard Worker // temp[0] = GET_HEX_CHAR((b >> 4)); // big-endian
260*f6dc9357SAndroid Build Coastguard Worker // temp[1] = GET_HEX_CHAR((b & 0xF)); // big-endian
261*f6dc9357SAndroid Build Coastguard Worker temp[2] = 0;
262*f6dc9357SAndroid Build Coastguard Worker printf("%s", temp);
263*f6dc9357SAndroid Build Coastguard Worker }
264*f6dc9357SAndroid Build Coastguard Worker printf("\n");
265*f6dc9357SAndroid Build Coastguard Worker */
266*f6dc9357SAndroid Build Coastguard Worker
267*f6dc9357SAndroid Build Coastguard Worker // ret2 =
268*f6dc9357SAndroid Build Coastguard Worker pthread_attr_setaffinity_np(&attr, sizeof(*cpuSet), cpuSet);
269*f6dc9357SAndroid Build Coastguard Worker // if (ret2) ret = ret2;
270*f6dc9357SAndroid Build Coastguard Worker #endif
271*f6dc9357SAndroid Build Coastguard Worker }
272*f6dc9357SAndroid Build Coastguard Worker
273*f6dc9357SAndroid Build Coastguard Worker ret = pthread_create(&p->_tid, &attr, func, param);
274*f6dc9357SAndroid Build Coastguard Worker
275*f6dc9357SAndroid Build Coastguard Worker if (!ret)
276*f6dc9357SAndroid Build Coastguard Worker {
277*f6dc9357SAndroid Build Coastguard Worker p->_created = 1;
278*f6dc9357SAndroid Build Coastguard Worker /*
279*f6dc9357SAndroid Build Coastguard Worker if (cpuSet)
280*f6dc9357SAndroid Build Coastguard Worker {
281*f6dc9357SAndroid Build Coastguard Worker // ret2 =
282*f6dc9357SAndroid Build Coastguard Worker pthread_setaffinity_np(p->_tid, sizeof(*cpuSet), cpuSet);
283*f6dc9357SAndroid Build Coastguard Worker // if (ret2) ret = ret2;
284*f6dc9357SAndroid Build Coastguard Worker }
285*f6dc9357SAndroid Build Coastguard Worker */
286*f6dc9357SAndroid Build Coastguard Worker }
287*f6dc9357SAndroid Build Coastguard Worker }
288*f6dc9357SAndroid Build Coastguard Worker // ret2 =
289*f6dc9357SAndroid Build Coastguard Worker pthread_attr_destroy(&attr);
290*f6dc9357SAndroid Build Coastguard Worker // if (ret2 != 0) ret = ret2;
291*f6dc9357SAndroid Build Coastguard Worker return ret;
292*f6dc9357SAndroid Build Coastguard Worker }
293*f6dc9357SAndroid Build Coastguard Worker
294*f6dc9357SAndroid Build Coastguard Worker
Thread_Create(CThread * p,THREAD_FUNC_TYPE func,LPVOID param)295*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param)
296*f6dc9357SAndroid Build Coastguard Worker {
297*f6dc9357SAndroid Build Coastguard Worker return Thread_Create_With_CpuSet(p, func, param, NULL);
298*f6dc9357SAndroid Build Coastguard Worker }
299*f6dc9357SAndroid Build Coastguard Worker
300*f6dc9357SAndroid Build Coastguard Worker
Thread_Create_With_Affinity(CThread * p,THREAD_FUNC_TYPE func,LPVOID param,CAffinityMask affinity)301*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity)
302*f6dc9357SAndroid Build Coastguard Worker {
303*f6dc9357SAndroid Build Coastguard Worker Print("Thread_Create_WithAffinity")
304*f6dc9357SAndroid Build Coastguard Worker CCpuSet cs;
305*f6dc9357SAndroid Build Coastguard Worker unsigned i;
306*f6dc9357SAndroid Build Coastguard Worker CpuSet_Zero(&cs);
307*f6dc9357SAndroid Build Coastguard Worker for (i = 0; i < sizeof(affinity) * 8; i++)
308*f6dc9357SAndroid Build Coastguard Worker {
309*f6dc9357SAndroid Build Coastguard Worker if (affinity == 0)
310*f6dc9357SAndroid Build Coastguard Worker break;
311*f6dc9357SAndroid Build Coastguard Worker if (affinity & 1)
312*f6dc9357SAndroid Build Coastguard Worker {
313*f6dc9357SAndroid Build Coastguard Worker CpuSet_Set(&cs, i);
314*f6dc9357SAndroid Build Coastguard Worker }
315*f6dc9357SAndroid Build Coastguard Worker affinity >>= 1;
316*f6dc9357SAndroid Build Coastguard Worker }
317*f6dc9357SAndroid Build Coastguard Worker return Thread_Create_With_CpuSet(p, func, param, &cs);
318*f6dc9357SAndroid Build Coastguard Worker }
319*f6dc9357SAndroid Build Coastguard Worker
320*f6dc9357SAndroid Build Coastguard Worker
Thread_Close(CThread * p)321*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Close(CThread *p)
322*f6dc9357SAndroid Build Coastguard Worker {
323*f6dc9357SAndroid Build Coastguard Worker // Print("Thread_Close")
324*f6dc9357SAndroid Build Coastguard Worker int ret;
325*f6dc9357SAndroid Build Coastguard Worker if (!p->_created)
326*f6dc9357SAndroid Build Coastguard Worker return 0;
327*f6dc9357SAndroid Build Coastguard Worker
328*f6dc9357SAndroid Build Coastguard Worker ret = pthread_detach(p->_tid);
329*f6dc9357SAndroid Build Coastguard Worker p->_tid = 0;
330*f6dc9357SAndroid Build Coastguard Worker p->_created = 0;
331*f6dc9357SAndroid Build Coastguard Worker return ret;
332*f6dc9357SAndroid Build Coastguard Worker }
333*f6dc9357SAndroid Build Coastguard Worker
334*f6dc9357SAndroid Build Coastguard Worker
Thread_Wait_Close(CThread * p)335*f6dc9357SAndroid Build Coastguard Worker WRes Thread_Wait_Close(CThread *p)
336*f6dc9357SAndroid Build Coastguard Worker {
337*f6dc9357SAndroid Build Coastguard Worker // Print("Thread_Wait_Close")
338*f6dc9357SAndroid Build Coastguard Worker void *thread_return;
339*f6dc9357SAndroid Build Coastguard Worker int ret;
340*f6dc9357SAndroid Build Coastguard Worker if (!p->_created)
341*f6dc9357SAndroid Build Coastguard Worker return EINVAL;
342*f6dc9357SAndroid Build Coastguard Worker
343*f6dc9357SAndroid Build Coastguard Worker ret = pthread_join(p->_tid, &thread_return);
344*f6dc9357SAndroid Build Coastguard Worker // probably we can't use that (_tid) after pthread_join(), so we close thread here
345*f6dc9357SAndroid Build Coastguard Worker p->_created = 0;
346*f6dc9357SAndroid Build Coastguard Worker p->_tid = 0;
347*f6dc9357SAndroid Build Coastguard Worker return ret;
348*f6dc9357SAndroid Build Coastguard Worker }
349*f6dc9357SAndroid Build Coastguard Worker
350*f6dc9357SAndroid Build Coastguard Worker
351*f6dc9357SAndroid Build Coastguard Worker
Event_Create(CEvent * p,int manualReset,int signaled)352*f6dc9357SAndroid Build Coastguard Worker static WRes Event_Create(CEvent *p, int manualReset, int signaled)
353*f6dc9357SAndroid Build Coastguard Worker {
354*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_init(&p->_mutex, NULL))
355*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_cond_init(&p->_cond, NULL))
356*f6dc9357SAndroid Build Coastguard Worker p->_manual_reset = manualReset;
357*f6dc9357SAndroid Build Coastguard Worker p->_state = (signaled ? True : False);
358*f6dc9357SAndroid Build Coastguard Worker p->_created = 1;
359*f6dc9357SAndroid Build Coastguard Worker return 0;
360*f6dc9357SAndroid Build Coastguard Worker }
361*f6dc9357SAndroid Build Coastguard Worker
ManualResetEvent_Create(CManualResetEvent * p,int signaled)362*f6dc9357SAndroid Build Coastguard Worker WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled)
363*f6dc9357SAndroid Build Coastguard Worker { return Event_Create(p, True, signaled); }
ManualResetEvent_CreateNotSignaled(CManualResetEvent * p)364*f6dc9357SAndroid Build Coastguard Worker WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p)
365*f6dc9357SAndroid Build Coastguard Worker { return ManualResetEvent_Create(p, 0); }
AutoResetEvent_Create(CAutoResetEvent * p,int signaled)366*f6dc9357SAndroid Build Coastguard Worker WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled)
367*f6dc9357SAndroid Build Coastguard Worker { return Event_Create(p, False, signaled); }
AutoResetEvent_CreateNotSignaled(CAutoResetEvent * p)368*f6dc9357SAndroid Build Coastguard Worker WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p)
369*f6dc9357SAndroid Build Coastguard Worker { return AutoResetEvent_Create(p, 0); }
370*f6dc9357SAndroid Build Coastguard Worker
371*f6dc9357SAndroid Build Coastguard Worker
372*f6dc9357SAndroid Build Coastguard Worker #if defined(Z7_LLVM_CLANG_VERSION) && (__clang_major__ == 13)
373*f6dc9357SAndroid Build Coastguard Worker // freebsd:
374*f6dc9357SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Wthread-safety-analysis"
375*f6dc9357SAndroid Build Coastguard Worker #endif
376*f6dc9357SAndroid Build Coastguard Worker
Event_Set(CEvent * p)377*f6dc9357SAndroid Build Coastguard Worker WRes Event_Set(CEvent *p)
378*f6dc9357SAndroid Build Coastguard Worker {
379*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_lock(&p->_mutex))
380*f6dc9357SAndroid Build Coastguard Worker p->_state = True;
381*f6dc9357SAndroid Build Coastguard Worker {
382*f6dc9357SAndroid Build Coastguard Worker const int res1 = pthread_cond_broadcast(&p->_cond);
383*f6dc9357SAndroid Build Coastguard Worker const int res2 = pthread_mutex_unlock(&p->_mutex);
384*f6dc9357SAndroid Build Coastguard Worker return (res2 ? res2 : res1);
385*f6dc9357SAndroid Build Coastguard Worker }
386*f6dc9357SAndroid Build Coastguard Worker }
387*f6dc9357SAndroid Build Coastguard Worker
Event_Reset(CEvent * p)388*f6dc9357SAndroid Build Coastguard Worker WRes Event_Reset(CEvent *p)
389*f6dc9357SAndroid Build Coastguard Worker {
390*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_lock(&p->_mutex))
391*f6dc9357SAndroid Build Coastguard Worker p->_state = False;
392*f6dc9357SAndroid Build Coastguard Worker return pthread_mutex_unlock(&p->_mutex);
393*f6dc9357SAndroid Build Coastguard Worker }
394*f6dc9357SAndroid Build Coastguard Worker
Event_Wait(CEvent * p)395*f6dc9357SAndroid Build Coastguard Worker WRes Event_Wait(CEvent *p)
396*f6dc9357SAndroid Build Coastguard Worker {
397*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_lock(&p->_mutex))
398*f6dc9357SAndroid Build Coastguard Worker while (p->_state == False)
399*f6dc9357SAndroid Build Coastguard Worker {
400*f6dc9357SAndroid Build Coastguard Worker // ETIMEDOUT
401*f6dc9357SAndroid Build Coastguard Worker // ret =
402*f6dc9357SAndroid Build Coastguard Worker pthread_cond_wait(&p->_cond, &p->_mutex);
403*f6dc9357SAndroid Build Coastguard Worker // if (ret != 0) break;
404*f6dc9357SAndroid Build Coastguard Worker }
405*f6dc9357SAndroid Build Coastguard Worker if (p->_manual_reset == False)
406*f6dc9357SAndroid Build Coastguard Worker {
407*f6dc9357SAndroid Build Coastguard Worker p->_state = False;
408*f6dc9357SAndroid Build Coastguard Worker }
409*f6dc9357SAndroid Build Coastguard Worker return pthread_mutex_unlock(&p->_mutex);
410*f6dc9357SAndroid Build Coastguard Worker }
411*f6dc9357SAndroid Build Coastguard Worker
Event_Close(CEvent * p)412*f6dc9357SAndroid Build Coastguard Worker WRes Event_Close(CEvent *p)
413*f6dc9357SAndroid Build Coastguard Worker {
414*f6dc9357SAndroid Build Coastguard Worker if (!p->_created)
415*f6dc9357SAndroid Build Coastguard Worker return 0;
416*f6dc9357SAndroid Build Coastguard Worker p->_created = 0;
417*f6dc9357SAndroid Build Coastguard Worker {
418*f6dc9357SAndroid Build Coastguard Worker const int res1 = pthread_mutex_destroy(&p->_mutex);
419*f6dc9357SAndroid Build Coastguard Worker const int res2 = pthread_cond_destroy(&p->_cond);
420*f6dc9357SAndroid Build Coastguard Worker return (res1 ? res1 : res2);
421*f6dc9357SAndroid Build Coastguard Worker }
422*f6dc9357SAndroid Build Coastguard Worker }
423*f6dc9357SAndroid Build Coastguard Worker
424*f6dc9357SAndroid Build Coastguard Worker
Semaphore_Create(CSemaphore * p,UInt32 initCount,UInt32 maxCount)425*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
426*f6dc9357SAndroid Build Coastguard Worker {
427*f6dc9357SAndroid Build Coastguard Worker if (initCount > maxCount || maxCount < 1)
428*f6dc9357SAndroid Build Coastguard Worker return EINVAL;
429*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_init(&p->_mutex, NULL))
430*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_cond_init(&p->_cond, NULL))
431*f6dc9357SAndroid Build Coastguard Worker p->_count = initCount;
432*f6dc9357SAndroid Build Coastguard Worker p->_maxCount = maxCount;
433*f6dc9357SAndroid Build Coastguard Worker p->_created = 1;
434*f6dc9357SAndroid Build Coastguard Worker return 0;
435*f6dc9357SAndroid Build Coastguard Worker }
436*f6dc9357SAndroid Build Coastguard Worker
437*f6dc9357SAndroid Build Coastguard Worker
Semaphore_OptCreateInit(CSemaphore * p,UInt32 initCount,UInt32 maxCount)438*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount)
439*f6dc9357SAndroid Build Coastguard Worker {
440*f6dc9357SAndroid Build Coastguard Worker if (Semaphore_IsCreated(p))
441*f6dc9357SAndroid Build Coastguard Worker {
442*f6dc9357SAndroid Build Coastguard Worker /*
443*f6dc9357SAndroid Build Coastguard Worker WRes wres = Semaphore_Close(p);
444*f6dc9357SAndroid Build Coastguard Worker if (wres != 0)
445*f6dc9357SAndroid Build Coastguard Worker return wres;
446*f6dc9357SAndroid Build Coastguard Worker */
447*f6dc9357SAndroid Build Coastguard Worker if (initCount > maxCount || maxCount < 1)
448*f6dc9357SAndroid Build Coastguard Worker return EINVAL;
449*f6dc9357SAndroid Build Coastguard Worker // return EINVAL; // for debug
450*f6dc9357SAndroid Build Coastguard Worker p->_count = initCount;
451*f6dc9357SAndroid Build Coastguard Worker p->_maxCount = maxCount;
452*f6dc9357SAndroid Build Coastguard Worker return 0;
453*f6dc9357SAndroid Build Coastguard Worker }
454*f6dc9357SAndroid Build Coastguard Worker return Semaphore_Create(p, initCount, maxCount);
455*f6dc9357SAndroid Build Coastguard Worker }
456*f6dc9357SAndroid Build Coastguard Worker
457*f6dc9357SAndroid Build Coastguard Worker
Semaphore_ReleaseN(CSemaphore * p,UInt32 releaseCount)458*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 releaseCount)
459*f6dc9357SAndroid Build Coastguard Worker {
460*f6dc9357SAndroid Build Coastguard Worker UInt32 newCount;
461*f6dc9357SAndroid Build Coastguard Worker int ret;
462*f6dc9357SAndroid Build Coastguard Worker
463*f6dc9357SAndroid Build Coastguard Worker if (releaseCount < 1)
464*f6dc9357SAndroid Build Coastguard Worker return EINVAL;
465*f6dc9357SAndroid Build Coastguard Worker
466*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_lock(&p->_mutex))
467*f6dc9357SAndroid Build Coastguard Worker
468*f6dc9357SAndroid Build Coastguard Worker newCount = p->_count + releaseCount;
469*f6dc9357SAndroid Build Coastguard Worker if (newCount > p->_maxCount)
470*f6dc9357SAndroid Build Coastguard Worker ret = ERROR_TOO_MANY_POSTS; // EINVAL;
471*f6dc9357SAndroid Build Coastguard Worker else
472*f6dc9357SAndroid Build Coastguard Worker {
473*f6dc9357SAndroid Build Coastguard Worker p->_count = newCount;
474*f6dc9357SAndroid Build Coastguard Worker ret = pthread_cond_broadcast(&p->_cond);
475*f6dc9357SAndroid Build Coastguard Worker }
476*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_unlock(&p->_mutex))
477*f6dc9357SAndroid Build Coastguard Worker return ret;
478*f6dc9357SAndroid Build Coastguard Worker }
479*f6dc9357SAndroid Build Coastguard Worker
Semaphore_Wait(CSemaphore * p)480*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_Wait(CSemaphore *p)
481*f6dc9357SAndroid Build Coastguard Worker {
482*f6dc9357SAndroid Build Coastguard Worker RINOK(pthread_mutex_lock(&p->_mutex))
483*f6dc9357SAndroid Build Coastguard Worker while (p->_count < 1)
484*f6dc9357SAndroid Build Coastguard Worker {
485*f6dc9357SAndroid Build Coastguard Worker pthread_cond_wait(&p->_cond, &p->_mutex);
486*f6dc9357SAndroid Build Coastguard Worker }
487*f6dc9357SAndroid Build Coastguard Worker p->_count--;
488*f6dc9357SAndroid Build Coastguard Worker return pthread_mutex_unlock(&p->_mutex);
489*f6dc9357SAndroid Build Coastguard Worker }
490*f6dc9357SAndroid Build Coastguard Worker
Semaphore_Close(CSemaphore * p)491*f6dc9357SAndroid Build Coastguard Worker WRes Semaphore_Close(CSemaphore *p)
492*f6dc9357SAndroid Build Coastguard Worker {
493*f6dc9357SAndroid Build Coastguard Worker if (!p->_created)
494*f6dc9357SAndroid Build Coastguard Worker return 0;
495*f6dc9357SAndroid Build Coastguard Worker p->_created = 0;
496*f6dc9357SAndroid Build Coastguard Worker {
497*f6dc9357SAndroid Build Coastguard Worker const int res1 = pthread_mutex_destroy(&p->_mutex);
498*f6dc9357SAndroid Build Coastguard Worker const int res2 = pthread_cond_destroy(&p->_cond);
499*f6dc9357SAndroid Build Coastguard Worker return (res1 ? res1 : res2);
500*f6dc9357SAndroid Build Coastguard Worker }
501*f6dc9357SAndroid Build Coastguard Worker }
502*f6dc9357SAndroid Build Coastguard Worker
503*f6dc9357SAndroid Build Coastguard Worker
504*f6dc9357SAndroid Build Coastguard Worker
CriticalSection_Init(CCriticalSection * p)505*f6dc9357SAndroid Build Coastguard Worker WRes CriticalSection_Init(CCriticalSection *p)
506*f6dc9357SAndroid Build Coastguard Worker {
507*f6dc9357SAndroid Build Coastguard Worker // Print("CriticalSection_Init")
508*f6dc9357SAndroid Build Coastguard Worker if (!p)
509*f6dc9357SAndroid Build Coastguard Worker return EINTR;
510*f6dc9357SAndroid Build Coastguard Worker return pthread_mutex_init(&p->_mutex, NULL);
511*f6dc9357SAndroid Build Coastguard Worker }
512*f6dc9357SAndroid Build Coastguard Worker
CriticalSection_Enter(CCriticalSection * p)513*f6dc9357SAndroid Build Coastguard Worker void CriticalSection_Enter(CCriticalSection *p)
514*f6dc9357SAndroid Build Coastguard Worker {
515*f6dc9357SAndroid Build Coastguard Worker // Print("CriticalSection_Enter")
516*f6dc9357SAndroid Build Coastguard Worker if (p)
517*f6dc9357SAndroid Build Coastguard Worker {
518*f6dc9357SAndroid Build Coastguard Worker // int ret =
519*f6dc9357SAndroid Build Coastguard Worker pthread_mutex_lock(&p->_mutex);
520*f6dc9357SAndroid Build Coastguard Worker }
521*f6dc9357SAndroid Build Coastguard Worker }
522*f6dc9357SAndroid Build Coastguard Worker
CriticalSection_Leave(CCriticalSection * p)523*f6dc9357SAndroid Build Coastguard Worker void CriticalSection_Leave(CCriticalSection *p)
524*f6dc9357SAndroid Build Coastguard Worker {
525*f6dc9357SAndroid Build Coastguard Worker // Print("CriticalSection_Leave")
526*f6dc9357SAndroid Build Coastguard Worker if (p)
527*f6dc9357SAndroid Build Coastguard Worker {
528*f6dc9357SAndroid Build Coastguard Worker // int ret =
529*f6dc9357SAndroid Build Coastguard Worker pthread_mutex_unlock(&p->_mutex);
530*f6dc9357SAndroid Build Coastguard Worker }
531*f6dc9357SAndroid Build Coastguard Worker }
532*f6dc9357SAndroid Build Coastguard Worker
CriticalSection_Delete(CCriticalSection * p)533*f6dc9357SAndroid Build Coastguard Worker void CriticalSection_Delete(CCriticalSection *p)
534*f6dc9357SAndroid Build Coastguard Worker {
535*f6dc9357SAndroid Build Coastguard Worker // Print("CriticalSection_Delete")
536*f6dc9357SAndroid Build Coastguard Worker if (p)
537*f6dc9357SAndroid Build Coastguard Worker {
538*f6dc9357SAndroid Build Coastguard Worker // int ret =
539*f6dc9357SAndroid Build Coastguard Worker pthread_mutex_destroy(&p->_mutex);
540*f6dc9357SAndroid Build Coastguard Worker }
541*f6dc9357SAndroid Build Coastguard Worker }
542*f6dc9357SAndroid Build Coastguard Worker
InterlockedIncrement(LONG volatile * addend)543*f6dc9357SAndroid Build Coastguard Worker LONG InterlockedIncrement(LONG volatile *addend)
544*f6dc9357SAndroid Build Coastguard Worker {
545*f6dc9357SAndroid Build Coastguard Worker // Print("InterlockedIncrement")
546*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_HACK_UNSAFE_ATOMIC
547*f6dc9357SAndroid Build Coastguard Worker LONG val = *addend + 1;
548*f6dc9357SAndroid Build Coastguard Worker *addend = val;
549*f6dc9357SAndroid Build Coastguard Worker return val;
550*f6dc9357SAndroid Build Coastguard Worker #else
551*f6dc9357SAndroid Build Coastguard Worker
552*f6dc9357SAndroid Build Coastguard Worker #if defined(__clang__) && (__clang_major__ >= 8)
553*f6dc9357SAndroid Build Coastguard Worker #pragma GCC diagnostic ignored "-Watomic-implicit-seq-cst"
554*f6dc9357SAndroid Build Coastguard Worker #endif
555*f6dc9357SAndroid Build Coastguard Worker return __sync_add_and_fetch(addend, 1);
556*f6dc9357SAndroid Build Coastguard Worker #endif
557*f6dc9357SAndroid Build Coastguard Worker }
558*f6dc9357SAndroid Build Coastguard Worker
InterlockedDecrement(LONG volatile * addend)559*f6dc9357SAndroid Build Coastguard Worker LONG InterlockedDecrement(LONG volatile *addend)
560*f6dc9357SAndroid Build Coastguard Worker {
561*f6dc9357SAndroid Build Coastguard Worker // Print("InterlockedDecrement")
562*f6dc9357SAndroid Build Coastguard Worker #ifdef USE_HACK_UNSAFE_ATOMIC
563*f6dc9357SAndroid Build Coastguard Worker LONG val = *addend - 1;
564*f6dc9357SAndroid Build Coastguard Worker *addend = val;
565*f6dc9357SAndroid Build Coastguard Worker return val;
566*f6dc9357SAndroid Build Coastguard Worker #else
567*f6dc9357SAndroid Build Coastguard Worker return __sync_sub_and_fetch(addend, 1);
568*f6dc9357SAndroid Build Coastguard Worker #endif
569*f6dc9357SAndroid Build Coastguard Worker }
570*f6dc9357SAndroid Build Coastguard Worker
571*f6dc9357SAndroid Build Coastguard Worker #endif // _WIN32
572*f6dc9357SAndroid Build Coastguard Worker
AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent * p)573*f6dc9357SAndroid Build Coastguard Worker WRes AutoResetEvent_OptCreate_And_Reset(CAutoResetEvent *p)
574*f6dc9357SAndroid Build Coastguard Worker {
575*f6dc9357SAndroid Build Coastguard Worker if (Event_IsCreated(p))
576*f6dc9357SAndroid Build Coastguard Worker return Event_Reset(p);
577*f6dc9357SAndroid Build Coastguard Worker return AutoResetEvent_CreateNotSignaled(p);
578*f6dc9357SAndroid Build Coastguard Worker }
579*f6dc9357SAndroid Build Coastguard Worker
580*f6dc9357SAndroid Build Coastguard Worker #undef PRF
581*f6dc9357SAndroid Build Coastguard Worker #undef Print
582