home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
NeXTSTEP 3.2 (Developer)
/
NS_dev_3.2.iso
/
NextDeveloper
/
Headers
/
mach
/
cthreads.h
< prev
next >
Wrap
Text File
|
1992-12-07
|
6KB
|
266 lines
/*
* Cthreads.
*/
#ifndef _CTHREADS_
#define _CTHREADS_ 1
typedef void *any_t;
#import <mach/mach.h>
#ifndef TRUE
#define TRUE 1
#define FALSE 0
#endif TRUE
#ifndef MACRO_BEGIN
#define NEVER FALSE
#define MACRO_BEGIN do {
#define MACRO_END } while (NEVER)
#endif MACRO_BEGIN
/*
* C Threads package initialization.
*/
extern void cthread_init();
#ifdef __STRICT_BSD__
extern void *calloc(unsigned, unsigned);
#else
#import <stdlib.h>
#endif
/*
* Queues.
*/
typedef struct cthread_queue {
struct cthread_queue_item *head;
struct cthread_queue_item *tail;
} *cthread_queue_t;
typedef struct cthread_queue_item {
struct cthread_queue_item *next;
} *cthread_queue_item_t;
#define NO_QUEUE_ITEM ((cthread_queue_item_t) 0)
#define QUEUE_INITIALIZER { NO_QUEUE_ITEM, NO_QUEUE_ITEM }
#define cthread_queue_alloc() ((cthread_queue_t) calloc(1, sizeof(struct cthread_queue)))
#define cthread_queue_init(q) ((q)->head = (q)->tail = 0)
#define cthread_queue_free(q) free((any_t) (q))
#define cthread_queue_enq(q, x) \
MACRO_BEGIN \
(x)->next = 0; \
if ((q)->tail == 0) \
(q)->head = (cthread_queue_item_t) (x); \
else \
(q)->tail->next = (cthread_queue_item_t) (x); \
(q)->tail = (cthread_queue_item_t) (x); \
MACRO_END
#define cthread_queue_preq(q, x) \
MACRO_BEGIN \
if ((q)->tail == 0) \
(q)->tail = (cthread_queue_item_t) (x); \
((cthread_queue_item_t) (x))->next = (q)->head; \
(q)->head = (cthread_queue_item_t) (x); \
MACRO_END
#define cthread_queue_head(q, t) ((t) ((q)->head))
#define cthread_queue_deq(q, t, x) \
MACRO_BEGIN \
if (((x) = (t) ((q)->head)) != 0 && \
((q)->head = (cthread_queue_item_t) ((x)->next)) == 0) \
(q)->tail = 0; \
MACRO_END
#define cthread_queue_map(q, t, f) \
MACRO_BEGIN \
register cthread_queue_item_t x, next; \
for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next) { \
next = x->next; \
(*(f))((t) x); \
} \
MACRO_END
/*
* Spin locks.
*/
extern void spin_lock(int *p);
extern void spin_unlock(int *p);
/*
* Mutex objects.
*/
typedef struct mutex {
int lock;
char *name;
} *mutex_t;
#define MUTEX_INITIALIZER { 0, 0 }
#define mutex_alloc() ((mutex_t) calloc(1, sizeof(struct mutex)))
#define mutex_init(m) ((m)->lock = 0)
#define mutex_set_name(m, x) ((m)->name = (x))
#define mutex_name(m) ((m)->name != 0 ? (m)->name : "?")
#define mutex_clear(m) /* nop */
#define mutex_free(m) free((any_t) (m))
#define mutex_lock(m) \
MACRO_BEGIN \
if (! mutex_try_lock(m)) mutex_wait_lock(m); \
MACRO_END
extern int mutex_try_lock(mutex_t m); /* nonblocking */
extern void mutex_wait_lock(mutex_t m); /* blocking */
extern void mutex_unlock(mutex_t m);
/*
* Condition variables.
*/
typedef struct condition {
int lock;
struct cthread_queue queue;
char *name;
} *condition_t;
#define CONDITION_INITIALIZER { 0, QUEUE_INITIALIZER, 0 }
#define condition_alloc() ((condition_t) calloc(1, sizeof(struct condition)))
#define condition_init(c) MACRO_BEGIN (c)->lock = 0; cthread_queue_init(&(c)->queue); MACRO_END
#define condition_set_name(c, x) ((c)->name = (x))
#define condition_name(c) ((c)->name != 0 ? (c)->name : "?")
#define condition_clear(c) MACRO_BEGIN condition_broadcast(c); spin_lock(&(c)->lock); MACRO_END
#define condition_free(c) MACRO_BEGIN condition_clear(c); free((any_t) (c)); MACRO_END
#define condition_signal(c) \
MACRO_BEGIN \
if ((c)->queue.head) cond_signal(c); \
MACRO_END
#define condition_broadcast(c) \
MACRO_BEGIN \
if ((c)->queue.head) cond_broadcast(c); \
MACRO_END
extern void cond_signal(condition_t c);
extern void cond_broadcast(condition_t c);
extern void condition_wait(condition_t c, mutex_t m);
/*
* Threads.
*/
typedef any_t (*cthread_fn_t)(any_t arg);
#import <setjmp.h>
typedef struct cthread {
struct cthread *next;
#if NeXT
thread_t real_thread;
#endif NeXT
struct mutex lock;
struct condition done;
int state;
jmp_buf catch;
cthread_fn_t func;
any_t arg;
any_t result;
const char *name;
any_t data;
} *cthread_t;
#define NO_CTHREAD ((cthread_t) 0)
extern cthread_t cthread_fork(cthread_fn_t func, any_t arg);
extern void cthread_detach(cthread_t t);
extern any_t cthread_join(cthread_t t);
extern void cthread_yield(void);
extern void cthread_exit(any_t result);
extern kern_return_t cthread_priority(
cthread_t t,
int priority,
boolean_t set_max);
extern kern_return_t cthread_max_priority(
cthread_t t,
processor_set_t pset,
int max_priority);
extern kern_return_t cthread_abort(cthread_t t);
/*
* This structure must agree with struct cproc in cthread_internals.h
*/
typedef struct ur_cthread {
struct ur_cthread *next;
cthread_t incarnation;
} *ur_cthread_t;
extern int cthread_sp(void);
extern int cthread_stack_mask;
extern ur_cthread_t ur_cthread_self(void);
#define cthread_thread(c) (c->real_thread)
extern void cthread_set_errno_self(int e);
extern int cthread_errno(void);
#define cthread_assoc(id, t) (((ur_cthread_t) (id))->incarnation = (t))
#define cthread_self() (ur_cthread_self()->incarnation)
extern void cthread_set_name(cthread_t t, const char *name);
extern const char *cthread_name(cthread_t t);
extern int cthread_count(void);
extern void cthread_set_limit(int n);
extern int cthread_limit(void);
#define cthread_set_data(t, x) ((t)->data = (x))
#define cthread_data(t) ((t)->data)
/*
* Machine-dependent definitions.
*/
#import <mach/machine/cthreads.h>
/*
* Debugging support.
*/
#ifdef CTHREADS_DEBUG
#ifndef ASSERT
/*
* Assertion macro, similar to <assert.h>
*/
#import <stdio.h>
#define ASSERT(p) \
MACRO_BEGIN \
if (!(p)) { \
fprintf(stderr, \
"File %s, line %d: assertion p failed.\n", \
__FILE__, __LINE__); \
abort(); \
} \
MACRO_END
#endif ASSERT
#define SHOULDNT_HAPPEN 0
extern int cthread_debug;
#else CTHREADS_DEBUG
#ifndef ASSERT
#define ASSERT(p)
#endif ASSERT
#endif CTHREADS_DEBUG
#endif _CTHREADS_