xref: /relibc/pthreads-emb/pthread.h (revision 7af8bdd54f609ebec03115d05be2bcc851986fad)
1 /* This is an implementation of the threads API of POSIX 1003.1-2001.
2  *
3  * --------------------------------------------------------------------------
4  *
5  *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
6  *      Copyright(C) 2008 Jason Schmidlapp
7  *
8  *      Contact Email: jschmidlapp@users.sourceforge.net
9  *
10  *
11  *      Pthreads-embedded (PTE) - POSIX Threads Library for embedded systems
12  *      Copyright(C) 2008 Jason Schmidlapp
13  *
14  *      Contact Email: jschmidlapp@users.sourceforge.net
15  *
16  *
17  *      Based upon Pthreads-win32 - POSIX Threads Library for Win32
18  *      Copyright(C) 1998 John E. Bossom
19  *      Copyright(C) 1999,2005 Pthreads-win32 contributors
20  *
21  *      Contact Email: rpj@callisto.canberra.edu.au
22  *
23  *      The original list of contributors to the Pthreads-win32 project
24  *      is contained in the file CONTRIBUTORS.ptw32 included with the
25  *      source code distribution. The list can also be seen at the
26  *      following World Wide Web location:
27  *      http://sources.redhat.com/pthreads-win32/contributors.html
28  *
29  *      This library is free software; you can redistribute it and/or
30  *      modify it under the terms of the GNU Lesser General Public
31  *      License as published by the Free Software Foundation; either
32  *      version 2 of the License, or (at your option) any later version.
33  *
34  *      This library is distributed in the hope that it will be useful,
35  *      but WITHOUT ANY WARRANTY; without even the implied warranty of
36  *      MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
37  *      Lesser General Public License for more details.
38  *
39  *      You should have received a copy of the GNU Lesser General Public
40  *      License along with this library in the file COPYING.LIB;
41  *      if not, write to the Free Software Foundation, Inc.,
42  *      59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
43  */
44 #if !defined( PTHREAD_H )
45 #define PTHREAD_H
46 
47 #include <pte_types.h>
48 
49 #include <sched.h>
50 
51 #define PTE_VERSION 2,8,0,0
52 #define PTE_VERSION_STRING "2, 8, 0, 0\0"
53 
54 /* There are two implementations of cancel cleanup.
55  * Note that pthread.h is included in both application
56  * compilation units and also internally for the library.
57  * The code here and within the library aims to work
58  * for all reasonable combinations of environments.
59  *
60  * The two implementations are:
61  *
62  *   C
63  *   C++
64  *
65  */
66 
67 /*
68  * Define defaults for cleanup code.
69  * Note: Unless the build explicitly defines one of the following, then
70  * we default to standard C style cleanup. This style uses setjmp/longjmp
71  * in the cancelation and thread exit implementations and therefore won't
72  * do stack unwinding if linked to applications that have it (e.g.
73  * C++ apps). This is currently consistent with most/all commercial Unix
74  * POSIX threads implementations.
75  */
76 #if !defined( PTE_CLEANUP_CXX ) && !defined( PTE_CLEANUP_C )
77 # define PTE_CLEANUP_C
78 #endif
79 
80 #undef PTE_LEVEL
81 
82 #if defined(_POSIX_SOURCE)
83 #define PTE_LEVEL 0
84 /* Early POSIX */
85 #endif
86 
87 #if defined(_POSIX_C_SOURCE) && _POSIX_C_SOURCE >= 199309
88 #undef PTE_LEVEL
89 #define PTE_LEVEL 1
90 /* Include 1b, 1c and 1d */
91 #endif
92 
93 #if defined(INCLUDE_NP)
94 #undef PTE_LEVEL
95 #define PTE_LEVEL 2
96 /* Include Non-Portable extensions */
97 #endif
98 
99 #define PTE_LEVEL_MAX 3
100 
101 #if !defined(PTE_LEVEL)
102 #define PTE_LEVEL PTE_LEVEL_MAX
103 /* Include everything */
104 #endif
105 
106 /*
107  * -------------------------------------------------------------
108  *
109  *
110  * Module: pthread.h
111  *
112  * Purpose:
113  *      Provides an implementation of PThreads based upon the
114  *      standard:
115  *
116  *              POSIX 1003.1-2001
117  *  and
118  *    The Single Unix Specification version 3
119  *
120  *    (these two are equivalent)
121  *
122  *      in order to enhance code portability between Windows,
123  *  various commercial Unix implementations, and Linux.
124  *
125  *      See the ANNOUNCE file for a full list of conforming
126  *      routines and defined constants, and a list of missing
127  *      routines and constants not defined in this implementation.
128  *
129  * Authors:
130  *      There have been many contributors to this library.
131  *      The initial implementation was contributed by
132  *      John Bossom, and several others have provided major
133  *      sections or revisions of parts of the implementation.
134  *      Often significant effort has been contributed to
135  *      find and fix important bugs and other problems to
136  *      improve the reliability of the library, which sometimes
137  *      is not reflected in the amount of code which changed as
138  *      result.
139  *      As much as possible, the contributors are acknowledged
140  *      in the ChangeLog file in the source code distribution
141  *      where their changes are noted in detail.
142  *
143  *      Contributors are listed in the CONTRIBUTORS file.
144  *
145  *      As usual, all bouquets go to the contributors, and all
146  *      brickbats go to the project maintainer.
147  *
148  * Maintainer:
149  *      The code base for this project is coordinated and
150  *      eventually pre-tested, packaged, and made available by
151  *
152  *              Ross Johnson <rpj@callisto.canberra.edu.au>
153  *
154  * QA Testers:
155  *      Ultimately, the library is tested in the real world by
156  *      a host of competent and demanding scientists and
157  *      engineers who report bugs and/or provide solutions
158  *      which are then fixed or incorporated into subsequent
159  *      versions of the library. Each time a bug is fixed, a
160  *      test case is written to prove the fix and ensure
161  *      that later changes to the code don't reintroduce the
162  *      same error. The number of test cases is slowly growing
163  *      and therefore so is the code reliability.
164  *
165  * Compliance:
166  *      See the file ANNOUNCE for the list of implemented
167  *      and not-implemented routines and defined options.
168  *      Of course, these are all defined is this file as well.
169  *
170  * Web site:
171  *      The source code and other information about this library
172  *      are available from
173  *
174  *              http://sources.redhat.com/pthreads-win32/
175  *
176  * -------------------------------------------------------------
177  */
178 
179 #include <time.h>
180 
181 #include <setjmp.h>
182 #include <limits.h>
183 
184 /*
185  * Boolean values to make us independent of system includes.
186  */
187 enum
188 {
189   PTE_FALSE = 0,
190   PTE_TRUE = (! PTE_FALSE)
191 };
192 
193 
194     /*
195      * -------------------------------------------------------------
196      *
197      * POSIX 1003.1-2001 Options
198      * =========================
199      *
200      * Options are normally set in <unistd.h>, which is not provided
201      * with pthreads-embedded.
202      *
203      * For conformance with the Single Unix Specification (version 3), all of the
204      * options below are defined, and have a value of either -1 (not supported)
205      * or 200112L (supported).
206      *
207      * These options can neither be left undefined nor have a value of 0, because
208      * either indicates that sysconf(), which is not implemented, may be used at
209      * runtime to check the status of the option.
210      *
211      * _POSIX_THREADS (== 200112L)
212      *                      If == 200112L, you can use threads
213      *
214      * _POSIX_THREAD_ATTR_STACKSIZE (== 200112L)
215      *                      If == 200112L, you can control the size of a thread's
216      *                      stack
217      *                              pthread_attr_getstacksize
218      *                              pthread_attr_setstacksize
219      *
220      * _POSIX_THREAD_ATTR_STACKADDR (== -1)
221      *                      If == 200112L, you can allocate and control a thread's
222      *                      stack. If not supported, the following functions
223      *                      will return ENOSYS, indicating they are not
224      *                      supported:
225      *                              pthread_attr_getstackaddr
226      *                              pthread_attr_setstackaddr
227      *
228      * _POSIX_THREAD_PRIORITY_SCHEDULING (== -1)
229      *                      If == 200112L, you can use realtime scheduling.
230      *                      This option indicates that the behaviour of some
231      *                      implemented functions conforms to the additional TPS
232      *                      requirements in the standard. E.g. rwlocks favour
233      *                      writers over readers when threads have equal priority.
234      *
235      * _POSIX_THREAD_PRIO_INHERIT (== -1)
236      *                      If == 200112L, you can create priority inheritance
237      *                      mutexes.
238      *                              pthread_mutexattr_getprotocol +
239      *                              pthread_mutexattr_setprotocol +
240      *
241      * _POSIX_THREAD_PRIO_PROTECT (== -1)
242      *                      If == 200112L, you can create priority ceiling mutexes
243      *                      Indicates the availability of:
244      *                              pthread_mutex_getprioceiling
245      *                              pthread_mutex_setprioceiling
246      *                              pthread_mutexattr_getprioceiling
247      *                              pthread_mutexattr_getprotocol     +
248      *                              pthread_mutexattr_setprioceiling
249      *                              pthread_mutexattr_setprotocol     +
250      *
251      * _POSIX_THREAD_PROCESS_SHARED (== -1)
252      *                      If set, you can create mutexes and condition
253      *                      variables that can be shared with another
254      *                      process.If set, indicates the availability
255      *                      of:
256      *                              pthread_mutexattr_getpshared
257      *                              pthread_mutexattr_setpshared
258      *                              pthread_condattr_getpshared
259      *                              pthread_condattr_setpshared
260      *
261      * _POSIX_THREAD_SAFE_FUNCTIONS (== 200112L)
262      *                      If == 200112L you can use the special *_r library
263      *                      functions that provide thread-safe behaviour
264      *
265      * _POSIX_READER_WRITER_LOCKS (== 200112L)
266      *                      If == 200112L, you can use read/write locks
267      *
268      * _POSIX_SPIN_LOCKS (== 200112L)
269      *                      If == 200112L, you can use spin locks
270      *
271      * _POSIX_BARRIERS (== 200112L)
272      *                      If == 200112L, you can use barriers
273      *
274      *      + These functions provide both 'inherit' and/or
275      *        'protect' protocol, based upon these macro
276      *        settings.
277      *
278      * -------------------------------------------------------------
279      */
280 
281     /*
282      * POSIX Options
283      */
284 #undef _POSIX_THREADS
285 #define _POSIX_THREADS 200112L
286 
287 #undef _POSIX_READER_WRITER_LOCKS
288 #define _POSIX_READER_WRITER_LOCKS 200112L
289 
290 #undef _POSIX_SPIN_LOCKS
291 #define _POSIX_SPIN_LOCKS 200112L
292 
293 #undef _POSIX_BARRIERS
294 #define _POSIX_BARRIERS 200112L
295 
296 #undef _POSIX_THREAD_SAFE_FUNCTIONS
297 #define _POSIX_THREAD_SAFE_FUNCTIONS 200112L
298 
299 #undef _POSIX_THREAD_ATTR_STACKSIZE
300 #define _POSIX_THREAD_ATTR_STACKSIZE 200112L
301 
302     /*
303      * The following options are not supported
304      */
305 #undef _POSIX_THREAD_ATTR_STACKADDR
306 #define _POSIX_THREAD_ATTR_STACKADDR -1
307 
308 #undef _POSIX_THREAD_PRIO_INHERIT
309 #define _POSIX_THREAD_PRIO_INHERIT -1
310 
311 #undef _POSIX_THREAD_PRIO_PROTECT
312 #define _POSIX_THREAD_PRIO_PROTECT -1
313 
314     /* TPS is not fully supported.  */
315 #undef _POSIX_THREAD_PRIORITY_SCHEDULING
316 #define _POSIX_THREAD_PRIORITY_SCHEDULING -1
317 
318 #undef _POSIX_THREAD_PROCESS_SHARED
319 #define _POSIX_THREAD_PROCESS_SHARED -1
320 
321 
322     /*
323      * POSIX 1003.1-2001 Limits
324      * ===========================
325      *
326      * These limits are normally set in <limits.h>, which is not provided with
327      * pthreads-embedded.
328      *
329      * PTHREAD_DESTRUCTOR_ITERATIONS
330      *                      Maximum number of attempts to destroy
331      *                      a thread's thread-specific data on
332      *                      termination (must be at least 4)
333      *
334      * PTHREAD_KEYS_MAX
335      *                      Maximum number of thread-specific data keys
336      *                      available per process (must be at least 128)
337      *
338      * PTHREAD_STACK_MIN
339      *                      Minimum supported stack size for a thread
340      *
341      * PTHREAD_THREADS_MAX
342      *                      Maximum number of threads supported per
343      *                      process (must be at least 64).
344      *
345      * SEM_NSEMS_MAX
346      *                      The maximum number of semaphores a process can have.
347      *                      (must be at least 256)
348      *
349      * SEM_VALUE_MAX
350      *                      The maximum value a semaphore can have.
351      *                      (must be at least 32767)
352      *
353      */
354 #undef _POSIX_THREAD_DESTRUCTOR_ITERATIONS
355 #define _POSIX_THREAD_DESTRUCTOR_ITERATIONS     4
356 
357 #undef PTHREAD_DESTRUCTOR_ITERATIONS
358 #define PTHREAD_DESTRUCTOR_ITERATIONS           _POSIX_THREAD_DESTRUCTOR_ITERATIONS
359 
360 #undef _POSIX_THREAD_KEYS_MAX
361 #define _POSIX_THREAD_KEYS_MAX                  128
362 
363 #undef PTHREAD_KEYS_MAX
364 #define PTHREAD_KEYS_MAX                        _POSIX_THREAD_KEYS_MAX
365 
366 #undef PTHREAD_STACK_MIN
367 #define PTHREAD_STACK_MIN                       0
368 
369 #undef _POSIX_THREAD_THREADS_MAX
370 #define _POSIX_THREAD_THREADS_MAX               64
371 
372     /* Arbitrary value */
373 #undef PTHREAD_THREADS_MAX
374 #define PTHREAD_THREADS_MAX                     2019
375 
376 #undef _POSIX_SEM_NSEMS_MAX
377 #define _POSIX_SEM_NSEMS_MAX                    256
378 
379     /* Arbitrary value */
380 #undef SEM_NSEMS_MAX
381 #define SEM_NSEMS_MAX                           1024
382 
383 #undef _POSIX_SEM_VALUE_MAX
384 #define _POSIX_SEM_VALUE_MAX                    32767
385 
386 #undef SEM_VALUE_MAX
387 #define SEM_VALUE_MAX                           INT_MAX
388 
389     typedef void * pthread_t;
390     typedef struct pthread_attr_t_ * pthread_attr_t;
391     typedef struct pthread_once_t_ pthread_once_t;
392     typedef struct pthread_key_t_ * pthread_key_t;
393     typedef struct pthread_mutex_t_ * pthread_mutex_t;
394     typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
395     typedef struct pthread_cond_t_ * pthread_cond_t;
396     typedef struct pthread_condattr_t_ * pthread_condattr_t;
397     typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
398     typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
399     typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
400     typedef struct pthread_barrier_t_ * pthread_barrier_t;
401     typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
402 
403     /*
404      * ====================
405      * ====================
406      * POSIX Threads
407      * ====================
408      * ====================
409      */
410 
411     enum
412     {
413       /*
414        * pthread_attr_{get,set}detachstate
415        */
416       PTHREAD_CREATE_JOINABLE       = 0,  /* Default */
417       PTHREAD_CREATE_DETACHED       = 1,
418 
419       /*
420        * pthread_attr_{get,set}inheritsched
421        */
422       PTHREAD_INHERIT_SCHED         = 0,
423       PTHREAD_EXPLICIT_SCHED        = 1,  /* Default */
424 
425       /*
426        * pthread_{get,set}scope
427        */
428       PTHREAD_SCOPE_PROCESS         = 0,
429       PTHREAD_SCOPE_SYSTEM          = 1,  /* Default */
430       PTHREAD_SCOPE_PROCESS_VFPU    = 2,  /* PSP specific */
431 
432       /*
433        * pthread_setcancelstate paramters
434        */
435       PTHREAD_CANCEL_ENABLE         = 0,  /* Default */
436       PTHREAD_CANCEL_DISABLE        = 1,
437 
438       /*
439        * pthread_setcanceltype parameters
440        */
441       PTHREAD_CANCEL_ASYNCHRONOUS   = 0,
442       PTHREAD_CANCEL_DEFERRED       = 1,  /* Default */
443 
444       /*
445        * pthread_mutexattr_{get,set}pshared
446        * pthread_condattr_{get,set}pshared
447        */
448       PTHREAD_PROCESS_PRIVATE       = 0,
449       PTHREAD_PROCESS_SHARED        = 1,
450 
451       /*
452        * pthread_barrier_wait
453        */
454       PTHREAD_BARRIER_SERIAL_THREAD = -1
455     };
456 
457     /*
458      * ====================
459      * ====================
460      * Cancelation
461      * ====================
462      * ====================
463      */
464 #define PTHREAD_CANCELED       ((void *) -1)
465 
466 
467     /*
468      * ====================
469      * ====================
470      * Once Key
471      * ====================
472      * ====================
473      */
474 #define PTHREAD_ONCE_INIT       { PTE_FALSE, 0, 0, 0}
475 
476     struct pthread_once_t_
477       {
478         int          state;
479         void *       semaphore;
480         int 		   numSemaphoreUsers;
481         int          done;        /* indicates if user function has been executed */
482 //  void *       lock;
483 //  int          reserved1;
484 //  int          reserved2;
485       };
486 
487 
488     /*
489      * ====================
490      * ====================
491      * Object initialisers
492      * ====================
493      * ====================
494      */
495 #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
496 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
497 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
498 
499     /*
500      * Compatibility with LinuxThreads
501      */
502 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
503 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
504 
505 #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
506 
507 #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
508 
509 #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
510 
511 
512     /*
513      * Mutex types.
514      */
515     enum
516     {
517       /* Compatibility with LinuxThreads */
518       PTHREAD_MUTEX_FAST_NP,
519       PTHREAD_MUTEX_RECURSIVE_NP,
520       PTHREAD_MUTEX_ERRORCHECK_NP,
521       PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
522       PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
523       /* For compatibility with POSIX */
524       PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
525       PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
526       PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
527       PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
528     };
529 
530 
531     typedef struct pte_cleanup_t pte_cleanup_t;
532 
533     typedef void (*  pte_cleanup_callback_t)(void *);
534 
535     struct pte_cleanup_t
536       {
537         pte_cleanup_callback_t routine;
538         void *arg;
539         struct pte_cleanup_t *prev;
540       };
541 
542 #ifdef PTE_CLEANUP_C
543 
544     /*
545      * C implementation of PThreads cancel cleanup
546      */
547 
548 #define pthread_cleanup_push( _rout, _arg ) \
549         { \
550             pte_cleanup_t     _cleanup; \
551             \
552             pte_push_cleanup( &_cleanup, (pte_cleanup_callback_t) (_rout), (_arg) ); \
553 
554 #define pthread_cleanup_pop( _execute ) \
555             (void) pte_pop_cleanup( _execute ); \
556         }
557 
558 #else /* PTE_CLEANUP_C */
559 
560 #ifdef PTE_CLEANUP_CXX
561 
562     /*
563     * C++ version of cancel cleanup.
564     * - John E. Bossom.
565     */
566 
567     class PThreadCleanup
568       {
569         /*
570         * PThreadCleanup
571         *
572         * Purpose
573         *      This class is a C++ helper class that is
574         *      used to implement pthread_cleanup_push/
575         *      pthread_cleanup_pop.
576         *      The destructor of this class automatically
577         *      pops the pushed cleanup routine regardless
578         *      of how the code exits the scope
579         *      (i.e. such as by an exception)
580         */
581         pte_cleanup_callback_t cleanUpRout;
582         void    *       obj;
583         int             executeIt;
584 
585       public:
PThreadCleanup()586         PThreadCleanup() :
587             cleanUpRout( 0 ),
588             obj( 0 ),
589             executeIt( 0 )
590             /*
591             * No cleanup performed
592             */
593         {
594         }
595 
PThreadCleanup(pte_cleanup_callback_t routine,void * arg)596         PThreadCleanup(
597           pte_cleanup_callback_t routine,
598           void    *       arg ) :
599             cleanUpRout( routine ),
600             obj( arg ),
601             executeIt( 1 )
602             /*
603             * Registers a cleanup routine for 'arg'
604             */
605         {
606         }
607 
~PThreadCleanup()608         ~PThreadCleanup()
609         {
610           if ( executeIt )
611             {
612               (void) (*cleanUpRout)( obj );
613             }
614         }
615 
execute(int exec)616         void execute( int exec )
617         {
618           executeIt = exec;
619         }
620       };
621 
622     /*
623     * C++ implementation of PThreads cancel cleanup;
624     * This implementation takes advantage of a helper
625     * class who's destructor automatically calls the
626     * cleanup routine if we exit our scope weirdly
627     */
628 #define pthread_cleanup_push( _rout, _arg ) \
629         { \
630             PThreadCleanup  cleanup((pte_cleanup_callback_t)(_rout), \
631                                     (void *) (_arg) );
632 
633 #define pthread_cleanup_pop( _execute ) \
634             cleanup.execute( _execute ); \
635         }
636 
637 #else
638 
639 #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
640 
641 #endif /* PTE_CLEANUP_CXX */
642 
643 #endif /* PTE_CLEANUP_C */
644 
645 #ifdef __cplusplus
646 extern "C" {
647 #endif /* __cplusplus */
648 
649     /*
650      * ===============
651      * ===============
652      * Methods
653      * ===============
654      * ===============
655      */
656 
657     void  pthread_init (void);
658     void  pthread_terminate (void);
659 
660     /*
661      * PThread Attribute Functions
662      */
663     int  pthread_attr_init (pthread_attr_t * attr);
664 
665     int  pthread_attr_destroy (pthread_attr_t * attr);
666 
667     int  pthread_attr_getdetachstate (const pthread_attr_t * attr,
668                                       int *detachstate);
669 
670     int  pthread_attr_getstackaddr (const pthread_attr_t * attr,
671                                     void **stackaddr);
672 
673     int  pthread_attr_getstacksize (const pthread_attr_t * attr,
674                                     size_t * stacksize);
675 
676     int  pthread_attr_setdetachstate (pthread_attr_t * attr,
677                                       int detachstate);
678 
679     int  pthread_attr_setstackaddr (pthread_attr_t * attr,
680                                     void *stackaddr);
681 
682     int  pthread_attr_setstacksize (pthread_attr_t * attr,
683                                     size_t stacksize);
684 
685     int  pthread_attr_getschedparam (const pthread_attr_t *attr,
686                                      struct sched_param *param);
687 
688     int  pthread_attr_setschedparam (pthread_attr_t *attr,
689                                      const struct sched_param *param);
690 
691     int  pthread_attr_setschedpolicy (pthread_attr_t *,
692                                       int);
693 
694     int  pthread_attr_getschedpolicy (pthread_attr_t *,
695                                       int *);
696 
697     int  pthread_attr_setinheritsched(pthread_attr_t * attr,
698                                       int inheritsched);
699 
700     int  pthread_attr_getinheritsched(pthread_attr_t * attr,
701                                       int * inheritsched);
702 
703     int  pthread_attr_setscope (pthread_attr_t *,
704                                 int);
705 
706     int  pthread_attr_getscope (const pthread_attr_t *,
707                                 int *);
708 
709     /*
710      * PThread Functions
711      */
712     int  pthread_create (pthread_t * tid,
713                          const pthread_attr_t * attr,
714                          void *(*start) (void *),
715                          void *arg);
716 
717     int  pthread_detach (pthread_t tid);
718 
719     int  pthread_equal (pthread_t t1,
720                         pthread_t t2);
721 
722     void  pthread_exit (void *value_ptr);
723 
724     int  pthread_join (pthread_t thread,
725                        void **value_ptr);
726 
727     pthread_t  pthread_self (void);
728 
729     int  pthread_cancel (pthread_t thread);
730 
731     int  pthread_setcancelstate (int state,
732                                  int *oldstate);
733 
734     int  pthread_setcanceltype (int type,
735                                 int *oldtype);
736 
737     void  pthread_testcancel (void);
738 
739     int  pthread_once (pthread_once_t * once_control,
740                        void (*init_routine) (void));
741 
742 #if PTE_LEVEL >= PTE_LEVEL_MAX
743     pte_cleanup_t *  pte_pop_cleanup (int execute);
744 
745     void  pte_push_cleanup (pte_cleanup_t * cleanup,
746                             void (*routine) (void *),
747                             void *arg);
748 #endif /* PTE_LEVEL >= PTE_LEVEL_MAX */
749 
750     /*
751      * Thread Specific Data Functions
752      */
753     int  pthread_key_create (pthread_key_t * key,
754                              void (*destructor) (void *));
755 
756     int  pthread_key_delete (pthread_key_t key);
757 
758     int  pthread_setspecific (pthread_key_t key,
759                               const void *value);
760 
761     void *  pthread_getspecific (pthread_key_t key);
762 
763 
764     /*
765      * Mutex Attribute Functions
766      */
767     int  pthread_mutexattr_init (pthread_mutexattr_t * attr);
768 
769     int  pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
770 
771     int  pthread_mutexattr_getpshared (const pthread_mutexattr_t
772                                        * attr,
773                                        int *pshared);
774 
775     int  pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
776                                        int pshared);
777 
778     int  pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
779     int  pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
780 
781     /*
782      * Barrier Attribute Functions
783      */
784     int  pthread_barrierattr_init (pthread_barrierattr_t * attr);
785 
786     int  pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
787 
788     int  pthread_barrierattr_getpshared (const pthread_barrierattr_t
789                                          * attr,
790                                          int *pshared);
791 
792     int  pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
793                                          int pshared);
794 
795     /*
796      * Mutex Functions
797      */
798     int  pthread_mutex_init (pthread_mutex_t * mutex,
799                              const pthread_mutexattr_t * attr);
800 
801     int  pthread_mutex_destroy (pthread_mutex_t * mutex);
802 
803     int  pthread_mutex_lock (pthread_mutex_t * mutex);
804 
805     int  pthread_mutex_timedlock(pthread_mutex_t *mutex,
806                                  const struct timespec *abstime);
807 
808     int  pthread_mutex_trylock (pthread_mutex_t * mutex);
809 
810     int  pthread_mutex_unlock (pthread_mutex_t * mutex);
811 
812     /*
813      * Spinlock Functions
814      */
815     int  pthread_spin_init (pthread_spinlock_t * lock, int pshared);
816 
817     int  pthread_spin_destroy (pthread_spinlock_t * lock);
818 
819     int  pthread_spin_lock (pthread_spinlock_t * lock);
820 
821     int  pthread_spin_trylock (pthread_spinlock_t * lock);
822 
823     int  pthread_spin_unlock (pthread_spinlock_t * lock);
824 
825     /*
826      * Barrier Functions
827      */
828     int  pthread_barrier_init (pthread_barrier_t * barrier,
829                                const pthread_barrierattr_t * attr,
830                                unsigned int count);
831 
832     int  pthread_barrier_destroy (pthread_barrier_t * barrier);
833 
834     int  pthread_barrier_wait (pthread_barrier_t * barrier);
835 
836     /*
837      * Condition Variable Attribute Functions
838      */
839     int  pthread_condattr_init (pthread_condattr_t * attr);
840 
841     int  pthread_condattr_destroy (pthread_condattr_t * attr);
842 
843     int  pthread_condattr_getpshared (const pthread_condattr_t * attr,
844                                       int *pshared);
845 
846     int  pthread_condattr_setpshared (pthread_condattr_t * attr,
847                                       int pshared);
848 
849     int  pthread_condattr_getclock (const pthread_condattr_t * attr,
850                                     clockid_t *clock_id);
851 
852     int  pthread_condattr_setclock (pthread_condattr_t * attr,
853                                     clockid_t clock_id);
854 
855     /*
856      * Condition Variable Functions
857      */
858     int  pthread_cond_init (pthread_cond_t * cond,
859                             const pthread_condattr_t * attr);
860 
861     int  pthread_cond_destroy (pthread_cond_t * cond);
862 
863     int  pthread_cond_wait (pthread_cond_t * cond,
864                             pthread_mutex_t * mutex);
865 
866     int  pthread_cond_timedwait (pthread_cond_t * cond,
867                                  pthread_mutex_t * mutex,
868                                  const struct timespec *abstime);
869 
870     int  pthread_cond_signal (pthread_cond_t * cond);
871 
872     int  pthread_cond_broadcast (pthread_cond_t * cond);
873 
874     /*
875      * Scheduling
876      */
877     int  pthread_setschedparam (pthread_t thread,
878                                 int policy,
879                                 const struct sched_param *param);
880 
881     int  pthread_getschedparam (pthread_t thread,
882                                 int *policy,
883                                 struct sched_param *param);
884 
885     int  pthread_setconcurrency (int);
886 
887     int  pthread_getconcurrency (void);
888 
889     /*
890      * Read-Write Lock Functions
891      */
892     int  pthread_rwlock_init(pthread_rwlock_t *lock,
893                              const pthread_rwlockattr_t *attr);
894 
895     int  pthread_rwlock_destroy(pthread_rwlock_t *lock);
896 
897     int  pthread_rwlock_tryrdlock(pthread_rwlock_t *);
898 
899     int  pthread_rwlock_trywrlock(pthread_rwlock_t *);
900 
901     int  pthread_rwlock_rdlock(pthread_rwlock_t *lock);
902 
903     int  pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
904                                     const struct timespec *abstime);
905 
906     int  pthread_rwlock_wrlock(pthread_rwlock_t *lock);
907 
908     int  pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
909                                     const struct timespec *abstime);
910 
911     int  pthread_rwlock_unlock(pthread_rwlock_t *lock);
912 
913     int  pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
914 
915     int  pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
916 
917     int  pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
918                                         int *pshared);
919 
920     int  pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
921                                         int pshared);
922 
923 #if PTE_LEVEL >= PTE_LEVEL_MAX - 1
924 
925     /*
926      * Signal Functions. Should be defined in <signal.h> but we might
927      * already have signal.h that don't define these.
928      */
929     int  pthread_kill(pthread_t thread, int sig);
930 
931     /*
932      * Non-portable functions
933      */
934 
935     /*
936      * Compatibility with Linux.
937      */
938     int  pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
939                                       int kind);
940     int  pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
941                                       int *kind);
942 
943     /*
944      * Possibly supported by other POSIX threads implementations
945      */
946     int  pthread_delay_np (struct timespec * interval);
947     int  pthread_num_processors_np(void);
948 
949     /*
950      * Register a system time change with the library.
951      * Causes the library to perform various functions
952      * in response to the change. Should be called whenever
953      * the application's top level window receives a
954      * WM_TIMECHANGE message. It can be passed directly to
955      * pthread_create() as a new thread if desired.
956      */
957     void *  pthread_timechange_handler_np(void *);
958 
959 #endif /*PTE_LEVEL >= PTE_LEVEL_MAX - 1 */
960 
961 #ifdef __cplusplus
962 }
963 #endif /* cplusplus */
964 
965 #if PTE_LEVEL >= PTE_LEVEL_MAX
966 
967 
968 
969 #endif /* PTE_LEVEL >= PTE_LEVEL_MAX */
970 
971     /*
972      * Some compiler environments don't define some things.
973      */
974 #  define _ftime ftime
975 #  define _timeb timeb
976 
977 #ifdef __cplusplus
978 
979     /*
980      * Internal exceptions
981      */
982     class pte_exception {};
983     class pte_exception_cancel : public pte_exception {};
984     class pte_exception_exit   : public pte_exception {};
985 
986 #endif
987 
988 
989 #ifdef PTE_CXX_EXCEPTIONS
990 
991     /*
992      * Redefine the C++ catch keyword to ensure that applications
993      * propagate our internal exceptions up to the library's internal handlers.
994      */
995 #define catch( E ) \
996         catch( pte_exception & ) { throw; } \
997         catch( E )
998 
999 #endif /* ! PTE_CXX_EXCEPTIONS */
1000 
1001 #undef PTE_LEVEL
1002 #undef PTE_LEVEL_MAX
1003 
1004 #endif /* PTHREAD_H */
1005