git subrepo pull (merge) --force deps/libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / lzma-22.01 / include / Threads.h
CommitLineData
9e052883 1/* Threads.h -- multithreading library\r
22021-12-21 : Igor Pavlov : Public domain */\r
3\r
4#ifndef __7Z_THREADS_H\r
5#define __7Z_THREADS_H\r
6\r
7#ifdef _WIN32\r
648db22b 8#include <windows.h>\r
9e052883 9#else\r
10\r
11#if defined(__linux__)\r
12#if !defined(__APPLE__) && !defined(_AIX) && !defined(__ANDROID__)\r
13#ifndef _7ZIP_AFFINITY_DISABLE\r
14#define _7ZIP_AFFINITY_SUPPORTED\r
15// #pragma message(" ==== _7ZIP_AFFINITY_SUPPORTED")\r
16// #define _GNU_SOURCE\r
17#endif\r
18#endif\r
19#endif\r
20\r
21#include <pthread.h>\r
22\r
23#endif\r
24\r
25#include "7zTypes.h"\r
26\r
27EXTERN_C_BEGIN\r
28\r
29#ifdef _WIN32\r
30\r
31WRes HandlePtr_Close(HANDLE *h);\r
32WRes Handle_WaitObject(HANDLE h);\r
33\r
34typedef HANDLE CThread;\r
35\r
36#define Thread_Construct(p) { *(p) = NULL; }\r
37#define Thread_WasCreated(p) (*(p) != NULL)\r
38#define Thread_Close(p) HandlePtr_Close(p)\r
39// #define Thread_Wait(p) Handle_WaitObject(*(p))\r
40\r
41#ifdef UNDER_CE\r
42 // if (USE_THREADS_CreateThread is defined), we use _beginthreadex()\r
43 // if (USE_THREADS_CreateThread is not definned), we use CreateThread()\r
44 #define USE_THREADS_CreateThread\r
45#endif\r
46\r
47typedef\r
48 #ifdef USE_THREADS_CreateThread\r
49 DWORD\r
50 #else\r
51 unsigned\r
52 #endif\r
53 THREAD_FUNC_RET_TYPE;\r
54\r
55typedef DWORD_PTR CAffinityMask;\r
56typedef DWORD_PTR CCpuSet;\r
57\r
58#define CpuSet_Zero(p) { *(p) = 0; }\r
59#define CpuSet_Set(p, cpu) { *(p) |= ((DWORD_PTR)1 << (cpu)); }\r
60\r
61#else // _WIN32\r
62\r
63typedef struct _CThread\r
64{\r
65 pthread_t _tid;\r
66 int _created;\r
67} CThread;\r
68\r
69#define Thread_Construct(p) { (p)->_tid = 0; (p)->_created = 0; }\r
70#define Thread_WasCreated(p) ((p)->_created != 0)\r
71WRes Thread_Close(CThread *p);\r
72// #define Thread_Wait Thread_Wait_Close\r
73\r
74typedef void * THREAD_FUNC_RET_TYPE;\r
75\r
76typedef UInt64 CAffinityMask;\r
77\r
78#ifdef _7ZIP_AFFINITY_SUPPORTED\r
79\r
80typedef cpu_set_t CCpuSet;\r
81#define CpuSet_Zero(p) CPU_ZERO(p)\r
82#define CpuSet_Set(p, cpu) CPU_SET(cpu, p)\r
83#define CpuSet_IsSet(p, cpu) CPU_ISSET(cpu, p)\r
84\r
85#else\r
86\r
87typedef UInt64 CCpuSet;\r
88#define CpuSet_Zero(p) { *(p) = 0; }\r
89#define CpuSet_Set(p, cpu) { *(p) |= ((UInt64)1 << (cpu)); }\r
90#define CpuSet_IsSet(p, cpu) ((*(p) & ((UInt64)1 << (cpu))) != 0)\r
91\r
92#endif\r
93\r
94\r
95#endif // _WIN32\r
96\r
97\r
98#define THREAD_FUNC_CALL_TYPE MY_STD_CALL\r
99\r
100#if defined(_WIN32) && defined(__GNUC__)\r
101/* GCC compiler for x86 32-bit uses the rule:\r
102 the stack is 16-byte aligned before CALL instruction for function calling.\r
103 But only root function main() contains instructions that\r
104 set 16-byte alignment for stack pointer. And another functions\r
105 just keep alignment, if it was set in some parent function.\r
106 \r
107 The problem:\r
108 if we create new thread in MinGW (GCC) 32-bit x86 via _beginthreadex() or CreateThread(),\r
109 the root function of thread doesn't set 16-byte alignment.\r
110 And stack frames in all child functions also will be unaligned in that case.\r
111 \r
112 Here we set (force_align_arg_pointer) attribute for root function of new thread.\r
113 Do we need (force_align_arg_pointer) also for another systems? */\r
114 \r
115 #define THREAD_FUNC_ATTRIB_ALIGN_ARG __attribute__((force_align_arg_pointer))\r
116 // #define THREAD_FUNC_ATTRIB_ALIGN_ARG // for debug : bad alignment in SSE functions\r
117#else\r
118 #define THREAD_FUNC_ATTRIB_ALIGN_ARG\r
119#endif\r
120\r
121#define THREAD_FUNC_DECL THREAD_FUNC_ATTRIB_ALIGN_ARG THREAD_FUNC_RET_TYPE THREAD_FUNC_CALL_TYPE\r
122\r
123typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);\r
124WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);\r
125WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity);\r
126WRes Thread_Wait_Close(CThread *p);\r
127\r
128#ifdef _WIN32\r
129#define Thread_Create_With_CpuSet(p, func, param, cs) \\r
130 Thread_Create_With_Affinity(p, func, param, *cs)\r
131#else\r
132WRes Thread_Create_With_CpuSet(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, const CCpuSet *cpuSet);\r
133#endif\r
134\r
135\r
136#ifdef _WIN32\r
137\r
138typedef HANDLE CEvent;\r
139typedef CEvent CAutoResetEvent;\r
140typedef CEvent CManualResetEvent;\r
141#define Event_Construct(p) *(p) = NULL\r
142#define Event_IsCreated(p) (*(p) != NULL)\r
143#define Event_Close(p) HandlePtr_Close(p)\r
144#define Event_Wait(p) Handle_WaitObject(*(p))\r
145WRes Event_Set(CEvent *p);\r
146WRes Event_Reset(CEvent *p);\r
147WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);\r
148WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);\r
149WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);\r
150WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);\r
151\r
152typedef HANDLE CSemaphore;\r
153#define Semaphore_Construct(p) *(p) = NULL\r
154#define Semaphore_IsCreated(p) (*(p) != NULL)\r
155#define Semaphore_Close(p) HandlePtr_Close(p)\r
156#define Semaphore_Wait(p) Handle_WaitObject(*(p))\r
157WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
158WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
159WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);\r
160WRes Semaphore_Release1(CSemaphore *p);\r
161\r
162typedef CRITICAL_SECTION CCriticalSection;\r
163WRes CriticalSection_Init(CCriticalSection *p);\r
164#define CriticalSection_Delete(p) DeleteCriticalSection(p)\r
165#define CriticalSection_Enter(p) EnterCriticalSection(p)\r
166#define CriticalSection_Leave(p) LeaveCriticalSection(p)\r
167\r
168\r
169#else // _WIN32\r
170\r
171typedef struct _CEvent\r
172{\r
173 int _created;\r
174 int _manual_reset;\r
175 int _state;\r
176 pthread_mutex_t _mutex;\r
177 pthread_cond_t _cond;\r
178} CEvent;\r
179\r
180typedef CEvent CAutoResetEvent;\r
181typedef CEvent CManualResetEvent;\r
182\r
183#define Event_Construct(p) (p)->_created = 0\r
184#define Event_IsCreated(p) ((p)->_created)\r
185\r
186WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);\r
187WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);\r
188WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);\r
189WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);\r
190WRes Event_Set(CEvent *p);\r
191WRes Event_Reset(CEvent *p);\r
192WRes Event_Wait(CEvent *p);\r
193WRes Event_Close(CEvent *p);\r
194\r
195\r
196typedef struct _CSemaphore\r
197{\r
198 int _created;\r
199 UInt32 _count;\r
200 UInt32 _maxCount;\r
201 pthread_mutex_t _mutex;\r
202 pthread_cond_t _cond;\r
203} CSemaphore;\r
204\r
205#define Semaphore_Construct(p) (p)->_created = 0\r
206#define Semaphore_IsCreated(p) ((p)->_created)\r
207\r
208WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
209WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
210WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);\r
211#define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1)\r
212WRes Semaphore_Wait(CSemaphore *p);\r
213WRes Semaphore_Close(CSemaphore *p);\r
214\r
215\r
216typedef struct _CCriticalSection\r
217{\r
218 pthread_mutex_t _mutex;\r
219} CCriticalSection;\r
220\r
221WRes CriticalSection_Init(CCriticalSection *p);\r
222void CriticalSection_Delete(CCriticalSection *cs);\r
223void CriticalSection_Enter(CCriticalSection *cs);\r
224void CriticalSection_Leave(CCriticalSection *cs);\r
225\r
226LONG InterlockedIncrement(LONG volatile *addend);\r
227\r
228#endif // _WIN32\r
229\r
230EXTERN_C_END\r
231\r
232#endif\r