summaryrefslogtreecommitdiff
path: root/libthreads
diff options
context:
space:
mode:
Diffstat (limited to 'libthreads')
-rw-r--r--libthreads/call.c51
-rw-r--r--libthreads/cprocs.c170
-rw-r--r--libthreads/cthread_data.c90
-rw-r--r--libthreads/cthread_internals.h111
-rw-r--r--libthreads/cthreads.c157
-rw-r--r--libthreads/cthreads.h417
-rw-r--r--libthreads/i386/cthreads.h21
-rw-r--r--libthreads/i386/lock.s28
-rw-r--r--libthreads/i386/thread.c63
-rw-r--r--libthreads/mig_support.c106
-rw-r--r--libthreads/sync.c9
11 files changed, 616 insertions, 607 deletions
diff --git a/libthreads/call.c b/libthreads/call.c
index ec25345c..85bd4f38 100644
--- a/libthreads/call.c
+++ b/libthreads/call.c
@@ -1,84 +1,79 @@
-/*
+/*
* 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: call.c,v $
- * Revision 1.1 1992/10/06 18:31:03 mib
- * entered into RCS
- *
+ * $Log: call.c,v $
+ * Revision 2.5 93/01/14 18:04:38 danner
+ * Converted file to ANSI C.
+ * [92/12/18 pds]
+ *
* Revision 2.4 91/05/14 17:56:00 mrt
* Correcting copyright
- *
+ *
* Revision 2.3 91/02/14 14:19:20 mrt
* Added new Mach copyright
* [91/02/13 12:40:44 mrt]
- *
+ *
* Revision 2.2 90/01/19 14:36:50 rwd
* Created. Routines to replace thread_* and cthread_call_on.
* [90/01/03 rwd]
- *
+ *
*/
#include <cthreads.h>
#include "cthread_internals.h"
-#ifdef THREAD_CALLS
-kern_return_t cthread_get_state(thread)
-cthread_t thread;
+#if defined(THREAD_CALLS)
+kern_return_t cthread_get_state(cthread_t thread)
{
cproc_t p = thread->ur;
}
-kern_return_t cthread_set_state(thread)
-cthread_t thread;
+kern_return_t cthread_set_state(cthread_t thread)
{
cproc_t p = thread->ur;
}
-kern_return_t cthread_abort(thread)
-cthread_t thread;
+kern_return_t cthread_abort(cthread_t thread)
{
cproc_t p = thread->ur;
}
-kern_return_t cthread_resume(thread)
-cthread_t thread;
+kern_return_t cthread_resume(cthread_t thread)
{
cproc_t p = thread->ur;
}
-kern_return_t cthread_suspend(thread)
-cthread_t thread;
+kern_return_t cthread_suspend(cthread_t thread)
{
cproc_t p = thread->ur;
}
-kern_return_t cthread_call_on(thread)
-cthread_t thread;
+kern_return_t cthread_call_on(cthread_t thread)
{
cproc_t p = thread->ur;
}
-#endif /* THREAD_CALLS */
+#endif /* defined(THREAD_CALLS) */
diff --git a/libthreads/cprocs.c b/libthreads/cprocs.c
index dd8ed95c..91e689f8 100644
--- a/libthreads/cprocs.c
+++ b/libthreads/cprocs.c
@@ -1,6 +1,6 @@
/*
* Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * Copyright (c) 1993-1989 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
@@ -25,72 +25,24 @@
*/
/*
* HISTORY
- * $Log: cprocs.c,v $
- * Revision 1.14 2002/05/08 09:32:11 roland
- * 2002-05-07 Roland McGrath <roland@frob.com>
+ * 26-Oct-94 Johannes Helander (jvh) Helsinki University of Technology
+ * Set the wait_type field.
*
- * * cprocs.c (cproc_list_lock): Declare type as spin_lock_t.
+ * $Log: cprocs.c,v $
+ * Revision 2.18 93/03/09 10:59:10 danner
+ * Lint.
+ * [93/03/06 af]
*
- * Revision 1.13 2001/03/31 23:01:01 roland
- * 2001-03-31 Roland McGrath <roland@frob.com>
+ * Revision 2.17 93/01/19 08:55:44 danner
+ * Added missing spin_lock_t type from cproc_list_lock decl.
+ * [92/12/30 af]
*
- * * 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.12 2000/01/10 14:42:30 kettenis
- * 2000-01-10 Mark Kettenis <kettenis@gnu.org>
- *
- * * cprocs.c: Include <assert.h>
- *
- * Revision 1.11 2000/01/09 23:00:18 roland
- * 2000-01-09 Roland McGrath <roland@baalperazim.frob.com>
- *
- * * cprocs.c (cproc_alloc): Initialize P->wired and P->msg here (code
- * from cthread_wire).
- * (cthread_wire): Reduce to just an assert, cthreads always wired.
- * (chtread_unwire): Abort if called.
- *
- * Revision 1.10 1998/07/20 06:59:14 roland
- * 1998-07-20 Roland McGrath <roland@baalperazim.frob.com>
- *
- * * i386/csw.S (cproc_prepare): Take address of cthread_body as third
- * arg, so we don't have to deal with PIC magic to find its address
- * without producing a text reloc.
- * * cprocs.c (cproc_create): Pass &cthread_body to cproc_prepare.
- *
- * Revision 1.9 1996/11/18 23:54:51 thomas
- * Mon Nov 18 16:36:56 1996 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
- *
- * * cprocs.c (cproc_create): Cast CHILD in assignment.
- *
- * Revision 1.8 1995/12/06 19:48:34 mib
- * (condition_unimplies): Take address of (*impp)->next in assignment to
- * IMPP on loop step instruction.
- *
- * Revision 1.7 1995/09/22 17:51:10 roland
- * Include hurd/threadvar.h.
- *
- * Revision 1.6 1995/08/30 15:57:47 mib
- * Repair typos.
- *
- * Revision 1.5 1995/08/30 15:50:53 mib
- * (cond_signal): If this condition has implications, see if one of them
- * needs to be signalled when we have no waiters.
- * (cond_broadcast): Signal the implications list too.
- * (condition_implies, condition_unimplies): New functions.
- *
- * Revision 1.4 1995/04/04 21:04:29 roland
- * (mutex_lock_solid, mutex_unlock_solid): Renamed to __*.
- * (_cthread_mutex_lock_routine, _cthread_mutex_unlock_routine): Variables
- * removed.
- *
- * Revision 1.3 1994/05/19 04:55:30 roland
- * entered into RCS
+ * Revision 2.16 93/01/14 18:04:46 danner
+ * Convert file to ANSI C.
+ * [92/12/18 pds]
+ * 64bit cleanup.
+ * [92/12/10 21:08:32 af]
*
* Revision 2.15 92/03/06 14:09:31 rpd
* Replaced swtch_pri with yield.
@@ -270,15 +222,6 @@
#include <assert.h>
/*
- * C Threads imports:
- */
-extern void alloc_stack();
-extern void cproc_switch(); /* cproc context switch */
-extern void cproc_start_wait(); /* cproc idle thread */
-extern vm_offset_t cproc_stack_base(); /* return start of stack */
-extern vm_offset_t stack_init();
-
-/*
* Port_entry's are used by cthread_mach_msg to store information
* about each port/port_set for which it is managing threads
*/
@@ -358,8 +301,8 @@ private mach_msg_header_t wakeup_msg; /* prebuilt message used by idle
* Return current value for max kernel threads
* Note: 0 means no limit
*/
-
-cthread_kernel_limit()
+int
+cthread_kernel_limit(void)
{
return cthread_max_kernel_threads;
}
@@ -370,8 +313,8 @@ cthread_kernel_limit()
* over maximum.
*/
-cthread_set_kernel_limit(n)
- int n;
+void
+cthread_set_kernel_limit(int n)
{
cthread_max_kernel_threads = n;
}
@@ -380,7 +323,8 @@ cthread_set_kernel_limit(n)
* Wire a cthread to its current kernel thread
*/
-void cthread_wire()
+void
+cthread_wire(void)
{
register cproc_t p = cproc_self();
kern_return_t r;
@@ -393,7 +337,8 @@ void cthread_wire()
* Unwire a cthread. Deallocate its wait port.
*/
-void cthread_unwire()
+void
+cthread_unwire(void)
{
register cproc_t p = cproc_self();
@@ -416,7 +361,7 @@ void cthread_unwire()
}
private cproc_t
-cproc_alloc()
+cproc_alloc(void)
{
register cproc_t p = (cproc_t) malloc(sizeof(struct cproc));
kern_return_t r;
@@ -466,7 +411,7 @@ cproc_alloc()
*/
vm_offset_t
-cproc_init()
+cproc_init(void)
{
kern_return_t r;
@@ -503,9 +448,7 @@ cproc_init()
* synching on its lock. Just send message to wired cproc.
*/
-private int cproc_ready(p, preq)
- register cproc_t p;
- register int preq;
+private boolean_t cproc_ready(register cproc_t p, register int preq)
{
register cproc_t s=cproc_self();
kern_return_t r;
@@ -586,8 +529,7 @@ private int cproc_ready(p, preq)
*/
void
-cproc_waiting(p)
- register cproc_t p;
+cproc_waiting(cproc_t p)
{
mach_msg_header_t msg;
register cproc_t new;
@@ -634,8 +576,8 @@ cproc_waiting(p)
*
*/
-cproc_t
-cproc_waiter()
+private cproc_t
+cproc_waiter(void)
{
register cproc_t waiter;
@@ -667,7 +609,8 @@ cproc_waiter()
* You must hold cproc_self()->lock when called.
*/
-cproc_block()
+private void
+cproc_block(void)
{
extern unsigned int __hurd_threadvar_max; /* GNU */
register cproc_t waiter, new, p = cproc_self();
@@ -755,7 +698,7 @@ cproc_block()
* Implement C threads using MACH threads.
*/
cproc_t
-cproc_create()
+cproc_create(void)
{
register cproc_t child = cproc_alloc();
register kern_return_t r;
@@ -805,9 +748,7 @@ cproc_create()
}
void
-condition_wait(c, m)
- register condition_t c;
- mutex_t m;
+condition_wait(condition_t c, mutex_t m)
{
register cproc_t p = cproc_self();
@@ -877,8 +818,7 @@ condition_unimplies (condition_t implicator, condition_t implicatand)
/* Signal one waiter on C. If there were no waiters at all, return
0, else return 1. */
int
-cond_signal(c)
- register condition_t c;
+cond_signal(condition_t c)
{
register cproc_t p;
struct cond_imp *imp;
@@ -899,8 +839,7 @@ cond_signal(c)
}
void
-cond_broadcast(c)
- register condition_t c;
+cond_broadcast(condition_t c)
{
register cproc_t p;
struct cthread_queue blocked_queue;
@@ -931,7 +870,7 @@ cond_broadcast(c)
}
void
-cthread_yield()
+cthread_yield(void)
{
register cproc_t new, p = cproc_self();
@@ -1040,8 +979,8 @@ __mutex_unlock_solid(void *ptr)
* call to occur as often as is possible.
*/
-private port_entry_t get_port_entry(port, min, max)
- mach_port_t port;
+private port_entry_t
+get_port_entry(mach_port_t port, int min, int max)
{
register port_entry_t i;
@@ -1064,8 +1003,8 @@ private port_entry_t get_port_entry(port, min, max)
return i;
}
-cthread_msg_busy(port, min, max)
- mach_port_t port;
+void
+cthread_msg_busy(mach_port_t port, int min, int max)
{
register port_entry_t port_entry;
register cproc_t new, p = cproc_self();
@@ -1096,8 +1035,8 @@ cthread_msg_busy(port, min, max)
}
-cthread_msg_active(port, min, max)
-mach_port_t port;
+void
+cthread_msg_active(mach_port_t port, int min, int max)
{
register cproc_t p = cproc_self();
register port_entry_t port_entry;
@@ -1115,17 +1054,11 @@ mach_port_t port;
}
mach_msg_return_t
-cthread_mach_msg(header, option,
- send_size, rcv_size, rcv_name,
- timeout, notify, min, max)
- register mach_msg_header_t *header;
- register mach_msg_option_t option;
- mach_msg_size_t send_size;
- mach_msg_size_t rcv_size;
- register mach_port_t rcv_name;
- mach_msg_timeout_t timeout;
- mach_port_t notify;
- int min, max;
+cthread_mach_msg(register mach_msg_header_t *header,
+ register mach_msg_option_t option, mach_msg_size_t send_size,
+ mach_msg_size_t rcv_size, register mach_port_t rcv_name,
+ mach_msg_timeout_t timeout, mach_port_t notify, int min,
+ int max)
{
register port_entry_t port_entry;
register cproc_t p = cproc_self();
@@ -1184,7 +1117,8 @@ cthread_mach_msg(header, option,
return r;
}
-cproc_fork_prepare()
+void
+cproc_fork_prepare(void)
{
register cproc_t p = cproc_self();
@@ -1193,7 +1127,8 @@ cproc_fork_prepare()
spin_lock(&cproc_list_lock);
}
-cproc_fork_parent()
+void
+cproc_fork_parent(void)
{
register cproc_t p = cproc_self();
@@ -1202,7 +1137,8 @@ cproc_fork_parent()
vm_inherit(mach_task_self(),p->stack_base, p->stack_size, VM_INHERIT_NONE);
}
-cproc_fork_child()
+void
+cproc_fork_child(void)
{
register cproc_t l,p = cproc_self();
cproc_t m;
diff --git a/libthreads/cthread_data.c b/libthreads/cthread_data.c
index 12d10610..02e6fa82 100644
--- a/libthreads/cthread_data.c
+++ b/libthreads/cthread_data.c
@@ -1,20 +1,26 @@
-/*
+/*
* Mach Operating System
- * Copyright (c) 1991 Carnegie-Mellon University
+ * Copyright (c) 1992,1991 Carnegie-Mellon University
* All rights reserved. The CMU software License Agreement specifies
* the terms and conditions for use and redistribution.
*/
/*
* HISTORY
- * $Log: cthread_data.c,v $
- * Revision 1.1 1992/10/06 18:31:04 mib
- * entered into RCS
- *
+ * $Log: cthread_data.c,v $
+ * Revision 2.4 93/05/10 17:51:20 rvb
+ * Make cthread_set_data and cthread_data macros.
+ * [93/05/06 rvb]
+ *
+ * Revision 2.3 93/01/14 18:04:52 danner
+ * Converted file to ANSI C.
+ * Removed usage of obsolete type any_t.
+ * [92/12/18 pds]
+ *
* Revision 2.2 92/05/23 11:35:17 jfriedl
* Snarfed from multi-server sources at CMU.
* No stdio (for use with single-server).
- *
- *
+ *
+ *
* Revision 2.2 91/03/25 14:14:45 jjc
* For compatibility with cthread_data:
* 1) Added routines, cthread_data and cthread_set_data,
@@ -27,25 +33,25 @@
* Made simple implementation from POSIX threads specification for
* thread specific data.
* [91/03/07 jjc]
- *
+ *
*/
-#include <cthreads.h>
+#include <stdio.h>
+#include <cthreads.h>
-#ifdef CTHREAD_DATA
-#define CTHREAD_KEY_FIRST (cthread_key_t)1 /* first free key */
-#else /* CTHREAD_DATA */
-#define CTHREAD_KEY_FIRST CTHREAD_KEY_NULL /* first free key */
-#endif /* CTHREAD_DATA */
#define CTHREAD_KEY_MAX (cthread_key_t)8 /* max. no. of keys */
#define CTHREAD_KEY_NULL (cthread_key_t)0
-#ifdef CTHREAD_DATA
+#if defined(CTHREAD_DATA)
/*
* Key reserved for cthread_data
*/
#define CTHREAD_KEY_RESERVED CTHREAD_KEY_NULL
-#endif /* CTHREAD_DATA */
+
+#define CTHREAD_KEY_FIRST (cthread_key_t)1 /* first free key */
+#else /* not defined(CTHREAD_DATA) */
+#define CTHREAD_KEY_FIRST CTHREAD_KEY_NULL /* first free key */
+#endif /* defined(CTHREAD_DATA) */
/* lock protecting key creation */
@@ -61,8 +67,8 @@ cthread_key_t cthread_key = CTHREAD_KEY_FIRST;
* maintained on a thread specific basis.
* Returns 0 if successful and returns -1 otherwise.
*/
-cthread_keycreate(key)
-cthread_key_t *key;
+int
+cthread_keycreate(cthread_key_t *key)
{
if (cthread_key >= CTHREAD_KEY_FIRST && cthread_key < CTHREAD_KEY_MAX) {
mutex_lock((mutex_t)&cthread_data_lock);
@@ -83,20 +89,19 @@ cthread_key_t *key;
* If the calling thread doesn't have a value for the given key,
* the value returned is CTHREAD_DATA_VALUE_NULL.
*/
-cthread_getspecific(key, value)
-cthread_key_t key;
-any_t *value;
+int
+cthread_getspecific(cthread_key_t key, void **value)
{
register cthread_t self;
- register any_t *thread_data;
+ register void **thread_data;
*value = CTHREAD_DATA_VALUE_NULL;
if (key < CTHREAD_KEY_NULL || key >= cthread_key)
return(-1);
self = cthread_self();
- thread_data = (any_t *)(self->private_data);
- if (thread_data != (any_t *)0)
+ thread_data = (void **)(self->private_data);
+ if (thread_data != NULL)
*value = thread_data[key];
return(0);
@@ -107,20 +112,19 @@ any_t *value;
* Set private data associated with given key
* Returns 0 if successful and returns -1 otherwise.
*/
-cthread_setspecific(key, value)
-cthread_key_t key;
-any_t value;
+int
+cthread_setspecific(cthread_key_t key, void *value)
{
register int i;
register cthread_t self;
- register any_t *thread_data;
+ register void **thread_data;
if (key < CTHREAD_KEY_NULL || key >= cthread_key)
return(-1);
self = cthread_self();
- thread_data = (any_t *)(self->private_data);
- if (thread_data != (any_t *)0)
+ thread_data = (void **)(self->private_data);
+ if (thread_data != NULL)
thread_data[key] = value;
else {
/*
@@ -128,12 +132,12 @@ any_t value;
* point cthread_data at it, and then set the
* data for the given key with the given value.
*/
- thread_data = (any_t *)malloc(CTHREAD_KEY_MAX * sizeof(any_t));
- if (thread_data == (any_t *)0) {
+ thread_data = malloc(CTHREAD_KEY_MAX * sizeof(void *));
+ if (thread_data == NULL) {
printf("cthread_setspecific: malloc failed\n");
return(-1);
}
- self->private_data = (any_t)thread_data;
+ self->private_data = thread_data;
for (i = 0; i < CTHREAD_KEY_MAX; i++)
thread_data[i] = CTHREAD_DATA_VALUE_NULL;
@@ -144,16 +148,15 @@ any_t value;
}
-#ifdef CTHREAD_DATA
+#if defined(CTHREAD_DATA_XX)
/*
* Set thread specific "global" variable,
* using new POSIX routines.
* Crash and burn if the thread given isn't the calling thread.
* XXX For compatibility with old cthread_set_data() XXX
*/
-cthread_set_data(t, x)
-cthread_t t;
-any_t x;
+int
+cthread_set_data(cthread_t t, void *x)
{
register cthread_t self;
@@ -162,6 +165,7 @@ any_t x;
return(cthread_setspecific(CTHREAD_KEY_RESERVED, x));
else {
ASSERT(t == self);
+ return(-1);
}
}
@@ -172,12 +176,11 @@ any_t x;
* Crash and burn if the thread given isn't the calling thread.
* XXX For compatibility with old cthread_data() XXX
*/
-any_t
-cthread_data(t)
-cthread_t t;
+void *
+cthread_data(cthread_t t)
{
register cthread_t self;
- any_t value;
+ void *value;
self = cthread_self();
if (t == self) {
@@ -186,6 +189,7 @@ cthread_t t;
}
else {
ASSERT(t == self);
+ return(NULL);
}
}
-#endif /* CTHREAD_DATA */
+#endif /* defined(CTHREAD_DATA_XX) */
diff --git a/libthreads/cthread_internals.h b/libthreads/cthread_internals.h
index 69e71180..7c557428 100644
--- a/libthreads/cthread_internals.h
+++ b/libthreads/cthread_internals.h
@@ -1,6 +1,6 @@
/*
* 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
@@ -25,23 +25,28 @@
*/
/*
* HISTORY
- * $Log: cthread_internals.h,v $
- * Revision 1.4 2001/03/31 23:01:01 roland
- * 2001-03-31 Roland McGrath <roland@frob.com>
+ * 26-Oct-94 Johannes Helander (jvh) Helsinki University of Technology
+ * Defined WAIT_DEBUG and initialized wait_enum
*
- * * 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.
+ * $Log: cthread_internals.h,v $
+ * Revision 2.17 93/05/10 21:33:36 rvb
+ * Context is a natural_t. Assumming, that is, that on
+ * some future architecture one word might be enough.
+ * [93/05/06 09:19:35 af]
*
- * Revision 1.3 1995/08/29 14:49:20 mib
- * (cproc_block): Provide decl.
+ * Revision 2.16 93/05/10 17:51:23 rvb
+ * Flush stdlib
+ * [93/05/05 09:12:29 rvb]
*
- * Revision 1.2 1994/05/05 10:58:01 roland
- * entered into RCS
+ * Revision 2.15 93/01/14 18:04:56 danner
+ * Added declarations for library-internal routines.
+ * [92/12/18 pds]
+ *
+ * Replaced malloc and mach_error declarations with includes of
+ * mach_error.h and stdlib.h.
+ * [92/06/13 pds]
+ * 64bit cleanup.
+ * [92/12/01 af]
*
* Revision 2.14 92/08/03 18:03:56 jfriedl
* Made state element of struct cproc volatile.
@@ -160,7 +165,7 @@ typedef struct cproc {
mach_port_t reply_port; /* for mig_get_reply_port() */
#endif
- int context;
+ natural_t context;
spin_lock_t lock;
volatile int state; /* current state */
#define CPROC_RUNNING 0
@@ -173,15 +178,13 @@ typedef struct cproc {
mach_msg_header_t msg;
- unsigned int stack_base;
- unsigned int stack_size;
+ vm_offset_t stack_base;
+ vm_offset_t stack_size;
} *cproc_t;
#define NO_CPROC ((cproc_t) 0)
#define cproc_self() ((cproc_t) ur_cthread_self())
-int cproc_block ();
-
#if 0
/* This declaration conflicts with <stdlib.h> in GNU. */
/*
@@ -221,3 +224,71 @@ extern void mach_error();
#define yield() \
(void) thread_switch(MACH_PORT_NULL, SWITCH_OPTION_DEPRESS, 10)
+
+/*
+ * Functions implemented in malloc.c.
+ */
+
+#if defined(DEBUG)
+extern void print_malloc_free_list(void);
+#endif /* defined(DEBUG) */
+
+extern void malloc_fork_prepare(void);
+
+extern void malloc_fork_parent(void);
+
+extern void malloc_fork_child(void);
+
+
+/*
+ * Functions implemented in stack.c.
+ */
+
+extern vm_offset_t stack_init(cproc_t _cproc);
+
+extern void alloc_stack(cproc_t _cproc);
+
+extern vm_offset_t cproc_stack_base(cproc_t _cproc, int _offset);
+
+extern void stack_fork_child(void);
+
+/*
+ * Functions implemented in cprocs.c.
+ */
+
+extern vm_offset_t cproc_init(void);
+
+extern void cproc_waiting(cproc_t _waiter);
+
+extern cproc_t cproc_create(void);
+
+extern void cproc_fork_prepare(void);
+
+extern void cproc_fork_parent(void);
+
+extern void cproc_fork_child(void);
+
+/*
+ * Function implemented in cthreads.c.
+ */
+
+extern void cthread_body(cproc_t _self);
+
+/*
+ * Functions from machine dependent files.
+ */
+
+extern void cproc_switch(natural_t *_cur, const natural_t *_new,
+ spin_lock_t *_lock);
+
+extern void cproc_start_wait(natural_t *_parent, cproc_t _child,
+ vm_offset_t _stackp,
+ spin_lock_t *_lock);
+
+extern void cproc_prepare(cproc_t _child,
+ natural_t *_child_context,
+ vm_offset_t _stackp,
+ void (*cthread_body_pc)());
+
+extern void cproc_setup(cproc_t _child, thread_t _mach_thread,
+ void (*_routine)(cproc_t));
diff --git a/libthreads/cthreads.c b/libthreads/cthreads.c
index 12126f20..645ac939 100644
--- a/libthreads/cthreads.c
+++ b/libthreads/cthreads.c
@@ -1,6 +1,6 @@
/*
* 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
@@ -25,52 +25,24 @@
*/
/*
* HISTORY
- * $Log: cthreads.c,v $
- * Revision 1.10 2001/03/31 23:01:01 roland
- * 2001-03-31 Roland McGrath <roland@frob.com>
+ * 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++.
*
- * * 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.
+ * $Log: cthreads.c,v $
+ * 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 1.9 1998/11/22 18:18:10 roland
- * 1998-11-12 Mark Kettenis <kettenis@phys.uva.nl>
+ * 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]
*
- * * cthreads.c (cthread_init): Move cthread_alloc call before
- * cproc_init call, since cthread_alloc uses malloc, and malloc won't
- * work between initializing the new stack and switching over to it.
- *
- * Revision 1.8 1998/06/10 19:38:01 tb
- * Tue Jun 9 13:50:09 1998 Thomas Bushnell, n/BSG <tb@mit.edu>
- *
- * * cthreads.c (cthread_fork_prepare): Don't call
- * malloc_fork_prepare since we are no longer providing our own
- * malloc in this library.
- * (cthread_fork_parent): Likewise, for malloc_fork_parent.
- * (cthread_fork_child): Likewize, for malloc_fork_child.
- *
- * Revision 1.7 1997/08/20 19:41:20 thomas
- * Wed Aug 20 15:39:44 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
- *
- * * cthreads.c (cthread_body): Wire self before calling user work
- * function. This way all cthreads will be wired, which the ports
- * library (and hurd_thread_cancel, etc.) depend on.
- *
- * Revision 1.6 1997/06/10 01:22:19 thomas
- * Mon Jun 9 21:18:46 1997 Thomas Bushnell, n/BSG <thomas@gnu.ai.mit.edu>
- *
- * * cthreads.c (cthread_fork): Delete debugging oddity that crept
- * into source.
- *
- * Revision 1.5 1997/04/04 01:30:35 thomas
- * *** empty log message ***
- *
- * Revision 1.4 1994/05/05 18:13:57 roland
- * entered into RCS
+ * 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.
@@ -147,33 +119,19 @@
*/
#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:
- */
-
-/*
* Thread status bits.
*/
#define T_MAIN 0x1
#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;
@@ -189,9 +147,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;
@@ -223,8 +179,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;
@@ -232,8 +187,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;
@@ -242,9 +197,9 @@ cthread_init()
if (cthreads_started)
return 0;
- t = cthread_alloc((cthread_fn_t) 0, (any_t) 0);
stack = cproc_init();
cthread_cprocs = 1;
+ t = cthread_alloc((cthread_fn_t) 0, (void *) 0);
#ifdef cthread_md_init
cthread_md_init();
@@ -270,16 +225,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;
@@ -297,8 +251,7 @@ cthread_body(self)
*/
mutex_unlock(&cthread_lock);
cthread_assoc(self, t); /* assume thread's identity */
- if (_setjmp(t->catch) == 0) { /* catch for cthread_exit() */
- cthread_wire ();
+ if (_setjmp(t->catch_exit) == 0) { /* catch for cthread_exit() */
/*
* Execute the fork request.
*/
@@ -333,9 +286,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;
@@ -367,11 +318,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);
@@ -385,21 +335,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)(long)result);
+ exit((int) (integer_t) result);
} else {
- _longjmp(t->catch, TRUE);
+ _longjmp(t->catch_exit, TRUE);
}
}
@@ -410,60 +363,60 @@ 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;
+ malloc_fork_child();
cproc_fork_child();
mutex_unlock(&cthread_lock);
spin_unlock(&free_lock);
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_) */
diff --git a/libthreads/i386/cthreads.h b/libthreads/i386/cthreads.h
index 8ffe4b72..643e7350 100644
--- a/libthreads/i386/cthreads.h
+++ b/libthreads/i386/cthreads.h
@@ -1,6 +1,6 @@
/*
* Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
+ * Copyright (c) 1993,1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
@@ -26,6 +26,15 @@
/*
* HISTORY
* $Log: cthreads.h,v $
+ * Revision 2.9 93/01/24 13:24:58 danner
+ * Move ! in spin_try_lock to give the compiler
+ * a fighting chance.
+ * [92/11/19 rvb]
+ *
+ * Revision 2.8 93/01/14 18:05:09 danner
+ * asm -> __asm__
+ * [93/01/10 danner]
+ *
* Revision 2.7 92/01/03 20:36:59 dbg
* Add volatile to spin_lock_t. Change spin_unlock and
* spin_try_lock definitions back to memory operands, but rely on
@@ -66,21 +75,21 @@ typedef volatile int spin_lock_t;
#define spin_unlock(p) \
({ register int _u__ ; \
- asm volatile("xorl %0, %0; \n\
+ __asm__ volatile("xorl %0, %0; \n\
xchgl %0, %1" \
: "=&r" (_u__), "=m" (*(p)) ); \
0; })
#define spin_try_lock(p)\
- ({ boolean_t _r__; \
- asm volatile("movl $1, %0; \n\
+ (!({ boolean_t _r__; \
+ __asm__ volatile("movl $1, %0; \n\
xchgl %0, %1" \
: "=&r" (_r__), "=m" (*(p)) ); \
- !_r__; })
+ _r__; }))
#define cthread_sp() \
({ int _sp__; \
- asm("movl %%esp, %0" \
+ __asm__("movl %%esp, %0" \
: "=g" (_sp__) ); \
_sp__; })
diff --git a/libthreads/i386/lock.s b/libthreads/i386/lock.s
index e27fa7ff..f064e5bb 100644
--- a/libthreads/i386/lock.s
+++ b/libthreads/i386/lock.s
@@ -26,6 +26,10 @@
/*
* HISTORY
* $Log: lock.s,v $
+ * Revision 2.6 93/05/10 17:51:38 rvb
+ * Use C Comment
+ * [93/05/04 18:14:05 rvb]
+ *
* Revision 2.5 91/05/14 17:57:20 mrt
* Correcting copyright
*
@@ -49,22 +53,22 @@
* boolean_t spin_try_lock(int *m)
*/
ENTRY(spin_try_lock)
- movl 4(%esp),%ecx / point at mutex
- movl $1,%eax / set locked value in acc
- xchg %eax,(%ecx) / swap with mutex
- / xchg with memory is automatically
- / locked
- xorl $1,%eax / 1 (locked) => FALSE
- / 0 (locked) => TRUE
+ movl 4(%esp),%ecx /* point at mutex */
+ movl $1,%eax /* set locked value in acc */
+ xchg %eax,(%ecx) /* swap with mutex */
+ /* xchg with memory is automatically */
+ /* locked */
+ xorl $1,%eax /* 1 (locked) => FALSE */
+ /* 0 (locked) => TRUE */
ret
/*
* void spin_unlock(int *m)
*/
ENTRY(spin_unlock)
- movl 4(%esp),%ecx / point at mutex
- xorl %eax,%eax / set unlocked value in acc
- xchg %eax,(%ecx) / swap with mutex
- / xchg with memory is automatically
- / locked
+ movl 4(%esp),%ecx /* point at mutex */
+ xorl %eax,%eax /* set unlocked value in acc */
+ xchg %eax,(%ecx) /* swap with mutex */
+ /* xchg with memory is automatically */
+ /* locked */
ret
diff --git a/libthreads/i386/thread.c b/libthreads/i386/thread.c
index c6781b9d..c0195a8b 100644
--- a/libthreads/i386/thread.c
+++ b/libthreads/i386/thread.c
@@ -1,6 +1,6 @@
/*
* Mach Operating System
- * Copyright (c) 1991,1990 Carnegie Mellon University
+ * Copyright (c) 1992,1991,1990 Carnegie Mellon University
* All Rights Reserved.
*
* Permission to use, copy, modify and distribute this software and its
@@ -25,44 +25,20 @@
*/
/*
* HISTORY
- * $Log: thread.c,v $
- * Revision 1.5 2001/03/31 23:03:03 roland
- * 2001-03-31 Roland McGrath <roland@frob.com>
+ * $Log: thread.c,v $
+ * Revision 2.8 93/02/02 21:54:58 mrt
+ * Changed include of mach/mach.h to mach.h.
+ * [93/02/02 mrt]
*
- * * 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.
- * * i386/thread.c: Likewise.
- *
- * Revision 1.4 2001/02/26 04:15:27 roland
- * 2001-02-25 Roland McGrath <roland@frob.com>
- *
- * * i386/thread.c: Remove superfluous bzero decl,
- * just include <strings.h> instead.
- *
- * Revision 1.3 1997/02/18 22:53:31 miles
- * (cproc_setup):
- * Correctly leave space at top of stack for account for GNU per-thread
- * variables.
- *
- * Revision 1.2 1994/05/04 19:05:26 mib
- * entered into RCS
+ * Revision 2.7 93/01/14 18:05:15 danner
+ * Converted file to ANSI C.
+ * Fixed argument types.
+ * [92/12/18 pds]
*
* Revision 2.6 91/07/31 18:37:07 dbg
* Undefine cthread_sp macro around function definition.
* [91/07/30 17:36:23 dbg]
*
- * Revision 2.5 91/05/14 17:57:27 mrt
- * Correcting copyright
- *
- * Revision 2.4 91/02/14 14:20:21 mrt
- * Changed to new Mach copyright
- * [91/02/13 12:20:10 mrt]
- *
* Revision 2.3 90/06/02 15:13:53 rpd
* Added definition of cthread_sp.
* [90/06/02 rpd]
@@ -78,15 +54,13 @@
*/
#ifndef lint
-static char rcs_id[] = "$Header: cvs-sans-libpthread/hurd/libthreads/i386/thread.c,v 1.6 2001/12/22 21:02:31 roland Exp $";
+char rcs_id[] = "$Header: cvs-sans-libpthread/hurd/libthreads/i386/thread.c,v 1.7 2002/05/27 02:50:10 roland Exp $";
#endif /* not lint */
-#include "../cthreads.h"
-#include "../cthread_internals.h"
-#include <strings.h>
-#include <mach/mach.h>
-
+#include <cthreads.h>
+#include "cthread_internals.h"
+#include <mach.h>
/*
* Set up the initial state of a MACH thread
@@ -94,10 +68,7 @@ static char rcs_id[] = "$Header: cvs-sans-libpthread/hurd/libthreads/i386/thread
* when it is resumed.
*/
void
-cproc_setup(child, thread, routine)
- register cproc_t child;
- int thread;
- int routine;
+cproc_setup(register cproc_t child, thread_t thread, void (*routine)(cproc_t))
{
extern unsigned int __hurd_threadvar_max; /* GNU */
register int *top = (int *)
@@ -118,7 +89,7 @@ cproc_setup(child, thread, routine)
count = i386_THREAD_STATE_COUNT;
MACH_CALL(thread_get_state(thread,i386_THREAD_STATE,(thread_state_t) &state,&count),r);
- ts->eip = routine;
+ ts->eip = (int) routine;
*--top = (int) child; /* argument to function */
*--top = 0; /* fake return address */
ts->uesp = (int) top; /* set stack pointer */
@@ -127,12 +98,12 @@ cproc_setup(child, thread, routine)
MACH_CALL(thread_set_state(thread,i386_THREAD_STATE,(thread_state_t) &state,i386_THREAD_STATE_COUNT),r);
}
-#ifdef cthread_sp
+#if defined(cthread_sp)
#undef cthread_sp
#endif
int
-cthread_sp()
+cthread_sp(void)
{
return (int) __thread_stack_pointer ();
}
diff --git a/libthreads/mig_support.c b/libthreads/mig_support.c
index bb9e6a5e..01e5deb0 100644
--- a/libthreads/mig_support.c
+++ b/libthreads/mig_support.c
@@ -1,54 +1,68 @@
-/*
+/*
* Mach Operating System
- * Copyright (c) 1991,1990,1989 Carnegie Mellon University
+ * Copyright (c) 1993-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
+ * 26-Feb-94 Johannes Helander (jvh) at Helsinki University of Technology
+ * Added mach_put_reply_port. mig_dealloc_reply_port now takes the
+ * port as an argument.
+ *
* $Log: mig_support.c,v $
+ * Revision 2.8 93/01/24 13:27:14 danner
+ * Corrrected include of mach/mach.h to mach.h
+ * [93/01/16 mrt]
+ *
+ * Revision 2.7 93/01/14 18:05:37 danner
+ * Converted file to ANSI C.
+ * Made argument to mig_init a void * for compatibility with
+ * mig_init in libmach.
+ * [92/12/18 pds]
+ *
* Revision 2.6 91/05/14 17:57:41 mrt
* Correcting copyright
- *
+ *
* Revision 2.5 91/02/14 14:20:30 mrt
* Added new Mach copyright
* [91/02/13 12:41:26 mrt]
- *
+ *
* Revision 2.4 90/08/07 14:31:41 rpd
* Removed RCS keyword nonsense.
- *
+ *
* Revision 2.3 90/08/07 14:27:48 rpd
* When we recycle the global reply port by giving it to the first
* cthread, clear the global reply port. This will take care of
* someone accidently calling this twice.
* [90/08/07 rwd]
- *
+ *
* Revision 2.2 90/06/02 15:14:04 rpd
* Converted to new IPC.
* [90/03/20 20:56:50 rpd]
- *
+ *
* Revision 2.1 89/08/03 17:09:50 rwd
* Created.
- *
+ *
* 18-Jan-89 David Golub (dbg) at Carnegie-Mellon University
* Replaced task_data() by thread_reply().
*
@@ -75,7 +89,9 @@
*/
-#include <mach/mach.h>
+#include <mach.h>
+#include <mach/mig_support.h>
+#include <mach/mach_traps.h>
#include <cthreads.h>
#include "cthread_internals.h"
@@ -88,8 +104,7 @@ private mach_port_t mig_reply_port = MACH_PORT_NULL;
* called and again with initial cproc at end of cthread_init.
*/
void
-mig_init(initial)
- register cproc_t initial;
+mig_init(register void *initial)
{
if (initial == NO_CPROC) {
/* called from mach_init before cthread_init,
@@ -101,23 +116,16 @@ mig_init(initial)
/* recycle global reply port as this cthread's reply port */
multithreaded = TRUE;
- initial->reply_port = mig_reply_port;
+ ((cproc_t) initial)->reply_port = mig_reply_port;
mig_reply_port = MACH_PORT_NULL;
}
}
-void
-__mig_init (initial)
- register cproc_t initial;
-{
- mig_init (initial);
-}
-
/*
* Called by mig interface code whenever a reply port is needed.
*/
mach_port_t
-mig_get_reply_port()
+mig_get_reply_port(void)
{
register mach_port_t reply_port;
@@ -137,18 +145,13 @@ mig_get_reply_port()
return reply_port;
}
-mach_port_t
-__mig_get_reply_port()
-{
- return mig_get_reply_port();
-}
-
/*
* Called by mig interface code after a timeout on the reply port.
* May also be called by user.
*/
+/*ARGSUSED*/
void
-mig_dealloc_reply_port()
+mig_dealloc_reply_port(mach_port_t p)
{
register mach_port_t reply_port;
@@ -169,8 +172,45 @@ mig_dealloc_reply_port()
MACH_PORT_RIGHT_RECEIVE, -1);
}
+/*
+ * Called by mig interfaces when done with a port.
+ * Used to provide the same interface as needed when a custom
+ * allocator is used.
+ */
+
+/*ARGSUSED*/
+void
+mig_put_reply_port(mach_port_t port)
+{
+ /* Do nothing */
+}
+
+void
+__mig_init(register void *initial)
+{
+ mig_init (initial);
+}
+
+mach_port_t
+__mig_get_reply_port(void)
+{
+ return mig_get_reply_port();
+}
+
+void
+__mig_dealloc_reply_port(mach_port_t p)
+{
+ mig_dealloc_reply_port(p);
+}
+
+void
+__mig_put_reply_port(mach_port_t port)
+{
+ mig_put_reply_port(port);
+}
+
void
-__mig_dealloc_reply_port ()
+__mig_dealloc_reply_port (void)
{
mig_dealloc_reply_port ();
}
diff --git a/libthreads/sync.c b/libthreads/sync.c
index e17280aa..d65eb654 100644
--- a/libthreads/sync.c
+++ b/libthreads/sync.c
@@ -1,6 +1,6 @@
/*
* 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
@@ -26,6 +26,10 @@
/*
* HISTORY
* $Log: sync.c,v $
+ * Revision 2.8 93/01/14 18:06:23 danner
+ * Converted file to ANSI C.
+ * [92/12/18 pds]
+ *
* Revision 2.7 92/03/06 14:09:59 rpd
* Replaced swtch_pri with yield.
* [92/03/06 rpd]
@@ -69,8 +73,7 @@
int cthread_spin_count=0;
void
-spin_lock_solid(p)
- register spin_lock_t *p;
+spin_lock_solid(register spin_lock_t *p)
{
while (spin_lock_locked(p) || !spin_try_lock(p)) {
#ifdef STATISTICS