aboutsummaryrefslogtreecommitdiff
path: root/libthreads/cthreads.c
diff options
context:
space:
mode:
Diffstat (limited to 'libthreads/cthreads.c')
-rw-r--r--libthreads/cthreads.c196
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);