home *** CD-ROM | disk | FTP | other *** search
/ NeXTSTEP 3.2 (Developer) / NS_dev_3.2.iso / NextDeveloper / Headers / mach / cthreads.h < prev    next >
Text File  |  1992-12-07  |  6KB  |  266 lines

  1. /*
  2.  * Cthreads.
  3.  */
  4.  
  5. #ifndef    _CTHREADS_
  6. #define    _CTHREADS_ 1
  7.  
  8. typedef void *any_t;
  9.  
  10. #import <mach/mach.h>
  11.  
  12. #ifndef    TRUE
  13. #define    TRUE    1
  14. #define    FALSE    0
  15. #endif    TRUE
  16.  
  17. #ifndef MACRO_BEGIN
  18.  
  19. #define    NEVER FALSE
  20.  
  21. #define    MACRO_BEGIN    do {
  22. #define    MACRO_END    } while (NEVER)
  23.  
  24. #endif    MACRO_BEGIN
  25.  
  26. /*
  27.  * C Threads package initialization.
  28.  */
  29. extern void cthread_init();
  30.  
  31. #ifdef __STRICT_BSD__
  32. extern void *calloc(unsigned, unsigned);
  33. #else
  34. #import <stdlib.h>
  35. #endif
  36.  
  37. /*
  38.  * Queues.
  39.  */
  40. typedef struct cthread_queue {
  41.     struct cthread_queue_item *head;
  42.     struct cthread_queue_item *tail;
  43. } *cthread_queue_t;
  44.  
  45. typedef struct cthread_queue_item {
  46.     struct cthread_queue_item *next;
  47. } *cthread_queue_item_t;
  48.  
  49. #define    NO_QUEUE_ITEM    ((cthread_queue_item_t) 0)
  50.  
  51. #define    QUEUE_INITIALIZER    { NO_QUEUE_ITEM, NO_QUEUE_ITEM }
  52.  
  53. #define    cthread_queue_alloc()    ((cthread_queue_t) calloc(1, sizeof(struct cthread_queue)))
  54. #define    cthread_queue_init(q)    ((q)->head = (q)->tail = 0)
  55. #define    cthread_queue_free(q)    free((any_t) (q))
  56.  
  57. #define    cthread_queue_enq(q, x) \
  58.     MACRO_BEGIN \
  59.         (x)->next = 0; \
  60.         if ((q)->tail == 0) \
  61.             (q)->head = (cthread_queue_item_t) (x); \
  62.         else \
  63.             (q)->tail->next = (cthread_queue_item_t) (x); \
  64.         (q)->tail = (cthread_queue_item_t) (x); \
  65.     MACRO_END
  66.  
  67. #define    cthread_queue_preq(q, x) \
  68.     MACRO_BEGIN \
  69.         if ((q)->tail == 0) \
  70.             (q)->tail = (cthread_queue_item_t) (x); \
  71.         ((cthread_queue_item_t) (x))->next = (q)->head; \
  72.         (q)->head = (cthread_queue_item_t) (x); \
  73.     MACRO_END
  74.  
  75. #define    cthread_queue_head(q, t)    ((t) ((q)->head))
  76.  
  77. #define    cthread_queue_deq(q, t, x) \
  78.     MACRO_BEGIN \
  79.         if (((x) = (t) ((q)->head)) != 0 && \
  80.             ((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \
  81.             (q)->tail = 0; \
  82.     MACRO_END
  83.  
  84. #define    cthread_queue_map(q, t, f) \
  85.     MACRO_BEGIN \
  86.         register cthread_queue_item_t x, next; \
  87.         for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \
  88.             next = x->next; \
  89.             (*(f))((t) x); \
  90.         } \
  91.     MACRO_END
  92.  
  93. /*
  94.  * Spin locks.
  95.  */
  96. extern void spin_lock(int *p);
  97. extern void spin_unlock(int *p);
  98.  
  99. /*
  100.  * Mutex objects.
  101.  */
  102. typedef struct mutex {
  103.     int lock;
  104.     char *name;
  105. } *mutex_t;
  106.  
  107. #define    MUTEX_INITIALIZER    { 0, 0 }
  108.  
  109. #define    mutex_alloc()        ((mutex_t) calloc(1, sizeof(struct mutex)))
  110. #define    mutex_init(m)        ((m)->lock = 0)
  111. #define    mutex_set_name(m, x)    ((m)->name = (x))
  112. #define    mutex_name(m)        ((m)->name != 0 ? (m)->name : "?")
  113. #define    mutex_clear(m)        /* nop */
  114. #define    mutex_free(m)        free((any_t) (m))
  115.  
  116. #define    mutex_lock(m) \
  117.     MACRO_BEGIN \
  118.         if (! mutex_try_lock(m)) mutex_wait_lock(m); \
  119.     MACRO_END
  120.  
  121. extern int mutex_try_lock(mutex_t m);    /* nonblocking */
  122. extern void mutex_wait_lock(mutex_t m);    /* blocking */
  123. extern void mutex_unlock(mutex_t m);
  124.  
  125. /*
  126.  * Condition variables.
  127.  */
  128. typedef struct condition {
  129.     int lock;
  130.     struct cthread_queue queue;
  131.     char *name;
  132. } *condition_t;
  133.  
  134. #define    CONDITION_INITIALIZER        { 0, QUEUE_INITIALIZER, 0 }
  135.  
  136. #define    condition_alloc()        ((condition_t) calloc(1, sizeof(struct condition)))
  137. #define    condition_init(c)        MACRO_BEGIN (c)->lock = 0; cthread_queue_init(&(c)->queue); MACRO_END
  138. #define    condition_set_name(c, x)    ((c)->name = (x))
  139. #define    condition_name(c)        ((c)->name != 0 ? (c)->name : "?")
  140. #define    condition_clear(c)        MACRO_BEGIN condition_broadcast(c); spin_lock(&(c)->lock); MACRO_END
  141. #define    condition_free(c)        MACRO_BEGIN condition_clear(c); free((any_t) (c)); MACRO_END
  142.  
  143. #define    condition_signal(c) \
  144.     MACRO_BEGIN \
  145.         if ((c)->queue.head) cond_signal(c); \
  146.     MACRO_END
  147.  
  148. #define    condition_broadcast(c) \
  149.     MACRO_BEGIN \
  150.         if ((c)->queue.head) cond_broadcast(c); \
  151.     MACRO_END
  152.  
  153. extern void cond_signal(condition_t c);
  154. extern void cond_broadcast(condition_t c);
  155. extern void condition_wait(condition_t c, mutex_t m);
  156.  
  157. /*
  158.  * Threads.
  159.  */
  160.  
  161. typedef any_t (*cthread_fn_t)(any_t arg);
  162.  
  163. #import <setjmp.h>
  164.  
  165. typedef struct cthread {
  166.     struct cthread *next;
  167. #if    NeXT
  168.     thread_t real_thread;
  169. #endif    NeXT
  170.     struct mutex lock;
  171.     struct condition done;
  172.     int state;
  173.     jmp_buf catch;
  174.     cthread_fn_t func;
  175.     any_t arg;
  176.     any_t result;
  177.     const char *name;
  178.     any_t data;
  179. } *cthread_t;
  180.  
  181. #define    NO_CTHREAD    ((cthread_t) 0)
  182.  
  183. extern cthread_t cthread_fork(cthread_fn_t func, any_t arg);
  184. extern void cthread_detach(cthread_t t);
  185. extern any_t cthread_join(cthread_t t);
  186. extern void cthread_yield(void);
  187. extern void cthread_exit(any_t result);
  188. extern kern_return_t cthread_priority(
  189.     cthread_t    t,
  190.     int        priority,
  191.     boolean_t    set_max);
  192. extern kern_return_t cthread_max_priority(
  193.     cthread_t    t,
  194.     processor_set_t    pset,
  195.     int        max_priority);
  196. extern kern_return_t cthread_abort(cthread_t t);
  197.  
  198. /*
  199.  * This structure must agree with struct cproc in cthread_internals.h
  200.  */
  201. typedef struct ur_cthread {
  202.     struct ur_cthread *next;
  203.     cthread_t incarnation;
  204. } *ur_cthread_t;
  205.  
  206. extern int cthread_sp(void);
  207.  
  208. extern int cthread_stack_mask;
  209.  
  210. extern ur_cthread_t ur_cthread_self(void);
  211. #define cthread_thread(c)    (c->real_thread)
  212. extern void cthread_set_errno_self(int e);
  213. extern int cthread_errno(void);
  214. #define    cthread_assoc(id, t)    (((ur_cthread_t) (id))->incarnation = (t))
  215. #define    cthread_self()        (ur_cthread_self()->incarnation)
  216.  
  217. extern void cthread_set_name(cthread_t t, const char *name);
  218. extern const char *cthread_name(cthread_t t);
  219. extern int cthread_count(void);
  220. extern void cthread_set_limit(int n);
  221. extern int cthread_limit(void);
  222.  
  223. #define    cthread_set_data(t, x)    ((t)->data = (x))
  224. #define    cthread_data(t)        ((t)->data)
  225.  
  226. /*
  227.  * Machine-dependent definitions.
  228.  */
  229. #import <mach/machine/cthreads.h>
  230.  
  231. /*
  232.  * Debugging support.
  233.  */
  234. #ifdef    CTHREADS_DEBUG
  235.  
  236. #ifndef    ASSERT
  237. /*
  238.  * Assertion macro, similar to <assert.h>
  239.  */
  240. #import <stdio.h>
  241. #define    ASSERT(p) \
  242.     MACRO_BEGIN \
  243.         if (!(p)) { \
  244.             fprintf(stderr, \
  245.                 "File %s, line %d: assertion p failed.\n", \
  246.                 __FILE__, __LINE__); \
  247.             abort(); \
  248.         } \
  249.     MACRO_END
  250.  
  251. #endif    ASSERT
  252.  
  253. #define    SHOULDNT_HAPPEN    0
  254.  
  255. extern int cthread_debug;
  256.  
  257. #else    CTHREADS_DEBUG
  258.  
  259. #ifndef    ASSERT
  260. #define    ASSERT(p)
  261. #endif    ASSERT
  262.  
  263. #endif    CTHREADS_DEBUG
  264.  
  265. #endif    _CTHREADS_
  266.