diff options
Diffstat (limited to 'libthreads/cthreads.c')
-rw-r--r-- | libthreads/cthreads.c | 196 |
1 files changed, 116 insertions, 80 deletions
diff --git a/libthreads/cthreads.c b/libthreads/cthreads.c index d45a02b4..aef20bed 100644 --- a/libthreads/cthreads.c +++ b/libthreads/cthreads.c @@ -1,78 +1,125 @@ -/* +/* * Mach Operating System - * Copyright (c) 1991,1990,1989 Carnegie Mellon University + * Copyright (c) 1992,1991,1990,1989 Carnegie Mellon University * All Rights Reserved. - * + * * Permission to use, copy, modify and distribute this software and its * documentation is hereby granted, provided that both the copyright * notice and this permission notice appear in all copies of the * software, derivative works or modified versions, and any portions * thereof, and that both notices appear in supporting documentation. - * + * * CARNEGIE MELLON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" * CONDITION. CARNEGIE MELLON DISCLAIMS ANY LIABILITY OF ANY KIND FOR * ANY DAMAGES WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE. - * + * * Carnegie Mellon requests users of this software to return to - * + * * Software Distribution Coordinator or Software.Distribution@CS.CMU.EDU * School of Computer Science * Carnegie Mellon University * Pittsburgh PA 15213-3890 - * + * * any improvements or extensions that they make and grant Carnegie Mellon * the rights to redistribute these changes. */ /* * HISTORY - * $Log: cthreads.c,v $ + * 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++. + * + * $Log: cthreads.c,v $ + * Revision 1.15 2002/07/31 02:35:14 marcus + * Add comment to last change, for the benefit of the next merge :) + * + * Revision 1.14 2002/07/31 02:20:44 marcus + * 2002-07-29 Marcus Brinkmann <marcus@gnu.org> + * + * * cthreads.c (cthread_init): Move cthread_alloc call before + * cproc_init call (lost in merge). + * + * Revision 1.13 2002/05/28 23:55:55 roland + * 2002-05-28 Roland McGrath <roland@frob.com> + * + * * cthreads.c (cthread_fork_prepare, cthread_fork_parent, + * cthread_fork_child): Don't call malloc_fork_* (lost in merge). + * + * Revision 1.12 2002/05/27 02:50:10 roland + * 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. + * + * Revision 2.13 93/01/21 12:27:55 danner + * Remove deadlock in cproc_fork_child; must release malloc lock first. + * [93/01/19 16:37:43 bershad] + * + * Revision 2.12 93/01/14 18:05:00 danner + * Converted file to ANSI C. + * Removed use of obsolete type any_t. + * [92/12/18 pds] + * 64bit cleanup. + * [92/12/01 af] + * + * Free private_data in cthread_exit, from Mike Kupfer. + * [92/11/30 af] + * * Revision 2.11 92/07/20 13:33:37 cmaeda * In cthread_init, do machine dependent initialization if it's defined. * [92/05/11 14:41:08 cmaeda] - * + * * Revision 2.10 91/08/28 11:19:26 jsb * Fixed mig_init initialization in cthread_fork_child. * [91/08/23 rpd] - * + * * Revision 2.9 91/07/31 18:34:23 dbg * Fix bad self-pointer reference. - * + * * Don't declare _setjmp and _longjmp; they are included by * cthreads.h. * [91/07/30 17:33:50 dbg] - * + * * Revision 2.8 91/05/14 17:56:31 mrt * Correcting copyright - * + * * Revision 2.7 91/02/14 14:19:47 mrt * Added new Mach copyright * [91/02/13 12:41:07 mrt] - * + * * Revision 2.6 90/11/05 14:37:03 rpd * Added cthread_fork_{prepare,parent,child}. * [90/11/02 rwd] - * + * * Add spin_lock_t. * [90/10/31 rwd] - * + * * Revision 2.5 90/08/07 14:30:58 rpd * Removed RCS keyword nonsense. - * + * * Revision 2.4 90/06/02 15:13:49 rpd * Converted to new IPC. * [90/03/20 20:56:44 rpd] - * + * * Revision 2.3 90/01/19 14:37:12 rwd * Make cthread_init return pointer to new stack. * [89/12/18 19:17:45 rwd] - * + * * Revision 2.2 89/12/08 19:53:37 rwd * Change cproc and cthread counters to globals with better names. * [89/11/02 rwd] - * + * * Revision 2.1 89/08/03 17:09:34 rwd * Created. - * + * * * 31-Dec-87 Eric Cooper (ecc) at Carnegie Mellon University * Changed cthread_exit() logic for the case of the main thread, @@ -101,22 +148,12 @@ */ #include <cthreads.h> +#include <mach/mig_support.h> #include "cthread_internals.h" -/* - * C Threads imports: - */ -extern void cproc_create(); -extern vm_offset_t cproc_init(); -extern void mig_init(); - -/* - * Mach imports: - */ - -/* - * C library imports: - */ +#ifdef HAVE_USELOCALE +# include <locale.h> +#endif /* * Thread status bits. @@ -125,9 +162,9 @@ extern void mig_init(); #define T_RETURNED 0x2 #define T_DETACHED 0x4 -#ifdef DEBUG +#if defined(DEBUG) int cthread_debug = FALSE; -#endif DEBUG +#endif /* defined(DEBUG) */ private struct cthread_queue cthreads = QUEUE_INITIALIZER; private struct mutex cthread_lock = MUTEX_INITIALIZER; @@ -143,9 +180,7 @@ private spin_lock_t free_lock = SPIN_LOCK_INITIALIZER; /* unlocked */ private struct cthread initial_cthread = { 0 }; private cthread_t -cthread_alloc(func, arg) - cthread_fn_t func; - any_t arg; +cthread_alloc(cthread_fn_t func, void *arg) { register cthread_t t = NO_CTHREAD; @@ -177,8 +212,7 @@ cthread_alloc(func, arg) } private void -cthread_free(t) - register cthread_t t; +cthread_free(cthread_t t) { spin_lock(&free_lock); t->next = free_cthreads; @@ -186,8 +220,8 @@ cthread_free(t) spin_unlock(&free_lock); } -int -cthread_init() +vm_offset_t +cthread_init(void) { static int cthreads_started = FALSE; register cproc_t p; @@ -196,9 +230,13 @@ cthread_init() if (cthreads_started) return 0; + + /* cthread_alloc must be called before cproc_init, because + malloc is not usable between initializing the new stack and + switching to it. */ + t = cthread_alloc((cthread_fn_t) 0, (any_t) 0); stack = cproc_init(); cthread_cprocs = 1; - t = cthread_alloc((cthread_fn_t) 0, (any_t) 0); #ifdef cthread_md_init cthread_md_init(); @@ -224,16 +262,15 @@ cthread_init() /* * Used for automatic initialization by crt0. - * Cast needed since too many C compilers choke on the type void (*)(). */ -int (*_cthread_init_routine)() = (int (*)()) cthread_init; +vm_offset_t (*_cthread_init_routine)(void) = cthread_init; + /* * Procedure invoked at the base of each cthread. */ void -cthread_body(self) - cproc_t self; +cthread_body(cproc_t self) { register cthread_t t; @@ -251,10 +288,15 @@ cthread_body(self) */ mutex_unlock(&cthread_lock); cthread_assoc(self, t); /* assume thread's identity */ - if (_setjmp(t->catch) == 0) { /* catch for cthread_exit() */ + if (_setjmp(t->catch_exit) == 0) { /* catch for cthread_exit() */ /* * Execute the fork request. */ +#ifdef HAVE_USELOCALE + /* A fresh thread needs to be bound to the + global locale. */ + uselocale (LC_GLOBAL_LOCALE); +#endif t->result = (*(t->func))(t->arg); } /* @@ -286,9 +328,7 @@ cthread_body(self) } cthread_t -cthread_fork(func, arg) - cthread_fn_t func; - any_t arg; +cthread_fork(cthread_fn_t func, void *arg) { register cthread_t t; @@ -320,11 +360,10 @@ cthread_detach(t) } } -any_t -cthread_join(t) - cthread_t t; +void * +cthread_join(cthread_t t) { - any_t result; + void *result; TRACE(printf("[%s] join(%s)\n", cthread_name(cthread_self()), cthread_name(t))); mutex_lock(&t->lock); @@ -338,21 +377,24 @@ cthread_join(t) } void -cthread_exit(result) - any_t result; +cthread_exit(void *result) { register cthread_t t = cthread_self(); TRACE(printf("[%s] exit()\n", cthread_name(t))); t->result = result; + if (t->private_data != 0) { + free((char *)t->private_data); + t->private_data = 0; + } if (t->state & T_MAIN) { mutex_lock(&cthread_lock); while (cthread_cthreads > 1) condition_wait(&cthread_idle, &cthread_lock); mutex_unlock(&cthread_lock); - exit((int) result); + exit((int) (integer_t) result); } else { - _longjmp(t->catch, TRUE); + _longjmp(t->catch_exit, TRUE); } } @@ -363,64 +405,58 @@ cthread_exit(result) int (*_cthread_exit_routine)() = (int (*)()) cthread_exit; void -cthread_set_name(t, name) - cthread_t t; - char *name; +cthread_set_name(cthread_t t, const char *name) { t->name = name; } -char * -cthread_name(t) - cthread_t t; +const char * +cthread_name(cthread_t t) { - return (t == NO_CTHREAD - ? "idle" - : (t->name == 0 ? "?" : t->name)); + return (t == NO_CTHREAD ? "idle" : (t->name == 0 ? "?" : t->name)); } int -cthread_limit() +cthread_limit(void) { return cthread_max_cprocs; } void -cthread_set_limit(n) - int n; +cthread_set_limit(int n) { cthread_max_cprocs = n; } int -cthread_count() +cthread_count(void) { return cthread_cthreads; } -cthread_fork_prepare() +void +cthread_fork_prepare(void) { spin_lock(&free_lock); mutex_lock(&cthread_lock); - malloc_fork_prepare(); cproc_fork_prepare(); } -cthread_fork_parent() +void +cthread_fork_parent(void) { cproc_fork_parent(); - malloc_fork_parent(); mutex_unlock(&cthread_lock); spin_unlock(&free_lock); } -cthread_fork_child() +void +cthread_fork_child(void) { cthread_t t; cproc_t p; cproc_fork_child(); - malloc_fork_child(); mutex_unlock(&cthread_lock); spin_unlock(&free_lock); condition_init(&cthread_needed); |