]> git.saurik.com Git - apple/libc.git/blob - threads.subproj/cthreads.c
Libc-166.tar.gz
[apple/libc.git] / threads.subproj / cthreads.c
1 /*
2 * Copyright (c) 1999 Apple Computer, Inc. All rights reserved.
3 *
4 * @APPLE_LICENSE_HEADER_START@
5 *
6 * The contents of this file constitute Original Code as defined in and
7 * are subject to the Apple Public Source License Version 1.1 (the
8 * "License"). You may not use this file except in compliance with the
9 * License. Please obtain a copy of the License at
10 * http://www.apple.com/publicsource and read it before using this file.
11 *
12 * This Original Code and all software distributed under the License are
13 * distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY KIND, EITHER
14 * EXPRESS OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES,
15 * INCLUDING WITHOUT LIMITATION, ANY WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE OR NON-INFRINGEMENT. Please see the
17 * License for the specific language governing rights and limitations
18 * under the License.
19 *
20 * @APPLE_LICENSE_HEADER_END@
21 */
22 /*
23 * cthreads.c - by Eric Cooper
24 *
25 * Implementation of cthread_fork, cthread_join, cthread_exit, etc.
26 * HISTORY
27 * 22-July-93 Blaine Garst
28 * fixed association of read_thread info
29 * fixed kernel cache set up of cproc info
30 *
31 */
32 #include <stdlib.h>
33 #include "cthreads.h"
34 #include "cthread_internals.h"
35 #include "pthread_internals.h"
36 /*
37 * C Threads imports:
38 */
39 extern void cproc_init();
40 extern thread_port_t cproc_create();
41 extern void mig_init();
42 extern void _pthread_set_self(pthread_t);
43
44 /*
45 * Mach imports:
46 */
47 extern void mig_fork_child();
48
49 /*
50 * C library imports:
51 */
52 extern int _setjmp(jmp_buf env);
53 extern void _longjmp(jmp_buf env, int val);
54
55 /*
56 * Thread status bits.
57 */
58 #define T_MAIN 0x1
59 #define T_RETURNED 0x2
60 #define T_DETACHED 0x4
61
62 #ifdef CTHREADS_DEBUG
63 int cthread_debug = FALSE;
64 #endif CTHREADS_DEBUG
65
66 /*
67 * Routines for supporting fork() of multi-threaded programs.
68 */
69
70
71 extern void _malloc_fork_prepare(), _malloc_fork_parent();
72 extern void _malloc_fork_child();
73 extern void _cproc_fork_child(), _stack_fork_child();
74 extern void _lu_fork_child(void);
75 extern void _pthread_fork_child(void);
76
77 static pthread_t psaved_self = 0;
78 static pthread_lock_t psaved_self_global_lock = LOCK_INITIALIZER;
79
80 void _cthread_fork_prepare()
81 /*
82 * Prepare cthreads library to fork() a multi-threaded program. All cthread
83 * library critical section locks are acquired before a fork() and released
84 * afterwards to insure no cthread data structure is left in an inconsistent
85 * state in the child, which comes up with only the forking thread running.
86 */
87 {
88 _spin_lock(&psaved_self_global_lock);
89 psaved_self = pthread_self();
90 _spin_lock(&psaved_self->lock);
91 _malloc_fork_prepare();
92 }
93
94 void _cthread_fork_parent()
95 /*
96 * Called in the parent process after a fork syscall.
97 * Releases locks acquired by cthread_fork_prepare().
98 */
99 {
100 _malloc_fork_parent();
101 _spin_unlock(&psaved_self->lock);
102 _spin_unlock(&psaved_self_global_lock);
103
104 }
105
106 void _cthread_fork_child()
107 /*
108 * Called in the child process after a fork syscall. Releases locks acquired
109 * by cthread_fork_prepare(). Deallocates cthread data structures which
110 * described other threads in our parent. Makes this thread the main thread.
111 *
112 * The mach_init() routine must be called in the child before this routine.
113 */
114 {
115 pthread_t p = psaved_self;
116
117 _pthread_set_self(p);
118 _spin_unlock(&psaved_self_global_lock);
119 mig_fork_child();
120 _malloc_fork_child();
121 p->kernel_thread = mach_thread_self();
122 p->reply_port = MACH_PORT_NULL;
123 p->mutexes = NULL;
124 p->cleanup_stack = NULL;
125 p->death = MACH_PORT_NULL;
126 p->joiners = MACH_PORT_NULL;
127 p->num_joiners = 0;
128 p->detached = _PTHREAD_CREATE_PARENT;
129 _spin_unlock(&p->lock);
130
131 _cproc_fork_child();
132
133 _lu_fork_child();
134
135 _pthread_fork_child();
136
137 __is_threaded = 0;
138 mig_init(1); /* enable multi-threaded mig interfaces */
139
140 }
141