1 /**
2  * D header file for POSIX.
3  *
4  * Copyright: Public Domain
5  * License:   Public Domain
6  * Authors:   Sean Kelly
7  * Standards: The Open Group Base Specifications Issue 6, IEEE Std 1003.1, 2004 Edition
8  */
9 module tango.stdc.posix.pthread;
10 
11 private import tango.stdc.posix.config;
12 version (solaris) private import tango.stdc.stdint;
13 
14 public import tango.stdc.posix.sys.types;
15 public import tango.stdc.posix.sched;
16 public import tango.stdc.posix.time;
17 
18 extern (C):
19 
20 //
21 // Required
22 //
23 /*
24 PTHREAD_CANCEL_ASYNCHRONOUS
25 PTHREAD_CANCEL_ENABLE
26 PTHREAD_CANCEL_DEFERRED
27 PTHREAD_CANCEL_DISABLE
28 PTHREAD_CANCELED
29 PTHREAD_COND_INITIALIZER
30 PTHREAD_CREATE_DETACHED
31 PTHREAD_CREATE_JOINABLE
32 PTHREAD_EXPLICIT_SCHED
33 PTHREAD_INHERIT_SCHED
34 PTHREAD_MUTEX_INITIALIZER
35 PTHREAD_ONCE_INIT
36 PTHREAD_PROCESS_SHARED
37 PTHREAD_PROCESS_PRIVATE
38 
39 int pthread_atfork(void function(), void function(), void function());
40 int pthread_attr_destroy(pthread_attr_t*);
41 int pthread_attr_getdetachstate(in pthread_attr_t*, int*);
42 int pthread_attr_getschedparam(in pthread_attr_t*, sched_param*);
43 int pthread_attr_init(pthread_attr_t*);
44 int pthread_attr_setdetachstate(pthread_attr_t*, int);
45 int pthread_attr_setschedparam(in pthread_attr_t*, sched_param*);
46 int pthread_cancel(pthread_t);
47 void pthread_cleanup_push(void function(void*), void*);
48 void pthread_cleanup_pop(int);
49 int pthread_cond_broadcast(pthread_cond_t*);
50 int pthread_cond_destroy(pthread_cond_t*);
51 int pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*);
52 int pthread_cond_signal(pthread_cond_t*);
53 int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*);
54 int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
55 int pthread_condattr_destroy(pthread_condattr_t*);
56 int pthread_condattr_init(pthread_condattr_t*);
57 int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
58 int pthread_detach(pthread_t);
59 int pthread_equal(pthread_t, pthread_t);
60 void pthread_exit(void*);
61 void* pthread_getspecific(pthread_key_t);
62 int pthread_join(pthread_t, void**);
63 int pthread_key_create(pthread_key_t*, void function(void*));
64 int pthread_key_delete(pthread_key_t);
65 int pthread_mutex_destroy(pthread_mutex_t*);
66 int pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*);
67 int pthread_mutex_lock(pthread_mutex_t*);
68 int pthread_mutex_trylock(pthread_mutex_t*);
69 int pthread_mutex_unlock(pthread_mutex_t*);
70 int pthread_mutexattr_destroy(pthread_mutexattr_t*);
71 int pthread_mutexattr_init(pthread_mutexattr_t*);
72 int pthread_once(pthread_once_t*, void function());
73 int pthread_rwlock_destroy(pthread_rwlock_t*);
74 int pthread_rwlock_init(in pthread_rwlock_t*, pthread_rwlockattr_t*);
75 int pthread_rwlock_rdlock(pthread_rwlock_t*);
76 int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
77 int pthread_rwlock_trywrlock(pthread_rwlock_t*);
78 int pthread_rwlock_unlock(pthread_rwlock_t*);
79 int pthread_rwlock_wrlock(pthread_rwlock_t*);
80 int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
81 int pthread_rwlockattr_init(pthread_rwlockattr_t*);
82 pthread_t pthread_self();
83 int pthread_setcancelstate(int, int*);
84 int pthread_setcanceltype(int, int*);
85 int pthread_setspecific(pthread_key_t, in void*);
86 void pthread_testcancel();
87 */
88 version( linux )
89 {
90     enum
91     {
92         PTHREAD_CANCEL_ENABLE,
93         PTHREAD_CANCEL_DISABLE
94     }
95 
96     enum
97     {
98         PTHREAD_CANCEL_DEFERRED,
99         PTHREAD_CANCEL_ASYNCHRONOUS
100     }
101 
102     const PTHREAD_CANCELED = cast(void*) -1;
103 
104     //const pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
105 
106     enum
107     {
108         PTHREAD_CREATE_JOINABLE,
109         PTHREAD_CREATE_DETACHED
110     }
111 
112     enum
113     {
114         PTHREAD_INHERIT_SCHED,
115         PTHREAD_EXPLICIT_SCHED
116     }
117 
118     //const pthread_mutex_t PTHREAD_MUTEX_INITIALIZER = { 0, 0, null, PTHREAD_MUTEX_NORMAL, { 0, 0 } };
119 
120     const PTHREAD_ONCE_INIT = 0;
121 
122     enum
123     {
124         PTHREAD_PROCESS_PRIVATE,
125         PTHREAD_PROCESS_SHARED
126     }
127 }
128 else version( darwin )
129 {
130     enum
131     {
132         PTHREAD_CANCEL_ENABLE   = 1,
133         PTHREAD_CANCEL_DISABLE  = 0
134     }
135 
136     enum
137     {
138         PTHREAD_CANCEL_DEFERRED     = 2,
139         PTHREAD_CANCEL_ASYNCHRONOUS = 0
140     }
141 
142     const PTHREAD_CANCELED = cast(void*) -1;
143 
144     //const pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
145 
146     enum
147     {
148         PTHREAD_CREATE_JOINABLE = 1,
149         PTHREAD_CREATE_DETACHED = 2
150     }
151 
152     enum
153     {
154         PTHREAD_INHERIT_SCHED   = 1,
155         PTHREAD_EXPLICIT_SCHED  = 2
156     }
157 
158     //const pthread_mutex_t PTHREAD_MUTEX_INITIALIZER = { 0, 0, null, PTHREAD_MUTEX_NORMAL, { 0, 0 } };
159 
160     const PTHREAD_ONCE_INIT = 0;
161 
162     enum
163     {
164         PTHREAD_PROCESS_PRIVATE = 2,
165         PTHREAD_PROCESS_SHARED  = 1
166     }
167 }
168 else version( solaris )
169 {   
170     const PTHREAD_CANCELED = cast(void*)-19;
171 
172     //const pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 };
173     //const pthread_mutex_t PTHREAD_MUTEX_INITIALIZER = { 0, 0, null, PTHREAD_MUTEX_NORMAL, { 0, 0 } };
174 
175     enum
176     {
177         PTHREAD_CANCEL_ENABLE       = 0x00,
178         PTHREAD_CANCEL_DISABLE      = 0x01,
179         PTHREAD_CANCEL_DEFERRED     = 0x00,
180         PTHREAD_CANCEL_ASYNCHRONOUS = 0x02,
181         PTHREAD_CREATE_JOINABLE     = 0,
182         PTHREAD_CREATE_DETACHED     = 0x40,
183         PTHREAD_INHERIT_SCHED       = 1,
184         PTHREAD_EXPLICIT_SCHED      = 0,
185         PTHREAD_PROCESS_PRIVATE     = 0,
186         PTHREAD_PROCESS_SHARED      = 1
187     }
188 
189 
190     const PTHREAD_ONCE_INIT = 0; /*
191         #define PTHREAD_ONCE_NOTDONE    0
192         #define PTHREAD_ONCE_DONE       1
193         #define PTHREAD_ONCE_INIT       { {0, 0, 0, PTHREAD_ONCE_NOTDONE} }
194     */
195 } else version( FreeBSD ) { 
196     enum 
197     { 
198         PTHREAD_CANCEL_ENABLE   = 0, 
199         PTHREAD_CANCEL_DISABLE  = 1 
200     } 
201  
202     enum 
203     { 
204         PTHREAD_CANCEL_DEFERRED     = 0, 
205         PTHREAD_CANCEL_ASYNCHRONOUS = 2 
206     } 
207  
208     const PTHREAD_CANCELED = cast(void*) -1; 
209  
210     //const pthread_mutex_t PTHREAD_COND_INITIALIZER = { __LOCK_ALT_INITIALIZER, 0, "", 0 }; 
211  
212     enum 
213     { 
214         PTHREAD_CREATE_JOINABLE = 0, 
215         PTHREAD_CREATE_DETACHED = 0x1 
216     } 
217  
218     enum 
219     { 
220         PTHREAD_INHERIT_SCHED   = 0x4, 
221         PTHREAD_EXPLICIT_SCHED  = 0 
222     } 
223  
224     //const pthread_mutex_t PTHREAD_MUTEX_INITIALIZER = { 0, 0, null, PTHREAD_MUTEX_NORMAL, { 0, 0 } }; 
225  
226     const PTHREAD_ONCE_INIT = [0, 0]; 
227  
228     enum 
229     { 
230         PTHREAD_PROCESS_PRIVATE = 0, 
231         PTHREAD_PROCESS_SHARED  = 1 
232     } 
233 } 
234 
235 int pthread_atfork(void function(), void function(), void function());
236 int pthread_attr_destroy(pthread_attr_t*);
237 int pthread_attr_getdetachstate(in pthread_attr_t*, int*);
238 int pthread_attr_getschedparam(in pthread_attr_t*, sched_param*);
239 int pthread_attr_init(pthread_attr_t*);
240 int pthread_attr_setdetachstate(pthread_attr_t*, int);
241 int pthread_attr_setschedparam(in pthread_attr_t*, sched_param*);
242 int pthread_cancel(pthread_t);
243 
244 version( linux )
245 {
246     alias void function(void*) _pthread_cleanup_routine;
247 
248     struct _pthread_cleanup_buffer
249     {
250         _pthread_cleanup_routine    __routine;
251         void*                       __arg;
252         int                         __canceltype;
253         _pthread_cleanup_buffer*    __prev;
254     }
255 
256     void _pthread_cleanup_push(_pthread_cleanup_buffer*, _pthread_cleanup_routine, void*);
257     void _pthread_cleanup_pop(_pthread_cleanup_buffer*, int);
258 
259     struct pthread_cleanup
260     {
261         _pthread_cleanup_buffer buffer = void;
262 
263         void push()( _pthread_cleanup_routine routine, void* arg )
264         {
265             _pthread_cleanup_push( &buffer, routine, arg );
266         }
267 
268         void pop()( int execute )
269         {
270             _pthread_cleanup_pop( &buffer, execute );
271         }
272     }
273 }
274 else version( darwin )
275 {
276     alias void function(void*) _pthread_cleanup_routine;
277 
278     struct _pthread_cleanup_buffer
279     {
280         _pthread_cleanup_routine    __routine;
281         void*                       __arg;
282         _pthread_cleanup_buffer*    __next;
283     }
284 
285     struct pthread_cleanup
286     {
287         _pthread_cleanup_buffer buffer = void;
288 
289         void push()( _pthread_cleanup_routine routine, void* arg )
290         {
291             pthread_t self       = pthread_self();
292             buffer.__routine     = routine;
293             buffer.__arg         = arg;
294             buffer.__next        = cast(_pthread_cleanup_buffer*) self.__cleanup_stack;
295             self.__cleanup_stack = cast(pthread_handler_rec*) &buffer;
296         }
297 
298         void pop()( int execute )
299         {
300             pthread_t self       = pthread_self();
301             self.__cleanup_stack = cast(pthread_handler_rec*) buffer.__next;
302             if( execute )
303             {
304                 buffer.__routine( buffer.__arg );
305             }
306         }
307     }
308 }
309 else version( solaris )
310 {
311     alias void function(void*) _pthread_cleanup_routine;
312 
313     struct _pthread_cleanup_buffer {
314         uintptr_t[4]   pthread_cleanup_pad;
315     }
316     
317     void __pthread_cleanup_push(_pthread_cleanup_routine, void*, caddr_t, _pthread_cleanup_buffer*);
318     void __pthread_cleanup_pop(int, _pthread_cleanup_buffer*);
319     caddr_t _getfp();
320 
321     struct pthread_cleanup
322     {
323         private _pthread_cleanup_buffer buffer = void;
324 
325         void push()( _pthread_cleanup_routine routine, void* arg )
326         {
327             __pthread_cleanup_push( routine, arg, _getfp(), &buffer );
328         }
329 
330         void pop()( int execute )
331         {
332             __pthread_cleanup_pop( execute, &buffer );
333         }
334     }
335 }
336 else
337 {
338     void pthread_cleanup_push(void function(void*), void*);
339     void pthread_cleanup_pop(int);
340 }
341 
342 int pthread_cond_broadcast(pthread_cond_t*);
343 int pthread_cond_destroy(pthread_cond_t*);
344 int pthread_cond_init(in pthread_cond_t*, pthread_condattr_t*);
345 int pthread_cond_signal(pthread_cond_t*);
346 int pthread_cond_timedwait(pthread_cond_t*, pthread_mutex_t*, in timespec*);
347 int pthread_cond_wait(pthread_cond_t*, pthread_mutex_t*);
348 int pthread_condattr_destroy(pthread_condattr_t*);
349 int pthread_condattr_init(pthread_condattr_t*);
350 int pthread_create(pthread_t*, in pthread_attr_t*, void* function(void*), void*);
351 int pthread_detach(pthread_t);
352 int pthread_equal(pthread_t, pthread_t);
353 void pthread_exit(void*);
354 void* pthread_getspecific(pthread_key_t);
355 int pthread_join(pthread_t, void**);
356 int pthread_key_create(pthread_key_t*, void function(void*));
357 int pthread_key_delete(pthread_key_t);
358 int pthread_mutex_destroy(pthread_mutex_t*);
359 int pthread_mutex_init(pthread_mutex_t*, pthread_mutexattr_t*);
360 int pthread_mutex_lock(pthread_mutex_t*);
361 int pthread_mutex_trylock(pthread_mutex_t*);
362 int pthread_mutex_unlock(pthread_mutex_t*);
363 int pthread_mutexattr_destroy(pthread_mutexattr_t*);
364 int pthread_mutexattr_init(pthread_mutexattr_t*);
365 int pthread_once(pthread_once_t*, void function());
366 int pthread_rwlock_destroy(pthread_rwlock_t*);
367 int pthread_rwlock_init(in pthread_rwlock_t*, pthread_rwlockattr_t*);
368 int pthread_rwlock_rdlock(pthread_rwlock_t*);
369 int pthread_rwlock_tryrdlock(pthread_rwlock_t*);
370 int pthread_rwlock_trywrlock(pthread_rwlock_t*);
371 int pthread_rwlock_unlock(pthread_rwlock_t*);
372 int pthread_rwlock_wrlock(pthread_rwlock_t*);
373 int pthread_rwlockattr_destroy(pthread_rwlockattr_t*);
374 int pthread_rwlockattr_init(pthread_rwlockattr_t*);
375 pthread_t pthread_self();
376 int pthread_setcancelstate(int, int*);
377 int pthread_setcanceltype(int, int*);
378 int pthread_setspecific(pthread_key_t, in void*);
379 void pthread_testcancel();
380 
381 //
382 // Barrier (BAR)
383 //
384 /*
385 PTHREAD_BARRIER_SERIAL_THREAD
386 
387 int pthread_barrier_destroy(pthread_barrier_t*);
388 int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
389 int pthread_barrier_wait(pthread_barrier_t*);
390 int pthread_barrierattr_destroy(pthread_barrierattr_t*);
391 int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*); (BAR|TSH)
392 int pthread_barrierattr_init(pthread_barrierattr_t*);
393 int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int); (BAR|TSH)
394 */
395 
396 version( linux )
397 {
398     const PTHREAD_BARRIER_SERIAL_THREAD = -1;
399 
400     int pthread_barrier_destroy(pthread_barrier_t*);
401     int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
402     int pthread_barrier_wait(pthread_barrier_t*);
403     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
404     int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
405     int pthread_barrierattr_init(pthread_barrierattr_t*);
406     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
407 }
408 else version( darwin )
409 {
410     // NOTE: The following definitions are Tango-specific because darwin does
411     //       not support them directly.
412 
413     const PTHREAD_BARRIER_SERIAL_THREAD = -1;
414 
415     int pthread_barrier_destroy(pthread_barrier_t*);
416     int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
417     int pthread_barrier_wait(pthread_barrier_t*);
418     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
419     int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
420     int pthread_barrierattr_init(pthread_barrierattr_t*);
421     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
422 }
423 else version( solaris )
424 {
425     const PTHREAD_BARRIER_SERIAL_THREAD = -2;
426     
427     int pthread_barrierattr_init(pthread_barrierattr_t*);
428     int pthread_barrierattr_destroy(pthread_barrierattr_t*);
429     int pthread_barrierattr_setpshared(pthread_barrierattr_t*, int);
430     int pthread_barrierattr_getpshared(in pthread_barrierattr_t*, int*);
431     int pthread_barrier_init(pthread_barrier_t*, in pthread_barrierattr_t*, uint);
432     int pthread_barrier_destroy(pthread_barrier_t*);
433     int pthread_barrier_wait(pthread_barrier_t*);
434 }
435 
436 //
437 // Clock (CS)
438 //
439 /*
440 int pthread_condattr_getclock(in pthread_condattr_t*, clockid_t*);
441 int pthread_condattr_setclock(pthread_condattr_t*, clockid_t);
442 */
443 
444 //
445 // Spinlock (SPI)
446 //
447 /*
448 int pthread_spin_destroy(pthread_spinlock_t*);
449 int pthread_spin_init(pthread_spinlock_t*, int);
450 int pthread_spin_lock(pthread_spinlock_t*);
451 int pthread_spin_trylock(pthread_spinlock_t*);
452 int pthread_spin_unlock(pthread_spinlock_t*);
453 */
454 
455 version( linux )
456 {
457     int pthread_spin_destroy(pthread_spinlock_t*);
458     int pthread_spin_init(pthread_spinlock_t*, int);
459     int pthread_spin_lock(pthread_spinlock_t*);
460     int pthread_spin_trylock(pthread_spinlock_t*);
461     int pthread_spin_unlock(pthread_spinlock_t*);
462 }
463 else version( solaris )
464 {
465     int pthread_spin_init(pthread_spinlock_t*, int);
466     int pthread_spin_destroy(pthread_spinlock_t*);
467     int pthread_spin_lock(pthread_spinlock_t*);
468     int pthread_spin_trylock(pthread_spinlock_t*);
469     int pthread_spin_unlock(pthread_spinlock_t*);
470 }
471 
472 //
473 // XOpen (XSI)
474 //
475 /*
476 PTHREAD_MUTEX_DEFAULT
477 PTHREAD_MUTEX_ERRORCHECK
478 PTHREAD_MUTEX_NORMAL
479 PTHREAD_MUTEX_RECURSIVE
480 
481 int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
482 int pthread_attr_setguardsize(pthread_attr_t*, size_t);
483 int pthread_getconcurrency();
484 int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
485 int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
486 int pthread_setconcurrency(int);
487 */
488 
489 version( linux )
490 {
491     const PTHREAD_MUTEX_NORMAL      = 0;
492     const PTHREAD_MUTEX_RECURSIVE   = 1;
493     const PTHREAD_MUTEX_ERRORCHECK  = 2;
494     const PTHREAD_MUTEX_DEFAULT     = PTHREAD_MUTEX_NORMAL;
495 
496     int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
497     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
498     int pthread_getconcurrency();
499     int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
500     int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
501     int pthread_setconcurrency(int);
502 }
503 else version( darwin )
504 {
505     const PTHREAD_MUTEX_NORMAL      = 0;
506     const PTHREAD_MUTEX_ERRORCHECK  = 1;
507     const PTHREAD_MUTEX_RECURSIVE   = 2;
508     const PTHREAD_MUTEX_DEFAULT     = PTHREAD_MUTEX_NORMAL;
509 
510     int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
511     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
512     int pthread_getconcurrency();
513     int pthread_mutexattr_gettype(in pthread_mutexattr_t*, int*);
514     int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
515     int pthread_setconcurrency(int);
516 }
517 else version( FreeBSD )
518 {
519     enum
520     {
521         PTHREAD_MUTEX_ERRORCHECK    = 1,
522         PTHREAD_MUTEX_RECURSIVE     = 2,
523         PTHREAD_MUTEX_NORMAL        = 3,
524         PTHREAD_MUTEX_ADAPTIVE_NP   = 4,
525         PTHREAD_MUTEX_TYPE_MAX
526     }
527     const PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_ERRORCHECK;
528 
529     int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
530     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
531     int pthread_getconcurrency();
532     int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
533     int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
534     int pthread_setconcurrency(int);
535 }
536 else version( solaris )
537 {
538     enum
539     {
540         PTHREAD_MUTEX_NORMAL        = 0x0,
541         PTHREAD_MUTEX_ERRORCHECK    = 0x2,
542         PTHREAD_MUTEX_RECURSIVE     = 0x4,
543     }
544     const PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL;
545     
546     int pthread_attr_getguardsize(in pthread_attr_t*, size_t*);
547     int pthread_attr_setguardsize(pthread_attr_t*, size_t);
548     int pthread_getconcurrency();
549     int pthread_mutexattr_gettype(pthread_mutexattr_t*, int*);
550     int pthread_mutexattr_settype(pthread_mutexattr_t*, int);
551     int pthread_setconcurrency(int);
552 }
553 
554 //
555 // CPU Time (TCT)
556 //
557 /*
558 int pthread_getcpuclockid(pthread_t, clockid_t*);
559 */
560 
561 version( linux )
562 {
563     int pthread_getcpuclockid(pthread_t, clockid_t*);
564 }
565 
566 //
567 // Timeouts (TMO)
568 //
569 /*
570 int pthread_mutex_timedlock(pthread_mutex_t*, timespec*);
571 int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
572 int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
573 */
574 
575 version( linux )
576 {
577     int pthread_mutex_timedlock(pthread_mutex_t*, timespec*);
578     int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
579     int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
580 }
581 else version( darwin )
582 {
583     int pthread_mutex_timedlock(pthread_mutex_t*, timespec*);
584     int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
585     int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
586 }
587 else version( solaris )
588 {
589     int pthread_mutex_timedlock(pthread_mutex_t*, timespec*);
590     int pthread_rwlock_timedrdlock(pthread_rwlock_t*, in timespec*);
591     int pthread_rwlock_timedwrlock(pthread_rwlock_t*, in timespec*);
592 }
593 
594 //
595 // Priority (TPI|TPP)
596 //
597 /*
598 PTHREAD_PRIO_INHERIT (TPI)
599 PTHREAD_PRIO_NONE (TPP|TPI)
600 PTHREAD_PRIO_PROTECT (TPI)
601 
602 int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*); (TPP)
603 int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*); (TPP)
604 int pthread_mutexattr_getprioceiling(pthread_mutexattr_t*, int*); (TPP)
605 int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*); (TPI|TPP)
606 int pthread_mutexattr_setprioceiling(pthread_mutexattr_t*, int); (TPP)
607 int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int); (TPI|TPP)
608 */
609 
610 version( solaris )
611 {
612     enum {
613         PTHREAD_PRIO_NONE       = 0x00,
614         PTHREAD_PRIO_INHERIT    = 0x10,
615         PTHREAD_PRIO_PROTECT    = 0x20
616     }
617     int pthread_mutex_setprioceiling(pthread_mutex_t*, int, int*);
618     int pthread_mutex_getprioceiling(in pthread_mutex_t*, int*);
619     int pthread_mutexattr_setprotocol(pthread_mutexattr_t*, int);
620     int pthread_mutexattr_getprotocol(in pthread_mutexattr_t*, int*);
621     int pthread_mutexattr_setprioceiling(pthread_mutexattr_t *, int);
622     int pthread_mutexattr_getprioceiling(in pthread_mutexattr_t*, int*);
623 }
624 
625 //
626 // Scheduling (TPS)
627 //
628 /*
629 PTHREAD_SCOPE_PROCESS
630 PTHREAD_SCOPE_SYSTEM
631 
632 int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
633 int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
634 int pthread_attr_getscope(in pthread_attr_t*, int*);
635 int pthread_attr_setinheritsched(pthread_attr_t*, int);
636 int pthread_attr_setschedpolicy(pthread_attr_t*, int);
637 int pthread_attr_setscope(pthread_attr_t*, int);
638 int pthread_getschedparam(pthread_t, int*, sched_param*);
639 int pthread_setschedparam(pthread_t, int, in sched_param*);
640 int pthread_setschedprio(pthread_t, int);
641 */
642 
643 version( linux )
644 {
645     enum
646     {
647         PTHREAD_SCOPE_SYSTEM,
648         PTHREAD_SCOPE_PROCESS
649     }
650 
651     int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
652     int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
653     int pthread_attr_getscope(in pthread_attr_t*, int*);
654     int pthread_attr_setinheritsched(pthread_attr_t*, int);
655     int pthread_attr_setschedpolicy(pthread_attr_t*, int);
656     int pthread_attr_setscope(pthread_attr_t*, int);
657     int pthread_getschedparam(pthread_t, int*, sched_param*);
658     int pthread_setschedparam(pthread_t, int, in sched_param*);
659     //int pthread_setschedprio(pthread_t, int);
660 }
661 else version( darwin )
662 {
663     enum
664     {
665         PTHREAD_SCOPE_SYSTEM    = 1,
666         PTHREAD_SCOPE_PROCESS   = 2
667     }
668 
669     int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
670     int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
671     int pthread_attr_getscope(in pthread_attr_t*, int*);
672     int pthread_attr_setinheritsched(pthread_attr_t*, int);
673     int pthread_attr_setschedpolicy(pthread_attr_t*, int);
674     int pthread_attr_setscope(pthread_attr_t*, int);
675     int pthread_getschedparam(pthread_t, int*, sched_param*);
676     int pthread_setschedparam(pthread_t, int, in sched_param*);
677     //int pthread_setschedprio(pthread_t, int);
678 }
679 else version( FreeBSD )
680 {
681     enum
682     {
683         PTHREAD_SCOPE_PROCESS   = 0,
684         PTHREAD_SCOPE_SYSTEM    = 0x2
685     }
686 
687     int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
688     int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
689     int pthread_attr_getscope(in pthread_attr_t*, int*);
690     int pthread_attr_setinheritsched(pthread_attr_t*, int);
691     int pthread_attr_setschedpolicy(pthread_attr_t*, int);
692     int pthread_attr_setscope(in pthread_attr_t*, int);
693     int pthread_getschedparam(pthread_t, int*, sched_param*);
694     int pthread_setschedparam(pthread_t, int, sched_param*);
695     //int pthread_setschedprio(pthread_t, int);
696 }
697 else version( solaris )
698 {
699     enum
700     {
701         PTHREAD_SCOPE_PROCESS   = 0,
702         PTHREAD_SCOPE_SYSTEM    = 0x01
703     }
704 
705     int pthread_attr_getinheritsched(in pthread_attr_t*, int*);
706     int pthread_attr_getschedpolicy(in pthread_attr_t*, int*);
707     int pthread_attr_getscope(in pthread_attr_t*, int*);
708     int pthread_attr_setinheritsched(pthread_attr_t*, int);
709     int pthread_attr_setschedpolicy(pthread_attr_t*, int);
710     int pthread_attr_setscope(in pthread_attr_t*, int);
711     int pthread_getschedparam(pthread_t, int*, sched_param*);
712     int pthread_setschedparam(pthread_t, int, sched_param*);
713     //int pthread_setschedprio(pthread_t, int);
714 }
715 
716 //
717 // Stack (TSA|TSS)
718 //
719 /*
720 int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*); (TSA|TSS)
721 int pthread_attr_getstackaddr(in pthread_attr_t*, void**); (TSA)
722 int pthread_attr_getstacksize(in pthread_attr_t*, size_t*); (TSS)
723 int pthread_attr_setstack(pthread_attr_t*, void*, size_t); (TSA|TSS)
724 int pthread_attr_setstackaddr(pthread_attr_t*, void*); (TSA)
725 int pthread_attr_setstacksize(pthread_attr_t*, size_t); (TSS)
726 */
727 
728 version( linux )
729 {
730     int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
731     int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
732     int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
733     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
734     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
735     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
736 }
737 else version( darwin )
738 {
739     int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
740     int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
741     int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
742     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
743     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
744     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
745 }
746 else version( FreeBSD )
747 {
748     int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
749     int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
750     int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
751     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
752     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
753     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
754 }
755 else version( solaris )
756 {
757     int pthread_attr_getstack(in pthread_attr_t*, void**, size_t*);
758     int pthread_attr_getstackaddr(in pthread_attr_t*, void**);
759     int pthread_attr_getstacksize(in pthread_attr_t*, size_t*);
760     int pthread_attr_setstack(pthread_attr_t*, void*, size_t);
761     int pthread_attr_setstackaddr(pthread_attr_t*, void*);
762     int pthread_attr_setstacksize(pthread_attr_t*, size_t);
763 }
764 
765 //
766 // Shared Synchronization (TSH)
767 //
768 /*
769 int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
770 int pthread_condattr_setpshared(pthread_condattr_t*, int);
771 int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
772 int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
773 int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
774 int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
775 */
776 
777 version( solaris )
778 {
779     int pthread_condattr_setpshared(pthread_condattr_t*, int);
780     int pthread_condattr_getpshared(in pthread_condattr_t*, int*);
781     int pthread_mutexattr_setpshared(pthread_mutexattr_t*, int);
782     int pthread_mutexattr_getpshared(in pthread_mutexattr_t*, int*);
783     int pthread_rwlockattr_getpshared(in pthread_rwlockattr_t*, int*);
784     int pthread_rwlockattr_setpshared(pthread_rwlockattr_t*, int);
785 }