diff options
author | Roland McGrath <roland@gnu.org> | 2002-05-27 02:50:10 +0000 |
---|---|---|
committer | Roland McGrath <roland@gnu.org> | 2002-05-27 02:50:10 +0000 |
commit | 2d3e2366b453da9b4288c30f3f894fccef1e7914 (patch) | |
tree | 2ada3140e12e0ba146954f447b0be0eb51f83fa0 /libthreads/cthreads.h | |
parent | 9403905d538fbb6fd33fa8439978a868aef56d9e (diff) |
2002-05-26 Roland McGrath <roland@frob.com>
Changes merged from CMU MK83a version:
* cthreads.h, options.h: Various cleanups.
* call.c, cthread_data.c, sync.c, mig_support.c: Likewise.
* i386/cthreads.h, i386/thread.c, i386/lock.s: Likewise.
* cthread_internals.h: Add decls for internal functions.
(struct cproc): Use vm_offset_t for stack_base and stack_size members.
Use natural_t for context member.
* cprocs.c: Use prototypes for all defns.
* cthreads.c: Likewise.
(cthread_exit): Cast any_t to integer_t before int.
Diffstat (limited to 'libthreads/cthreads.h')
-rw-r--r-- | libthreads/cthreads.h | 417 |
1 files changed, 220 insertions, 197 deletions
diff --git a/libthreads/cthreads.h b/libthreads/cthreads.h index c1dfd44c..26abfd6a 100644 --- a/libthreads/cthreads.h +++ b/libthreads/cthreads.h @@ -1,6 +1,6 @@ /* * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * Copyright (c) 1993,1992,1991,1990,1989 Carnegie Mellon University * All Rights Reserved. * * Permission to use, copy, modify and distribute this software and its @@ -25,67 +25,58 @@ */ /* * HISTORY - * $Log: cthreads.h,v $ - * Revision 1.16 2001/03/31 23:01:01 roland - * 2001-03-31 Roland McGrath <roland@frob.com> - * - * * cthreads.h: Fix obsolescent #endif syntax. - * * cthread_internals.h: Likewise. - * * cancel-cond.c: Likewise. - * * stack.c: Likewise. - * * cthreads.c: Likewise. - * * cprocs.c: Likewise. - * * call.c: Likewise. - * - * Revision 1.15 1999/06/13 18:54:42 roland - * 1999-06-13 Roland McGrath <roland@baalperazim.frob.com> - * - * * cthreads.h (MACRO_BEGIN, MACRO_END): #undef before unconditionally - * redefining. Use GCC extension for statement expression with value 0. - * - * Revision 1.14 1999/05/30 01:39:48 roland - * 1999-05-29 Roland McGrath <roland@baalperazim.frob.com> - * - * * cthreads.h (mutex_clear): Change again, to call mutex_init. - * - * Revision 1.13 1999/05/29 18:59:10 roland - * 1999-05-29 Roland McGrath <roland@baalperazim.frob.com> - * - * * cthreads.h (mutex_clear): Change from syntax error to no-op (with - * warning avoidance). - * - * Revision 1.12 1996/05/04 10:06:31 roland - * [lint] (NEVER): Spurious global variable removed. - * [!lint] (NEVER): Useless macro removed. - * - * Revision 1.11 1996/01/24 18:37:59 roland - * Use prototypes for functions of zero args. - * - * Revision 1.10 1995/09/13 19:50:07 mib - * (CONDITION_INITIALIZER): Provide initial zero for IMPLICATIONS member. - * (condition_init): Bother initializing NAME and IMPLICATIONS members. - * - * Revision 1.9 1995/08/30 15:51:41 mib - * (condition_implies, condition_unimplies): New functions. - * (struct condition): New member `implications'. - * (cond_imp): New structure. - * (cond_signal): Return int now. - * (condition_broadcast): Always call cond_broadcast if this condition - * has implications. - * (condition_signal): Always call cond_signal if this condition has - * implications. - * - * Revision 1.8 1995/08/30 15:10:23 mib - * (hurd_condition_wait): Provide declaration. - * - * Revision 1.7 1995/07/18 17:15:51 mib - * Reverse previous change. - * - * Revision 1.5 1995/04/04 21:06:16 roland - * (mutex_lock, mutex_unlock): Use __ names for *_solid. - * - * Revision 1.4 1994/05/05 10:52:06 roland - * entered into RCS + * 20-Oct-93 Tero Kivinen (kivinen) at Helsinki University of Technology + * Renamed cthread_t->catch to to cthread_t->catch_exit, because + * catch is reserved word in c++. + * + * 12-Oct-93 Johannes Helander (jvh) at Helsinki University of Technology + * Added CONDITION_NAMED_INITIALIZER and MUTEX_NAMED_INITIALIZER1 + * macros. They take one argument: a name string. + * + * $Log: cthreads.h,v $ + * Revision 2.17 93/05/10 19:43:11 rvb + * Removed include of stdlib.h and just define malloc + * [93/04/27 mrt] + * + * Revision 2.16 93/05/10 17:51:26 rvb + * Just imagine how much more useful TWO special/fast lookup + * variables could be. (Actually, I am planning on using this + * for bsdss -- for multiple threads per task. If I don't, I'll + * remove the feature.) + * [93/05/10 rvb] + * Big mistake here! CTHREAD_DATA must always be set TRUE. + * cthreads.h is included by import_mach.h by lots of files + * that are not compiled with -DCTHREAD_DATA. This means + * they see a different structure for cthread_t than the + * cthread library -- which is compiled with CTHREAD_DATA. + * Also, make cthread_set_data and cthread_data macros. + * [93/05/06 rvb] + * Flush stdlib + * [93/05/05 rvb] + * + * Revision 2.15 93/01/27 09:03:32 danner + * Updated include of mach/mach.h to mach.h + * + * + * Revision 2.14 93/01/24 13:24:50 danner + * Get MACRO_BEGIN, MACRO_END, NEVER, ... from sys/macro_help.h + * why define it here. + * [92/10/20 rvb] + * + * Revision 2.13 93/01/14 18:05:04 danner + * Added MACRO_BEGIN and MACRO_END to definition of spin_lock. + * Fixed return value of cthread_set_data. + * Added prototypes for other miscellaneous functions. + * [92/12/18 pds] + * Converted file to ANSI C. + * Added declarations of cthread_fork_{prepare,parent,child}. + * Added include of <sys/macro_help.h>. + * [92/12/13 pds] + * + * Replaced calloc declaration with an include of stdlib.h. + * [92/06/15 pds] + * 64bit cleanup. + * [92/12/02 af] * * Revision 2.12 92/05/22 18:38:36 jfriedl * From Mike Kupfer <kupfer@sprite.Berkeley.EDU>: @@ -225,62 +216,46 @@ #ifndef _CTHREADS_ #define _CTHREADS_ 1 -/* MIB XXX */ -#define CTHREAD_DATA +#define WAIT_DEBUG /* XXX should be defined somewhere else */ #if 0 /* This is CMU's machine-dependent file. In GNU all of the machine dependencies are dealt with in libc. */ #include <machine/cthreads.h> +#include <mach.h> +#include <sys/macro_help.h> +#include <mach/machine/vm_param.h> + +#ifdef __STDC__ +extern void *malloc(); #else -#include <machine-sp.h> -#define cthread_sp() ((vm_address_t) __thread_stack_pointer ()) +extern char *malloc(); #endif -#if c_plusplus || __STDC__ - -#ifndef C_ARG_DECLS -#define C_ARG_DECLS(arglist) arglist -#endif /* not C_ARG_DECLS */ - -typedef void *any_t; - -#else /* not (c_plusplus || __STDC__) */ - -#ifndef C_ARG_DECLS -#define C_ARG_DECLS(arglist) () -#endif /* not C_ARG_DECLS */ - -typedef char *any_t; +#else /* GNU */ +# include <stdlib.h> +# include <mach.h> +# include <mach/machine/vm_param.h> +# include <machine-sp.h> +# define cthread_sp() ((vm_address_t) __thread_stack_pointer ()) +# define MACRO_BEGIN __extension__ ({ +# define MACRO_END 0; }) +#endif -#endif /* not (c_plusplus || __STDC__) */ +typedef void *any_t; /* XXX - obsolete, should be deleted. */ -#include <mach/mach.h> -#include <mach/machine/vm_param.h> - -#ifndef TRUE +#if defined(TRUE) +#else /* not defined(TRUE) */ #define TRUE 1 #define FALSE 0 -#endif /* TRUE */ - - -#undef MACRO_BEGIN -#undef MACRO_END -#define MACRO_BEGIN __extension__ ({ -#define MACRO_END 0; }) - +#endif /* * C Threads package initialization. */ -extern int cthread_init C_ARG_DECLS((void)); -#if 0 -/* This prototype is broken for GNU. */ -extern any_t calloc C_ARG_DECLS((unsigned n, unsigned size)); -#else -#include <stdlib.h> -#endif +extern vm_offset_t cthread_init(void); + /* * Queues. @@ -300,7 +275,7 @@ typedef struct cthread_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_free(q) free((q)) #define cthread_queue_enq(q, x) \ MACRO_BEGIN \ @@ -332,7 +307,7 @@ typedef struct cthread_queue_item { #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) { \ + for (x = (cthread_queue_item_t) ((q)->head); x != 0; x = next){\ next = x->next; \ (*(f))((t) x); \ } \ @@ -349,20 +324,24 @@ typedef struct cthread_queue_item { /* * Spin locks. */ -extern void -spin_lock_solid C_ARG_DECLS((spin_lock_t *p)); +extern void spin_lock_solid(spin_lock_t *_lock); -#ifndef spin_unlock -extern void -spin_unlock C_ARG_DECLS((spin_lock_t *p)); +#if defined(spin_unlock) +#else /* not defined(spin_unlock) */ +extern void spin_unlock(spin_lock_t *_lock); #endif -#ifndef spin_try_lock -extern int -spin_try_lock C_ARG_DECLS((spin_lock_t *p)); +#if defined(spin_try_lock) +#else /* not defined(spin_try_lock) */ +extern boolean_t spin_try_lock(spin_lock_t *_lock); #endif -#define spin_lock(p) ({if (!spin_try_lock(p)) spin_lock_solid(p);}) +#define spin_lock(p) \ + MACRO_BEGIN \ + if (!spin_try_lock(p)) { \ + spin_lock_solid(p); \ + } \ + MACRO_END #endif /* End unused CMU code. */ @@ -376,12 +355,15 @@ typedef struct mutex { see if it gets the mutex. */ spin_lock_t held; spin_lock_t lock; - char *name; + const char *name; struct cthread_queue queue; + /* holder is for WAIT_DEBUG. Not ifdeffed to keep size constant. */ + struct cthread *holder; } *mutex_t; /* Rearranged accordingly for GNU: */ -#define MUTEX_INITIALIZER { SPIN_LOCK_INITIALIZER, SPIN_LOCK_INITIALIZER, 0, QUEUE_INITIALIZER } +#define MUTEX_INITIALIZER { SPIN_LOCK_INITIALIZER, SPIN_LOCK_INITIALIZER, 0, QUEUE_INITIALIZER, } +#define MUTEX_NAMED_INITIALIZER(Name) { SPIN_LOCK_INITIALIZER, SPIN_LOCK_INITIALIZER, Name, QUEUE_INITIALIZER, } #define mutex_alloc() ((mutex_t) calloc(1, sizeof(struct mutex))) #define mutex_init(m) \ @@ -389,37 +371,52 @@ typedef struct mutex { spin_lock_init(&(m)->lock); \ cthread_queue_init(&(m)->queue); \ spin_lock_init(&(m)->held); \ + (m)->holder = 0; \ MACRO_END #define mutex_set_name(m, x) ((m)->name = (x)) #define mutex_name(m) ((m)->name != 0 ? (m)->name : "?") -#define mutex_clear(m) mutex_init(m) -#define mutex_free(m) free((any_t) (m)) - -extern void __mutex_lock_solid (void *mutex); /* blocking -- roland@gnu */ -extern void __mutex_unlock_solid (void *mutex); /* roland@gnu */ +#define mutex_clear(m) /* nop */??? +#define mutex_free(m) free((m)) #define mutex_try_lock(m) spin_try_lock(&(m)->held) +#if defined(WAIT_DEBUG) #define mutex_lock(m) \ MACRO_BEGIN \ if (!spin_try_lock(&(m)->held)) { \ __mutex_lock_solid(m); \ } \ + (m)->holder = cthread_self(); \ MACRO_END #define mutex_unlock(m) \ MACRO_BEGIN \ if (spin_unlock(&(m)->held), \ - cthread_queue_head(&(m)->queue, void *) != 0) { \ + cthread_queue_head(&(m)->queue, vm_offset_t) != 0) { \ __mutex_unlock_solid(m); \ } \ + (m)->holder = 0; \ MACRO_END - +#else /* defined(WAIT_DEBUG */ +#define mutex_lock(m) \ + MACRO_BEGIN \ + if (!spin_try_lock(&(m)->held)) { \ + __mutex_lock_solid(m); \ + } \ + MACRO_END +#define mutex_unlock(m) \ + MACRO_BEGIN \ + if (spin_unlock(&(m)->held), \ + cthread_queue_head(&(m)->queue, vm_offset_t) != 0) { \ + __mutex_unlock_solid(m); \ + } \ + MACRO_END +#endif /* defined(WAIT_DEBUG) */ /* * Condition variables. */ typedef struct condition { spin_lock_t lock; struct cthread_queue queue; - char *name; + const char *name; struct cond_imp *implications; } *condition_t; @@ -430,8 +427,10 @@ struct cond_imp }; #define CONDITION_INITIALIZER { SPIN_LOCK_INITIALIZER, QUEUE_INITIALIZER, 0, 0 } +#define CONDITION_NAMED_INITIALIZER(Name) { SPIN_LOCK_INITIALIZER, QUEUE_INITIALIZER, Name, 0 } -#define condition_alloc() ((condition_t) calloc(1, sizeof(struct condition))) +#define condition_alloc() \ + ((condition_t) calloc(1, sizeof(struct condition))) #define condition_init(c) \ MACRO_BEGIN \ spin_lock_init(&(c)->lock); \ @@ -449,7 +448,7 @@ struct cond_imp #define condition_free(c) \ MACRO_BEGIN \ condition_clear(c); \ - free((any_t) (c)); \ + free((c)); \ MACRO_END #define condition_signal(c) \ @@ -466,29 +465,17 @@ struct cond_imp } \ MACRO_END -extern int -cond_signal C_ARG_DECLS((condition_t c)); - -extern void -cond_broadcast C_ARG_DECLS((condition_t c)); - -extern void -condition_wait C_ARG_DECLS((condition_t c, mutex_t m)); +extern int cond_signal(condition_t _cond); -extern int -hurd_condition_wait C_ARG_DECLS((condition_t c, mutex_t m)); +extern void cond_broadcast(condition_t _cond); -extern void -condition_implies C_ARG_DECLS((condition_t implicator, condition_t implicatand)); - -extern void -condition_unimplies C_ARG_DECLS((condition_t implicator, condition_t implicatand)); +extern void condition_wait(condition_t _cond, mutex_t _mutex); /* * Threads. */ -typedef any_t (*cthread_fn_t) C_ARG_DECLS((any_t arg)); +typedef void * (*cthread_fn_t)(void *arg); #include <setjmp.h> @@ -497,34 +484,28 @@ typedef struct cthread { struct mutex lock; struct condition done; int state; - jmp_buf catch; + jmp_buf catch_exit; cthread_fn_t func; - any_t arg; - any_t result; - char *name; -#ifdef CTHREAD_DATA - any_t data; -#endif /* CTHREAD_DATA */ - any_t private_data; + void *arg; + void *result; + const char *name; + void *data; + void *ldata; + void *private_data; struct ur_cthread *ur; } *cthread_t; #define NO_CTHREAD ((cthread_t) 0) -extern cthread_t -cthread_fork C_ARG_DECLS((cthread_fn_t func, any_t arg)); +extern cthread_t cthread_fork(cthread_fn_t _func, void *_arg); -extern void -cthread_detach C_ARG_DECLS((cthread_t t)); +extern void cthread_detach(cthread_t _thread); -extern any_t -cthread_join C_ARG_DECLS((cthread_t t)); +extern any_t cthread_join(cthread_t _thread); -extern void -cthread_yield C_ARG_DECLS((void)); +extern void cthread_yield(void); -extern void -cthread_exit C_ARG_DECLS((any_t result)); +extern void cthread_exit(void *_result); /* * This structure must agree with struct cproc in cthread_internals.h @@ -535,20 +516,20 @@ typedef struct ur_cthread { } *ur_cthread_t; #ifndef cthread_sp -extern int -cthread_sp C_ARG_DECLS((void)); +extern vm_offset_t +cthread_sp(void); #endif -extern int cthread_stack_mask; +extern vm_offset_t cthread_stack_mask; -#ifdef STACK_GROWTH_UP +#if defined(STACK_GROWTH_UP) #define ur_cthread_ptr(sp) \ (* (ur_cthread_t *) ((sp) & cthread_stack_mask)) -#else /* STACK_GROWTH_UP */ +#else /* not defined(STACK_GROWTH_UP) */ #define ur_cthread_ptr(sp) \ (* (ur_cthread_t *) ( ((sp) | cthread_stack_mask) + 1 \ - sizeof(ur_cthread_t *)) ) -#endif /* STACK_GROWTH_UP */ +#endif /* defined(STACK_GROWTH_UP) */ #define ur_cthread_self() (ur_cthread_ptr(cthread_sp())) @@ -556,37 +537,80 @@ extern int cthread_stack_mask; ((t) ? ((t)->ur = (ur_cthread_t)(id)) : 0)) #define cthread_self() (ur_cthread_self()->incarnation) -extern void -cthread_set_name C_ARG_DECLS((cthread_t t, char *name)); +extern void cthread_set_name(cthread_t _thread, const char *_name); + +extern const char * cthread_name(cthread_t _thread); + +extern int cthread_count(void); + +extern void cthread_set_limit(int _limit); -extern char * -cthread_name C_ARG_DECLS((cthread_t t)); +extern int cthread_limit(void); -extern int -cthread_count C_ARG_DECLS((void)); +extern void cthread_set_kernel_limit(int _n); -extern void -cthread_set_limit C_ARG_DECLS((int n)); +extern int cthread_kernel_limit(void); -extern int -cthread_limit C_ARG_DECLS((void)); +extern void cthread_wire(void); -extern void -cthread_wire C_ARG_DECLS((void)); +extern void cthread_unwire(void); -#ifdef CTHREAD_DATA +extern void cthread_msg_busy(mach_port_t _port, int _min, int _max); + +extern void cthread_msg_active(mach_port_t _prt, int _min, int _max); + +extern mach_msg_return_t cthread_mach_msg(mach_msg_header_t *_header, + mach_msg_option_t _option, + mach_msg_size_t _send_size, + mach_msg_size_t _rcv_size, + mach_port_t _rcv_name, + mach_msg_timeout_t _timeout, + mach_port_t _notify, + int _min, int _max); + +extern void cthread_fork_prepare(void); + +extern void cthread_fork_parent(void); + +extern void cthread_fork_child(void); + +#if defined(THREAD_CALLS) +/* + * Routines to replace thread_*. + */ +extern kern_return_t cthread_get_state(cthread_t _thread); + +extern kern_return_t cthread_set_state(cthread_t _thread); + +extern kern_return_t cthread_abort(cthread_t _thread); + +extern kern_return_t cthread_resume(cthread_t _thread); + +extern kern_return_t cthread_suspend(cthread_t _thread); + +extern kern_return_t cthread_call_on(cthread_t _thread); +#endif /* defined(THREAD_CALLS) */ + +#if defined(CTHREAD_DATA_XX) /* * Set or get thread specific "global" variable * * The thread given must be the calling thread (ie. thread_self). * XXX This is for compatibility with the old cthread_data. XXX */ -extern int -cthread_set_data C_ARG_DECLS((cthread_t t, any_t x)); +extern int cthread_set_data(cthread_t _thread, void *_val); + +extern void * cthread_data(cthread_t _thread); +#else /* defined(CTHREAD_DATA_XX) */ + +#define cthread_set_data(_thread, _val) ((_thread)->data) = (void *)(_val); +#define cthread_data(_thread) ((_thread)->data) + +#define cthread_set_ldata(_thread, _val) ((_thread)->ldata) = (void *)(_val); +#define cthread_ldata(_thread) ((_thread)->ldata) + +#endif /* defined(CTHREAD_DATA_XX) */ -extern any_t -cthread_data C_ARG_DECLS((cthread_t t)); -#endif /* CTHREAD_DATA */ /* * Support for POSIX thread specific data @@ -594,7 +618,7 @@ cthread_data C_ARG_DECLS((cthread_t t)); * Multiplexes a thread specific "global" variable * into many thread specific "global" variables. */ -#define CTHREAD_DATA_VALUE_NULL (any_t)0 +#define CTHREAD_DATA_VALUE_NULL (void *)0 #define CTHREAD_KEY_INVALID (cthread_key_t)-1 typedef int cthread_key_t; @@ -604,27 +628,25 @@ typedef int cthread_key_t; * Different threads may use same key, but the values bound to the key are * maintained on a thread specific basis. */ -extern int -cthread_keycreate C_ARG_DECLS((cthread_key_t *key)); +extern int cthread_keycreate(cthread_key_t *_key); /* * Get value currently bound to key for calling thread */ -extern int -cthread_getspecific C_ARG_DECLS((cthread_key_t key, any_t *value)); +extern int cthread_getspecific(cthread_key_t _key, void **_value); /* * Bind value to given key for calling thread */ -extern int -cthread_setspecific C_ARG_DECLS((cthread_key_t key, any_t value)); +extern int cthread_setspecific(cthread_key_t _key, void *_value); /* * Debugging support. */ -#ifdef DEBUG +#if defined(DEBUG) -#ifndef ASSERT +#if defined(ASSERT) +#else /* not defined(ASSERT) */ /* * Assertion macro, similar to <assert.h> */ @@ -639,18 +661,19 @@ cthread_setspecific C_ARG_DECLS((cthread_key_t key, any_t value)); } \ MACRO_END -#endif /* ASSERT */ +#endif /* defined(ASSERT) */ #define SHOULDNT_HAPPEN 0 extern int cthread_debug; -#else /* DEBUG */ +#else /* not defined(DEBUG) */ -#ifndef ASSERT +#if defined(ASSERT) +#else /* not defined(ASSERT) */ #define ASSERT(p) -#endif /* ASSERT */ +#endif /* defined(ASSERT) */ -#endif /* DEBUG */ +#endif /* defined(DEBUG) */ -#endif /* _CTHREADS_ */ +#endif /* not defined(_CTHREADS_) */ |