Codebase list kodi-pvr-mythtv / 50c60f91-7f13-4eb4-950b-464d3a931a00/main
New upstream snapshot. Debian Janitor 2 years ago
6 changed file(s) with 2035 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
0 # build artifacts
1 build/
2 pvr.*/addon.xml
3
4 # Debian build files
5 debian/changelog
6 debian/files
7 debian/*.log
8 debian/*.substvars
9 debian/.debhelper/
10 debian/tmp/
11 debian/kodi-pvr-*/
12 obj-x86_64-linux-gnu/
13
14 # commonly used editors
15 # vim
16 *.swp
17
18 # Eclipse
19 *.project
20 *.cproject
21 .classpath
22 *.sublime-*
23 .settings/
24
25 # KDevelop 4
26 *.kdev4
27
28 # gedit
29 *~
30
31 # CLion
32 /.idea
33
34 # clion
35 .idea/
36
37 # to prevent add after a "git format-patch VALUE" and "git add ." call
38 /*.patch
39
40 # Visual Studio Code
41 .vscode
42
43 # to prevent add if project code opened by Visual Studio over CMake file
44 .vs/
45
46 # others
47 nbproject
48 cppmyth_config.h
0 kodi-pvr-mythtv (7.3.1+ds1+git20210307.1.caf638b-1) UNRELEASED; urgency=low
1
2 * New upstream snapshot.
3
4 -- Debian Janitor <janitor@jelmer.uk> Thu, 26 Aug 2021 16:12:04 -0000
5
06 kodi-pvr-mythtv (7.3.1+ds1-2) unstable; urgency=medium
17
28 * Restrict watchfile to current stable Kodi codename
0 // ISO C9x compliant inttypes.h for Microsoft Visual Studio
1 // Based on ISO/IEC 9899:TC2 Committee draft (May 6, 2005) WG14/N1124
2 //
3 // Copyright (c) 2006 Alexander Chemeris
4 //
5 // Redistribution and use in source and binary forms, with or without
6 // modification, are permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice,
9 // this list of conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright
12 // notice, this list of conditions and the following disclaimer in the
13 // documentation and/or other materials provided with the distribution.
14 //
15 // 3. The name of the author may be used to endorse or promote products
16 // derived from this software without specific prior written permission.
17 //
18 // THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED
19 // WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
20 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
21 // EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
22 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
23 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
24 // OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
25 // WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
26 // OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
27 // ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 //
29 ///////////////////////////////////////////////////////////////////////////////
30
31 #ifndef _MSC_VER // [
32 #error "Use this header only with Microsoft Visual C++ compilers!"
33 #endif // _MSC_VER ]
34
35 #ifndef _MSC_INTTYPES_H_ // [
36 #define _MSC_INTTYPES_H_
37
38 #include "stdint.h"
39
40 // 7.8 Format conversion of integer types
41
42 typedef struct {
43 intmax_t quot;
44 intmax_t rem;
45 } imaxdiv_t;
46
47 // 7.8.1 Macros for format specifiers
48
49 #if !defined(__cplusplus) || defined(__STDC_FORMAT_MACROS) // [ See footnote 185 at page 198
50
51 // The fprintf macros for signed integers are:
52 #define PRId8 "d"
53 #define PRIi8 "i"
54 #define PRIdLEAST8 "d"
55 #define PRIiLEAST8 "i"
56 #define PRIdFAST8 "d"
57 #define PRIiFAST8 "i"
58
59 #define PRId16 "hd"
60 #define PRIi16 "hi"
61 #define PRIdLEAST16 "hd"
62 #define PRIiLEAST16 "hi"
63 #define PRIdFAST16 "hd"
64 #define PRIiFAST16 "hi"
65
66 #define PRId32 "I32d"
67 #define PRIi32 "I32i"
68 #define PRIdLEAST32 "I32d"
69 #define PRIiLEAST32 "I32i"
70 #define PRIdFAST32 "I32d"
71 #define PRIiFAST32 "I32i"
72
73 #define PRId64 "I64d"
74 #define PRIi64 "I64i"
75 #define PRIdLEAST64 "I64d"
76 #define PRIiLEAST64 "I64i"
77 #define PRIdFAST64 "I64d"
78 #define PRIiFAST64 "I64i"
79
80 #define PRIdMAX "I64d"
81 #define PRIiMAX "I64i"
82
83 #define PRIdPTR "Id"
84 #define PRIiPTR "Ii"
85
86 // The fprintf macros for unsigned integers are:
87 #define PRIo8 "o"
88 #define PRIu8 "u"
89 #define PRIx8 "x"
90 #define PRIX8 "X"
91 #define PRIoLEAST8 "o"
92 #define PRIuLEAST8 "u"
93 #define PRIxLEAST8 "x"
94 #define PRIXLEAST8 "X"
95 #define PRIoFAST8 "o"
96 #define PRIuFAST8 "u"
97 #define PRIxFAST8 "x"
98 #define PRIXFAST8 "X"
99
100 #define PRIo16 "ho"
101 #define PRIu16 "hu"
102 #define PRIx16 "hx"
103 #define PRIX16 "hX"
104 #define PRIoLEAST16 "ho"
105 #define PRIuLEAST16 "hu"
106 #define PRIxLEAST16 "hx"
107 #define PRIXLEAST16 "hX"
108 #define PRIoFAST16 "ho"
109 #define PRIuFAST16 "hu"
110 #define PRIxFAST16 "hx"
111 #define PRIXFAST16 "hX"
112
113 #define PRIo32 "I32o"
114 #define PRIu32 "I32u"
115 #define PRIx32 "I32x"
116 #define PRIX32 "I32X"
117 #define PRIoLEAST32 "I32o"
118 #define PRIuLEAST32 "I32u"
119 #define PRIxLEAST32 "I32x"
120 #define PRIXLEAST32 "I32X"
121 #define PRIoFAST32 "I32o"
122 #define PRIuFAST32 "I32u"
123 #define PRIxFAST32 "I32x"
124 #define PRIXFAST32 "I32X"
125
126 #define PRIo64 "I64o"
127 #define PRIu64 "I64u"
128 #define PRIx64 "I64x"
129 #define PRIX64 "I64X"
130 #define PRIoLEAST64 "I64o"
131 #define PRIuLEAST64 "I64u"
132 #define PRIxLEAST64 "I64x"
133 #define PRIXLEAST64 "I64X"
134 #define PRIoFAST64 "I64o"
135 #define PRIuFAST64 "I64u"
136 #define PRIxFAST64 "I64x"
137 #define PRIXFAST64 "I64X"
138
139 #define PRIoMAX "I64o"
140 #define PRIuMAX "I64u"
141 #define PRIxMAX "I64x"
142 #define PRIXMAX "I64X"
143
144 #define PRIoPTR "Io"
145 #define PRIuPTR "Iu"
146 #define PRIxPTR "Ix"
147 #define PRIXPTR "IX"
148
149 #define PRIdS "Id"
150 #define PRIuS "Iu"
151
152 // The fscanf macros for signed integers are:
153 #define SCNd8 "d"
154 #define SCNi8 "i"
155 #define SCNdLEAST8 "d"
156 #define SCNiLEAST8 "i"
157 #define SCNdFAST8 "d"
158 #define SCNiFAST8 "i"
159
160 #define SCNd16 "hd"
161 #define SCNi16 "hi"
162 #define SCNdLEAST16 "hd"
163 #define SCNiLEAST16 "hi"
164 #define SCNdFAST16 "hd"
165 #define SCNiFAST16 "hi"
166
167 #define SCNd32 "ld"
168 #define SCNi32 "li"
169 #define SCNdLEAST32 "ld"
170 #define SCNiLEAST32 "li"
171 #define SCNdFAST32 "ld"
172 #define SCNiFAST32 "li"
173
174 #define SCNd64 "I64d"
175 #define SCNi64 "I64i"
176 #define SCNdLEAST64 "I64d"
177 #define SCNiLEAST64 "I64i"
178 #define SCNdFAST64 "I64d"
179 #define SCNiFAST64 "I64i"
180
181 #define SCNdMAX "I64d"
182 #define SCNiMAX "I64i"
183
184 #ifdef _WIN64 // [
185 # define SCNdPTR "I64d"
186 # define SCNiPTR "I64i"
187 #else // _WIN64 ][
188 # define SCNdPTR "ld"
189 # define SCNiPTR "li"
190 #endif // _WIN64 ]
191
192 // The fscanf macros for unsigned integers are:
193 #define SCNo8 "o"
194 #define SCNu8 "u"
195 #define SCNx8 "x"
196 #define SCNX8 "X"
197 #define SCNoLEAST8 "o"
198 #define SCNuLEAST8 "u"
199 #define SCNxLEAST8 "x"
200 #define SCNXLEAST8 "X"
201 #define SCNoFAST8 "o"
202 #define SCNuFAST8 "u"
203 #define SCNxFAST8 "x"
204 #define SCNXFAST8 "X"
205
206 #define SCNo16 "ho"
207 #define SCNu16 "hu"
208 #define SCNx16 "hx"
209 #define SCNX16 "hX"
210 #define SCNoLEAST16 "ho"
211 #define SCNuLEAST16 "hu"
212 #define SCNxLEAST16 "hx"
213 #define SCNXLEAST16 "hX"
214 #define SCNoFAST16 "ho"
215 #define SCNuFAST16 "hu"
216 #define SCNxFAST16 "hx"
217 #define SCNXFAST16 "hX"
218
219 #define SCNo32 "lo"
220 #define SCNu32 "lu"
221 #define SCNx32 "lx"
222 #define SCNX32 "lX"
223 #define SCNoLEAST32 "lo"
224 #define SCNuLEAST32 "lu"
225 #define SCNxLEAST32 "lx"
226 #define SCNXLEAST32 "lX"
227 #define SCNoFAST32 "lo"
228 #define SCNuFAST32 "lu"
229 #define SCNxFAST32 "lx"
230 #define SCNXFAST32 "lX"
231
232 #define SCNo64 "I64o"
233 #define SCNu64 "I64u"
234 #define SCNx64 "I64x"
235 #define SCNX64 "I64X"
236 #define SCNoLEAST64 "I64o"
237 #define SCNuLEAST64 "I64u"
238 #define SCNxLEAST64 "I64x"
239 #define SCNXLEAST64 "I64X"
240 #define SCNoFAST64 "I64o"
241 #define SCNuFAST64 "I64u"
242 #define SCNxFAST64 "I64x"
243 #define SCNXFAST64 "I64X"
244
245 #define SCNoMAX "I64o"
246 #define SCNuMAX "I64u"
247 #define SCNxMAX "I64x"
248 #define SCNXMAX "I64X"
249
250 #ifdef _WIN64 // [
251 # define SCNoPTR "I64o"
252 # define SCNuPTR "I64u"
253 # define SCNxPTR "I64x"
254 # define SCNXPTR "I64X"
255 #else // _WIN64 ][
256 # define SCNoPTR "lo"
257 # define SCNuPTR "lu"
258 # define SCNxPTR "lx"
259 # define SCNXPTR "lX"
260 #endif // _WIN64 ]
261
262 #endif // __STDC_FORMAT_MACROS ]
263
264 // 7.8.2 Functions for greatest-width integer types
265
266 // 7.8.2.1 The imaxabs function
267 #define imaxabs _abs64
268
269 // 7.8.2.2 The imaxdiv function
270
271 // This is modified version of div() function from Microsoft's div.c found
272 // in %MSVC.NET%\crt\src\div.c
273 #ifdef STATIC_IMAXDIV // [
274 static
275 #else // STATIC_IMAXDIV ][
276 _inline
277 #endif // STATIC_IMAXDIV ]
278 imaxdiv_t __cdecl imaxdiv(intmax_t numer, intmax_t denom)
279 {
280 imaxdiv_t result;
281
282 result.quot = numer / denom;
283 result.rem = numer % denom;
284
285 if (numer < 0 && result.rem > 0) {
286 // did division wrong; must fix up
287 ++result.quot;
288 result.rem -= denom;
289 }
290
291 return result;
292 }
293
294 // 7.8.2.3 The strtoimax and strtoumax functions
295 #define strtoimax _strtoi64
296 #define strtoumax _strtoui64
297
298 // 7.8.2.4 The wcstoimax and wcstoumax functions
299 #define wcstoimax _wcstoi64
300 #define wcstoumax _wcstoui64
301
302
303 #endif // _MSC_INTTYPES_H_ ]
0 #pragma once
1
2 #if !defined(__WINDOWS__)
3 #define __WINDOWS__
4 #endif
5
6 /* Enable LEAN_AND_MEAN support */
7 #define WIN32_LEAN_AND_MEAN
8
9 /* Don't define min() and max() to prevent a clash with std::min() and std::max */
10 #ifndef NOMINMAX
11 #define NOMINMAX
12 #endif
13
14 /* Disable warning C4005: '_WINSOCKAPI_' : macro redefinition */
15 #pragma warning(disable:4005)
16 #include <WinSock2.h>
17 #pragma warning(default:4005)
18 #include <Windows.h>
19 #include <wchar.h>
20 #include <time.h>
21 #include <sys/timeb.h>
22 #include <io.h>
23 #include <stdlib.h>
24 #include <errno.h>
25 #include <stddef.h>
26 #include <stdint.h>
27 #ifndef __STDC_FORMAT_MACROS
28 #define __STDC_FORMAT_MACROS
29 #endif
30
31 /* prevent inclusion of wingdi.h */
32 #define NOGDI
33
34 typedef SOCKET net_socket_t;
35 #define INVALID_SOCKET_VALUE INVALID_SOCKET
36
37 /* OS dependent path separator */
38 #ifndef PATH_SEPARATOR_CHAR
39 #define PATH_SEPARATOR_CHAR '\\'
40 #define PATH_SEPARATOR_STRING "\\"
41 #endif
42
43 #ifndef _SSIZE_T_DEFINED
44 #ifdef _WIN64
45 typedef __int64 ssize_t;
46 #else
47 typedef _W64 int ssize_t;
48 #endif
49 #define _SSIZE_T_DEFINED
50 #endif
51
52 __inline int usleep(unsigned int usec)
53 {
54 Sleep((DWORD)(usec / 1000));
55 return 0;
56 }
57
58 __inline unsigned int sleep(unsigned int sec)
59 {
60 Sleep((DWORD)(sec * 1000));
61 return 0;
62 }
63
64 /* Using MS Visual C++ compilers */
65 #if defined(_MSC_VER)
66
67 #if (_MSC_VER < 1800)
68 #include "msc_inttypes.h"
69 #else
70 #include <inttypes.h>
71 #endif
72
73 struct timezone
74 {
75 int tz_minuteswest;
76 int tz_dsttime;
77 };
78
79 /* String to 64-bit int */
80 #if (_MSC_VER < 1800)
81 #define atoll(S) _atoi64(S)
82 #endif
83
84 /* Prevent deprecation warnings */
85 #if (_MSC_VER < 1900)
86 #define snprintf _snprintf
87 #endif
88
89 #define strnicmp _strnicmp
90
91 #else
92 #include <inttypes.h>
93 #endif /* _MSC_VER */
0 /*
1 * Posix Threads library for Microsoft Windows
2 *
3 * Use at own risk, there is no implied warranty to this code.
4 * It uses undocumented features of Microsoft Windows that can change
5 * at any time in the future.
6 *
7 * (C) 2010 Lockless Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 *
14 * * Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * * Neither the name of Lockless Inc. nor the names of its contributors may be
20 * used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 * OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 /*
36 * Version 1.0.1 Released 2 Feb 2012
37 * Fixes pthread_barrier_destroy() to wait for threads to exit the barrier.
38 */
39
40 #include "winpthreads.h"
41 #include <sys/timeb.h>
42 #include <setjmp.h>
43 #include <intrin.h>
44 #include <process.h>
45
46 typedef struct _pthread_cleanup _pthread_cleanup;
47 struct _pthread_cleanup
48 {
49 void (*func)(void *);
50 void *arg;
51 _pthread_cleanup *next;
52 };
53
54 struct _pthread_v
55 {
56 void *ret_arg;
57 void *(* func)(void *);
58 _pthread_cleanup *clean;
59 HANDLE h;
60 int cancelled;
61 unsigned p_state;
62 unsigned keymax;
63 void **keyval;
64
65 jmp_buf jb;
66 };
67
68 volatile long _pthread_cancelling;
69
70 int _pthread_concur;
71
72 /* Will default to zero as needed */
73 pthread_once_t _pthread_tls_once;
74 DWORD _pthread_tls;
75
76 /* Note initializer is zero, so this works */
77 pthread_rwlock_t _pthread_key_lock;
78 unsigned _pthread_key_max;
79 unsigned _pthread_key_sch;
80 void (**_pthread_key_dest)(void *);
81
82
83 #define pthread_cleanup_push(F, A)\
84 {\
85 const _pthread_cleanup _pthread_cup = {(F), (A), pthread_self()->clean};\
86 _ReadWriteBarrier();\
87 pthread_self()->clean = (_pthread_cleanup *) &_pthread_cup;\
88 _ReadWriteBarrier()
89
90 /* Note that if async cancelling is used, then there is a race here */
91 #define pthread_cleanup_pop(E)\
92 (pthread_self()->clean = _pthread_cup.next, (E ? _pthread_cup.func(_pthread_cup.arg) : 0));}
93
94 static void _pthread_once_cleanup(pthread_once_t *o)
95 {
96 *o = 0;
97 }
98
99 int pthread_once(pthread_once_t *o, void (*func)(void))
100 {
101 long state = *o;
102
103 _ReadWriteBarrier();
104
105 while (state != 1)
106 {
107 if (!state)
108 {
109 if (!_InterlockedCompareExchange(o, 2, 0))
110 {
111 /* Success */
112 pthread_cleanup_push((void(*)(void*))_pthread_once_cleanup, o);
113 func();
114 pthread_cleanup_pop(0);
115
116 /* Mark as done */
117 *o = 1;
118
119 return 0;
120 }
121 }
122
123 YieldProcessor();
124
125 _ReadWriteBarrier();
126
127 state = *o;
128 }
129
130 /* Done */
131 return 0;
132 }
133
134 static int _pthread_once_raw(pthread_once_t *o, void (*func)(void))
135 {
136 long state = *o;
137
138 _ReadWriteBarrier();
139
140 while (state != 1)
141 {
142 if (!state)
143 {
144 if (!_InterlockedCompareExchange(o, 2, 0))
145 {
146 /* Success */
147 func();
148
149 /* Mark as done */
150 *o = 1;
151
152 return 0;
153 }
154 }
155
156 YieldProcessor();
157
158 _ReadWriteBarrier();
159
160 state = *o;
161 }
162
163 /* Done */
164 return 0;
165 }
166
167 int pthread_mutex_lock(pthread_mutex_t *m)
168 {
169 EnterCriticalSection(m);
170 return 0;
171 }
172
173 int pthread_mutex_unlock(pthread_mutex_t *m)
174 {
175 LeaveCriticalSection(m);
176 return 0;
177 }
178
179 int pthread_mutex_trylock(pthread_mutex_t *m)
180 {
181 return TryEnterCriticalSection(m) ? 0 : EBUSY;
182 }
183
184 int pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *a)
185 {
186 (void) a;
187 InitializeCriticalSection(m);
188
189 return 0;
190 }
191
192 int pthread_mutex_destroy(pthread_mutex_t *m)
193 {
194 DeleteCriticalSection(m);
195 return 0;
196 }
197
198 int pthread_equal(pthread_t t1, pthread_t t2)
199 {
200 return t1 == t2;
201 }
202
203 int pthread_rwlock_init(pthread_rwlock_t *l, pthread_rwlockattr_t *a)
204 {
205 (void) a;
206 InitializeSRWLock(l);
207
208 return 0;
209 }
210
211 int pthread_rwlock_destroy(pthread_rwlock_t *l)
212 {
213 (void) *l;
214 return 0;
215 }
216
217 int pthread_rwlock_rdlock(pthread_rwlock_t *l)
218 {
219 pthread_testcancel();
220 AcquireSRWLockShared(l);
221
222 return 0;
223 }
224
225 int pthread_rwlock_wrlock(pthread_rwlock_t *l)
226 {
227 pthread_testcancel();
228 AcquireSRWLockExclusive(l);
229
230 return 0;
231 }
232
233 int pthread_rwlock_unlock(pthread_rwlock_t *l)
234 {
235 void *state = *(void **)l;
236
237 if (state == (void *)1)
238 {
239 /* Known to be an exclusive lock */
240 ReleaseSRWLockExclusive(l);
241 }
242 else
243 {
244 /* A shared unlock will work */
245 ReleaseSRWLockShared(l);
246 }
247
248 return 0;
249 }
250
251 int pthread_rwlock_tryrdlock(pthread_rwlock_t *l)
252 {
253 /* Get the current state of the lock */
254 void *state = *(void **)l;
255
256 if (!state)
257 {
258 /* Unlocked to locked */
259 if (!_InterlockedCompareExchangePointer((void *volatile *)l, (void *)0x11, NULL)) return 0;
260 return EBUSY;
261 }
262
263 /* A single writer exists */
264 if (state == (void *)1) return EBUSY;
265
266 /* Multiple writers exist? */
267 if ((uintptr_t)state & 14) return EBUSY;
268
269 if (_InterlockedCompareExchangePointer((void *volatile *)l, (void *)((uintptr_t)state + 16), state) == state) return 0;
270
271 return EBUSY;
272 }
273
274 int pthread_rwlock_trywrlock(pthread_rwlock_t *l)
275 {
276 /* Try to grab lock if it has no users */
277 if (!_InterlockedCompareExchangePointer((void *volatile *)l, (void *)1, NULL)) return 0;
278
279 return EBUSY;
280 }
281
282 void pthread_tls_init(void)
283 {
284 _pthread_tls = TlsAlloc();
285
286 /* Cannot continue if out of indexes */
287 if (_pthread_tls == TLS_OUT_OF_INDEXES) abort();
288 }
289
290 static void _pthread_cleanup_dest(pthread_t t)
291 {
292 unsigned i, j;
293
294 for (j = 0; j < PTHREAD_DESTRUCTOR_ITERATIONS; j++)
295 {
296 int flag = 0;
297
298 for (i = 0; i < t->keymax; i++)
299 {
300 void *val = t->keyval[i];
301
302 if (val)
303 {
304 pthread_rwlock_rdlock(&_pthread_key_lock);
305 if ((uintptr_t) _pthread_key_dest[i] > 1)
306 {
307 /* Call destructor */
308 t->keyval[i] = NULL;
309 _pthread_key_dest[i](val);
310 flag = 1;
311 }
312 pthread_rwlock_unlock(&_pthread_key_lock);
313 }
314 }
315
316 /* Nothing to do? */
317 if (!flag) return;
318 }
319 }
320
321 pthread_t pthread_self(void)
322 {
323 pthread_t t;
324
325 _pthread_once_raw(&_pthread_tls_once, pthread_tls_init);
326
327 t = (struct _pthread_v*)TlsGetValue(_pthread_tls);
328 /* Main thread? */
329 if (!t)
330 {
331 t = (struct _pthread_v*)malloc(sizeof(struct _pthread_v));
332
333 /* If cannot initialize main thread, then the only thing we can do is abort */
334 if (!t) abort();
335
336 t->ret_arg = NULL;
337 t->func = NULL;
338 t->clean = NULL;
339 t->cancelled = 0;
340 t->p_state = PTHREAD_DEFAULT_ATTR;
341 t->keymax = 0;
342 t->keyval = NULL;
343 t->h = GetCurrentThread();
344
345 /* Save for later */
346 TlsSetValue(_pthread_tls, t);
347
348 if (setjmp(t->jb))
349 {
350 /* Make sure we free ourselves if we are detached */
351 if (!t->h) free(t);
352
353 /* Time to die */
354 _endthreadex(0);
355 }
356 }
357
358 return t;
359 }
360
361 static unsigned long long _pthread_time_in_ms(void)
362 {
363 struct __timeb64 tb;
364
365 _ftime64(&tb);
366
367 return tb.time * 1000 + tb.millitm;
368 }
369
370 static unsigned long long _pthread_time_in_ms_from_timespec(const struct timespec *ts)
371 {
372 unsigned long long t = ts->tv_sec * 1000;
373 t += ts->tv_nsec / 1000000;
374
375 return t;
376 }
377
378 static unsigned long long _pthread_rel_time_in_ms(const struct timespec *ts)
379 {
380 unsigned long long t1 = _pthread_time_in_ms_from_timespec(ts);
381 unsigned long long t2 = _pthread_time_in_ms();
382
383 /* Prevent underflow */
384 if (t1 < t2) return 0;
385 return t1 - t2;
386 }
387
388 int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts)
389 {
390 unsigned long long ct = _pthread_time_in_ms();
391 unsigned long long t = _pthread_time_in_ms_from_timespec(ts);
392
393 pthread_testcancel();
394
395 /* Use a busy-loop */
396 while (1)
397 {
398 /* Try to grab lock */
399 if (!pthread_rwlock_tryrdlock(l)) return 0;
400
401 /* Get current time */
402 ct = _pthread_time_in_ms();
403
404 /* Have we waited long enough? */
405 if (ct > t) return ETIMEDOUT;
406 }
407 }
408
409 int pthread_rwlock_timedwrlock(pthread_rwlock_t *l, const struct timespec *ts)
410 {
411 unsigned long long ct = _pthread_time_in_ms();
412 unsigned long long t = _pthread_time_in_ms_from_timespec(ts);
413
414 pthread_testcancel();
415
416 /* Use a busy-loop */
417 while (1)
418 {
419 /* Try to grab lock */
420 if (!pthread_rwlock_trywrlock(l)) return 0;
421
422 /* Get current time */
423 ct = _pthread_time_in_ms();
424
425 /* Have we waited long enough? */
426 if (ct > t) return ETIMEDOUT;
427 }
428 }
429
430 int pthread_get_concurrency(int *val)
431 {
432 *val = _pthread_concur;
433 return 0;
434 }
435
436 int pthread_set_concurrency(int val)
437 {
438 _pthread_concur = val;
439 return 0;
440 }
441
442 int pthread_exit(void *res)
443 {
444 pthread_t t = pthread_self();
445
446 t->ret_arg = res;
447
448 _pthread_cleanup_dest(t);
449
450 longjmp(t->jb, 1);
451 }
452
453
454 static void _pthread_invoke_cancel(void)
455 {
456 _pthread_cleanup *pcup;
457
458 _InterlockedDecrement(&_pthread_cancelling);
459
460 /* Call cancel queue */
461 for (pcup = pthread_self()->clean; pcup; pcup = pcup->next)
462 {
463 pcup->func(pcup->arg);
464 }
465
466 pthread_exit(PTHREAD_CANCELED);
467 }
468
469 void pthread_testcancel(void)
470 {
471 if (_pthread_cancelling)
472 {
473 pthread_t t = pthread_self();
474
475 if (t->cancelled && (t->p_state & PTHREAD_CANCEL_ENABLE))
476 {
477 _pthread_invoke_cancel();
478 }
479 }
480 }
481
482
483 int pthread_cancel(pthread_t t)
484 {
485 #if !defined(WINAPI_FAMILY) || (WINAPI_FAMILY != WINAPI_FAMILY_APP)
486 if (t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS)
487 {
488 /* Dangerous asynchronous cancelling */
489 CONTEXT ctxt;
490
491 /* Already done? */
492 if (t->cancelled) return ESRCH;
493
494 ctxt.ContextFlags = CONTEXT_CONTROL;
495
496 SuspendThread(t->h);
497 GetThreadContext(t->h, &ctxt);
498 #ifdef _M_X64
499 ctxt.Rip = (uintptr_t) _pthread_invoke_cancel;
500 #else
501 ctxt.Eip = (uintptr_t) _pthread_invoke_cancel;
502 #endif
503 SetThreadContext(t->h, &ctxt);
504
505 /* Also try deferred Cancelling */
506 t->cancelled = 1;
507
508 /* Notify everyone to look */
509 _InterlockedIncrement(&_pthread_cancelling);
510
511 ResumeThread(t->h);
512 }
513 else
514 #endif
515 {
516 /* Safe deferred Cancelling */
517 t->cancelled = 1;
518
519 /* Notify everyone to look */
520 _InterlockedIncrement(&_pthread_cancelling);
521 }
522
523 return 0;
524 }
525
526 static unsigned _pthread_get_state(pthread_attr_t *attr, unsigned flag)
527 {
528 return attr->p_state & flag;
529 }
530
531 static int _pthread_set_state(pthread_attr_t *attr, unsigned flag, unsigned val)
532 {
533 if (~flag & val) return EINVAL;
534 attr->p_state &= ~flag;
535 attr->p_state |= val;
536
537 return 0;
538 }
539
540 int pthread_attr_init(pthread_attr_t *attr)
541 {
542 attr->p_state = PTHREAD_DEFAULT_ATTR;
543 attr->stack = NULL;
544 attr->s_size = 0;
545 return 0;
546 }
547
548 int pthread_attr_destroy(pthread_attr_t *attr)
549 {
550 /* No need to do anything */
551 return 0;
552 }
553
554
555 int pthread_attr_setdetachstate(pthread_attr_t *a, int flag)
556 {
557 return _pthread_set_state(a, PTHREAD_CREATE_DETACHED, flag);
558 }
559
560 int pthread_attr_getdetachstate(pthread_attr_t *a, int *flag)
561 {
562 *flag = _pthread_get_state(a, PTHREAD_CREATE_DETACHED);
563 return 0;
564 }
565
566 int pthread_attr_setinheritsched(pthread_attr_t *a, int flag)
567 {
568 return _pthread_set_state(a, PTHREAD_INHERIT_SCHED, flag);
569 }
570
571 int pthread_attr_getinheritsched(pthread_attr_t *a, int *flag)
572 {
573 *flag = _pthread_get_state(a, PTHREAD_INHERIT_SCHED);
574 return 0;
575 }
576
577 int pthread_attr_setscope(pthread_attr_t *a, int flag)
578 {
579 return _pthread_set_state(a, PTHREAD_SCOPE_SYSTEM, flag);
580 }
581
582 int pthread_attr_getscope(pthread_attr_t *a, int *flag)
583 {
584 *flag = _pthread_get_state(a, PTHREAD_SCOPE_SYSTEM);
585 return 0;
586 }
587
588 int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stack)
589 {
590 *stack = attr->stack;
591 return 0;
592 }
593
594 int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack)
595 {
596 attr->stack = stack;
597 return 0;
598 }
599
600 int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *size)
601 {
602 *size = attr->s_size;
603 return 0;
604 }
605
606 int pthread_attr_setstacksize(pthread_attr_t *attr, size_t size)
607 {
608 attr->s_size = size;
609 return 0;
610 }
611
612 #define pthread_attr_getguardsize(A, S) ENOTSUP
613 #define pthread_attr_setgaurdsize(A, S) ENOTSUP
614 #define pthread_attr_getschedparam(A, S) ENOTSUP
615 #define pthread_attr_setschedparam(A, S) ENOTSUP
616 #define pthread_attr_getschedpolicy(A, S) ENOTSUP
617 #define pthread_attr_setschedpolicy(A, S) ENOTSUP
618
619
620 int pthread_setcancelstate(int state, int *oldstate)
621 {
622 pthread_t t = pthread_self();
623
624 if ((state & PTHREAD_CANCEL_ENABLE) != state) return EINVAL;
625 if (oldstate) *oldstate = t->p_state & PTHREAD_CANCEL_ENABLE;
626 t->p_state &= ~PTHREAD_CANCEL_ENABLE;
627 t->p_state |= state;
628
629 return 0;
630 }
631
632 int pthread_setcanceltype(int type, int *oldtype)
633 {
634 pthread_t t = pthread_self();
635
636 if ((type & PTHREAD_CANCEL_ASYNCHRONOUS) != type) return EINVAL;
637 if (oldtype) *oldtype = t->p_state & PTHREAD_CANCEL_ASYNCHRONOUS;
638 t->p_state &= ~PTHREAD_CANCEL_ASYNCHRONOUS;
639 t->p_state |= type;
640
641 return 0;
642 }
643
644 unsigned __stdcall pthread_create_wrapper(void *args)
645 {
646 struct _pthread_v *tv = (struct _pthread_v*)args;
647
648 _pthread_once_raw(&_pthread_tls_once, pthread_tls_init);
649
650 TlsSetValue(_pthread_tls, tv);
651
652 if (!setjmp(tv->jb))
653 {
654 /* Call function and save return value */
655 tv->ret_arg = tv->func(tv->ret_arg);
656
657 /* Clean up destructors */
658 _pthread_cleanup_dest(tv);
659 }
660
661 /* If we exit too early, then we can race with create */
662 while (tv->h == (HANDLE) -1)
663 {
664 YieldProcessor();
665 _ReadWriteBarrier();
666 }
667
668 /* Make sure we free ourselves if we are detached */
669 if (!tv->h) free(tv);
670
671 return 0;
672 }
673
674 int pthread_create(pthread_t *th, pthread_attr_t *attr, void *(* func)(void *), void *arg)
675 {
676 struct _pthread_v *tv = (struct _pthread_v*)malloc(sizeof(struct _pthread_v));
677 unsigned ssize = 0;
678
679 if (!tv) return 1;
680
681 *th = tv;
682
683 /* Save data in pthread_t */
684 tv->ret_arg = arg;
685 tv->func = func;
686 tv->clean = NULL;
687 tv->cancelled = 0;
688 tv->p_state = PTHREAD_DEFAULT_ATTR;
689 tv->keymax = 0;
690 tv->keyval = NULL;
691 tv->h = (HANDLE) -1;
692
693 if (attr)
694 {
695 tv->p_state = attr->p_state;
696 ssize = (unsigned) attr->s_size;
697 }
698
699 /* Make sure tv->h has value of -1 */
700 _ReadWriteBarrier();
701
702 tv->h = (HANDLE) _beginthreadex(NULL, ssize, pthread_create_wrapper, tv, 0, NULL);
703
704 /* Failed */
705 if (!tv->h) return 1;
706
707 if (tv->p_state & PTHREAD_CREATE_DETACHED)
708 {
709 CloseHandle(tv->h);
710 _ReadWriteBarrier();
711 tv->h = 0;
712 }
713
714 return 0;
715 }
716
717 int pthread_join(pthread_t t, void **res)
718 {
719 struct _pthread_v *tv = t;
720
721 pthread_testcancel();
722
723 WaitForSingleObject(tv->h, INFINITE);
724 CloseHandle(tv->h);
725
726 /* Obtain return value */
727 if (res) *res = tv->ret_arg;
728
729 free(tv);
730
731 return 0;
732 }
733
734 int pthread_detach(pthread_t t)
735 {
736 struct _pthread_v *tv = t;
737
738 /*
739 * This can't race with thread exit because
740 * our call would be undefined if called on a dead thread.
741 */
742
743 CloseHandle(tv->h);
744 _ReadWriteBarrier();
745 tv->h = 0;
746
747 return 0;
748 }
749
750 int pthread_mutexattr_init(pthread_mutexattr_t *a)
751 {
752 *a = 0;
753 return 0;
754 }
755
756 int pthread_mutexattr_destroy(pthread_mutexattr_t *a)
757 {
758 (void) a;
759 return 0;
760 }
761
762 int pthread_mutexattr_gettype(pthread_mutexattr_t *a, int *type)
763 {
764 *type = *a & 3;
765
766 return 0;
767 }
768
769 int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type)
770 {
771 if ((unsigned) type > 3) return EINVAL;
772 *a &= ~3;
773 *a |= type;
774
775 return 0;
776 }
777
778 int pthread_mutexattr_getpshared(pthread_mutexattr_t *a, int *type)
779 {
780 *type = *a & 4;
781
782 return 0;
783 }
784
785 int pthread_mutexattr_setpshared(pthread_mutexattr_t * a, int type)
786 {
787 if ((type & 4) != type) return EINVAL;
788
789 *a &= ~4;
790 *a |= type;
791
792 return 0;
793 }
794
795 int pthread_mutexattr_getprotocol(pthread_mutexattr_t *a, int *type)
796 {
797 *type = *a & (8 + 16);
798
799 return 0;
800 }
801
802 int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type)
803 {
804 if ((type & (8 + 16)) != 8 + 16) return EINVAL;
805
806 *a &= ~(8 + 16);
807 *a |= type;
808
809 return 0;
810 }
811
812 int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *a, int * prio)
813 {
814 *prio = *a / PTHREAD_PRIO_MULT;
815 return 0;
816 }
817
818 int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio)
819 {
820 *a &= (PTHREAD_PRIO_MULT - 1);
821 *a += prio * PTHREAD_PRIO_MULT;
822
823 return 0;
824 }
825
826 int pthread_mutex_timedlock(pthread_mutex_t *m, struct timespec *ts)
827 {
828 unsigned long long t, ct;
829
830 struct _pthread_crit_t
831 {
832 void *debug;
833 LONG count;
834 LONG r_count;
835 HANDLE owner;
836 HANDLE sem;
837 ULONG_PTR spin;
838 };
839
840 /* Try to lock it without waiting */
841 if (!pthread_mutex_trylock(m)) return 0;
842
843 ct = _pthread_time_in_ms();
844 t = _pthread_time_in_ms_from_timespec(ts);
845
846 while (1)
847 {
848 /* Have we waited long enough? */
849 if (ct > t) return ETIMEDOUT;
850
851 /* Wait on semaphore within critical section */
852 WaitForSingleObject(((struct _pthread_crit_t *)m)->sem, (DWORD)(t - ct));
853
854 /* Try to grab lock */
855 if (!pthread_mutex_trylock(m)) return 0;
856
857 /* Get current time */
858 ct = _pthread_time_in_ms();
859 }
860 }
861
862 #define _PTHREAD_BARRIER_FLAG (1<<30)
863
864 int pthread_barrier_destroy(pthread_barrier_t *b)
865 {
866 EnterCriticalSection(&b->m);
867
868 while (b->total > _PTHREAD_BARRIER_FLAG)
869 {
870 /* Wait until everyone exits the barrier */
871 SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
872 }
873
874 LeaveCriticalSection(&b->m);
875
876 DeleteCriticalSection(&b->m);
877
878 return 0;
879 }
880
881 int pthread_barrier_init(pthread_barrier_t *b, void *attr, int count)
882 {
883 /* Ignore attr */
884 (void) attr;
885
886 b->count = count;
887 b->total = 0;
888
889 InitializeCriticalSection(&b->m);
890 InitializeConditionVariable(&b->cv);
891
892 return 0;
893 }
894
895 int pthread_barrier_wait(pthread_barrier_t *b)
896 {
897 EnterCriticalSection(&b->m);
898
899 while (b->total > _PTHREAD_BARRIER_FLAG)
900 {
901 /* Wait until everyone exits the barrier */
902 SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
903 }
904
905 /* Are we the first to enter? */
906 if (b->total == _PTHREAD_BARRIER_FLAG) b->total = 0;
907
908 b->total++;
909
910 if (b->total == b->count)
911 {
912 b->total += _PTHREAD_BARRIER_FLAG - 1;
913 WakeAllConditionVariable(&b->cv);
914
915 LeaveCriticalSection(&b->m);
916
917 return 1;
918 }
919 else
920 {
921 while (b->total < _PTHREAD_BARRIER_FLAG)
922 {
923 /* Wait until enough threads enter the barrier */
924 SleepConditionVariableCS(&b->cv, &b->m, INFINITE);
925 }
926
927 b->total--;
928
929 /* Get entering threads to wake up */
930 if (b->total == _PTHREAD_BARRIER_FLAG) WakeAllConditionVariable(&b->cv);
931
932 LeaveCriticalSection(&b->m);
933
934 return 0;
935 }
936 }
937
938 int pthread_barrierattr_init(void **attr)
939 {
940 *attr = NULL;
941 return 0;
942 }
943
944 int pthread_barrierattr_destroy(void **attr)
945 {
946 /* Ignore attr */
947 (void) attr;
948
949 return 0;
950 }
951
952 int pthread_barrierattr_setpshared(void **attr, int s)
953 {
954 *attr = (void *) s;
955 return 0;
956 }
957
958 int pthread_barrierattr_getpshared(void **attr, int *s)
959 {
960 *s = (int) (size_t) *attr;
961
962 return 0;
963 }
964
965 int pthread_key_create(pthread_key_t *key, void (* dest)(void *))
966 {
967 unsigned i;
968 unsigned nmax;
969 void (**d)(void *);
970
971 if (!key) return EINVAL;
972
973 pthread_rwlock_wrlock(&_pthread_key_lock);
974
975 for (i = _pthread_key_sch; i < _pthread_key_max; i++)
976 {
977 if (!_pthread_key_dest[i])
978 {
979 *key = i;
980 if (dest)
981 {
982 _pthread_key_dest[i] = dest;
983 }
984 else
985 {
986 _pthread_key_dest[i] = (void(*)(void *))1;
987 }
988 pthread_rwlock_unlock(&_pthread_key_lock);
989
990 return 0;
991 }
992 }
993
994 for (i = 0; i < _pthread_key_sch; i++)
995 {
996 if (!_pthread_key_dest[i])
997 {
998 *key = i;
999 if (dest)
1000 {
1001 _pthread_key_dest[i] = dest;
1002 }
1003 else
1004 {
1005 _pthread_key_dest[i] = (void(*)(void *))1;
1006 }
1007 pthread_rwlock_unlock(&_pthread_key_lock);
1008
1009 return 0;
1010 }
1011 }
1012
1013 if (!_pthread_key_max) _pthread_key_max = 1;
1014 if (_pthread_key_max == PTHREAD_KEYS_MAX)
1015 {
1016 pthread_rwlock_unlock(&_pthread_key_lock);
1017
1018 return ENOMEM;
1019 }
1020
1021 nmax = _pthread_key_max * 2;
1022 if (nmax > PTHREAD_KEYS_MAX) nmax = PTHREAD_KEYS_MAX;
1023
1024 /* No spare room anywhere */
1025 d = (void (**)(void*))realloc(_pthread_key_dest, nmax * sizeof(*d));
1026 if (!d)
1027 {
1028 pthread_rwlock_unlock(&_pthread_key_lock);
1029
1030 return ENOMEM;
1031 }
1032
1033 /* Clear new region */
1034 memset((void *) &d[_pthread_key_max], 0, (nmax-_pthread_key_max)*sizeof(void *));
1035
1036 /* Use new region */
1037 _pthread_key_dest = d;
1038 _pthread_key_sch = _pthread_key_max + 1;
1039 *key = _pthread_key_max;
1040 _pthread_key_max = nmax;
1041
1042 if (dest)
1043 {
1044 _pthread_key_dest[*key] = dest;
1045 }
1046 else
1047 {
1048 _pthread_key_dest[*key] = (void(*)(void *))1;
1049 }
1050
1051 pthread_rwlock_unlock(&_pthread_key_lock);
1052
1053 return 0;
1054 }
1055
1056 int pthread_key_delete(pthread_key_t key)
1057 {
1058 if (key > _pthread_key_max) return EINVAL;
1059 if (!_pthread_key_dest) return EINVAL;
1060
1061 pthread_rwlock_wrlock(&_pthread_key_lock);
1062 _pthread_key_dest[key] = NULL;
1063
1064 /* Start next search from our location */
1065 if (_pthread_key_sch > key) _pthread_key_sch = key;
1066
1067 pthread_rwlock_unlock(&_pthread_key_lock);
1068
1069 return 0;
1070 }
1071
1072 void *pthread_getspecific(pthread_key_t key)
1073 {
1074 pthread_t t = pthread_self();
1075
1076 if (key >= t->keymax) return NULL;
1077
1078 return t->keyval[key];
1079
1080 }
1081
1082 int pthread_setspecific(pthread_key_t key, const void *value)
1083 {
1084 pthread_t t = pthread_self();
1085
1086 if (key > t->keymax)
1087 {
1088 int keymax = (key + 1) * 2;
1089 void **kv = (void**)realloc(t->keyval, keymax * sizeof(void *));
1090
1091 if (!kv) return ENOMEM;
1092
1093 /* Clear new region */
1094 memset(&kv[t->keymax], 0, (keymax - t->keymax)*sizeof(void*));
1095
1096 t->keyval = kv;
1097 t->keymax = keymax;
1098 }
1099
1100 t->keyval[key] = (void *) value;
1101
1102 return 0;
1103 }
1104
1105
1106 int pthread_spin_init(pthread_spinlock_t *l, int pshared)
1107 {
1108 (void) pshared;
1109
1110 *l = 0;
1111 return 0;
1112 }
1113
1114 int pthread_spin_destroy(pthread_spinlock_t *l)
1115 {
1116 (void) l;
1117 return 0;
1118 }
1119
1120 /* No-fair spinlock due to lack of knowledge of thread number */
1121 int pthread_spin_lock(pthread_spinlock_t *l)
1122 {
1123 while (_InterlockedExchange(l, EBUSY))
1124 {
1125 /* Don't lock the bus whilst waiting */
1126 while (*l)
1127 {
1128 YieldProcessor();
1129
1130 /* Compiler barrier. Prevent caching of *l */
1131 _ReadWriteBarrier();
1132 }
1133 }
1134
1135 return 0;
1136 }
1137
1138 int pthread_spin_trylock(pthread_spinlock_t *l)
1139 {
1140 return _InterlockedExchange(l, EBUSY);
1141 }
1142
1143 int pthread_spin_unlock(pthread_spinlock_t *l)
1144 {
1145 /* Compiler barrier. The store below acts with release symmantics */
1146 _ReadWriteBarrier();
1147
1148 *l = 0;
1149
1150 return 0;
1151 }
1152
1153 int pthread_cond_init(pthread_cond_t *c, pthread_condattr_t *a)
1154 {
1155 (void) a;
1156
1157 InitializeConditionVariable(c);
1158 return 0;
1159 }
1160
1161 int pthread_cond_signal(pthread_cond_t *c)
1162 {
1163 WakeConditionVariable(c);
1164 return 0;
1165 }
1166
1167 int pthread_cond_broadcast(pthread_cond_t *c)
1168 {
1169 WakeAllConditionVariable(c);
1170 return 0;
1171 }
1172
1173 int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m)
1174 {
1175 pthread_testcancel();
1176 SleepConditionVariableCS(c, m, INFINITE);
1177 return 0;
1178 }
1179
1180 int pthread_cond_destroy(pthread_cond_t *c)
1181 {
1182 (void) c;
1183 return 0;
1184 }
1185
1186 int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, struct timespec *t)
1187 {
1188 unsigned long long tm = _pthread_rel_time_in_ms(t);
1189
1190 pthread_testcancel();
1191
1192 if (!SleepConditionVariableCS(c, m, (DWORD)tm)) return ETIMEDOUT;
1193
1194 /* We can have a spurious wakeup after the timeout */
1195 if (!_pthread_rel_time_in_ms(t)) return ETIMEDOUT;
1196
1197 return 0;
1198 }
1199
1200 int pthread_condattr_destroy(pthread_condattr_t *a)
1201 {
1202 (void) a;
1203 return 0;
1204 }
1205
1206 int pthread_condattr_init(pthread_condattr_t *a)
1207 {
1208 *a = 0;
1209 return 0;
1210 }
1211
1212 int pthread_condattr_getpshared(pthread_condattr_t *a, int *s)
1213 {
1214 *s = *a;
1215 return 0;
1216 }
1217
1218 int pthread_condattr_setpshared(pthread_condattr_t *a, int s)
1219 {
1220 *a = s;
1221 return 0;
1222 }
1223
1224 int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a)
1225 {
1226 (void) a;
1227 return 0;
1228 }
1229
1230 int pthread_rwlockattr_init(pthread_rwlockattr_t *a)
1231 {
1232 *a = 0;
1233 return 0;
1234 }
1235
1236 int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s)
1237 {
1238 *s = *a;
1239 return 0;
1240 }
1241
1242 int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s)
1243 {
1244 *a = s;
1245 return 0;
1246 }
0 /*
1 * Posix Threads library for Microsoft Windows
2 *
3 * Use at own risk, there is no implied warranty to this code.
4 * It uses undocumented features of Microsoft Windows that can change
5 * at any time in the future.
6 *
7 * (C) 2010 Lockless Inc.
8 * All rights reserved.
9 *
10 * Redistribution and use in source and binary forms, with or without modification,
11 * are permitted provided that the following conditions are met:
12 *
13 *
14 * * Redistributions of source code must retain the above copyright notice,
15 * this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright notice,
17 * this list of conditions and the following disclaimer in the documentation
18 * and/or other materials provided with the distribution.
19 * * Neither the name of Lockless Inc. nor the names of its contributors may be
20 * used to endorse or promote products derived from this software without
21 * specific prior written permission.
22 *
23 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AN
24 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
25 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
26 * IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT,
27 * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
28 * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
29 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
30 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
31 * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED
32 * OF THE POSSIBILITY OF SUCH DAMAGE.
33 */
34
35 #ifndef WIN_PTHREADS
36 #define WIN_PTHREADS
37
38 #include <Windows.h>
39 #include <errno.h>
40
41 #ifdef __cplusplus
42 extern "C" {
43 #endif
44
45 #ifndef ETIMEDOUT
46 #define ETIMEDOUT 110
47 #endif
48 #ifndef ENOTSUP
49 #define ENOTSUP 134
50 #endif
51
52 #define PTHREAD_CANCEL_DISABLE 0
53 #define PTHREAD_CANCEL_ENABLE 0x01
54
55 #define PTHREAD_CANCEL_DEFERRED 0
56 #define PTHREAD_CANCEL_ASYNCHRONOUS 0x02
57
58 #define PTHREAD_CREATE_JOINABLE 0
59 #define PTHREAD_CREATE_DETACHED 0x04
60
61 #define PTHREAD_EXPLICT_SCHED 0
62 #define PTHREAD_INHERIT_SCHED 0x08
63
64 #define PTHREAD_SCOPE_PROCESS 0
65 #define PTHREAD_SCOPE_SYSTEM 0x10
66
67 #define PTHREAD_DEFAULT_ATTR (PTHREAD_CANCEL_ENABLE)
68
69 #define PTHREAD_CANCELED ((void *) 0xDEADBEEF)
70
71 #define PTHREAD_ONCE_INIT 0
72 #define PTHREAD_MUTEX_INITIALIZER {(void*)-1,-1,0,0,0,0}
73 #define PTHREAD_RWLOCK_INITIALIZER {0}
74 #define PTHREAD_COND_INITIALIZER {0}
75 #define PTHREAD_BARRIER_INITIALIZER \
76 {0,0,PTHREAD_MUTEX_INITIALIZER,PTHREAD_COND_INITIALIZER}
77 #define PTHREAD_SPINLOCK_INITIALIZER 0
78
79 #define PTHREAD_DESTRUCTOR_ITERATIONS 256
80 #define PTHREAD_KEYS_MAX (1<<20)
81
82 #define PTHREAD_MUTEX_NORMAL 0
83 #define PTHREAD_MUTEX_ERRORCHECK 1
84 #define PTHREAD_MUTEX_RECURSIVE 2
85 #define PTHREAD_MUTEX_DEFAULT 3
86 #define PTHREAD_MUTEX_SHARED 4
87 #define PTHREAD_MUTEX_PRIVATE 0
88 #define PTHREAD_PRIO_NONE 0
89 #define PTHREAD_PRIO_INHERIT 8
90 #define PTHREAD_PRIO_PROTECT 16
91 #define PTHREAD_PRIO_MULT 32
92 #define PTHREAD_PROCESS_SHARED 0
93 #define PTHREAD_PROCESS_PRIVATE 1
94
95 #define PTHREAD_BARRIER_SERIAL_THREAD 1
96
97 /* Windows doesn't have this, so declare it ourselves. */
98 #if (_MSC_VER < 1900)
99 struct timespec
100 {
101 /* long long in windows is the same as long in unix for 64bit */
102 long long tv_sec;
103 long long tv_nsec;
104 };
105 #else
106 #include <time.h>
107 #endif
108
109 struct _pthread_v;
110 typedef struct _pthread_v *pthread_t;
111
112 struct pthread_barrier_t
113 {
114 int count;
115 int total;
116 CRITICAL_SECTION m;
117 CONDITION_VARIABLE cv;
118 };
119
120 typedef struct pthread_barrier_t pthread_barrier_t;
121
122 struct pthread_attr_t
123 {
124 unsigned p_state;
125 void *stack;
126 size_t s_size;
127 };
128
129 typedef struct pthread_attr_t pthread_attr_t;
130
131 typedef long pthread_once_t;
132 typedef unsigned pthread_mutexattr_t;
133 typedef SRWLOCK pthread_rwlock_t;
134 typedef CRITICAL_SECTION pthread_mutex_t;
135 typedef unsigned pthread_key_t;
136 typedef void *pthread_barrierattr_t;
137 typedef long pthread_spinlock_t;
138 typedef int pthread_condattr_t;
139 typedef CONDITION_VARIABLE pthread_cond_t;
140 typedef int pthread_rwlockattr_t;
141
142 extern pthread_t pthread_self(void);
143
144 extern int pthread_once(pthread_once_t *o, void(*func)(void));
145
146 extern int pthread_mutex_lock(pthread_mutex_t *m);
147
148 extern int pthread_mutex_unlock(pthread_mutex_t *m);
149
150 extern int pthread_mutex_trylock(pthread_mutex_t *m);
151
152 extern int pthread_mutex_init(pthread_mutex_t *m, pthread_mutexattr_t *a);
153
154 extern int pthread_mutex_destroy(pthread_mutex_t *m);
155
156 #define pthread_mutex_getprioceiling(M, P) ENOTSUP
157 #define pthread_mutex_setprioceiling(M, P) ENOTSUP
158
159 extern int pthread_equal(pthread_t t1, pthread_t t2);
160
161 extern int pthread_rwlock_init(pthread_rwlock_t *l, pthread_rwlockattr_t *a);
162
163 extern int pthread_rwlock_destroy(pthread_rwlock_t *l);
164
165 extern int pthread_rwlock_rdlock(pthread_rwlock_t *l);
166
167 extern int pthread_rwlock_wrlock(pthread_rwlock_t *l);
168
169 extern int pthread_rwlock_unlock(pthread_rwlock_t *l);
170
171 extern int pthread_rwlock_tryrdlock(pthread_rwlock_t *l);
172
173 extern int pthread_rwlock_trywrlock(pthread_rwlock_t *l);
174
175 extern void pthread_tls_init(void);
176
177 extern int pthread_rwlock_timedrdlock(pthread_rwlock_t *l, const struct timespec *ts);
178
179 extern int pthread_rwlock_timedwrlock(pthread_rwlock_t *l, const struct timespec *ts);
180
181 extern int pthread_get_concurrency(int *val);
182
183 extern int pthread_set_concurrency(int val);
184
185 #define pthread_getschedparam(T, P, S) ENOTSUP
186 #define pthread_setschedparam(T, P, S) ENOTSUP
187 #define pthread_getcpuclockid(T, C) ENOTSUP
188
189 extern int pthread_exit(void *res);
190
191 extern void pthread_testcancel(void);
192
193 extern int pthread_cancel(pthread_t t);
194
195 extern int pthread_attr_init(pthread_attr_t *attr);
196
197 extern int pthread_attr_destroy(pthread_attr_t *attr);
198
199 extern int pthread_attr_setdetachstate(pthread_attr_t *a, int flag);
200
201 extern int pthread_attr_getdetachstate(pthread_attr_t *a, int *flag);
202
203 extern int pthread_attr_setinheritsched(pthread_attr_t *a, int flag);
204
205 extern int pthread_attr_getinheritsched(pthread_attr_t *a, int *flag);
206
207 extern int pthread_attr_setscope(pthread_attr_t *a, int flag);
208
209 extern int pthread_attr_getscope(pthread_attr_t *a, int *flag);
210
211 extern int pthread_attr_getstackaddr(pthread_attr_t *attr, void **stack);
212
213 extern int pthread_attr_setstackaddr(pthread_attr_t *attr, void *stack);
214
215 extern int pthread_attr_getstacksize(pthread_attr_t *attr, size_t *size);
216
217 extern int pthread_attr_setstacksize(pthread_attr_t *attr, size_t size);
218
219 #define pthread_attr_getguardsize(A, S) ENOTSUP
220 #define pthread_attr_setgaurdsize(A, S) ENOTSUP
221 #define pthread_attr_getschedparam(A, S) ENOTSUP
222 #define pthread_attr_setschedparam(A, S) ENOTSUP
223 #define pthread_attr_getschedpolicy(A, S) ENOTSUP
224 #define pthread_attr_setschedpolicy(A, S) ENOTSUP
225
226 extern int pthread_setcancelstate(int state, int *oldstate);
227
228 extern int pthread_setcanceltype(int type, int *oldtype);
229
230 extern unsigned __stdcall pthread_create_wrapper(void *args);
231
232 extern int pthread_create(pthread_t *th, pthread_attr_t *attr, void *(*func)(void *), void *arg);
233
234 extern int pthread_join(pthread_t t, void **res);
235
236 extern int pthread_detach(pthread_t t);
237
238 extern int pthread_mutexattr_init(pthread_mutexattr_t *a);
239
240 extern int pthread_mutexattr_destroy(pthread_mutexattr_t *a);
241
242 extern int pthread_mutexattr_gettype(pthread_mutexattr_t *a, int *type);
243
244 extern int pthread_mutexattr_settype(pthread_mutexattr_t *a, int type);
245
246 extern int pthread_mutexattr_getpshared(pthread_mutexattr_t *a, int *type);
247
248 extern int pthread_mutexattr_setpshared(pthread_mutexattr_t * a, int type);
249
250 extern int pthread_mutexattr_getprotocol(pthread_mutexattr_t *a, int *type);
251
252 extern int pthread_mutexattr_setprotocol(pthread_mutexattr_t *a, int type);
253
254 extern int pthread_mutexattr_getprioceiling(pthread_mutexattr_t *a, int * prio);
255
256 extern int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *a, int prio);
257
258 extern int pthread_mutex_timedlock(pthread_mutex_t *m, struct timespec *ts);
259
260 extern int pthread_barrier_destroy(pthread_barrier_t *b);
261
262 extern int pthread_barrier_init(pthread_barrier_t *b, void *attr, int count);
263
264 extern int pthread_barrier_wait(pthread_barrier_t *b);
265
266 extern int pthread_barrierattr_init(void **attr);
267
268 extern int pthread_barrierattr_destroy(void **attr);
269
270 extern int pthread_barrierattr_setpshared(void **attr, int s);
271
272 extern int pthread_barrierattr_getpshared(void **attr, int *s);
273
274 extern int pthread_key_create(pthread_key_t *key, void(*dest)(void *));
275
276 extern int pthread_key_delete(pthread_key_t key);
277
278 extern void *pthread_getspecific(pthread_key_t key);
279
280 extern int pthread_setspecific(pthread_key_t key, const void *value);
281
282 extern int pthread_spin_init(pthread_spinlock_t *l, int pshared);
283
284 extern int pthread_spin_destroy(pthread_spinlock_t *l);
285
286 extern int pthread_spin_lock(pthread_spinlock_t *l);
287
288 extern int pthread_spin_trylock(pthread_spinlock_t *l);
289
290 extern int pthread_spin_unlock(pthread_spinlock_t *l);
291
292 extern int pthread_cond_init(pthread_cond_t *c, pthread_condattr_t *a);
293
294 extern int pthread_cond_signal(pthread_cond_t *c);
295
296 extern int pthread_cond_broadcast(pthread_cond_t *c);
297
298 extern int pthread_cond_wait(pthread_cond_t *c, pthread_mutex_t *m);
299
300 extern int pthread_cond_destroy(pthread_cond_t *c);
301
302 extern int pthread_cond_timedwait(pthread_cond_t *c, pthread_mutex_t *m, struct timespec *t);
303
304 extern int pthread_condattr_destroy(pthread_condattr_t *a);
305
306 #define pthread_condattr_getclock(A, C) ENOTSUP
307 #define pthread_condattr_setclock(A, C) ENOTSUP
308
309 extern int pthread_condattr_init(pthread_condattr_t *a);
310
311 extern int pthread_condattr_getpshared(pthread_condattr_t *a, int *s);
312
313 extern int pthread_condattr_setpshared(pthread_condattr_t *a, int s);
314
315 extern int pthread_rwlockattr_destroy(pthread_rwlockattr_t *a);
316
317 extern int pthread_rwlockattr_init(pthread_rwlockattr_t *a);
318
319 extern int pthread_rwlockattr_getpshared(pthread_rwlockattr_t *a, int *s);
320
321 extern int pthread_rwlockattr_setpshared(pthread_rwlockattr_t *a, int s);
322
323 /* No fork() in windows - so ignore this */
324 #define pthread_atfork(F1,F2,F3) 0
325
326 /* Windows has rudimentary signals support */
327 #define pthread_kill(T, S) 0
328 #define pthread_sigmask(H, S1, S2) 0
329
330 #ifdef __cplusplus
331 }
332 #endif
333
334 #endif /* WIN_PTHREADS */