1 |
/* |
/* |
2 |
* Mach Operating System |
* Mach Operating System |
3 |
* Copyright (c) 1991,1990,1989 Carnegie Mellon University |
* Copyright (c) 1993-1989 Carnegie Mellon University |
4 |
* All Rights Reserved. |
* All Rights Reserved. |
5 |
* |
* |
6 |
* Permission to use, copy, modify and distribute this software and its |
* Permission to use, copy, modify and distribute this software and its |
25 |
*/ |
*/ |
26 |
/* |
/* |
27 |
* HISTORY |
* HISTORY |
28 |
* $Log$ |
* 26-Oct-94 Johannes Helander (jvh) Helsinki University of Technology |
29 |
* Revision 1.15 2002/05/08 09:37:04 roland |
* Set the wait_type field. |
|
* 2002-05-08 Roland McGrath <roland@frob.com> |
|
|
* |
|
|
* * cthread_internals.h: int -> void * for `busy' member. |
|
|
* * cprocs.c (cthread_mach_msg): Don't cast to int when setting it. |
|
|
* * cprocs.c (cthread_mag_active): Likewise. |
|
|
* |
|
|
* Revision 1.14 2002/05/08 09:32:11 roland |
|
|
* 2002-05-07 Roland McGrath <roland@frob.com> |
|
30 |
* |
* |
31 |
* * cprocs.c (cproc_list_lock): Declare type as spin_lock_t. |
* $Log$ |
32 |
* |
* Revision 1.16 2002/05/27 02:50:10 roland |
33 |
* Revision 1.13 2001/03/31 23:01:01 roland |
* 2002-05-26 Roland McGrath <roland@frob.com> |
|
* 2001-03-31 Roland McGrath <roland@frob.com> |
|
34 |
* |
* |
35 |
* * cthreads.h: Fix obsolescent #endif syntax. |
* Changes merged from CMU MK83a version: |
36 |
* * cthread_internals.h: Likewise. |
* * cthreads.h, options.h: Various cleanups. |
37 |
* * cancel-cond.c: Likewise. |
* * call.c, cthread_data.c, sync.c, mig_support.c: Likewise. |
38 |
* * stack.c: Likewise. |
* * i386/cthreads.h, i386/thread.c, i386/lock.s: Likewise. |
39 |
|
* * cthread_internals.h: Add decls for internal functions. |
40 |
|
* (struct cproc): Use vm_offset_t for stack_base and stack_size members. |
41 |
|
* Use natural_t for context member. |
42 |
|
* * cprocs.c: Use prototypes for all defns. |
43 |
* * cthreads.c: Likewise. |
* * cthreads.c: Likewise. |
44 |
* * cprocs.c: Likewise. |
* (cthread_exit): Cast any_t to integer_t before int. |
|
* * 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. |
|
45 |
* |
* |
46 |
* Revision 1.3 1994/05/19 04:55:30 roland |
* Revision 2.18 93/03/09 10:59:10 danner |
47 |
* entered into RCS |
* Lint. |
48 |
|
* [93/03/06 af] |
49 |
|
* |
50 |
|
* Revision 2.17 93/01/19 08:55:44 danner |
51 |
|
* Added missing spin_lock_t type from cproc_list_lock decl. |
52 |
|
* [92/12/30 af] |
53 |
|
* |
54 |
|
* |
55 |
|
* Revision 2.16 93/01/14 18:04:46 danner |
56 |
|
* Convert file to ANSI C. |
57 |
|
* [92/12/18 pds] |
58 |
|
* 64bit cleanup. |
59 |
|
* [92/12/10 21:08:32 af] |
60 |
* |
* |
61 |
* Revision 2.15 92/03/06 14:09:31 rpd |
* Revision 2.15 92/03/06 14:09:31 rpd |
62 |
* Replaced swtch_pri with yield. |
* Replaced swtch_pri with yield. |
236 |
#include <assert.h> |
#include <assert.h> |
237 |
|
|
238 |
/* |
/* |
|
* 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(); |
|
|
|
|
|
/* |
|
239 |
* Port_entry's are used by cthread_mach_msg to store information |
* Port_entry's are used by cthread_mach_msg to store information |
240 |
* about each port/port_set for which it is managing threads |
* about each port/port_set for which it is managing threads |
241 |
*/ |
*/ |
315 |
* Return current value for max kernel threads |
* Return current value for max kernel threads |
316 |
* Note: 0 means no limit |
* Note: 0 means no limit |
317 |
*/ |
*/ |
318 |
|
int |
319 |
cthread_kernel_limit() |
cthread_kernel_limit(void) |
320 |
{ |
{ |
321 |
return cthread_max_kernel_threads; |
return cthread_max_kernel_threads; |
322 |
} |
} |
327 |
* over maximum. |
* over maximum. |
328 |
*/ |
*/ |
329 |
|
|
330 |
cthread_set_kernel_limit(n) |
void |
331 |
int n; |
cthread_set_kernel_limit(int n) |
332 |
{ |
{ |
333 |
cthread_max_kernel_threads = n; |
cthread_max_kernel_threads = n; |
334 |
} |
} |
337 |
* Wire a cthread to its current kernel thread |
* Wire a cthread to its current kernel thread |
338 |
*/ |
*/ |
339 |
|
|
340 |
void cthread_wire() |
void |
341 |
|
cthread_wire(void) |
342 |
{ |
{ |
343 |
register cproc_t p = cproc_self(); |
register cproc_t p = cproc_self(); |
344 |
kern_return_t r; |
kern_return_t r; |
351 |
* Unwire a cthread. Deallocate its wait port. |
* Unwire a cthread. Deallocate its wait port. |
352 |
*/ |
*/ |
353 |
|
|
354 |
void cthread_unwire() |
void |
355 |
|
cthread_unwire(void) |
356 |
{ |
{ |
357 |
register cproc_t p = cproc_self(); |
register cproc_t p = cproc_self(); |
358 |
|
|
375 |
} |
} |
376 |
|
|
377 |
private cproc_t |
private cproc_t |
378 |
cproc_alloc() |
cproc_alloc(void) |
379 |
{ |
{ |
380 |
register cproc_t p = (cproc_t) malloc(sizeof(struct cproc)); |
register cproc_t p = (cproc_t) malloc(sizeof(struct cproc)); |
381 |
kern_return_t r; |
kern_return_t r; |
425 |
*/ |
*/ |
426 |
|
|
427 |
vm_offset_t |
vm_offset_t |
428 |
cproc_init() |
cproc_init(void) |
429 |
{ |
{ |
430 |
kern_return_t r; |
kern_return_t r; |
431 |
|
|
462 |
* synching on its lock. Just send message to wired cproc. |
* synching on its lock. Just send message to wired cproc. |
463 |
*/ |
*/ |
464 |
|
|
465 |
private int cproc_ready(p, preq) |
private boolean_t cproc_ready(register cproc_t p, register int preq) |
|
register cproc_t p; |
|
|
register int preq; |
|
466 |
{ |
{ |
467 |
register cproc_t s=cproc_self(); |
register cproc_t s=cproc_self(); |
468 |
kern_return_t r; |
kern_return_t r; |
543 |
*/ |
*/ |
544 |
|
|
545 |
void |
void |
546 |
cproc_waiting(p) |
cproc_waiting(cproc_t p) |
|
register cproc_t p; |
|
547 |
{ |
{ |
548 |
mach_msg_header_t msg; |
mach_msg_header_t msg; |
549 |
register cproc_t new; |
register cproc_t new; |
590 |
* |
* |
591 |
*/ |
*/ |
592 |
|
|
593 |
cproc_t |
private cproc_t |
594 |
cproc_waiter() |
cproc_waiter(void) |
595 |
{ |
{ |
596 |
register cproc_t waiter; |
register cproc_t waiter; |
597 |
|
|
623 |
* You must hold cproc_self()->lock when called. |
* You must hold cproc_self()->lock when called. |
624 |
*/ |
*/ |
625 |
|
|
626 |
cproc_block() |
private void |
627 |
|
cproc_block(void) |
628 |
{ |
{ |
629 |
extern unsigned int __hurd_threadvar_max; /* GNU */ |
extern unsigned int __hurd_threadvar_max; /* GNU */ |
630 |
register cproc_t waiter, new, p = cproc_self(); |
register cproc_t waiter, new, p = cproc_self(); |
712 |
* Implement C threads using MACH threads. |
* Implement C threads using MACH threads. |
713 |
*/ |
*/ |
714 |
cproc_t |
cproc_t |
715 |
cproc_create() |
cproc_create(void) |
716 |
{ |
{ |
717 |
register cproc_t child = cproc_alloc(); |
register cproc_t child = cproc_alloc(); |
718 |
register kern_return_t r; |
register kern_return_t r; |
762 |
} |
} |
763 |
|
|
764 |
void |
void |
765 |
condition_wait(c, m) |
condition_wait(condition_t c, mutex_t m) |
|
register condition_t c; |
|
|
mutex_t m; |
|
766 |
{ |
{ |
767 |
register cproc_t p = cproc_self(); |
register cproc_t p = cproc_self(); |
768 |
|
|
832 |
/* Signal one waiter on C. If there were no waiters at all, return |
/* Signal one waiter on C. If there were no waiters at all, return |
833 |
0, else return 1. */ |
0, else return 1. */ |
834 |
int |
int |
835 |
cond_signal(c) |
cond_signal(condition_t c) |
|
register condition_t c; |
|
836 |
{ |
{ |
837 |
register cproc_t p; |
register cproc_t p; |
838 |
struct cond_imp *imp; |
struct cond_imp *imp; |
853 |
} |
} |
854 |
|
|
855 |
void |
void |
856 |
cond_broadcast(c) |
cond_broadcast(condition_t c) |
|
register condition_t c; |
|
857 |
{ |
{ |
858 |
register cproc_t p; |
register cproc_t p; |
859 |
struct cthread_queue blocked_queue; |
struct cthread_queue blocked_queue; |
884 |
} |
} |
885 |
|
|
886 |
void |
void |
887 |
cthread_yield() |
cthread_yield(void) |
888 |
{ |
{ |
889 |
register cproc_t new, p = cproc_self(); |
register cproc_t new, p = cproc_self(); |
890 |
|
|
993 |
* call to occur as often as is possible. |
* call to occur as often as is possible. |
994 |
*/ |
*/ |
995 |
|
|
996 |
private port_entry_t get_port_entry(port, min, max) |
private port_entry_t |
997 |
mach_port_t port; |
get_port_entry(mach_port_t port, int min, int max) |
998 |
{ |
{ |
999 |
register port_entry_t i; |
register port_entry_t i; |
1000 |
|
|
1017 |
return i; |
return i; |
1018 |
} |
} |
1019 |
|
|
1020 |
cthread_msg_busy(port, min, max) |
void |
1021 |
mach_port_t port; |
cthread_msg_busy(mach_port_t port, int min, int max) |
1022 |
{ |
{ |
1023 |
register port_entry_t port_entry; |
register port_entry_t port_entry; |
1024 |
register cproc_t new, p = cproc_self(); |
register cproc_t new, p = cproc_self(); |
1049 |
|
|
1050 |
} |
} |
1051 |
|
|
1052 |
cthread_msg_active(port, min, max) |
void |
1053 |
mach_port_t port; |
cthread_msg_active(mach_port_t port, int min, int max) |
1054 |
{ |
{ |
1055 |
register cproc_t p = cproc_self(); |
register cproc_t p = cproc_self(); |
1056 |
register port_entry_t port_entry; |
register port_entry_t port_entry; |
1068 |
} |
} |
1069 |
|
|
1070 |
mach_msg_return_t |
mach_msg_return_t |
1071 |
cthread_mach_msg(header, option, |
cthread_mach_msg(register mach_msg_header_t *header, |
1072 |
send_size, rcv_size, rcv_name, |
register mach_msg_option_t option, mach_msg_size_t send_size, |
1073 |
timeout, notify, min, max) |
mach_msg_size_t rcv_size, register mach_port_t rcv_name, |
1074 |
register mach_msg_header_t *header; |
mach_msg_timeout_t timeout, mach_port_t notify, int min, |
1075 |
register mach_msg_option_t option; |
int max) |
|
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; |
|
1076 |
{ |
{ |
1077 |
register port_entry_t port_entry; |
register port_entry_t port_entry; |
1078 |
register cproc_t p = cproc_self(); |
register cproc_t p = cproc_self(); |
1131 |
return r; |
return r; |
1132 |
} |
} |
1133 |
|
|
1134 |
cproc_fork_prepare() |
void |
1135 |
|
cproc_fork_prepare(void) |
1136 |
{ |
{ |
1137 |
register cproc_t p = cproc_self(); |
register cproc_t p = cproc_self(); |
1138 |
|
|
1141 |
spin_lock(&cproc_list_lock); |
spin_lock(&cproc_list_lock); |
1142 |
} |
} |
1143 |
|
|
1144 |
cproc_fork_parent() |
void |
1145 |
|
cproc_fork_parent(void) |
1146 |
{ |
{ |
1147 |
register cproc_t p = cproc_self(); |
register cproc_t p = cproc_self(); |
1148 |
|
|
1151 |
vm_inherit(mach_task_self(),p->stack_base, p->stack_size, VM_INHERIT_NONE); |
vm_inherit(mach_task_self(),p->stack_base, p->stack_size, VM_INHERIT_NONE); |
1152 |
} |
} |
1153 |
|
|
1154 |
cproc_fork_child() |
void |
1155 |
|
cproc_fork_child(void) |
1156 |
{ |
{ |
1157 |
register cproc_t l,p = cproc_self(); |
register cproc_t l,p = cproc_self(); |
1158 |
cproc_t m; |
cproc_t m; |