update libchdr
[pcsx_rearmed.git] / deps / libchdr / deps / lzma-22.01 / include / Threads.h
1 /* Threads.h -- multithreading library\r
2 2021-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
8 #include <Windows.h>\r
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
27 EXTERN_C_BEGIN\r
28 \r
29 #ifdef _WIN32\r
30 \r
31 WRes HandlePtr_Close(HANDLE *h);\r
32 WRes Handle_WaitObject(HANDLE h);\r
33 \r
34 typedef 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
47 typedef\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
55 typedef DWORD_PTR CAffinityMask;\r
56 typedef 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
63 typedef 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
71 WRes Thread_Close(CThread *p);\r
72 // #define Thread_Wait Thread_Wait_Close\r
73 \r
74 typedef void * THREAD_FUNC_RET_TYPE;\r
75 \r
76 typedef UInt64 CAffinityMask;\r
77 \r
78 #ifdef _7ZIP_AFFINITY_SUPPORTED\r
79 \r
80 typedef 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
87 typedef 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
123 typedef THREAD_FUNC_RET_TYPE (THREAD_FUNC_CALL_TYPE * THREAD_FUNC_TYPE)(void *);\r
124 WRes Thread_Create(CThread *p, THREAD_FUNC_TYPE func, LPVOID param);\r
125 WRes Thread_Create_With_Affinity(CThread *p, THREAD_FUNC_TYPE func, LPVOID param, CAffinityMask affinity);\r
126 WRes 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
132 WRes 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
138 typedef HANDLE CEvent;\r
139 typedef CEvent CAutoResetEvent;\r
140 typedef 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
145 WRes Event_Set(CEvent *p);\r
146 WRes Event_Reset(CEvent *p);\r
147 WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);\r
148 WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);\r
149 WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);\r
150 WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);\r
151 \r
152 typedef 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
157 WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
158 WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
159 WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);\r
160 WRes Semaphore_Release1(CSemaphore *p);\r
161 \r
162 typedef CRITICAL_SECTION CCriticalSection;\r
163 WRes 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
171 typedef 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
180 typedef CEvent CAutoResetEvent;\r
181 typedef CEvent CManualResetEvent;\r
182 \r
183 #define Event_Construct(p) (p)->_created = 0\r
184 #define Event_IsCreated(p) ((p)->_created)\r
185 \r
186 WRes ManualResetEvent_Create(CManualResetEvent *p, int signaled);\r
187 WRes ManualResetEvent_CreateNotSignaled(CManualResetEvent *p);\r
188 WRes AutoResetEvent_Create(CAutoResetEvent *p, int signaled);\r
189 WRes AutoResetEvent_CreateNotSignaled(CAutoResetEvent *p);\r
190 WRes Event_Set(CEvent *p);\r
191 WRes Event_Reset(CEvent *p);\r
192 WRes Event_Wait(CEvent *p);\r
193 WRes Event_Close(CEvent *p);\r
194 \r
195 \r
196 typedef 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
208 WRes Semaphore_Create(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
209 WRes Semaphore_OptCreateInit(CSemaphore *p, UInt32 initCount, UInt32 maxCount);\r
210 WRes Semaphore_ReleaseN(CSemaphore *p, UInt32 num);\r
211 #define Semaphore_Release1(p) Semaphore_ReleaseN(p, 1)\r
212 WRes Semaphore_Wait(CSemaphore *p);\r
213 WRes Semaphore_Close(CSemaphore *p);\r
214 \r
215 \r
216 typedef struct _CCriticalSection\r
217 {\r
218   pthread_mutex_t _mutex;\r
219 } CCriticalSection;\r
220 \r
221 WRes CriticalSection_Init(CCriticalSection *p);\r
222 void CriticalSection_Delete(CCriticalSection *cs);\r
223 void CriticalSection_Enter(CCriticalSection *cs);\r
224 void CriticalSection_Leave(CCriticalSection *cs);\r
225 \r
226 LONG InterlockedIncrement(LONG volatile *addend);\r
227 \r
228 #endif  // _WIN32\r
229 \r
230 EXTERN_C_END\r
231 \r
232 #endif\r