xref: /relibc/pthreads-emb/pthread.h (revision dc52dd286f8a3968dab4b88483b2b906fdca64cb)
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 
390     /*
391      * Generic handle type - intended to extend uniqueness beyond
392      * that available with a simple pointer. It should scale for either
393      * IA-32 or IA-64.
394      */
395     typedef struct
396       {
397         void * p;                   /* Pointer to actual object */
398         unsigned int x;             /* Extra information - reuse count etc */
399       } pte_handle_t;
400 
401     typedef pte_handle_t pthread_t;
402     typedef struct pthread_attr_t_ * pthread_attr_t;
403     typedef struct pthread_once_t_ pthread_once_t;
404     typedef struct pthread_key_t_ * pthread_key_t;
405     typedef struct pthread_mutex_t_ * pthread_mutex_t;
406     typedef struct pthread_mutexattr_t_ * pthread_mutexattr_t;
407     typedef struct pthread_cond_t_ * pthread_cond_t;
408     typedef struct pthread_condattr_t_ * pthread_condattr_t;
409     typedef struct pthread_rwlock_t_ * pthread_rwlock_t;
410     typedef struct pthread_rwlockattr_t_ * pthread_rwlockattr_t;
411     typedef struct pthread_spinlock_t_ * pthread_spinlock_t;
412     typedef struct pthread_barrier_t_ * pthread_barrier_t;
413     typedef struct pthread_barrierattr_t_ * pthread_barrierattr_t;
414 
415     /*
416      * ====================
417      * ====================
418      * POSIX Threads
419      * ====================
420      * ====================
421      */
422 
423     enum
424     {
425       /*
426        * pthread_attr_{get,set}detachstate
427        */
428       PTHREAD_CREATE_JOINABLE       = 0,  /* Default */
429       PTHREAD_CREATE_DETACHED       = 1,
430 
431       /*
432        * pthread_attr_{get,set}inheritsched
433        */
434       PTHREAD_INHERIT_SCHED         = 0,
435       PTHREAD_EXPLICIT_SCHED        = 1,  /* Default */
436 
437       /*
438        * pthread_{get,set}scope
439        */
440       PTHREAD_SCOPE_PROCESS         = 0,
441       PTHREAD_SCOPE_SYSTEM          = 1,  /* Default */
442       PTHREAD_SCOPE_PROCESS_VFPU    = 2,  /* PSP specific */
443 
444       /*
445        * pthread_setcancelstate paramters
446        */
447       PTHREAD_CANCEL_ENABLE         = 0,  /* Default */
448       PTHREAD_CANCEL_DISABLE        = 1,
449 
450       /*
451        * pthread_setcanceltype parameters
452        */
453       PTHREAD_CANCEL_ASYNCHRONOUS   = 0,
454       PTHREAD_CANCEL_DEFERRED       = 1,  /* Default */
455 
456       /*
457        * pthread_mutexattr_{get,set}pshared
458        * pthread_condattr_{get,set}pshared
459        */
460       PTHREAD_PROCESS_PRIVATE       = 0,
461       PTHREAD_PROCESS_SHARED        = 1,
462 
463       /*
464        * pthread_barrier_wait
465        */
466       PTHREAD_BARRIER_SERIAL_THREAD = -1
467     };
468 
469     /*
470      * ====================
471      * ====================
472      * Cancelation
473      * ====================
474      * ====================
475      */
476 #define PTHREAD_CANCELED       ((void *) -1)
477 
478 
479     /*
480      * ====================
481      * ====================
482      * Once Key
483      * ====================
484      * ====================
485      */
486 #define PTHREAD_ONCE_INIT       { PTE_FALSE, 0, 0, 0}
487 
488     struct pthread_once_t_
489       {
490         int          state;
491         void *       semaphore;
492         int 		   numSemaphoreUsers;
493         int          done;        /* indicates if user function has been executed */
494 //  void *       lock;
495 //  int          reserved1;
496 //  int          reserved2;
497       };
498 
499 
500     /*
501      * ====================
502      * ====================
503      * Object initialisers
504      * ====================
505      * ====================
506      */
507 #define PTHREAD_MUTEX_INITIALIZER ((pthread_mutex_t) -1)
508 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER ((pthread_mutex_t) -2)
509 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER ((pthread_mutex_t) -3)
510 
511     /*
512      * Compatibility with LinuxThreads
513      */
514 #define PTHREAD_RECURSIVE_MUTEX_INITIALIZER_NP PTHREAD_RECURSIVE_MUTEX_INITIALIZER
515 #define PTHREAD_ERRORCHECK_MUTEX_INITIALIZER_NP PTHREAD_ERRORCHECK_MUTEX_INITIALIZER
516 
517 #define PTHREAD_COND_INITIALIZER ((pthread_cond_t) -1)
518 
519 #define PTHREAD_RWLOCK_INITIALIZER ((pthread_rwlock_t) -1)
520 
521 #define PTHREAD_SPINLOCK_INITIALIZER ((pthread_spinlock_t) -1)
522 
523 
524     /*
525      * Mutex types.
526      */
527     enum
528     {
529       /* Compatibility with LinuxThreads */
530       PTHREAD_MUTEX_FAST_NP,
531       PTHREAD_MUTEX_RECURSIVE_NP,
532       PTHREAD_MUTEX_ERRORCHECK_NP,
533       PTHREAD_MUTEX_TIMED_NP = PTHREAD_MUTEX_FAST_NP,
534       PTHREAD_MUTEX_ADAPTIVE_NP = PTHREAD_MUTEX_FAST_NP,
535       /* For compatibility with POSIX */
536       PTHREAD_MUTEX_NORMAL = PTHREAD_MUTEX_FAST_NP,
537       PTHREAD_MUTEX_RECURSIVE = PTHREAD_MUTEX_RECURSIVE_NP,
538       PTHREAD_MUTEX_ERRORCHECK = PTHREAD_MUTEX_ERRORCHECK_NP,
539       PTHREAD_MUTEX_DEFAULT = PTHREAD_MUTEX_NORMAL
540     };
541 
542 
543     typedef struct pte_cleanup_t pte_cleanup_t;
544 
545     typedef void (*  pte_cleanup_callback_t)(void *);
546 
547     struct pte_cleanup_t
548       {
549         pte_cleanup_callback_t routine;
550         void *arg;
551         struct pte_cleanup_t *prev;
552       };
553 
554 #ifdef PTE_CLEANUP_C
555 
556     /*
557      * C implementation of PThreads cancel cleanup
558      */
559 
560 #define pthread_cleanup_push( _rout, _arg ) \
561         { \
562             pte_cleanup_t     _cleanup; \
563             \
564             pte_push_cleanup( &_cleanup, (pte_cleanup_callback_t) (_rout), (_arg) ); \
565 
566 #define pthread_cleanup_pop( _execute ) \
567             (void) pte_pop_cleanup( _execute ); \
568         }
569 
570 #else /* PTE_CLEANUP_C */
571 
572 #ifdef PTE_CLEANUP_CXX
573 
574     /*
575     * C++ version of cancel cleanup.
576     * - John E. Bossom.
577     */
578 
579     class PThreadCleanup
580       {
581         /*
582         * PThreadCleanup
583         *
584         * Purpose
585         *      This class is a C++ helper class that is
586         *      used to implement pthread_cleanup_push/
587         *      pthread_cleanup_pop.
588         *      The destructor of this class automatically
589         *      pops the pushed cleanup routine regardless
590         *      of how the code exits the scope
591         *      (i.e. such as by an exception)
592         */
593         pte_cleanup_callback_t cleanUpRout;
594         void    *       obj;
595         int             executeIt;
596 
597       public:
598         PThreadCleanup() :
599             cleanUpRout( 0 ),
600             obj( 0 ),
601             executeIt( 0 )
602             /*
603             * No cleanup performed
604             */
605         {
606         }
607 
608         PThreadCleanup(
609           pte_cleanup_callback_t routine,
610           void    *       arg ) :
611             cleanUpRout( routine ),
612             obj( arg ),
613             executeIt( 1 )
614             /*
615             * Registers a cleanup routine for 'arg'
616             */
617         {
618         }
619 
620         ~PThreadCleanup()
621         {
622           if ( executeIt )
623             {
624               (void) (*cleanUpRout)( obj );
625             }
626         }
627 
628         void execute( int exec )
629         {
630           executeIt = exec;
631         }
632       };
633 
634     /*
635     * C++ implementation of PThreads cancel cleanup;
636     * This implementation takes advantage of a helper
637     * class who's destructor automatically calls the
638     * cleanup routine if we exit our scope weirdly
639     */
640 #define pthread_cleanup_push( _rout, _arg ) \
641         { \
642             PThreadCleanup  cleanup((pte_cleanup_callback_t)(_rout), \
643                                     (void *) (_arg) );
644 
645 #define pthread_cleanup_pop( _execute ) \
646             cleanup.execute( _execute ); \
647         }
648 
649 #else
650 
651 #error ERROR [__FILE__, line __LINE__]: Cleanup type undefined.
652 
653 #endif /* PTE_CLEANUP_CXX */
654 
655 #endif /* PTE_CLEANUP_C */
656 
657 #ifdef __cplusplus
658 extern "C" {
659 #endif /* __cplusplus */
660 
661     /*
662      * ===============
663      * ===============
664      * Methods
665      * ===============
666      * ===============
667      */
668 
669     void  pthread_init (void);
670     void  pthread_terminate (void);
671 
672     /*
673      * PThread Attribute Functions
674      */
675     int  pthread_attr_init (pthread_attr_t * attr);
676 
677     int  pthread_attr_destroy (pthread_attr_t * attr);
678 
679     int  pthread_attr_getdetachstate (const pthread_attr_t * attr,
680                                       int *detachstate);
681 
682     int  pthread_attr_getstackaddr (const pthread_attr_t * attr,
683                                     void **stackaddr);
684 
685     int  pthread_attr_getstacksize (const pthread_attr_t * attr,
686                                     size_t * stacksize);
687 
688     int  pthread_attr_setdetachstate (pthread_attr_t * attr,
689                                       int detachstate);
690 
691     int  pthread_attr_setstackaddr (pthread_attr_t * attr,
692                                     void *stackaddr);
693 
694     int  pthread_attr_setstacksize (pthread_attr_t * attr,
695                                     size_t stacksize);
696 
697     int  pthread_attr_getschedparam (const pthread_attr_t *attr,
698                                      struct sched_param *param);
699 
700     int  pthread_attr_setschedparam (pthread_attr_t *attr,
701                                      const struct sched_param *param);
702 
703     int  pthread_attr_setschedpolicy (pthread_attr_t *,
704                                       int);
705 
706     int  pthread_attr_getschedpolicy (pthread_attr_t *,
707                                       int *);
708 
709     int  pthread_attr_setinheritsched(pthread_attr_t * attr,
710                                       int inheritsched);
711 
712     int  pthread_attr_getinheritsched(pthread_attr_t * attr,
713                                       int * inheritsched);
714 
715     int  pthread_attr_setscope (pthread_attr_t *,
716                                 int);
717 
718     int  pthread_attr_getscope (const pthread_attr_t *,
719                                 int *);
720 
721     /*
722      * PThread Functions
723      */
724     int  pthread_create (pthread_t * tid,
725                          const pthread_attr_t * attr,
726                          void *(*start) (void *),
727                          void *arg);
728 
729     int  pthread_detach (pthread_t tid);
730 
731     int  pthread_equal (pthread_t t1,
732                         pthread_t t2);
733 
734     void  pthread_exit (void *value_ptr);
735 
736     int  pthread_join (pthread_t thread,
737                        void **value_ptr);
738 
739     pthread_t  pthread_self (void);
740 
741     int  pthread_cancel (pthread_t thread);
742 
743     int  pthread_setcancelstate (int state,
744                                  int *oldstate);
745 
746     int  pthread_setcanceltype (int type,
747                                 int *oldtype);
748 
749     void  pthread_testcancel (void);
750 
751     int  pthread_once (pthread_once_t * once_control,
752                        void (*init_routine) (void));
753 
754 #if PTE_LEVEL >= PTE_LEVEL_MAX
755     pte_cleanup_t *  pte_pop_cleanup (int execute);
756 
757     void  pte_push_cleanup (pte_cleanup_t * cleanup,
758                             void (*routine) (void *),
759                             void *arg);
760 #endif /* PTE_LEVEL >= PTE_LEVEL_MAX */
761 
762     /*
763      * Thread Specific Data Functions
764      */
765     int  pthread_key_create (pthread_key_t * key,
766                              void (*destructor) (void *));
767 
768     int  pthread_key_delete (pthread_key_t key);
769 
770     int  pthread_setspecific (pthread_key_t key,
771                               const void *value);
772 
773     void *  pthread_getspecific (pthread_key_t key);
774 
775 
776     /*
777      * Mutex Attribute Functions
778      */
779     int  pthread_mutexattr_init (pthread_mutexattr_t * attr);
780 
781     int  pthread_mutexattr_destroy (pthread_mutexattr_t * attr);
782 
783     int  pthread_mutexattr_getpshared (const pthread_mutexattr_t
784                                        * attr,
785                                        int *pshared);
786 
787     int  pthread_mutexattr_setpshared (pthread_mutexattr_t * attr,
788                                        int pshared);
789 
790     int  pthread_mutexattr_settype (pthread_mutexattr_t * attr, int kind);
791     int  pthread_mutexattr_gettype (pthread_mutexattr_t * attr, int *kind);
792 
793     /*
794      * Barrier Attribute Functions
795      */
796     int  pthread_barrierattr_init (pthread_barrierattr_t * attr);
797 
798     int  pthread_barrierattr_destroy (pthread_barrierattr_t * attr);
799 
800     int  pthread_barrierattr_getpshared (const pthread_barrierattr_t
801                                          * attr,
802                                          int *pshared);
803 
804     int  pthread_barrierattr_setpshared (pthread_barrierattr_t * attr,
805                                          int pshared);
806 
807     /*
808      * Mutex Functions
809      */
810     int  pthread_mutex_init (pthread_mutex_t * mutex,
811                              const pthread_mutexattr_t * attr);
812 
813     int  pthread_mutex_destroy (pthread_mutex_t * mutex);
814 
815     int  pthread_mutex_lock (pthread_mutex_t * mutex);
816 
817     int  pthread_mutex_timedlock(pthread_mutex_t *mutex,
818                                  const struct timespec *abstime);
819 
820     int  pthread_mutex_trylock (pthread_mutex_t * mutex);
821 
822     int  pthread_mutex_unlock (pthread_mutex_t * mutex);
823 
824     /*
825      * Spinlock Functions
826      */
827     int  pthread_spin_init (pthread_spinlock_t * lock, int pshared);
828 
829     int  pthread_spin_destroy (pthread_spinlock_t * lock);
830 
831     int  pthread_spin_lock (pthread_spinlock_t * lock);
832 
833     int  pthread_spin_trylock (pthread_spinlock_t * lock);
834 
835     int  pthread_spin_unlock (pthread_spinlock_t * lock);
836 
837     /*
838      * Barrier Functions
839      */
840     int  pthread_barrier_init (pthread_barrier_t * barrier,
841                                const pthread_barrierattr_t * attr,
842                                unsigned int count);
843 
844     int  pthread_barrier_destroy (pthread_barrier_t * barrier);
845 
846     int  pthread_barrier_wait (pthread_barrier_t * barrier);
847 
848     /*
849      * Condition Variable Attribute Functions
850      */
851     int  pthread_condattr_init (pthread_condattr_t * attr);
852 
853     int  pthread_condattr_destroy (pthread_condattr_t * attr);
854 
855     int  pthread_condattr_getpshared (const pthread_condattr_t * attr,
856                                       int *pshared);
857 
858     int  pthread_condattr_setpshared (pthread_condattr_t * attr,
859                                       int pshared);
860 
861     /*
862      * Condition Variable Functions
863      */
864     int  pthread_cond_init (pthread_cond_t * cond,
865                             const pthread_condattr_t * attr);
866 
867     int  pthread_cond_destroy (pthread_cond_t * cond);
868 
869     int  pthread_cond_wait (pthread_cond_t * cond,
870                             pthread_mutex_t * mutex);
871 
872     int  pthread_cond_timedwait (pthread_cond_t * cond,
873                                  pthread_mutex_t * mutex,
874                                  const struct timespec *abstime);
875 
876     int  pthread_cond_signal (pthread_cond_t * cond);
877 
878     int  pthread_cond_broadcast (pthread_cond_t * cond);
879 
880     /*
881      * Scheduling
882      */
883     int  pthread_setschedparam (pthread_t thread,
884                                 int policy,
885                                 const struct sched_param *param);
886 
887     int  pthread_getschedparam (pthread_t thread,
888                                 int *policy,
889                                 struct sched_param *param);
890 
891     int  pthread_setconcurrency (int);
892 
893     int  pthread_getconcurrency (void);
894 
895     /*
896      * Read-Write Lock Functions
897      */
898     int  pthread_rwlock_init(pthread_rwlock_t *lock,
899                              const pthread_rwlockattr_t *attr);
900 
901     int  pthread_rwlock_destroy(pthread_rwlock_t *lock);
902 
903     int  pthread_rwlock_tryrdlock(pthread_rwlock_t *);
904 
905     int  pthread_rwlock_trywrlock(pthread_rwlock_t *);
906 
907     int  pthread_rwlock_rdlock(pthread_rwlock_t *lock);
908 
909     int  pthread_rwlock_timedrdlock(pthread_rwlock_t *lock,
910                                     const struct timespec *abstime);
911 
912     int  pthread_rwlock_wrlock(pthread_rwlock_t *lock);
913 
914     int  pthread_rwlock_timedwrlock(pthread_rwlock_t *lock,
915                                     const struct timespec *abstime);
916 
917     int  pthread_rwlock_unlock(pthread_rwlock_t *lock);
918 
919     int  pthread_rwlockattr_init (pthread_rwlockattr_t * attr);
920 
921     int  pthread_rwlockattr_destroy (pthread_rwlockattr_t * attr);
922 
923     int  pthread_rwlockattr_getpshared (const pthread_rwlockattr_t * attr,
924                                         int *pshared);
925 
926     int  pthread_rwlockattr_setpshared (pthread_rwlockattr_t * attr,
927                                         int pshared);
928 
929 #if PTE_LEVEL >= PTE_LEVEL_MAX - 1
930 
931     /*
932      * Signal Functions. Should be defined in <signal.h> but we might
933      * already have signal.h that don't define these.
934      */
935     int  pthread_kill(pthread_t thread, int sig);
936 
937     /*
938      * Non-portable functions
939      */
940 
941     /*
942      * Compatibility with Linux.
943      */
944     int  pthread_mutexattr_setkind_np(pthread_mutexattr_t * attr,
945                                       int kind);
946     int  pthread_mutexattr_getkind_np(pthread_mutexattr_t * attr,
947                                       int *kind);
948 
949     /*
950      * Possibly supported by other POSIX threads implementations
951      */
952     int  pthread_delay_np (struct timespec * interval);
953     int  pthread_num_processors_np(void);
954 
955     /*
956      * Register a system time change with the library.
957      * Causes the library to perform various functions
958      * in response to the change. Should be called whenever
959      * the application's top level window receives a
960      * WM_TIMECHANGE message. It can be passed directly to
961      * pthread_create() as a new thread if desired.
962      */
963     void *  pthread_timechange_handler_np(void *);
964 
965 #endif /*PTE_LEVEL >= PTE_LEVEL_MAX - 1 */
966 
967 #ifdef __cplusplus
968 }
969 #endif /* cplusplus */
970 
971 #if PTE_LEVEL >= PTE_LEVEL_MAX
972 
973 
974 
975 #endif /* PTE_LEVEL >= PTE_LEVEL_MAX */
976 
977     /*
978      * Some compiler environments don't define some things.
979      */
980 #  define _ftime ftime
981 #  define _timeb timeb
982 
983 #ifdef __cplusplus
984 
985     /*
986      * Internal exceptions
987      */
988     class pte_exception {};
989     class pte_exception_cancel : public pte_exception {};
990     class pte_exception_exit   : public pte_exception {};
991 
992 #endif
993 
994 
995 #ifdef PTE_CXX_EXCEPTIONS
996 
997     /*
998      * Redefine the C++ catch keyword to ensure that applications
999      * propagate our internal exceptions up to the library's internal handlers.
1000      */
1001 #define catch( E ) \
1002         catch( pte_exception & ) { throw; } \
1003         catch( E )
1004 
1005 #endif /* ! PTE_CXX_EXCEPTIONS */
1006 
1007 #undef PTE_LEVEL
1008 #undef PTE_LEVEL_MAX
1009 
1010 #endif /* PTHREAD_H */
1011