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