home *** CD-ROM | disk | FTP | other *** search
/ RISCWORLD 7 / RISCWORLD_VOL7.iso / Software / Issue4 / SDL / gcc346 / !gcc / include / unixlib / h / pthread < prev    next >
Encoding:
Text File  |  2006-09-17  |  22.4 KB  |  670 lines

  1. /****************************************************************************
  2.  *
  3.  * $Source: /usr/local/cvsroot/gccsdk/unixlib/source/clib/pthread.h,v $
  4.  * $Date: 2005/05/02 13:53:48 $
  5.  * $Revision: 1.19 $
  6.  * $State: Exp $
  7.  * $Author: nick $
  8.  *
  9.  ***************************************************************************/
  10.  
  11. /* pthread.h - IEEE Std 1003.1-2001 threads */
  12.  
  13. #ifndef __PTHREAD_H
  14.                                   
  15. #if (! defined __need_pthread_t)
  16. #define __PTHREAD_H
  17. #endif
  18.  
  19. #define __need_size_t
  20. #include <stddef.h>
  21.  
  22. #define __need_clock_t
  23. #include <time.h>
  24.  
  25. #include <sched.h>
  26. #include <bits/sched.h> /* for struct sched_param */
  27.  
  28. #ifndef __UNIXLIB_FEATURES
  29. #include <features.h>
  30. #endif
  31.  
  32. __BEGIN_DECLS
  33.  
  34. #if !defined __pthread_t_defined && (defined __PTHREAD_H || defined __need_pthread_t)
  35. #define __pthread_t_defined
  36.  
  37. /* Mutex/rwlock/cond var attributes structure */
  38. struct __pthread_lock_attr
  39. {
  40.   int pshared; /* can the mutex be shared between processes */
  41.   int type; /* mutex type */
  42. };
  43.  
  44. /* Mutex/rwlock type */
  45. enum __pthread_locktype
  46. {
  47.   LOCK_INVALID = 0,
  48.   LOCK_READ  = 'R',
  49.   LOCK_WRITE = 'W',
  50.   LOCK_MUTEX = 'M'
  51. };
  52.  
  53. /* Mutex/rwlock object */
  54. struct __pthread_lock
  55. {
  56.   /* Number of times the current thread has got this lock recursively */
  57.   unsigned int count;
  58.   /* Type of lock.  */
  59.   enum __pthread_locktype type;
  60.   /* Thread that currently owns the lock.  */
  61.   struct __pthread_thread *owner;
  62.   /* Linked list of threads that are blocked on this lock.  */
  63.   struct __pthread_thread *waiting;
  64.   /* Attributes of the lock.  */
  65.   struct __pthread_lock_attr attr;
  66. };
  67.  
  68. /* Condition var object */
  69. struct __pthread_cond
  70. {
  71.   /* Linked list of threads that are blocked on this condition var.  */
  72.   struct __pthread_thread *waiting;
  73. };
  74.  
  75. typedef struct __pthread_lock pthread_mutex_t;
  76. typedef struct __pthread_lock pthread_rwlock_t;
  77. typedef struct __pthread_cond pthread_cond_t;
  78.  
  79. typedef struct __pthread_lock_attr pthread_mutexattr_t;
  80. typedef struct __pthread_lock_attr pthread_rwlockattr_t;
  81. typedef struct __pthread_lock_attr pthread_condattr_t;
  82.  
  83. typedef struct __pthread_thread *pthread_t; /* Thread ID type */
  84.  
  85. /* Thread attributes object */
  86. struct __pthread_attr
  87. {
  88.   int detachstate;  /* Whether newly created threads should be joinable or detached */
  89.   size_t guardsize; /* Amount of extra memory to allocate at the end of the stack, in case of overflow */
  90.                     /* Not used under RISC OS as the stack is extensible */
  91.   void *stackaddr;  /* Address of the stack to use for the thread */
  92.                     /* Ignored under RISC OS, as a malloced area may be unsuitable for the stack */
  93.   size_t stacksize; /* Size to use for the thread's stack (ignored) */
  94.   struct sched_param param; /* Scheduling parameters. Currently ignored */
  95. };
  96.  
  97. typedef struct __pthread_attr pthread_attr_t;
  98.  
  99. typedef int pthread_key_t; /* Key type for thread specific data */
  100.  
  101. typedef int pthread_once_t; /* Type for pthread_once */
  102.  
  103. /* Current schedulability state of the thread */
  104. enum __pthread_state
  105. {
  106.   STATE_IDLE,
  107.   STATE_MUTEX_WAIT, /* Waiting for a mutex to become available */
  108.   STATE_COND_WAIT, /* Waiting for a condition variable to be signalled */
  109.   STATE_COND_TIMED_WAIT, /* Waiting for a condition variable with a timeout */
  110.   STATE_JOIN,
  111.   STATE_UNALLOCED,
  112.   STATE_BLOCKED, /* Waiting on a semaphore */
  113.  
  114.   /* All states below this point are for threads that may be switched in by the scheduler */
  115.   STATE_RUNNING, /* A normally running thread */
  116.   STATE_CLEANUP  /* A (possibly cancelled) thread that is running its cleanup handlers */
  117. };
  118.  
  119. /* Hold all details about the thread. A pthread_t points to one of these structures */
  120. struct __pthread_thread
  121. {
  122.   int magic; /* Magic number */
  123.  
  124.   /* Space for registers on the context switch */
  125.   struct __pthread_saved_context *saved_context;
  126.  
  127.   void *alloca[3]; /* Storage for alloca */
  128.  
  129.   int thread_errno; /* Value of errno for this thread */
  130.  
  131.   struct
  132.   {
  133.     int errnum;
  134.     char errmess[252];
  135.   } errbuf; /* Last RISC OS error from error handler */
  136.  
  137.   /* WARNING: Various assembly files refer to this structure, using
  138.      offsets defined in asm_dec.s
  139.      If you change the ordering of any of the elements above this
  140.      comment then make sure the offsets are kept in sync. */
  141.  
  142.  
  143.   struct __pthread_thread *next; /* Linked list of all threads */
  144.   enum __pthread_state state; /* Running/blocked/idle/etc. */
  145.   void *ret; /* Value returned from thread */
  146.  
  147.   void *(*start_routine)(void *); /* Function to call as the new thread */
  148.   void *arg; /* Argument to pass to the start_routine */
  149.  
  150.   /* Initial stack chunk allocated to thread */
  151.   struct __stack_chunk *stack;
  152.  
  153.   /* Thread that wishes to join with this thread */
  154.   struct __pthread_thread *joined;
  155.  
  156.   /* Linked list of keys associated with this thread */
  157.   struct __pthread_key *keys;
  158.  
  159.   /* Mutex that the thread is waiting for */
  160.   pthread_mutex_t *mutex;
  161.  
  162.   /* Type of mutex that the thread is waiting for */
  163.   enum __pthread_locktype mutextype;
  164.  
  165.   /* Condition var that the thread is waiting for */
  166.   pthread_cond_t *cond;
  167.  
  168.   /* Timeout value for condition var */
  169.   clock_t condtimeout;
  170.  
  171.   /* Next thread that is waiting on the same mutex/condition var */
  172.   struct __pthread_thread *nextwait;
  173.  
  174.   /* Linked list of cleanup functions to call when this thread exits */
  175.   struct __pthread_cleanup *cleanupfns;
  176.  
  177.   /* Scheduling parameters. Currently ignored */
  178.   struct sched_param __param;
  179.  
  180.   /* Scheduling policy.  Currently ignored.  */
  181.   int __policy;
  182.  
  183.   /* Cancelability state of this thread (enabled or disabled) */
  184.   unsigned int cancelstate : 1;
  185.  
  186.   /* Cancelability type (asynchronous or deferred) */
  187.   unsigned int canceltype : 1;
  188.  
  189.   /* Should this thread be cancelled when it next reaches a
  190.      cancellation point.  */
  191.   unsigned int cancelpending : 1;
  192.  
  193.   /* Is the thread detached of can it still be joined to.  */
  194.   unsigned int detachstate : 1;
  195.  
  196.   __sigset_t blocked; /* Signal mask for this thread. */
  197.   __sigset_t pending; /* Pending signals for this thread */
  198.   pthread_cond_t sigwait_cond;
  199. };
  200.  
  201. extern pthread_t __pthread_running_thread; /* Currently running thread */
  202.  
  203. #endif /* !defined __pthread_t_defined && (defined __PTHREAD_H || defined __need_pthread_t) */
  204. #undef __need_pthread_t
  205.  
  206. #ifdef __PTHREAD_H
  207.  
  208. /* Including pthread.h should make all symbols defined in time.h visible */
  209. #include <time.h> /* for struct timespec */
  210.  
  211. /* Main thread routines */
  212.  
  213. /* Run start_routine as a new thread */
  214. extern int pthread_create (pthread_t *__restrict thread,
  215.                const pthread_attr_t *__restrict attr,
  216.                void *(*start_routine) (void *),
  217.                void *__restrict arg) __THROW;
  218.  
  219. /* Exit from the current thread */
  220. extern void pthread_exit (void *value_ptr) __attribute__ ((__noreturn__));
  221.  
  222. /* Wait for another thread to finish and get its exit status.
  223.    This is a cancellation point.  */
  224. extern int pthread_join (pthread_t thread, void **value_ptr);
  225.  
  226. /* Detach a thread so all its memory is freed when it exits */
  227. extern int pthread_detach (pthread_t thread) __THROW;
  228.  
  229. /* Force a context switch as the current thread has nothing to do */
  230. extern void pthread_yield (void) __THROW;
  231.  
  232. /* Cancellation */
  233.  
  234. /* Exit status returned by a thread that has been cancelled */
  235. #define PTHREAD_CANCELED ((void*)1)
  236.  
  237. /* Enable a thread to be cancelled */
  238. #define PTHREAD_CANCEL_ENABLE 0
  239.  
  240. /* Disable thread from being cancelled */
  241. #define PTHREAD_CANCEL_DISABLE 1
  242.  
  243. /* Only cancel a thread when it reaches a cencellation point */
  244. #define PTHREAD_CANCEL_DEFERRED 0
  245.  
  246. /* Cancel a thread at any point */
  247. #define PTHREAD_CANCEL_ASYNCHRONOUS 1
  248.  
  249. /* Set whether the current thread can be cancelled or not */
  250. extern int pthread_setcancelstate (int state, int *oldstate);
  251.  
  252. /* Set whether the current thread can be cancelled asynchonously or not */
  253. extern int pthread_setcanceltype (int type, int *oldtype);
  254.  
  255. /* Introduce a cancellation point into the current thread */
  256. extern void pthread_testcancel (void);
  257.  
  258. /* Cancel a thread */
  259. extern int pthread_cancel (pthread_t thread);
  260.  
  261. /* Cleanup */
  262.  
  263. /* Record details of a cleanup handler */
  264. struct __pthread_cleanup
  265. {
  266.   void (*routine) (void*); /* Cleanup routine */
  267.   void *arg; /* Argument to call cleanup routine with */
  268.   struct __pthread_cleanup *next; /* Linked list of other cleanup handlers */
  269. };
  270.  
  271. /* Add a new cleanup handler */
  272. /* For every cleanup_push there must be exactly one corresponding cleanup_pop in the same scope */
  273. #define pthread_cleanup_push(cleanup_routine, cleanup_arg) \
  274. { \
  275.   struct __pthread_cleanup __pthread_cleanupblk; \
  276.   __pthread_cleanupblk.routine = cleanup_routine; \
  277.   __pthread_cleanupblk.arg = cleanup_arg; \
  278. \
  279.   __pthread_cleanup_push (&__pthread_cleanupblk);
  280.  
  281. /* Remove a cleanup handler, running it first if execute is nonzero */
  282. #define pthread_cleanup_pop(execute) \
  283.   if (execute && __pthread_cleanupblk.routine != NULL) \
  284.     __pthread_cleanupblk.routine(__pthread_cleanupblk.arg); \
  285. \
  286.   __pthread_cleanup_pop (); \
  287. }
  288.  
  289. /* Internal functions used by the above macros */
  290. extern void __pthread_cleanup_push (struct __pthread_cleanup *cleanup);
  291. extern void __pthread_cleanup_pop (void);
  292.  
  293. /* Thread attributes */
  294.  
  295. /* The thread should be created so other threads may join with it */
  296. #define PTHREAD_CREATE_JOINABLE 0
  297. /* The thread should be created detached, so no threads may join with it */
  298. #define PTHREAD_CREATE_DETACHED 1
  299.  
  300.  
  301. /* Initialise a thread attributes object with default values */
  302. extern int pthread_attr_init (pthread_attr_t *attr);
  303.  
  304. /* Destroy a thread attributes object (does nothing) */
  305. extern int pthread_attr_destroy (pthread_attr_t *attr);
  306.  
  307. /* Sets the detach state attribute */
  308. extern int pthread_attr_setdetachstate (pthread_attr_t *attr, int detachstate);
  309.  
  310. /* Gets the detach state attribute */
  311. extern int pthread_attr_getdetachstate (const pthread_attr_t *__restrict attr,
  312.                     int *detachstate);
  313.  
  314. /* Sets the size of the stack guard attribute
  315.    The stack guard is an area of memory at the end of the stack to
  316.    provide protection against stack overflow. This is ignored as
  317.    the stack is extensible. */
  318. extern int pthread_attr_setguardsize (pthread_attr_t *attr, size_t guardsize);
  319.  
  320. /* Gets the size of the stack guard attribute */
  321. extern int pthread_attr_getguardsize (const pthread_attr_t *__restrict attr,
  322.                       size_t *guardsize);
  323.  
  324. /* Sets the address of a thread's stack
  325.    This is ignored as there are limitations on what can be used
  326.    for the stack. */
  327. extern int pthread_attr_setstackaddr (pthread_attr_t *attr, void *stackaddr);
  328. /* Gets the address of a thread's stack */
  329. extern int pthread_attr_getstackaddr (const pthread_attr_t *__restrict attr,
  330.                       void **__restrict stackaddr);
  331.  
  332. /* Sets the size of a thread's stack (ignored) */
  333. extern int pthread_attr_setstacksize (pthread_attr_t *attr, size_t stacksize);
  334.  
  335. /* Gets the size of a thread's stack (as set with setstacksize) */
  336. extern int pthread_attr_getstacksize (const pthread_attr_t *__restrict attr,
  337.                       size_t *__restrict stacksize);
  338.  
  339. /* Set scheduling parameter attributes (currently ignored) */
  340. extern int pthread_attr_setschedparam (pthread_attr_t *__restrict attr,
  341.                        const struct sched_param *__restrict
  342.                        param);
  343.  
  344. /* Get scheduling parameter attributes */
  345. extern int pthread_attr_getschedparam (const pthread_attr_t *__restrict attr,
  346.                        struct sched_param *__restrict param);
  347.  
  348. /* Mutexes */
  349.  
  350. /* Static default initialiser for a pthread_mutex_t */
  351. #define PTHREAD_MUTEX_INITIALIZER {0,LOCK_MUTEX,NULL,NULL,{PTHREAD_PROCESS_PRIVATE,PTHREAD_MUTEX_DEFAULT}}
  352.  
  353. /* A recursively attempt to lock a mutex will cause deadlock */
  354. #define PTHREAD_MUTEX_NORMAL 0
  355. /* A recursively attempt to lock a mutex will cause an error to be returned */
  356. #define PTHREAD_MUTEX_ERRORCHECK 1
  357. /* A recursively attempt to lock a mutex will succeed */
  358. #define PTHREAD_MUTEX_RECURSIVE 2
  359. /* The default of the above settings */
  360. #define PTHREAD_MUTEX_DEFAULT 1
  361.  
  362. /* The mutex is private to the process */
  363. #define PTHREAD_PROCESS_PRIVATE 0
  364. /* The mutex is shared between processes (ignored) */
  365. #define PTHREAD_PROCESS_SHARED 1
  366.  
  367. /* Initialise a mutex object with the specified attributes */
  368. extern int pthread_mutex_init (pthread_mutex_t *__restrict mutex,
  369.                    const pthread_mutexattr_t *__restrict attr);
  370.  
  371. /* Destroy a mutex that is finished with */
  372. extern int pthread_mutex_destroy (pthread_mutex_t *mutex);
  373.  
  374. /* Lock a mutex, blocking if it is not available */
  375. extern int pthread_mutex_lock (pthread_mutex_t *mutex);
  376.  
  377. /* Try to lock a mutex, but don't block if it is unavailable */
  378. extern int pthread_mutex_trylock (pthread_mutex_t *mutex);
  379.  
  380. /* Unlock a previously locked mutex */
  381. extern int pthread_mutex_unlock (pthread_mutex_t *mutex);
  382.  
  383. /* Initialise an attributes object */
  384. extern int pthread_mutexattr_init (pthread_mutexattr_t *attr);
  385.  
  386. /* Destroy an attributes object */
  387. extern int pthread_mutexattr_destroy (pthread_mutexattr_t *attr);
  388.  
  389. /* Set the process shared attribute (ignored) */
  390. extern int pthread_mutexattr_setpshared (pthread_mutexattr_t *attr, int pshared);
  391. /* Get the process shared attribute */
  392. extern int pthread_mutexattr_getpshared (const pthread_mutexattr_t *__restrict
  393.                      attr, int *__restrict pshared);
  394.  
  395. /* Set the type of mutex (specifies the behaviour when a thread recursively locks the mutex) */
  396. extern int pthread_mutexattr_settype (pthread_mutexattr_t *attr, int type);
  397.  
  398. /* Get the type of mutex */
  399. extern int pthread_mutexattr_gettype (const pthread_mutexattr_t *__restrict
  400.                       attr, int *__restrict type);
  401.  
  402. /* Read/Write locks */
  403.  
  404. /* Static default initialiser for a pthread_rwlock_t */
  405. #define PTHREAD_RWLOCK_INITIALIZER {0,LOCK_READ,NULL,NULL,{PTHREAD_PROCESS_PRIVATE,PTHREAD_MUTEX_DEFAULT}}
  406.  
  407. /* Initialise a rwlock object with the specified attributes */
  408. extern int pthread_rwlock_init (pthread_rwlock_t *__restrict rwlock,
  409.                 const pthread_rwlockattr_t *__restrict attr);
  410.  
  411. /* Destroy a rwlock that is finished with */
  412. extern int pthread_rwlock_destroy (pthread_rwlock_t *rwlock);
  413.  
  414. /* Try to lock a rwlock for reading, blocking if unavailable */
  415. extern int pthread_rwlock_rdlock (pthread_rwlock_t *rwlock);
  416.  
  417. /* Try to lock a rwlock for reading, but don't block if it is unavailable */
  418. extern int pthread_rwlock_tryrdlock (pthread_rwlock_t *rwlock);
  419.  
  420. /* Try to lock a rwlock for writing, blocking if unavailable */
  421. extern int pthread_rwlock_wrlock (pthread_rwlock_t *rwlock);
  422.  
  423. /* Try to lock a rwlock for writing, but don't block if it is unavailable */
  424. extern int pthread_rwlock_trywrlock (pthread_rwlock_t *rwlock);
  425.  
  426. /* Unlock a previously locked rwlock */
  427. extern int pthread_rwlock_unlock (pthread_rwlock_t *rwlock);
  428.  
  429. /* Initialise an attributes object */
  430. extern int pthread_rwlockattr_init (pthread_rwlockattr_t *attr);
  431.  
  432. /* Destroy an attributes object */
  433. extern int pthread_rwlockattr_destroy (pthread_rwlockattr_t *attr);
  434.  
  435. /* Set the process shared attribute (ignored) */
  436. extern int pthread_rwlockattr_setpshared (pthread_rwlockattr_t *attr,
  437.                       int pshared);
  438.  
  439. /* Get the process shared attribute */
  440. extern int pthread_rwlockattr_getpshared (const pthread_rwlockattr_t *
  441.                       __restrict attr,
  442.                       int *__restrict pshared);
  443.  
  444. /* Condition variables */
  445.  
  446. /* Static default initialiser for a pthread_cond_t */
  447. #define PTHREAD_COND_INITIALIZER {NULL}
  448.  
  449. /* Initialise a condition variable with the given attributes */
  450. extern int pthread_cond_init (pthread_cond_t *__restrict cond,
  451.                   const pthread_condattr_t *__restrict attr);
  452.  
  453. /* Destroy a condition variable */
  454. extern int pthread_cond_destroy (pthread_cond_t *cond);
  455.  
  456. /* Wait for a condition variable to be signalled */
  457. extern int pthread_cond_wait (pthread_cond_t *__restrict cond,
  458.                   pthread_mutex_t *__restrict mutex);
  459.  
  460. /* Wait for a condition variable to be signalled, with a timeout */
  461. extern int pthread_cond_timedwait (pthread_cond_t *__restrict cond,
  462.                    pthread_mutex_t *__restrict mutex,
  463.                    const struct timespec *__restrict abstime);
  464.  
  465. /* Signal the specified condition var */
  466. extern int pthread_cond_signal (pthread_cond_t *cond);
  467.  
  468. /* Broadcast a signal to all threads waiting on this conition var */
  469. extern int pthread_cond_broadcast (pthread_cond_t *cond);
  470.  
  471. /* Initialise a condition variable attributes object */
  472. extern int pthread_condattr_init (pthread_condattr_t *attr);
  473.  
  474. /* Destroy an attributes object */
  475. extern int pthread_condattr_destroy (pthread_condattr_t *attr);
  476.  
  477. /* Set process shared attribute (ignored) */
  478. extern int pthread_condattr_setpshared (pthread_condattr_t *attr, int pshared);
  479.  
  480. /* Get process shared attribute */
  481. extern int pthread_condattr_getpshared (const pthread_condattr_t *
  482.                     __restrict attr,
  483.                     int *__restrict pshared);
  484.  
  485. /* Keys */
  486.  
  487. /* Maximum number of times a key destructor will be called */
  488. #define PTHREAD_DESTRUCTOR_ITERATIONS 50
  489. /* Maximum number of keys that can be created */
  490. #define PTHREAD_KEYS_MAX 256
  491.  
  492. /* Create a key and associate a destructor function with it */
  493. extern int pthread_key_create (pthread_key_t *key, void (*destructor) (void*));
  494.  
  495. /* Deletes a thread specific key (does not call the key's destructors) */
  496. extern int pthread_key_delete (pthread_key_t key);
  497.  
  498. /* Set a thread specific value to associate with the given key */
  499. extern int pthread_setspecific (pthread_key_t key, const void *value);
  500.  
  501. /* Read value associated with given key for the current thread
  502.    Returns NULL if no value has been set for this thread yet */
  503. extern void *pthread_getspecific (pthread_key_t key);
  504.  
  505. /* Miscellaneous */
  506.  
  507.  
  508. /* Max munber of threads that may be active at once */
  509. #define PTHREAD_THREADS_MAX 256
  510.  
  511. /* Size to allocate for a thread's initial stack chunk */
  512. #define PTHREAD_STACK_MIN 4096
  513.  
  514. /* Static default initialiser for a pthread_once_t */
  515. #define PTHREAD_ONCE_INIT 0
  516.  
  517. /* Ensure init_routine is called exactly once */
  518. extern int pthread_once (pthread_once_t *once_control,
  519.              void (*init_routine) (void));
  520.  
  521. /* Return the thread id of the current thread */
  522. extern pthread_t pthread_self (void);
  523.  
  524. /* Compare two thread ids */
  525. extern int pthread_equal (pthread_t t1, pthread_t t2);
  526.  
  527. /* Set handlers to be called when a process forks */
  528. extern int pthread_atfork (void (*prepare)(void), void (*parent)(void),
  529.                void (*child)(void));
  530.  
  531. /* Start the callevery interrupt */
  532. extern void __pthread_start_ticker (void);
  533. /* Remove the callevery interrupt */
  534. extern void __pthread_stop_ticker (void);
  535.  
  536. extern int pthread_setschedparam (pthread_t __thr,
  537.                   int __policy,
  538.                   const struct sched_param *__param) __THROW;
  539.  
  540. extern int pthread_getschedparam (pthread_t __thr,
  541.                   int *__policy,
  542.                   struct sched_param *__param)
  543.      __THROW;
  544.  
  545.  
  546. #ifdef __UNIXLIB_INTERNALS
  547.  
  548. /* Print lots of general debugging info */
  549. /*#define PTHREAD_DEBUG*/
  550. /* Print debug info for the context switcher */
  551. /*#define PTHREAD_DEBUG_CONTEXT*/
  552.  
  553. /* Magic number to check a pthread_t is valid */
  554. #define PTHREAD_MAGIC 0x52485450
  555.  
  556. #define __pthread_invalid(thread) \
  557.     (thread == NULL || thread->magic != PTHREAD_MAGIC)
  558.  
  559. /* Holds data about a thread specific key */
  560. struct __pthread_key
  561. {
  562.   pthread_key_t keyid; /* Key that this value is attached to */
  563.   union {
  564.     const void *constvalue;
  565.     void *nonconst;
  566.   } value; /* Value of the key for this thread. Mess around with a union
  567.               to get around const issues */
  568.   void (*destructor) (void*); /* Destructor function to call for this value */
  569.   struct __pthread_key *next; /* Linked list of all keys for this thread */
  570. };
  571.  
  572. /* Holds all the state associated with a thread when it is switched out */
  573. struct __pthread_saved_context
  574. {
  575.   int r[16]; /* User mode integer registers */
  576.   int spsr;
  577.   char fpregs[12*8]; /* Floating point registers */
  578.   int fpstatus; /* Floatingpoint status register */
  579. };
  580.  
  581. extern pthread_t __pthread_thread_list; /* Linked list of all threads */
  582. extern int __pthread_system_running; /* Has the thread system been initialised yet */
  583. extern int __pthread_num_running_threads; /* Number of threads currently running or blocked */
  584.  
  585. /* Called once early in program initialisation */
  586. extern void __pthread_prog_init (void);
  587.  
  588. /* Called if a non recoverable error is detected */
  589. extern void __pthread_fatal_error (const char *msg);
  590.  
  591. /* Initialise a new node, allocating it if node is NULL */
  592. extern pthread_t __pthread_new_node (pthread_t node);
  593.  
  594. /* Common routines used by mutex/rwlock/cond functions */
  595. extern int __pthread_lock_lock (pthread_mutex_t *mutex, const enum __pthread_locktype, const int trylock);
  596. extern int __pthread_lock_unlock (pthread_mutex_t *mutex, const int yield);
  597.  
  598. /* Call all cleanup handlers registered for the current thread */
  599. extern void __pthread_cleanup_callhandlers (void);
  600.  
  601. /* Call all destructors for remaining thread specific key values */
  602. extern void __pthread_key_calldestructors (void);
  603.  
  604. /* Called by fork() just before the fork is about to happen */
  605. extern void __pthread_atfork_callprepare (void);
  606. /* Called by fork() once the fork has happened */
  607. extern void __pthread_atfork_callparentchild (const int parent);
  608.  
  609. /* Allocate and initialise a stack chunk for a new thread */
  610. extern struct __stack_chunk *__pthread_new_stack (void);
  611.  
  612. /* Main scheduling code */
  613. extern void __pthread_context_switch (void);
  614.  
  615. /* Assembly functions */
  616.  
  617. /* Prevent the callevery interrupt from initialising a context switch.
  618.    Don't use this over a Wimp_Poll - instead use __pthread_stop_ticker */
  619. extern int __pthread_disable_ints (void);
  620. /* Allow the callevery interrupt from initialising a context switch */
  621. extern int __pthread_enable_ints (void);
  622. /* Initialise a context save area */
  623. extern void __pthread_init_save_area (struct __pthread_saved_context *);
  624. /* Calls alloca cleanup functions on thread exit */
  625. extern void __pthread_exit (void);
  626.  
  627.  
  628. /* Prevent the callevery interrupt from initialising a context switch,
  629.    and register a function to reenable them when the current function returns */
  630. extern void __pthread_protect_unsafe (void);
  631.  
  632. #if __UNIXLIB_FEATURE_PTHREADS
  633.  
  634. /* Should be placed at the beginning of a function body for a
  635.    thread safe function that is defined as a cancellation point */
  636. #define PTHREAD_SAFE_CANCELLATION if (__pthread_system_running) pthread_testcancel ();
  637.  
  638. /* Should be placed at the beginning of a function body for a
  639.    function that is not reentrant */
  640. #define PTHREAD_UNSAFE if (__pthread_system_running) __pthread_protect_unsafe ();
  641.  
  642. /* Should be placed at the beginning of a function body for a
  643.    function that is not reentrant and is also defined as a cancellation point */
  644. #define PTHREAD_UNSAFE_CANCELLATION \
  645. if (__pthread_system_running) \
  646.   { \
  647.     pthread_testcancel (); \
  648.     __pthread_protect_unsafe (); \
  649.   }
  650.  
  651. #else
  652.  
  653. #define PTHREAD_SAFE_CANCELLATION
  654. #define PTHREAD_UNSAFE
  655. #define PTHREAD_UNSAFE_CANCELLATION
  656.  
  657. #endif /* __UNIXLIB_FEATURE_PTHREADS */
  658.  
  659. /* zero if the context switcher is allowed to switch threads */
  660. extern int __pthread_worksemaphore;
  661.  
  662. #endif /* __UNIXLIB_INTERNALS */
  663.  
  664. #endif /* __PTHREAD_H */
  665.  
  666. __END_DECLS
  667.  
  668. #endif /* ! __PTHREAD_H */
  669.  
  670.