1 /**
2     D header file for POSIX.
3 
4     Copyright: Copyright Sean Kelly 2005 - 2009.
5     License:   $(HTTP www.boost.org/LICENSE_1_0.txt, Boost License 1.0).
6     Authors:   Sean Kelly, Alex Rønne Petersen
7     Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8 */
9 module nulib.posix.pthread;
10 import nulib.posix.ccfg;
11 
12 version (OSX)
13     version = Darwin;
14 else version (iOS)
15     version = Darwin;
16 else version (TVOS)
17     version = Darwin;
18 else version (WatchOS)
19     version = Darwin;
20 
21 extern(C) nothrow @nogc:
22 
23 //
24 // Thread (THR)
25 //
26 /*
27 pthread_attr_t
28 pthread_cond_t
29 pthread_condattr_t
30 pthread_key_t
31 pthread_mutex_t
32 pthread_mutexattr_t
33 pthread_once_t
34 pthread_rwlock_t
35 pthread_rwlockattr_t
36 pthread_t
37 */
38 
39 version (CRuntime_Glibc) {
40     version (X86) {
41         enum __SIZEOF_PTHREAD_ATTR_T = 36;
42         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
43         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
44         enum __SIZEOF_PTHREAD_COND_T = 48;
45         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
46         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
47         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
48         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
49         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
50     } else version (X86_64) {
51         static if (size_t.sizeof == 8) {
52             enum __SIZEOF_PTHREAD_ATTR_T = 56;
53             enum __SIZEOF_PTHREAD_MUTEX_T = 40;
54             enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
55             enum __SIZEOF_PTHREAD_COND_T = 48;
56             enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
57             enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
58             enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
59             enum __SIZEOF_PTHREAD_BARRIER_T = 32;
60             enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
61         } else {
62             enum __SIZEOF_PTHREAD_ATTR_T = 32;
63             enum __SIZEOF_PTHREAD_MUTEX_T = 32;
64             enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
65             enum __SIZEOF_PTHREAD_COND_T = 48;
66             enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
67             enum __SIZEOF_PTHREAD_RWLOCK_T = 44;
68             enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
69             enum __SIZEOF_PTHREAD_BARRIER_T = 20;
70             enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
71         }
72     } else version (AArch64) {
73         enum __SIZEOF_PTHREAD_ATTR_T = 64;
74         enum __SIZEOF_PTHREAD_MUTEX_T = 48;
75         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 8;
76         enum __SIZEOF_PTHREAD_COND_T = 48;
77         enum __SIZEOF_PTHREAD_CONDATTR_T = 8;
78         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
79         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
80         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
81         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 8;
82     } else version (ARM) {
83         enum __SIZEOF_PTHREAD_ATTR_T = 36;
84         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
85         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
86         enum __SIZEOF_PTHREAD_COND_T = 48;
87         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
88         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
89         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
90         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
91         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
92     } else version (HPPA) {
93         enum __SIZEOF_PTHREAD_ATTR_T = 36;
94         enum __SIZEOF_PTHREAD_MUTEX_T = 48;
95         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
96         enum __SIZEOF_PTHREAD_COND_T = 48;
97         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
98         enum __SIZEOF_PTHREAD_RWLOCK_T = 64;
99         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
100         enum __SIZEOF_PTHREAD_BARRIER_T = 48;
101         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
102     } else version (IA64) {
103         enum __SIZEOF_PTHREAD_ATTR_T = 56;
104         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
105         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
106         enum __SIZEOF_PTHREAD_COND_T = 48;
107         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
108         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
109         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
110         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
111         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
112     } else version (MIPS32) {
113         enum __SIZEOF_PTHREAD_ATTR_T = 36;
114         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
115         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
116         enum __SIZEOF_PTHREAD_COND_T = 48;
117         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
118         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
119         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
120         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
121         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
122     } else version (MIPS64) {
123         enum __SIZEOF_PTHREAD_ATTR_T = 56;
124         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
125         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
126         enum __SIZEOF_PTHREAD_COND_T = 48;
127         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
128         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
129         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
130         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
131         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
132     } else version (PPC) {
133         enum __SIZEOF_PTHREAD_ATTR_T = 36;
134         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
135         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
136         enum __SIZEOF_PTHREAD_COND_T = 48;
137         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
138         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
139         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
140         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
141         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
142     } else version (PPC64) {
143         enum __SIZEOF_PTHREAD_ATTR_T = 56;
144         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
145         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
146         enum __SIZEOF_PTHREAD_COND_T = 48;
147         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
148         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
149         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
150         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
151         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
152     } else version (RISCV32) {
153         enum __SIZEOF_PTHREAD_ATTR_T = 36;
154         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
155         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
156         enum __SIZEOF_PTHREAD_COND_T = 48;
157         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
158         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
159         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
160         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
161         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
162     } else version (RISCV64) {
163         enum __SIZEOF_PTHREAD_ATTR_T = 56;
164         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
165         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
166         enum __SIZEOF_PTHREAD_COND_T = 48;
167         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
168         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
169         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
170         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
171         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
172     } else version (SPARC) {
173         enum __SIZEOF_PTHREAD_ATTR_T = 36;
174         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
175         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
176         enum __SIZEOF_PTHREAD_COND_T = 48;
177         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
178         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
179         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
180         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
181         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
182     } else version (SPARC64) {
183         enum __SIZEOF_PTHREAD_ATTR_T = 56;
184         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
185         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
186         enum __SIZEOF_PTHREAD_COND_T = 48;
187         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
188         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
189         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
190         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
191         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
192     } else version (S390) {
193         enum __SIZEOF_PTHREAD_ATTR_T = 36;
194         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
195         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
196         enum __SIZEOF_PTHREAD_COND_T = 48;
197         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
198         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
199         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
200         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
201         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
202     } else version (SystemZ) {
203         enum __SIZEOF_PTHREAD_ATTR_T = 56;
204         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
205         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
206         enum __SIZEOF_PTHREAD_COND_T = 48;
207         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
208         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
209         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
210         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
211         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
212     } else version (LoongArch64) {
213         enum __SIZEOF_PTHREAD_ATTR_T = 56;
214         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
215         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
216         enum __SIZEOF_PTHREAD_COND_T = 48;
217         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
218         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
219         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
220         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
221         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
222     } else {
223         static assert(false, "Unsupported platform");
224     }
225 
226     union pthread_attr_t {
227         byte[__SIZEOF_PTHREAD_ATTR_T] __size;
228         c_long __align;
229     }
230 
231     private alias __atomic_lock_t = int;
232 
233     private struct _pthread_fastlock {
234         c_long __status;
235         __atomic_lock_t __spinlock;
236     }
237 
238     private alias _pthread_descr = void*;
239 
240     union pthread_cond_t {
241         byte[__SIZEOF_PTHREAD_COND_T] __size;
242         long __align;
243     }
244 
245     union pthread_condattr_t {
246         byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;
247         int __align;
248     }
249 
250     alias pthread_key_t = uint;
251 
252     union pthread_mutex_t {
253         byte[__SIZEOF_PTHREAD_MUTEX_T] __size;
254         c_long __align;
255     }
256 
257     union pthread_mutexattr_t {
258         byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;
259         int __align;
260     }
261 
262     alias pthread_once_t = int;
263 
264     struct pthread_rwlock_t {
265         byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;
266         c_long __align;
267     }
268 
269     struct pthread_rwlockattr_t {
270         byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;
271         c_long __align;
272     }
273 
274     alias pthread_t = c_ulong;
275 } else version (CRuntime_Musl) {
276     version (D_LP64) {
277         union pthread_attr_t {
278             int[14] __i;
279             ulong[7] __s;
280         }
281 
282         union pthread_cond_t {
283             int[12] __i;
284             void*[6] __p;
285         }
286 
287         union pthread_mutex_t {
288             int[10] __i;
289             void*[5] __p;
290         }
291 
292         union pthread_rwlock_t {
293             int[14] __i;
294             void*[7] __p;
295         }
296     } else {
297         union pthread_attr_t {
298             int[9] __i;
299             uint[9] __s;
300         }
301 
302         union pthread_cond_t {
303             int[12] __i;
304             void*[12] __p;
305         }
306 
307         union pthread_mutex_t {
308             int[6] __i;
309             void*[6] __p;
310         }
311 
312         union pthread_rwlock_t {
313             int[8] __i;
314             void*[8] __p;
315         }
316     }
317 
318     struct pthread_rwlockattr_t {
319         uint[2] __attr;
320     }
321 
322     alias pthread_key_t = uint;
323 
324     struct pthread_condattr_t {
325         uint __attr;
326     }
327 
328     struct pthread_mutexattr_t {
329         uint __attr;
330     }
331 
332     alias pthread_once_t = int;
333 
334     alias pthread_t = c_ulong;
335 } else version (Darwin) {
336     version (D_LP64) {
337         enum __PTHREAD_SIZE__ = 8176;
338         enum __PTHREAD_ATTR_SIZE__ = 56;
339         enum __PTHREAD_MUTEXATTR_SIZE__ = 8;
340         enum __PTHREAD_MUTEX_SIZE__ = 56;
341         enum __PTHREAD_CONDATTR_SIZE__ = 8;
342         enum __PTHREAD_COND_SIZE__ = 40;
343         enum __PTHREAD_ONCE_SIZE__ = 8;
344         enum __PTHREAD_RWLOCK_SIZE__ = 192;
345         enum __PTHREAD_RWLOCKATTR_SIZE__ = 16;
346     } else {
347         enum __PTHREAD_SIZE__ = 4088;
348         enum __PTHREAD_ATTR_SIZE__ = 36;
349         enum __PTHREAD_MUTEXATTR_SIZE__ = 8;
350         enum __PTHREAD_MUTEX_SIZE__ = 40;
351         enum __PTHREAD_CONDATTR_SIZE__ = 4;
352         enum __PTHREAD_COND_SIZE__ = 24;
353         enum __PTHREAD_ONCE_SIZE__ = 4;
354         enum __PTHREAD_RWLOCK_SIZE__ = 124;
355         enum __PTHREAD_RWLOCKATTR_SIZE__ = 12;
356     }
357 
358     struct pthread_handler_rec {
359         void function(void*) __routine;
360         void* __arg;
361         pthread_handler_rec* __next;
362     }
363 
364     struct pthread_attr_t {
365         c_long __sig;
366         byte[__PTHREAD_ATTR_SIZE__] __opaque;
367     }
368 
369     struct pthread_cond_t {
370         c_long __sig;
371         byte[__PTHREAD_COND_SIZE__] __opaque;
372     }
373 
374     struct pthread_condattr_t {
375         c_long __sig;
376         byte[__PTHREAD_CONDATTR_SIZE__] __opaque;
377     }
378 
379     alias pthread_key_t = c_ulong;
380 
381     struct pthread_mutex_t {
382         c_long __sig;
383         byte[__PTHREAD_MUTEX_SIZE__] __opaque;
384     }
385 
386     struct pthread_mutexattr_t {
387         c_long __sig;
388         byte[__PTHREAD_MUTEXATTR_SIZE__] __opaque;
389     }
390 
391     struct pthread_once_t {
392         c_long __sig;
393         byte[__PTHREAD_ONCE_SIZE__] __opaque;
394     }
395 
396     struct pthread_rwlock_t {
397         c_long __sig;
398         byte[__PTHREAD_RWLOCK_SIZE__] __opaque;
399     }
400 
401     struct pthread_rwlockattr_t {
402         c_long __sig;
403         byte[__PTHREAD_RWLOCKATTR_SIZE__] __opaque;
404     }
405 
406     private struct _opaque_pthread_t {
407         c_long __sig;
408         pthread_handler_rec* __cleanup_stack;
409         byte[__PTHREAD_SIZE__] __opaque;
410     }
411 
412     alias pthread_t = _opaque_pthread_t*;
413 } else version (FreeBSD) {
414     alias lwpid_t = int; // non-standard
415 
416     alias pthread_attr_t = void*;
417     alias pthread_cond_t = void*;
418     alias pthread_condattr_t = void*;
419     alias pthread_key_t = void*;
420     alias pthread_mutex_t = void*;
421     alias pthread_mutexattr_t = void*;
422     alias pthread_once_t = void*;
423     alias pthread_rwlock_t = void*;
424     alias pthread_rwlockattr_t = void*;
425     alias pthread_t = void*;
426 } else version (NetBSD) {
427     struct pthread_queue_t {
428         void* ptqh_first;
429         void** ptqh_last;
430     }
431 
432     alias lwpid_t = int;
433     alias pthread_spin_t = ubyte;
434     struct pthread_attr_t {
435         uint pta_magic;
436         int pta_flags;
437         void* pta_private;
438     }
439 
440     struct pthread_spinlock_t {
441         uint pts_magic;
442         pthread_spin_t pts_spin;
443         int pts_flags;
444     }
445 
446     struct pthread_cond_t {
447         uint ptc_magic;
448         pthread_spin_t ptc_lock;
449         pthread_queue_t ptc_waiters;
450         pthread_mutex_t* ptc_mutex;
451         void* ptc_private;
452     }
453 
454     struct pthread_condattr_t {
455         uint ptca_magic;
456         void* ptca_private;
457     }
458 
459     struct pthread_mutex_t {
460         uint ptm_magic;
461         pthread_spin_t ptm_errorcheck;
462         ubyte[3] ptm_pad1;
463         pthread_spin_t ptm_interlock;
464         ubyte[3] ptm_pad2;
465         pthread_t ptm_owner;
466         void* ptm_waiters;
467         uint ptm_recursed;
468         void* ptm_spare2;
469     }
470 
471     struct pthread_mutexattr_t {
472         uint ptma_magic;
473         void* ptma_private;
474     }
475 
476     struct pthread_once_t {
477         pthread_mutex_t pto_mutex;
478         int pto_done;
479     }
480 
481     struct pthread_rwlock_t {
482         uint ptr_magic;
483 
484         pthread_spin_t ptr_interlock;
485 
486         pthread_queue_t ptr_rblocked;
487         pthread_queue_t ptr_wblocked;
488         uint ptr_nreaders;
489         pthread_t ptr_owner;
490         void* ptr_private;
491     }
492 
493     struct pthread_rwlockattr_t {
494         uint ptra_magic;
495         void* ptra_private;
496     }
497 
498     alias pthread_key_t = uint;
499     alias pthread_t = void*;
500 } else version (OpenBSD) {
501     alias pthread_attr_t = void*;
502     alias pthread_cond_t = void*;
503     alias pthread_condattr_t = void*;
504     alias int pthread_key_t;
505     alias pthread_mutex_t = void*;
506     alias pthread_mutexattr_t = void*;
507 
508     private struct pthread_once {
509         int state;
510         pthread_mutex_t mutex;
511     }
512 
513     alias pthread_once_t = pthread_once;
514 
515     alias pthread_rwlock_t = void*;
516     alias pthread_rwlockattr_t = void*;
517     alias pthread_t = void*;
518 } else version (DragonFlyBSD) {
519     alias lwpid_t = int;
520 
521     alias pthread_attr_t = void*;
522     alias pthread_cond_t = void*;
523     alias pthread_condattr_t = void*;
524     alias pthread_key_t = void*;
525     alias pthread_mutex_t = void*;
526     alias pthread_mutexattr_t = void*;
527 
528     private struct pthread_once {
529         int state;
530         pthread_mutex_t mutex;
531     }
532 
533     alias pthread_once_t = pthread_once;
534 
535     alias pthread_rwlock_t = void*;
536     alias pthread_rwlockattr_t = void*;
537     alias pthread_t = void*;
538 } else version (Solaris) {
539     alias pthread_t = uint;
540 
541     struct pthread_attr_t {
542         void* __pthread_attrp;
543     }
544 
545     struct pthread_cond_t {
546         struct ___pthread_cond_flags {
547             ubyte[4] __pthread_cond_flags;
548             ushort __pthread_cond_type;
549             ushort __pthread_cond_magic;
550         }
551 
552         ___pthread_cond_flags __pthread_cond_flags;
553         ulong __pthread_cond_data;
554     }
555 
556     struct pthread_condattr_t {
557         void* __pthread_condattrp;
558     }
559 
560     struct pthread_rwlock_t {
561         int __pthread_rwlock_readers;
562         ushort __pthread_rwlock_type;
563         ushort __pthread_rwlock_magic;
564         pthread_mutex_t __pthread_rwlock_mutex;
565         pthread_cond_t __pthread_rwlock_readercv;
566         pthread_cond_t __pthread_rwlock_writercv;
567     }
568 
569     struct pthread_rwlockattr_t {
570         void* __pthread_rwlockattrp;
571     }
572 
573     struct pthread_mutex_t {
574         struct ___pthread_mutex_flags {
575             ushort __pthread_mutex_flag1;
576             ubyte __pthread_mutex_flag2;
577             ubyte __pthread_mutex_ceiling;
578             ushort __pthread_mutex_type;
579             ushort __pthread_mutex_magic;
580         }
581 
582         ___pthread_mutex_flags __pthread_mutex_flags;
583 
584         union ___pthread_mutex_lock {
585             struct ___pthread_mutex_lock64 {
586                 ubyte[8] __pthread_mutex_pad;
587             }
588 
589             ___pthread_mutex_lock64 __pthread_mutex_lock64;
590 
591             struct ___pthread_mutex_lock32 {
592                 uint __pthread_ownerpid;
593                 uint __pthread_lockword;
594             }
595 
596             ___pthread_mutex_lock32 __pthread_mutex_lock32;
597             ulong __pthread_mutex_owner64;
598         }
599 
600         ___pthread_mutex_lock __pthread_mutex_lock;
601         ulong __pthread_mutex_data;
602     }
603 
604     struct pthread_mutexattr_t {
605         void* __pthread_mutexattrp;
606     }
607 
608     struct pthread_once_t {
609         ulong[4] __pthread_once_pad;
610     }
611 
612     alias pthread_key_t = uint;
613 } else version (CRuntime_Bionic) {
614     struct pthread_attr_t {
615         uint flags;
616         void* stack_base;
617         size_t stack_size;
618         size_t guard_size;
619         int sched_policy;
620         int sched_priority;
621         version (D_LP64) char[16] __reserved = 0;
622     }
623 
624     struct pthread_cond_t {
625         version (D_LP64)
626             int[12] __private;
627         else
628             int[1] __private;
629     }
630 
631     alias pthread_condattr_t = c_long;
632     alias int pthread_key_t;
633 
634     struct pthread_mutex_t {
635         version (D_LP64)
636             int[10] __private;
637         else
638             int[1] __private;
639     }
640 
641     alias pthread_mutexattr_t = c_long;
642     alias int pthread_once_t;
643 
644     struct pthread_rwlock_t {
645         version (D_LP64)
646             int[14] __private;
647         else
648             int[10] __private;
649     }
650 
651     alias pthread_rwlockattr_t = c_long;
652     alias pthread_t = c_long;
653 } else version (CRuntime_UClibc) {
654     version (X86_64) {
655         enum __SIZEOF_PTHREAD_ATTR_T = 56;
656         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
657         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
658         enum __SIZEOF_PTHREAD_COND_T = 48;
659         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
660         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
661         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
662         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
663         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
664     } else version (MIPS32) {
665         enum __SIZEOF_PTHREAD_ATTR_T = 36;
666         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
667         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
668         enum __SIZEOF_PTHREAD_COND_T = 48;
669         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
670         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
671         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
672         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
673         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
674     } else version (MIPS64) {
675         enum __SIZEOF_PTHREAD_ATTR_T = 56;
676         enum __SIZEOF_PTHREAD_MUTEX_T = 40;
677         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
678         enum __SIZEOF_PTHREAD_COND_T = 48;
679         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
680         enum __SIZEOF_PTHREAD_RWLOCK_T = 56;
681         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
682         enum __SIZEOF_PTHREAD_BARRIER_T = 32;
683         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
684     } else version (ARM) {
685         enum __SIZEOF_PTHREAD_ATTR_T = 36;
686         enum __SIZEOF_PTHREAD_MUTEX_T = 24;
687         enum __SIZEOF_PTHREAD_MUTEXATTR_T = 4;
688         enum __SIZEOF_PTHREAD_COND_T = 48;
689         enum __SIZEOF_PTHREAD_COND_COMPAT_T = 12;
690         enum __SIZEOF_PTHREAD_CONDATTR_T = 4;
691         enum __SIZEOF_PTHREAD_RWLOCK_T = 32;
692         enum __SIZEOF_PTHREAD_RWLOCKATTR_T = 8;
693         enum __SIZEOF_PTHREAD_BARRIER_T = 20;
694         enum __SIZEOF_PTHREAD_BARRIERATTR_T = 4;
695     } else {
696         static assert(false, "Architecture unsupported");
697     }
698 
699     union pthread_attr_t {
700         byte[__SIZEOF_PTHREAD_ATTR_T] __size;
701         c_long __align;
702     }
703 
704     union pthread_cond_t {
705         struct data {
706             int __lock;
707             uint __futex;
708             ulong __total_seq;
709             ulong __wakeup_seq;
710             ulong __woken_seq;
711             void* __mutex;
712             uint __nwaiters;
713             uint __broadcast_seq;
714         }
715 
716         data __data;
717         byte[__SIZEOF_PTHREAD_COND_T] __size;
718         long __align;
719     }
720 
721     union pthread_condattr_t {
722         byte[__SIZEOF_PTHREAD_CONDATTR_T] __size;
723         c_long __align;
724     }
725 
726     alias pthread_key_t = uint;
727 
728     struct __pthread_slist_t {
729         __pthread_slist_t* __next;
730     }
731 
732     union pthread_mutex_t {
733         struct __pthread_mutex_s {
734             int __lock;
735             uint __count;
736             int __owner;
737             /* KIND must stay at this position in the structure to maintain
738            binary compatibility.  */
739             int __kind;
740             uint __nusers;
741             union {
742                 int __spins;
743                 __pthread_slist_t __list;
744             }
745         }
746 
747         __pthread_mutex_s __data;
748         byte[__SIZEOF_PTHREAD_MUTEX_T] __size;
749         c_long __align;
750     }
751 
752     union pthread_mutexattr_t {
753         byte[__SIZEOF_PTHREAD_MUTEXATTR_T] __size;
754         c_long __align;
755     }
756 
757     alias pthread_once_t = int;
758 
759     struct pthread_rwlock_t {
760         struct data {
761             int __lock;
762             uint __nr_readers;
763             uint __readers_wakeup;
764             uint __writer_wakeup;
765             uint __nr_readers_queued;
766             uint __nr_writers_queued;
767             version (BigEndian) {
768                 ubyte __pad1;
769                 ubyte __pad2;
770                 ubyte __shared;
771                 ubyte __flags;
772             } else {
773                 ubyte __flags;
774                 ubyte __shared;
775                 ubyte __pad1;
776                 ubyte __pad2;
777             }
778             int __writer;
779         }
780 
781         data __data;
782         byte[__SIZEOF_PTHREAD_RWLOCK_T] __size;
783         c_long __align;
784     }
785 
786     struct pthread_rwlockattr_t {
787         byte[__SIZEOF_PTHREAD_RWLOCKATTR_T] __size;
788         c_long __align;
789     }
790 
791     alias pthread_t = c_ulong;
792 } else {
793     static assert(false, "Unsupported platform");
794 }
795 
796 //
797 // Barrier (BAR)
798 //
799 /*
800 pthread_barrier_t
801 pthread_barrierattr_t
802 */
803 
804 version (CRuntime_Glibc) {
805     struct pthread_barrier_t {
806         byte[__SIZEOF_PTHREAD_BARRIER_T] __size;
807         c_long __align;
808     }
809 
810     struct pthread_barrierattr_t {
811         byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;
812         int __align;
813     }
814 } else version (FreeBSD) {
815     alias pthread_barrier_t = void*;
816     alias pthread_barrierattr_t = void*;
817 } else version (NetBSD) {
818     alias pthread_barrier_t = void*;
819     alias pthread_barrierattr_t = void*;
820 } else version (OpenBSD) {
821     alias pthread_barrier_t = void*;
822     alias pthread_barrierattr_t = void*;
823 } else version (DragonFlyBSD) {
824     alias pthread_barrier_t = void*;
825     alias pthread_barrierattr_t = void*;
826 } else version (Darwin) {
827 } else version (Solaris) {
828     struct pthread_barrier_t {
829         uint __pthread_barrier_count;
830         uint __pthread_barrier_current;
831         ulong __pthread_barrier_cycle;
832         ulong __pthread_barrier_reserved;
833         pthread_mutex_t __pthread_barrier_lock;
834         pthread_cond_t __pthread_barrier_cond;
835     }
836 
837     struct pthread_barrierattr_t {
838         void* __pthread_barrierattrp;
839     }
840 } else version (CRuntime_Bionic) {
841 } else version (CRuntime_Musl) {
842     version (D_LP64) {
843         union pthread_barrier_t {
844             int[8] __i;
845             void*[4] __p;
846         }
847     } else {
848         union pthread_barrier_t {
849             int[5] __i;
850             void*[5] __p;
851         }
852     }
853 
854     struct pthread_barrierattr_t {
855         uint __attr;
856     }
857 } else version (CRuntime_UClibc) {
858     struct pthread_barrier_t {
859         byte[__SIZEOF_PTHREAD_BARRIER_T] __size;
860         c_long __align;
861     }
862 
863     struct pthread_barrierattr_t {
864         byte[__SIZEOF_PTHREAD_BARRIERATTR_T] __size;
865         int __align;
866     }
867 } else {
868     static assert(false, "Unsupported platform");
869 }
870 
871 //
872 // Spin (SPN)
873 //
874 /*
875 pthread_spinlock_t
876 */
877 
878 version (CRuntime_Glibc) {
879     alias pthread_spinlock_t = int; // volatile
880 } else version (FreeBSD) {
881     alias pthread_spinlock_t = void*;
882 } else version (NetBSD) {
883     //already defined
884 } else version (OpenBSD) {
885     alias pthread_spinlock_t = void*;
886 } else version (DragonFlyBSD) {
887     alias pthread_spinlock_t = void*;
888 } else version (Solaris) {
889     alias pthread_spinlock_t = pthread_mutex_t;
890 } else version (CRuntime_UClibc) {
891     alias pthread_spinlock_t = int; // volatile
892 } else version (CRuntime_Musl) {
893     alias pthread_spinlock_t = int;
894 }
895 
896 //
897 // Required
898 //
899 /*
900 PTHREAD_CANCEL_ASYNCHRONOUS
901 PTHREAD_CANCEL_ENABLE
902 PTHREAD_CANCEL_DEFERRED
903 PTHREAD_CANCEL_DISABLE
904 PTHREAD_CANCELED
905 PTHREAD_COND_INITIALIZER
906 PTHREAD_CREATE_DETACHED
907 PTHREAD_CREATE_JOINABLE
908 PTHREAD_EXPLICIT_SCHED
909 PTHREAD_INHERIT_SCHED
910 PTHREAD_MUTEX_INITIALIZER
911 PTHREAD_ONCE_INIT
912 PTHREAD_PROCESS_SHARED
913 PTHREAD_PROCESS_PRIVATE
914 
915 int pthread_atfork(void function(), void function(), void function());
916 int pthread_attr_destroy(pthread_attr_t*);
917 int pthread_attr_getdetachstate(const scope pthread_attr_t*, int*);
918 int pthread_attr_getschedparam(const scope pthread_attr_t*, sched_param*);
919 int pthread_attr_init(pthread_attr_t*);
920 int pthread_attr_setdetachstate(pthread_attr_t*, int);
921 int pthread_attr_setschedparam(const scope pthread_attr_t*, sched_param*);
922 int pthread_cancel(pthread_t);
923 void pthread_cleanup_push(void function(void*), void*);
924 void pthread_cleanup_pop(int);
925 int pthread_cond_broadcast(pthread_cond_t*);
926 int pthread_cond_destroy(pthread_cond_t*);
927 int pthread_cond_init(const scope pthread_cond_t*, pthread_condattr_t*);
928 int pthread_cond_signal(pthread_cond_t*);
929 int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, const scope timespec*);
930 int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
931 int pthread_condattr_destroy(pthread_condattr_t*);
932 int pthread_condattr_init(pthread_condattr_t*);
933 int pthread_create(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
934 int pthread_detach(pthread_t);
935 int pthread_equal(pthread_t, pthread_t);
936 void pthread_exit(void*);
937 void* pthread_getspecific(pthread_key_t);
938 int pthread_join(pthread_t, void**);
939 int pthread_key_create(pthread_key_t*, void function(void*));
940 int pthread_key_delete(pthread_key_t);
941 int pthread_mutex_destroy(pthread_mutex_t*);
942 int pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*);
943 int pthread_mutex_lock(pthread_mutex_t*);
944 int pthread_mutex_trylock(pthread_mutex_t*);
945 int pthread_mutex_unlock(pthread_mutex_t*);
946 int pthread_mutexattr_destroy(pthread_mutexattr_t*);
947 int pthread_mutexattr_init(pthread_mutexattr_t*);
948 int pthread_once(pthread_once_t*, void function());
949 int pthread_rwlock_destroy(pthread_rwlock_t*);
950 int pthread_rwlock_init(pthread_rwlock_t*, const scope pthread_rwlockattr_t*);
951 int pthread_rwlock_rdlock(pthread_rwlock_t*);
952 int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
953 int pthread_rwlock_trywrlock(pthread_rwlock_t*);
954 int pthread_rwlock_unlock(pthread_rwlock_t*);
955 int pthread_rwlock_wrlock(pthread_rwlock_t*);
956 int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
957 int pthread_rwlockattr_init(pthread_rwlockattr_t*);
958 pthread_t pthread_self();
959 int pthread_setcancelstate(int, int*);
960 int pthread_setcanceltype(int, int*);
961 int pthread_setspecific(pthread_key_t, const scope void*);
962 void pthread_testcancel();
963 */
964 version (CRuntime_Glibc) {
965     enum {
966         PTHREAD_CANCEL_ENABLE,
967         PTHREAD_CANCEL_DISABLE
968     }
969 
970     enum {
971         PTHREAD_CANCEL_DEFERRED,
972         PTHREAD_CANCEL_ASYNCHRONOUS
973     }
974 
975     enum PTHREAD_CANCELED = cast(void*)-1;
976 
977     //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
978 
979     enum {
980         PTHREAD_CREATE_JOINABLE,
981         PTHREAD_CREATE_DETACHED
982     }
983 
984     enum {
985         PTHREAD_INHERIT_SCHED,
986         PTHREAD_EXPLICIT_SCHED
987     }
988 
989     enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
990     enum PTHREAD_ONCE_INIT = pthread_once_t.init;
991 
992     enum {
993         PTHREAD_PROCESS_PRIVATE,
994         PTHREAD_PROCESS_SHARED
995     }
996 } else version (Darwin) {
997     enum {
998         PTHREAD_CANCEL_ENABLE = 1,
999         PTHREAD_CANCEL_DISABLE = 0
1000     }
1001 
1002     enum {
1003         PTHREAD_CANCEL_DEFERRED = 2,
1004         PTHREAD_CANCEL_ASYNCHRONOUS = 0
1005     }
1006 
1007     enum PTHREAD_CANCELED = cast(void*)-1;
1008 
1009     //enum pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
1010 
1011     enum {
1012         PTHREAD_CREATE_JOINABLE = 1,
1013         PTHREAD_CREATE_DETACHED = 2
1014     }
1015 
1016     enum {
1017         PTHREAD_INHERIT_SCHED = 1,
1018         PTHREAD_EXPLICIT_SCHED = 2
1019     }
1020 
1021     enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0x32AAABA7);
1022     enum PTHREAD_ONCE_INIT = pthread_once_t(0x30b1bcba);
1023 
1024     enum {
1025         PTHREAD_PROCESS_PRIVATE = 2,
1026         PTHREAD_PROCESS_SHARED = 1
1027     }
1028 } else version (FreeBSD) {
1029     enum {
1030         PTHREAD_DETACHED = 0x1,
1031         PTHREAD_INHERIT_SCHED = 0x4,
1032         PTHREAD_NOFLOAT = 0x8,
1033 
1034         PTHREAD_CREATE_DETACHED = PTHREAD_DETACHED,
1035         PTHREAD_CREATE_JOINABLE = 0,
1036         PTHREAD_EXPLICIT_SCHED = 0,
1037     }
1038 
1039     enum {
1040         PTHREAD_PROCESS_PRIVATE = 0,
1041         PTHREAD_PROCESS_SHARED = 1,
1042     }
1043 
1044     enum {
1045         PTHREAD_CANCEL_ENABLE = 0,
1046         PTHREAD_CANCEL_DISABLE = 1,
1047         PTHREAD_CANCEL_DEFERRED = 0,
1048         PTHREAD_CANCEL_ASYNCHRONOUS = 2,
1049     }
1050 
1051     enum PTHREAD_CANCELED = cast(void*)-1;
1052 
1053     enum PTHREAD_NEEDS_INIT = 0;
1054     enum PTHREAD_DONE_INIT = 1;
1055 
1056     enum PTHREAD_MUTEX_INITIALIZER = null;
1057     enum PTHREAD_ONCE_INIT = null;
1058     enum PTHREAD_ADAPTIVE_MUTEX_INITIALIZER_NP = null;
1059     enum PTHREAD_COND_INITIALIZER = null;
1060     enum PTHREAD_RWLOCK_INITIALIZER = null;
1061 } else version (NetBSD) {
1062     enum PRI_NONE = -1;
1063     enum {
1064         PTHREAD_INHERIT_SCHED = 0x0,
1065 
1066         PTHREAD_CREATE_DETACHED = 1,
1067         PTHREAD_CREATE_JOINABLE = 0,
1068         PTHREAD_EXPLICIT_SCHED = 1,
1069     }
1070 
1071     enum {
1072         PTHREAD_PROCESS_PRIVATE = 0,
1073         PTHREAD_PROCESS_SHARED = 1,
1074     }
1075 
1076     enum {
1077         PTHREAD_CANCEL_ENABLE = 0,
1078         PTHREAD_CANCEL_DISABLE = 1,
1079         PTHREAD_CANCEL_DEFERRED = 0,
1080         PTHREAD_CANCEL_ASYNCHRONOUS = 1,
1081     }
1082 
1083     enum PTHREAD_CANCELED = cast(void*) 1;
1084 
1085     enum PTHREAD_DONE_INIT = 1;
1086 
1087     enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t(0x33330003);
1088 
1089     enum PTHREAD_ONCE_INIT = pthread_once_t(PTHREAD_MUTEX_INITIALIZER);
1090     enum PTHREAD_COND_INITIALIZER = pthread_cond_t(0x55550005);
1091     enum PTHREAD_RWLOCK_INITIALIZER = pthread_rwlock_t(0x99990009);
1092 } else version (OpenBSD) {
1093     enum {
1094         PTHREAD_DETACHED = 0x1,
1095         PTHREAD_INHERIT_SCHED = 0x4,
1096         PTHREAD_NOFLOAT = 0x8,
1097 
1098         PTHREAD_CREATE_DETACHED = PTHREAD_DETACHED,
1099         PTHREAD_CREATE_JOINABLE = 0,
1100         PTHREAD_EXPLICIT_SCHED = 0,
1101     }
1102 
1103     enum {
1104         PTHREAD_PROCESS_PRIVATE = 0,
1105         PTHREAD_PROCESS_SHARED = 1,
1106     }
1107 
1108     enum {
1109         PTHREAD_CANCEL_ENABLE = 0,
1110         PTHREAD_CANCEL_DISABLE = 1,
1111         PTHREAD_CANCEL_DEFERRED = 0,
1112         PTHREAD_CANCEL_ASYNCHRONOUS = 2,
1113     }
1114 
1115     enum PTHREAD_CANCELED = cast(void*) 1;
1116 
1117     enum {
1118         PTHREAD_NEEDS_INIT = 0,
1119         PTHREAD_DONE_INIT = 1,
1120     }
1121 
1122     enum PTHREAD_MUTEX_INITIALIZER = null;
1123     enum PTHREAD_ONCE_INIT = pthread_once_t.init;
1124     enum PTHREAD_COND_INITIALIZER = null;
1125     enum PTHREAD_RWLOCK_INITIALIZER = null;
1126 } else version (DragonFlyBSD) {
1127     enum {
1128         PTHREAD_DETACHED = 0x1,
1129         //PTHREAD_SCOPE_SYSTEM        = 0x2,    // defined below
1130         PTHREAD_INHERIT_SCHED = 0x4,
1131         PTHREAD_NOFLOAT = 0x8,
1132 
1133         PTHREAD_CREATE_DETACHED = PTHREAD_DETACHED,
1134         PTHREAD_CREATE_JOINABLE = 0,
1135         //PTHREAD_SCOPE_PROCESS       = 0,      // defined below
1136         PTHREAD_EXPLICIT_SCHED = 0,
1137     }
1138 
1139     enum {
1140         PTHREAD_PROCESS_PRIVATE = 0,
1141         PTHREAD_PROCESS_SHARED = 1,
1142     }
1143 
1144     enum {
1145         PTHREAD_CANCEL_ENABLE = 0,
1146         PTHREAD_CANCEL_DISABLE = 1,
1147         PTHREAD_CANCEL_DEFERRED = 0,
1148         PTHREAD_CANCEL_ASYNCHRONOUS = 2,
1149     }
1150 
1151     enum PTHREAD_CANCELED = cast(void*)-1;
1152 
1153     enum PTHREAD_NEEDS_INIT = 0;
1154     enum PTHREAD_DONE_INIT = 1;
1155 
1156     enum PTHREAD_MUTEX_INITIALIZER = null;
1157     enum PTHREAD_ONCE_INIT = pthread_once_t.init;
1158     enum PTHREAD_COND_INITIALIZER = null;
1159     enum PTHREAD_RWLOCK_INITIALIZER = null;
1160 } else version (Solaris) {
1161     enum {
1162         PTHREAD_INHERIT_SCHED = 0x01,
1163         PTHREAD_NOFLOAT = 0x08,
1164         PTHREAD_CREATE_DETACHED = 0x40,
1165         PTHREAD_CREATE_JOINABLE = 0x00,
1166         PTHREAD_EXPLICIT_SCHED = 0x00,
1167     }
1168 
1169     enum {
1170         PTHREAD_PROCESS_PRIVATE = 0,
1171         PTHREAD_PROCESS_SHARED = 1,
1172     }
1173 
1174     enum {
1175         PTHREAD_CANCEL_ENABLE = 0,
1176         PTHREAD_CANCEL_DISABLE = 1,
1177         PTHREAD_CANCEL_DEFERRED = 0,
1178         PTHREAD_CANCEL_ASYNCHRONOUS = 2,
1179     }
1180 
1181     enum PTHREAD_CANCELED = cast(void*)-19;
1182 
1183     enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
1184     enum PTHREAD_ONCE_INIT = pthread_once_t.init;
1185 } else version (CRuntime_Bionic) {
1186     enum {
1187         PTHREAD_CREATE_JOINABLE,
1188         PTHREAD_CREATE_DETACHED
1189     }
1190 
1191     enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
1192     enum PTHREAD_ONCE_INIT = pthread_once_t.init;
1193 
1194     enum {
1195         PTHREAD_PROCESS_PRIVATE,
1196         PTHREAD_PROCESS_SHARED
1197     }
1198 } else version (CRuntime_Musl) {
1199     enum {
1200         PTHREAD_CREATE_JOINABLE = 0,
1201         PTHREAD_CREATE_DETACHED = 1
1202     }
1203 
1204     enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
1205     enum PTHREAD_ONCE_INIT = pthread_once_t.init;
1206 
1207     enum {
1208         PTHREAD_PROCESS_PRIVATE = 0,
1209         PTHREAD_PROCESS_SHARED = 1
1210     }
1211 } else version (CRuntime_UClibc) {
1212     enum {
1213         PTHREAD_CANCEL_ENABLE,
1214         PTHREAD_CANCEL_DISABLE
1215     }
1216 
1217     enum {
1218         PTHREAD_CANCEL_DEFERRED,
1219         PTHREAD_CANCEL_ASYNCHRONOUS
1220     }
1221 
1222     enum PTHREAD_CANCELED = cast(void*)-1;
1223 
1224     enum PTHREAD_MUTEX_INITIALIZER = pthread_mutex_t.init;
1225     enum PTHREAD_ONCE_INIT = pthread_once_t.init;
1226 
1227     enum {
1228         PTHREAD_CREATE_JOINABLE,
1229         PTHREAD_CREATE_DETACHED
1230     }
1231 
1232     enum {
1233         PTHREAD_INHERIT_SCHED,
1234         PTHREAD_EXPLICIT_SCHED
1235     }
1236 
1237     enum {
1238         PTHREAD_PROCESS_PRIVATE,
1239         PTHREAD_PROCESS_SHARED
1240     }
1241 } else {
1242     static assert(false, "Unsupported platform");
1243 }
1244 
1245 alias void function(void*) _pthread_cleanup_routine;
1246 alias void function(void*) @nogc _pthread_cleanup_routine_nogc;
1247 version (CRuntime_Glibc) {
1248     struct _pthread_cleanup_buffer {
1249         _pthread_cleanup_routine __routine;
1250         void* __arg;
1251         int __canceltype;
1252         _pthread_cleanup_buffer* __prev;
1253     }
1254 
1255     void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);
1256     void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;
1257     void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
1258 
1259     struct pthread_cleanup {
1260         _pthread_cleanup_buffer buffer = void;
1261 
1262         extern (D) void push(F : _pthread_cleanup_routine)(F routine, void* arg) {
1263             _pthread_cleanup_push(&buffer, routine, arg);
1264         }
1265 
1266         extern (D) void pop()(int execute) {
1267             _pthread_cleanup_pop(&buffer, execute);
1268         }
1269     }
1270 } else version (Darwin) {
1271     struct _pthread_cleanup_buffer {
1272         _pthread_cleanup_routine __routine;
1273         void* __arg;
1274         _pthread_cleanup_buffer* __next;
1275     }
1276 
1277     struct pthread_cleanup {
1278         _pthread_cleanup_buffer buffer = void;
1279 
1280         extern (D) void push(F : _pthread_cleanup_routine)(F routine, void* arg) {
1281             pthread_t self = pthread_self();
1282             buffer.__routine = routine;
1283             buffer.__arg = arg;
1284             buffer.__next = cast(_pthread_cleanup_buffer*) self.__cleanup_stack;
1285             self.__cleanup_stack = cast(pthread_handler_rec*)&buffer;
1286         }
1287 
1288         extern (D) void pop()(int execute) {
1289             pthread_t self = pthread_self();
1290             self.__cleanup_stack = cast(pthread_handler_rec*) buffer.__next;
1291             if (execute) {
1292                 buffer.__routine(buffer.__arg);
1293             }
1294         }
1295     }
1296 } else version (FreeBSD) {
1297     struct _pthread_cleanup_info {
1298         uintptr_t[8] pthread_cleanup_pad;
1299     }
1300 
1301     struct pthread_cleanup {
1302         _pthread_cleanup_info __cleanup_info__ = void;
1303 
1304         extern (D) void push(F : _pthread_cleanup_routine)(F cleanup_routine, void* cleanup_arg) {
1305             __pthread_cleanup_push_imp(cleanup_routine, cleanup_arg, &__cleanup_info__);
1306         }
1307 
1308         extern (D) void pop()(int execute) {
1309             __pthread_cleanup_pop_imp(execute);
1310         }
1311     }
1312 
1313     void __pthread_cleanup_push_imp(_pthread_cleanup_routine, void*, _pthread_cleanup_info*);
1314     void __pthread_cleanup_push_imp(_pthread_cleanup_routine_nogc, void*, _pthread_cleanup_info*) @nogc;
1315     void __pthread_cleanup_pop_imp(int);
1316 } else version (DragonFlyBSD) {
1317     struct _pthread_cleanup_info {
1318         uintptr_t[8] pthread_cleanup_pad;
1319     }
1320 
1321     struct pthread_cleanup {
1322         _pthread_cleanup_info __cleanup_info__ = void;
1323 
1324         extern (D) void push()(_pthread_cleanup_routine cleanup_routine, void* cleanup_arg) {
1325             _pthread_cleanup_push(cleanup_routine, cleanup_arg, &__cleanup_info__);
1326         }
1327 
1328         extern (D) void pop()(int execute) {
1329             _pthread_cleanup_pop(execute);
1330         }
1331     }
1332 
1333     void _pthread_cleanup_push(_pthread_cleanup_routine, void*, _pthread_cleanup_info*);
1334     void _pthread_cleanup_pop(int);
1335 } else version (NetBSD) {
1336     struct _pthread_cleanup_store {
1337         void*[4] pthread_cleanup_pad;
1338     }
1339 
1340     struct pthread_cleanup {
1341         _pthread_cleanup_store __cleanup_info__ = void;
1342 
1343         extern (D) void push()(_pthread_cleanup_routine cleanup_routine, void* cleanup_arg) {
1344             pthread__cleanup_push(cleanup_routine, cleanup_arg, &__cleanup_info__);
1345         }
1346 
1347         extern (D) void pop()(int execute) {
1348             pthread__cleanup_pop(execute, &__cleanup_info__);
1349         }
1350     }
1351 
1352     void pthread__cleanup_push(_pthread_cleanup_routine, void*, void*);
1353     void pthread__cleanup_pop(int, void*);
1354 } else version (OpenBSD) {
1355     void pthread_cleanup_push(void function(void*), void*);
1356     void pthread_cleanup_pop(int);
1357 } else version (Solaris) {
1358     caddr_t _getfp();
1359 
1360     struct _pthread_cleanup_info {
1361         uintptr_t[4] pthread_cleanup_pad;
1362     }
1363 
1364     struct pthread_cleanup {
1365         _pthread_cleanup_info __cleanup_info__ = void;
1366 
1367         extern (D) void push(F : _pthread_cleanup_routine)(F cleanup_routine, void* cleanup_arg) {
1368             __pthread_cleanup_push(cleanup_routine, cleanup_arg, _getfp(), &__cleanup_info__);
1369         }
1370 
1371         extern (D) void pop()(int execute) {
1372             __pthread_cleanup_pop(execute, &__cleanup_info__);
1373         }
1374     }
1375 
1376     void __pthread_cleanup_push(_pthread_cleanup_routine, void*, caddr_t, _pthread_cleanup_info*);
1377     void __pthread_cleanup_push(_pthread_cleanup_routine_nogc, void*, caddr_t, _pthread_cleanup_info*) @nogc;
1378     void __pthread_cleanup_pop(int, _pthread_cleanup_info*);
1379 } else version (CRuntime_Bionic) {
1380     struct __pthread_cleanup_t {
1381         __pthread_cleanup_t* __cleanup_prev;
1382         _pthread_cleanup_routine __cleanup_routine;
1383         void* __cleanup_arg;
1384     }
1385 
1386     void __pthread_cleanup_push(__pthread_cleanup_t*, _pthread_cleanup_routine, void*);
1387     void __pthread_cleanup_push(__pthread_cleanup_t*, _pthread_cleanup_routine_nogc, void*) @nogc;
1388     void __pthread_cleanup_pop(__pthread_cleanup_t*, int);
1389 
1390     struct pthread_cleanup {
1391         __pthread_cleanup_t __cleanup = void;
1392 
1393         extern (D) void push(F : _pthread_cleanup_routine)(F routine, void* arg) {
1394             __pthread_cleanup_push(&__cleanup, routine, arg);
1395         }
1396 
1397         extern (D) void pop()(int execute) {
1398             __pthread_cleanup_pop(&__cleanup, execute);
1399         }
1400     }
1401 } else version (CRuntime_Musl) {
1402     struct __ptcb {
1403         _pthread_cleanup_routine f;
1404         void* __x;
1405         __ptcb* __next;
1406     }
1407 
1408     void _pthread_cleanup_push(__ptcb*, _pthread_cleanup_routine, void*);
1409     void _pthread_cleanup_pop(__ptcb*, int);
1410 
1411     struct pthread_cleanup {
1412         __ptcb __cleanup = void;
1413 
1414         extern (D) void push(F : _pthread_cleanup_routine)(F routine, void* arg) {
1415             _pthread_cleanup_push(&__cleanup, routine, arg);
1416         }
1417 
1418         extern (D) void pop()(int execute) {
1419             _pthread_cleanup_pop(&__cleanup, execute);
1420         }
1421     }
1422 } else version (CRuntime_UClibc) {
1423     struct _pthread_cleanup_buffer {
1424         _pthread_cleanup_routine __routine;
1425         void* __arg;
1426         int __canceltype;
1427         _pthread_cleanup_buffer* __prev;
1428     }
1429 
1430     void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);
1431     void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine_nogc, void*) @nogc;
1432     void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
1433 
1434     struct pthread_cleanup {
1435         _pthread_cleanup_buffer buffer = void;
1436 
1437         extern (D) void push(F : _pthread_cleanup_routine)(F routine, void* arg) {
1438             _pthread_cleanup_push(&buffer, routine, arg);
1439         }
1440 
1441         extern (D) void pop()(int execute) {
1442             _pthread_cleanup_pop(&buffer, execute);
1443         }
1444     }
1445 } else {
1446     static assert(false, "Unsupported platform");
1447 }
1448 
1449 int pthread_cond_broadcast(pthread_cond_t*);
1450 int pthread_cond_destroy(pthread_cond_t*);
1451 int pthread_cond_init(const scope pthread_cond_t*, pthread_condattr_t*) @trusted;
1452 int pthread_cond_signal(pthread_cond_t*);
1453 int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
1454 int pthread_condattr_destroy(pthread_condattr_t*);
1455 int pthread_condattr_init(pthread_condattr_t*);
1456 int pthread_create(pthread_t*, const scope pthread_attr_t*, void* function(void*), void*);
1457 int pthread_detach(pthread_t);
1458 int pthread_equal(pthread_t, pthread_t);
1459 void pthread_exit(void*);
1460 void* pthread_getspecific(pthread_key_t);
1461 int pthread_join(pthread_t, void**);
1462 int pthread_key_create(pthread_key_t*, void function(void*));
1463 int pthread_key_delete(pthread_key_t);
1464 int pthread_mutex_destroy(pthread_mutex_t*);
1465 int pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*) @trusted;
1466 int pthread_mutex_lock(pthread_mutex_t*);
1467 int pthread_mutex_lock(shared(pthread_mutex_t)*);
1468 int pthread_mutex_trylock(pthread_mutex_t*);
1469 int pthread_mutex_trylock(shared(pthread_mutex_t)*);
1470 int pthread_mutex_unlock(pthread_mutex_t*);
1471 int pthread_mutex_unlock(shared(pthread_mutex_t)*);
1472 int pthread_mutexattr_destroy(pthread_mutexattr_t*);
1473 int pthread_mutexattr_init(pthread_mutexattr_t*) @trusted;
1474 int pthread_once(pthread_once_t*, void function());
1475 int pthread_rwlock_destroy(pthread_rwlock_t*);
1476 int pthread_rwlock_init(pthread_rwlock_t*, const scope pthread_rwlockattr_t*);
1477 int pthread_rwlock_rdlock(pthread_rwlock_t*);
1478 int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
1479 int pthread_rwlock_trywrlock(pthread_rwlock_t*);
1480 int pthread_rwlock_unlock(pthread_rwlock_t*);
1481 int pthread_rwlock_wrlock(pthread_rwlock_t*);
1482 int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
1483 int pthread_rwlockattr_init(pthread_rwlockattr_t*);
1484 pthread_t pthread_self();
1485 int pthread_setcancelstate(int, int*);
1486 int pthread_setcanceltype(int, int*);
1487 int pthread_setspecific(pthread_key_t, const scope void*);
1488 void pthread_testcancel();
1489 int pthread_cancel(pthread_t);
1490 int pthread_attr_init(pthread_attr_t*);
1491 int pthread_attr_destroy(pthread_attr_t*);
1492 
1493 //
1494 // Barrier (BAR)
1495 //
1496 /*
1497 PTHREAD_BARRIER_SERIAL_THREAD
1498 
1499 int pthread_barrier_destroy(pthread_barrier_t*);
1500 int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1501 int pthread_barrier_wait(pthread_barrier_t*);
1502 int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1503 int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*); (BAR|TSH)
1504 int pthread_barrierattr_init(pthread_barrierattr_t*);
1505 int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); (BAR|TSH)
1506 */
1507 
1508 version (CRuntime_Glibc) {
1509     enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
1510 
1511     int pthread_barrier_destroy(pthread_barrier_t*);
1512     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1513     int pthread_barrier_wait(pthread_barrier_t*);
1514     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1515     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1516     int pthread_barrierattr_init(pthread_barrierattr_t*);
1517     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1518 } else version (FreeBSD) {
1519     enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
1520 
1521     int pthread_barrier_destroy(pthread_barrier_t*);
1522     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1523     int pthread_barrier_wait(pthread_barrier_t*);
1524     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1525     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1526     int pthread_barrierattr_init(pthread_barrierattr_t*);
1527     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1528 } else version (DragonFlyBSD) {
1529     enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
1530     enum PTHREAD_KEYS_MAX = 256;
1531     enum PTHREAD_STACK_MIN = 16384;
1532     enum PTHREAD_THREADS_MAX = c_ulong.max;
1533 
1534     int pthread_barrier_destroy(pthread_barrier_t*);
1535     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1536     int pthread_barrier_wait(pthread_barrier_t*);
1537     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1538     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1539     int pthread_barrierattr_init(pthread_barrierattr_t*);
1540     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1541 } else version (NetBSD) {
1542     enum PTHREAD_BARRIER_SERIAL_THREAD = 1234567;
1543 
1544     int pthread_barrier_destroy(pthread_barrier_t*);
1545     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1546     int pthread_barrier_wait(pthread_barrier_t*);
1547     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1548     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1549     int pthread_barrierattr_init(pthread_barrierattr_t*);
1550     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1551 } else version (OpenBSD) {
1552     enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
1553 
1554     int pthread_barrier_destroy(pthread_barrier_t*);
1555     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1556     int pthread_barrier_wait(pthread_barrier_t*);
1557     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1558     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1559     int pthread_barrierattr_init(pthread_barrierattr_t*);
1560     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1561 } else version (Darwin) {
1562 } else version (Solaris) {
1563     enum PTHREAD_BARRIER_SERIAL_THREAD = -2;
1564 
1565     int pthread_barrier_destroy(pthread_barrier_t*);
1566     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1567     int pthread_barrier_wait(pthread_barrier_t*);
1568     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1569     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1570     int pthread_barrierattr_init(pthread_barrierattr_t*);
1571     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1572 } else version (CRuntime_Bionic) {
1573 } else version (CRuntime_Musl) {
1574     enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
1575 
1576     int pthread_barrier_destroy(pthread_barrier_t*);
1577     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1578     int pthread_barrier_wait(pthread_barrier_t*);
1579     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1580     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1581     int pthread_barrierattr_init(pthread_barrierattr_t*);
1582     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1583 } else version (CRuntime_UClibc) {
1584     enum PTHREAD_BARRIER_SERIAL_THREAD = -1;
1585 
1586     int pthread_barrier_destroy(pthread_barrier_t*);
1587     int pthread_barrier_init(pthread_barrier_t*, const scope pthread_barrierattr_t*, uint);
1588     int pthread_barrier_wait(pthread_barrier_t*);
1589     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
1590     int pthread_barrierattr_getpshared(const scope pthread_barrierattr_t*, int*);
1591     int pthread_barrierattr_init(pthread_barrierattr_t*);
1592     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
1593 } else {
1594     static assert(false, "Unsupported platform");
1595 }
1596 
1597 //
1598 // Spinlock (SPI)
1599 //
1600 /*
1601 int pthread_spin_destroy(pthread_spinlock_t*);
1602 int pthread_spin_init(pthread_spinlock_t*, int);
1603 int pthread_spin_lock(pthread_spinlock_t*);
1604 int pthread_spin_trylock(pthread_spinlock_t*);
1605 int pthread_spin_unlock(pthread_spinlock_t*);
1606 */
1607 
1608 version (CRuntime_Glibc) {
1609     int pthread_spin_destroy(pthread_spinlock_t*);
1610     int pthread_spin_init(pthread_spinlock_t*, int);
1611     int pthread_spin_lock(pthread_spinlock_t*);
1612     int pthread_spin_trylock(pthread_spinlock_t*);
1613     int pthread_spin_unlock(pthread_spinlock_t*);
1614 } else version (FreeBSD) {
1615     int pthread_spin_init(pthread_spinlock_t*, int);
1616     int pthread_spin_destroy(pthread_spinlock_t*);
1617     int pthread_spin_lock(pthread_spinlock_t*);
1618     int pthread_spin_trylock(pthread_spinlock_t*);
1619     int pthread_spin_unlock(pthread_spinlock_t*);
1620 } else version (DragonFlyBSD) {
1621     int pthread_spin_init(pthread_spinlock_t*, int);
1622     int pthread_spin_destroy(pthread_spinlock_t*);
1623     int pthread_spin_lock(pthread_spinlock_t*);
1624     int pthread_spin_trylock(pthread_spinlock_t*);
1625     int pthread_spin_unlock(pthread_spinlock_t*);
1626 } else version (NetBSD) {
1627     int pthread_spin_init(pthread_spinlock_t*, int);
1628     int pthread_spin_destroy(pthread_spinlock_t*);
1629     int pthread_spin_lock(pthread_spinlock_t*);
1630     int pthread_spin_trylock(pthread_spinlock_t*);
1631     int pthread_spin_unlock(pthread_spinlock_t*);
1632 } else version (OpenBSD) {
1633     int pthread_spin_init(pthread_spinlock_t*, int);
1634     int pthread_spin_destroy(pthread_spinlock_t*);
1635     int pthread_spin_lock(pthread_spinlock_t*);
1636     int pthread_spin_trylock(pthread_spinlock_t*);
1637     int pthread_spin_unlock(pthread_spinlock_t*);
1638 } else version (Darwin) {
1639 } else version (Solaris) {
1640     int pthread_spin_init(pthread_spinlock_t*, int);
1641     int pthread_spin_destroy(pthread_spinlock_t*);
1642     int pthread_spin_lock(pthread_spinlock_t*);
1643     int pthread_spin_trylock(pthread_spinlock_t*);
1644     int pthread_spin_unlock(pthread_spinlock_t*);
1645 } else version (CRuntime_Bionic) {
1646 } else version (CRuntime_Musl) {
1647     int pthread_spin_destroy(pthread_spinlock_t*);
1648     int pthread_spin_init(pthread_spinlock_t*, int);
1649     int pthread_spin_lock(pthread_spinlock_t*);
1650     int pthread_spin_trylock(pthread_spinlock_t*);
1651     int pthread_spin_unlock(pthread_spinlock_t*);
1652 } else version (CRuntime_UClibc) {
1653     int pthread_spin_destroy(pthread_spinlock_t*);
1654     int pthread_spin_init(pthread_spinlock_t*, int);
1655     int pthread_spin_lock(pthread_spinlock_t*);
1656     int pthread_spin_trylock(pthread_spinlock_t*);
1657     int pthread_spin_unlock(pthread_spinlock_t*);
1658 } else {
1659     static assert(false, "Unsupported platform");
1660 }
1661 
1662 //
1663 // XOpen (XSI)
1664 //
1665 /*
1666 PTHREAD_MUTEX_DEFAULT
1667 PTHREAD_MUTEX_ERRORCHECK
1668 PTHREAD_MUTEX_NORMAL
1669 PTHREAD_MUTEX_RECURSIVE
1670 
1671 int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1672 int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1673 int pthread_getconcurrency();
1674 int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
1675 int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
1676 int pthread_setconcurrency(int);
1677 */
1678 
1679 version (CRuntime_Glibc) {
1680     enum PTHREAD_MUTEX_NORMAL = 0;
1681     enum PTHREAD_MUTEX_RECURSIVE = 1;
1682     enum PTHREAD_MUTEX_ERRORCHECK = 2;
1683     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
1684 
1685     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1686     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1687     int pthread_getconcurrency();
1688     int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
1689     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1690     int pthread_setconcurrency(int);
1691 } else version (Darwin) {
1692     enum PTHREAD_MUTEX_NORMAL = 0;
1693     enum PTHREAD_MUTEX_ERRORCHECK = 1;
1694     enum PTHREAD_MUTEX_RECURSIVE = 2;
1695     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
1696 
1697     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1698     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1699     int pthread_getconcurrency();
1700     int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
1701     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1702     int pthread_setconcurrency(int);
1703 } else version (FreeBSD) {
1704     enum {
1705         PTHREAD_MUTEX_ERRORCHECK = 1,
1706         PTHREAD_MUTEX_RECURSIVE = 2,
1707         PTHREAD_MUTEX_NORMAL = 3,
1708         PTHREAD_MUTEX_ADAPTIVE_NP = 4,
1709         PTHREAD_MUTEX_TYPE_MAX
1710     }
1711     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
1712 
1713     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1714     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1715     int pthread_getconcurrency();
1716     int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
1717     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1718     int pthread_setconcurrency(int);
1719 } else version (NetBSD) {
1720     enum {
1721         PTHREAD_MUTEX_NORMAL = 0,
1722         PTHREAD_MUTEX_ERRORCHECK = 1,
1723         PTHREAD_MUTEX_RECURSIVE = 2,
1724         PTHREAD_MUTEX_TYPE_MAX
1725     }
1726     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
1727 
1728     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1729     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1730     int pthread_getconcurrency();
1731     int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
1732     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1733     int pthread_setconcurrency(int);
1734 } else version (OpenBSD) {
1735     enum {
1736         PTHREAD_MUTEX_ERRORCHECK = 1,
1737         PTHREAD_MUTEX_RECURSIVE = 2,
1738         PTHREAD_MUTEX_NORMAL = 3,
1739         PTHREAD_MUTEX_ADAPTIVE_NP = 4,
1740         PTHREAD_MUTEX_TYPE_MAX
1741     }
1742     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
1743 
1744     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1745     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1746     int pthread_getconcurrency();
1747     int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
1748     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1749     int pthread_setconcurrency(int);
1750 } else version (DragonFlyBSD) {
1751     enum {
1752         PTHREAD_MUTEX_ERRORCHECK = 1,
1753         PTHREAD_MUTEX_RECURSIVE = 2,
1754         PTHREAD_MUTEX_NORMAL = 3,
1755         PTHREAD_MUTEX_TYPE_MAX
1756     }
1757     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
1758 
1759     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1760     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1761     int pthread_getconcurrency();
1762     int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
1763     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1764     int pthread_setconcurrency(int);
1765 } else version (Solaris) {
1766     enum {
1767         PTHREAD_MUTEX_ERRORCHECK = 2,
1768         PTHREAD_MUTEX_RECURSIVE = 4,
1769         PTHREAD_MUTEX_NORMAL = 0,
1770     }
1771 
1772     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
1773 
1774     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1775     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1776     int pthread_getconcurrency();
1777     int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
1778     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1779     int pthread_setconcurrency(int);
1780 } else version (CRuntime_Bionic) {
1781     enum PTHREAD_MUTEX_NORMAL = 0;
1782     enum PTHREAD_MUTEX_RECURSIVE = 1;
1783     enum PTHREAD_MUTEX_ERRORCHECK = 2;
1784     enum PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
1785 
1786     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1787     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1788     int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
1789     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1790 } else version (CRuntime_Musl) {
1791     enum {
1792         PTHREAD_MUTEX_NORMAL = 0,
1793         PTHREAD_MUTEX_RECURSIVE = 1,
1794         PTHREAD_MUTEX_ERRORCHECK = 2,
1795         PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL,
1796     }
1797     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1798 } else version (CRuntime_UClibc) {
1799     enum {
1800         PTHREAD_MUTEX_TIMED_NP,
1801         PTHREAD_MUTEX_RECURSIVE_NP,
1802         PTHREAD_MUTEX_ERRORCHECK_NP,
1803         PTHREAD_MUTEX_ADAPTIVE_NP,
1804         PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_TIMED_NP,
1805         PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
1806         PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
1807         PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL,
1808         PTHREAD_MUTEX_FAST_NP = PTHREAD_MUTEX_TIMED_NP
1809     }
1810 
1811     int pthread_attr_getguardsize(const scope pthread_attr_t*, size_t*);
1812     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
1813     int pthread_getconcurrency();
1814     int pthread_mutexattr_gettype(const scope pthread_mutexattr_t*, int*);
1815     int pthread_mutexattr_settype(pthread_mutexattr_t*, int) @trusted;
1816     int pthread_setconcurrency(int);
1817 } else {
1818     static assert(false, "Unsupported platform");
1819 }
1820 
1821 //
1822 // Priority (TPI|TPP)
1823 //
1824 /*
1825 PTHREAD_PRIO_INHERIT (TPI)
1826 PTHREAD_PRIO_NONE (TPP|TPI)
1827 PTHREAD_PRIO_PROTECT (TPI)
1828 
1829 int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*); (TPP)
1830 int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); (TPP)
1831 int pthread_mutexattr_getprioceiling(pthread_mutexattr_t*, int*); (TPP)
1832 int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*); (TPI|TPP)
1833 int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); (TPP)
1834 int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); (TPI|TPP)
1835 */
1836 version (Darwin) {
1837     enum {
1838         PTHREAD_PRIO_NONE,
1839         PTHREAD_PRIO_INHERIT,
1840         PTHREAD_PRIO_PROTECT
1841     }
1842 
1843     int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*);
1844     int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);
1845     int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*);
1846     int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*);
1847     int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
1848     int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
1849 } else version (Solaris) {
1850     enum {
1851         PTHREAD_PRIO_NONE = 0x00,
1852         PTHREAD_PRIO_INHERIT = 0x10,
1853         PTHREAD_PRIO_PROTECT = 0x20,
1854     }
1855 
1856     int pthread_mutex_getprioceiling(const scope pthread_mutex_t*, int*);
1857     int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);
1858     int pthread_mutexattr_getprioceiling(const scope pthread_mutexattr_t*, int*);
1859     int pthread_mutexattr_getprotocol(const scope pthread_mutexattr_t*, int*);
1860     int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int);
1861     int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
1862 }
1863 
1864 //
1865 // Stack (TSA|TSS)
1866 //
1867 /*
1868 int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*); (TSA|TSS)
1869 int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**); (TSA)
1870 int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*); (TSS)
1871 int pthread_attr_setstack(pthread_attr_t*, void*, size_t); (TSA|TSS)
1872 int pthread_attr_setstackaddr(pthread_attr_t*, void*); (TSA)
1873 int pthread_attr_setstacksize(pthread_attr_t*, size_t); (TSS)
1874 */
1875 
1876 version (CRuntime_Glibc) {
1877     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1878     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1879     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1880     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1881     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1882     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1883 } else version (Darwin) {
1884     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1885     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1886     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1887     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1888     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1889     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1890 } else version (FreeBSD) {
1891     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1892     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1893     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1894     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1895     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1896     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1897 } else version (NetBSD) {
1898     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1899     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1900     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1901     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1902     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1903     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1904 } else version (OpenBSD) {
1905     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1906     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1907     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1908     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1909     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1910     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1911 } else version (DragonFlyBSD) {
1912     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1913     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1914     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1915     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1916     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1917     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1918 } else version (Solaris) {
1919     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1920     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1921     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1922     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1923     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1924     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1925 } else version (CRuntime_Bionic) {
1926     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1927     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1928     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1929     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1930     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1931     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1932 } else version (CRuntime_Musl) {
1933     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1934     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1935 } else version (CRuntime_UClibc) {
1936     int pthread_attr_getstack(const scope pthread_attr_t*, void**, size_t*);
1937     int pthread_attr_getstackaddr(const scope pthread_attr_t*, void**);
1938     int pthread_attr_getstacksize(const scope pthread_attr_t*, size_t*);
1939     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
1940     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
1941     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
1942 } else {
1943     static assert(false, "Unsupported platform");
1944 }
1945 
1946 //
1947 // Shared Synchronization (TSH)
1948 //
1949 /*
1950 int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
1951 int pthread_condattr_setpshared(pthread_condattr_t*, int);
1952 int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
1953 int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
1954 int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
1955 int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
1956 */
1957 
1958 version (CRuntime_Glibc) {
1959     int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
1960     int pthread_condattr_setpshared(pthread_condattr_t*, int);
1961     int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
1962     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
1963     int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
1964     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
1965 } else version (FreeBSD) {
1966     int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
1967     int pthread_condattr_setpshared(pthread_condattr_t*, int);
1968     int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
1969     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
1970     int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
1971     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
1972 } else version (NetBSD) {
1973     int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
1974     int pthread_condattr_setpshared(pthread_condattr_t*, int);
1975     int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
1976     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
1977     int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
1978     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
1979 } else version (OpenBSD) {
1980 } else version (DragonFlyBSD) {
1981     int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
1982     int pthread_condattr_setpshared(pthread_condattr_t*, int);
1983     int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
1984     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
1985     int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
1986     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
1987 } else version (Darwin) {
1988     int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
1989     int pthread_condattr_setpshared(pthread_condattr_t*, int);
1990     int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
1991     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
1992     int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
1993     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
1994 } else version (Solaris) {
1995     int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
1996     int pthread_condattr_setpshared(pthread_condattr_t*, int);
1997     int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
1998     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
1999     int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
2000     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
2001 } else version (CRuntime_Bionic) {
2002     int pthread_condattr_getpshared(pthread_condattr_t*, int*);
2003     int pthread_condattr_setpshared(pthread_condattr_t*, int);
2004     int pthread_mutexattr_getpshared(pthread_mutexattr_t*, int*);
2005     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
2006     int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*);
2007     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
2008 } else version (CRuntime_Musl) {
2009     int pthread_condattr_getpshared(pthread_condattr_t*, int*);
2010     int pthread_condattr_setpshared(pthread_condattr_t*, int);
2011     int pthread_mutexattr_getpshared(pthread_mutexattr_t*, int*);
2012     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
2013     int pthread_rwlockattr_getpshared(pthread_rwlockattr_t*, int*);
2014     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
2015 } else version (CRuntime_UClibc) {
2016     int pthread_condattr_getpshared(const scope pthread_condattr_t*, int*);
2017     int pthread_condattr_setpshared(pthread_condattr_t*, int);
2018     int pthread_mutexattr_getpshared(const scope pthread_mutexattr_t*, int*);
2019     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
2020     int pthread_rwlockattr_getpshared(const scope pthread_rwlockattr_t*, int*);
2021     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
2022 } else {
2023     static assert(false, "Unsupported platform");
2024 }