Deleted Added
full compact
thr_create.c (116974) thr_create.c (117706)
1/*
2 * Copyright (c) 2003 Daniel M. Eischen <deischen@gdeb.com>
3 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 16 unchanged lines hidden (view full) ---

25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
1/*
2 * Copyright (c) 2003 Daniel M. Eischen <deischen@gdeb.com>
3 * Copyright (c) 1995-1998 John Birrell <jb@cimlogic.com.au>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:

--- 16 unchanged lines hidden (view full) ---

25 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
26 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
27 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
28 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
29 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
30 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
31 * SUCH DAMAGE.
32 *
33 * $FreeBSD: head/lib/libkse/thread/thr_create.c 116974 2003-06-28 09:41:59Z davidxu $
33 * $FreeBSD: head/lib/libkse/thread/thr_create.c 117706 2003-07-17 23:02:30Z davidxu $
34 */
35#include <errno.h>
36#include <stdlib.h>
37#include <string.h>
38#include <fcntl.h>
39#include <unistd.h>
40#include <stddef.h>
41#include <sys/time.h>

--- 10 unchanged lines hidden (view full) ---

52int _thread_ctx_offset = OFF(tmbx.tm_context);
53#undef OFF
54
55int _thread_PS_RUNNING_value = PS_RUNNING;
56int _thread_PS_DEAD_value = PS_DEAD;
57
58static void free_thread(struct pthread *curthread, struct pthread *thread);
59static int create_stack(struct pthread_attr *pattr);
34 */
35#include <errno.h>
36#include <stdlib.h>
37#include <string.h>
38#include <fcntl.h>
39#include <unistd.h>
40#include <stddef.h>
41#include <sys/time.h>

--- 10 unchanged lines hidden (view full) ---

52int _thread_ctx_offset = OFF(tmbx.tm_context);
53#undef OFF
54
55int _thread_PS_RUNNING_value = PS_RUNNING;
56int _thread_PS_DEAD_value = PS_DEAD;
57
58static void free_thread(struct pthread *curthread, struct pthread *thread);
59static int create_stack(struct pthread_attr *pattr);
60static void free_stack(struct pthread_attr *pattr);
60static void thread_start(struct pthread *curthread,
61 void *(*start_routine) (void *), void *arg);
62
63__weak_reference(_pthread_create, pthread_create);
64
65/*
66 * Some notes on new thread creation and first time initializion
67 * to enable multi-threading.

--- 18 unchanged lines hidden (view full) ---

86 * enabled on the initial thread's KSE, they must be now that
87 * there is more than one thread; this could be delayed until
88 * the initial KSEG has more than one thread.
89 */
90int
91_pthread_create(pthread_t * thread, const pthread_attr_t * attr,
92 void *(*start_routine) (void *), void *arg)
93{
61static void thread_start(struct pthread *curthread,
62 void *(*start_routine) (void *), void *arg);
63
64__weak_reference(_pthread_create, pthread_create);
65
66/*
67 * Some notes on new thread creation and first time initializion
68 * to enable multi-threading.

--- 18 unchanged lines hidden (view full) ---

87 * enabled on the initial thread's KSE, they must be now that
88 * there is more than one thread; this could be delayed until
89 * the initial KSEG has more than one thread.
90 */
91int
92_pthread_create(pthread_t * thread, const pthread_attr_t * attr,
93 void *(*start_routine) (void *), void *arg)
94{
94 struct kse *curkse;
95 struct pthread *curthread, *new_thread;
96 struct kse *kse = NULL;
97 struct kse_group *kseg = NULL;
98 void *p;
99 kse_critical_t crit;
100 int i;
101 int ret = 0;
102

--- 24 unchanged lines hidden (view full) ---

127 new_thread->alloc_addr = p;
128
129 /* Check if default thread attributes are required: */
130 if (attr == NULL || *attr == NULL)
131 /* Use the default thread attributes: */
132 new_thread->attr = _pthread_attr_default;
133 else
134 new_thread->attr = *(*attr);
95 struct pthread *curthread, *new_thread;
96 struct kse *kse = NULL;
97 struct kse_group *kseg = NULL;
98 void *p;
99 kse_critical_t crit;
100 int i;
101 int ret = 0;
102

--- 24 unchanged lines hidden (view full) ---

127 new_thread->alloc_addr = p;
128
129 /* Check if default thread attributes are required: */
130 if (attr == NULL || *attr == NULL)
131 /* Use the default thread attributes: */
132 new_thread->attr = _pthread_attr_default;
133 else
134 new_thread->attr = *(*attr);
135
135#ifdef SYSTEM_SCOPE_ONLY
136 new_thread->attr.flags |= PTHREAD_SCOPE_SYSTEM;
137#endif
136 if (create_stack(&new_thread->attr) != 0) {
137 /* Insufficient memory to create a stack: */
138 ret = EAGAIN;
139 _thr_free(curthread, new_thread);
140 }
141 else if (((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) &&
138 if (create_stack(&new_thread->attr) != 0) {
139 /* Insufficient memory to create a stack: */
140 ret = EAGAIN;
141 _thr_free(curthread, new_thread);
142 }
143 else if (((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) &&
142 (((kse = _kse_alloc(curthread)) == NULL)
144 (((kse = _kse_alloc(curthread, 1)) == NULL)
143 || ((kseg = _kseg_alloc(curthread)) == NULL))) {
144 /* Insufficient memory to create a new KSE/KSEG: */
145 ret = EAGAIN;
146 if (kse != NULL) {
147 kse->k_mbx.km_flags |= KMF_DONE;
148 _kse_free(curthread, kse);
149 }
145 || ((kseg = _kseg_alloc(curthread)) == NULL))) {
146 /* Insufficient memory to create a new KSE/KSEG: */
147 ret = EAGAIN;
148 if (kse != NULL) {
149 kse->k_mbx.km_flags |= KMF_DONE;
150 _kse_free(curthread, kse);
151 }
150 if ((new_thread->attr.flags & THR_STACK_USER) == 0) {
151 crit = _kse_critical_enter();
152 curkse = _get_curkse();
153 KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock);
154 /* Stack routines don't use malloc/free. */
155 _thr_stack_free(&new_thread->attr);
156 KSE_LOCK_RELEASE(curkse, &_thread_list_lock);
157 _kse_critical_leave(crit);
158 }
152 free_stack(&new_thread->attr);
159 _thr_free(curthread, new_thread);
160 }
161 else {
162 if (kseg != NULL) {
163 /* Add the KSE to the KSEG's list of KSEs. */
164 TAILQ_INSERT_HEAD(&kseg->kg_kseq, kse, k_kgqe);
165 kseg->kg_ksecount = 1;
166 kse->k_kseg = kseg;

--- 6 unchanged lines hidden (view full) ---

173 new_thread->magic = THR_MAGIC;
174
175 new_thread->slice_usec = -1;
176 new_thread->start_routine = start_routine;
177 new_thread->arg = arg;
178 new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
179 PTHREAD_CANCEL_DEFERRED;
180
153 _thr_free(curthread, new_thread);
154 }
155 else {
156 if (kseg != NULL) {
157 /* Add the KSE to the KSEG's list of KSEs. */
158 TAILQ_INSERT_HEAD(&kseg->kg_kseq, kse, k_kgqe);
159 kseg->kg_ksecount = 1;
160 kse->k_kseg = kseg;

--- 6 unchanged lines hidden (view full) ---

167 new_thread->magic = THR_MAGIC;
168
169 new_thread->slice_usec = -1;
170 new_thread->start_routine = start_routine;
171 new_thread->arg = arg;
172 new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
173 PTHREAD_CANCEL_DEFERRED;
174
181 /* Initialize the thread for signals: */
182 new_thread->sigmask = curthread->sigmask;
183
184 /* No thread is wanting to join to this one: */
185 new_thread->joiner = NULL;
186
187 /* Initialize the signal frame: */
188 new_thread->curframe = NULL;
189
190 /*
191 * Initialize the machine context.
192 * Enter a critical region to get consistent context.
193 */
194 crit = _kse_critical_enter();
195 THR_GETCONTEXT(&new_thread->tmbx.tm_context);
175 /* No thread is wanting to join to this one: */
176 new_thread->joiner = NULL;
177
178 /* Initialize the signal frame: */
179 new_thread->curframe = NULL;
180
181 /*
182 * Initialize the machine context.
183 * Enter a critical region to get consistent context.
184 */
185 crit = _kse_critical_enter();
186 THR_GETCONTEXT(&new_thread->tmbx.tm_context);
187 /* Initialize the thread for signals: */
188 new_thread->sigmask = curthread->sigmask;
196 _kse_critical_leave(crit);
197 new_thread->tmbx.tm_udata = new_thread;
198 new_thread->tmbx.tm_context.uc_sigmask =
199 new_thread->sigmask;
200 new_thread->tmbx.tm_context.uc_stack.ss_size =
201 new_thread->attr.stacksize_attr;
202 new_thread->tmbx.tm_context.uc_stack.ss_sp =
203 new_thread->attr.stackaddr_attr;

--- 69 unchanged lines hidden (view full) ---

273 * off the main process kseg.
274 */
275 if ((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) {
276 new_thread->kseg = _kse_initial->k_kseg;
277 new_thread->kse = _kse_initial;
278 }
279 else {
280 kse->k_curthread = NULL;
189 _kse_critical_leave(crit);
190 new_thread->tmbx.tm_udata = new_thread;
191 new_thread->tmbx.tm_context.uc_sigmask =
192 new_thread->sigmask;
193 new_thread->tmbx.tm_context.uc_stack.ss_size =
194 new_thread->attr.stacksize_attr;
195 new_thread->tmbx.tm_context.uc_stack.ss_sp =
196 new_thread->attr.stackaddr_attr;

--- 69 unchanged lines hidden (view full) ---

266 * off the main process kseg.
267 */
268 if ((new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM) == 0) {
269 new_thread->kseg = _kse_initial->k_kseg;
270 new_thread->kse = _kse_initial;
271 }
272 else {
273 kse->k_curthread = NULL;
281#ifdef NOT_YET
282 kse->k_kseg->kg_flags |= KGF_SINGLE_THREAD;
274 kse->k_kseg->kg_flags |= KGF_SINGLE_THREAD;
283#endif
284 new_thread->kse = kse;
285 new_thread->kseg = kse->k_kseg;
286 kse->k_mbx.km_udata = kse;
287 kse->k_mbx.km_curthread = NULL;
288 }
289
290 /*
291 * Schedule the new thread starting a new KSEG/KSE

--- 11 unchanged lines hidden (view full) ---

303
304 /* Return the status: */
305 return (ret);
306}
307
308static void
309free_thread(struct pthread *curthread, struct pthread *thread)
310{
275 new_thread->kse = kse;
276 new_thread->kseg = kse->k_kseg;
277 kse->k_mbx.km_udata = kse;
278 kse->k_mbx.km_curthread = NULL;
279 }
280
281 /*
282 * Schedule the new thread starting a new KSEG/KSE

--- 11 unchanged lines hidden (view full) ---

294
295 /* Return the status: */
296 return (ret);
297}
298
299static void
300free_thread(struct pthread *curthread, struct pthread *thread)
301{
302 free_stack(&thread->attr);
311 if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) {
312 /* Free the KSE and KSEG. */
313 _kseg_free(thread->kseg);
314 _kse_free(curthread, thread->kse);
315 }
316 _thr_free(curthread, thread);
317}
318

--- 8 unchanged lines hidden (view full) ---

327 pattr->flags |= THR_STACK_USER;
328 ret = 0;
329 }
330 else
331 ret = _thr_stack_alloc(pattr);
332 return (ret);
333}
334
303 if ((thread->attr.flags & PTHREAD_SCOPE_SYSTEM) != 0) {
304 /* Free the KSE and KSEG. */
305 _kseg_free(thread->kseg);
306 _kse_free(curthread, thread->kse);
307 }
308 _thr_free(curthread, thread);
309}
310

--- 8 unchanged lines hidden (view full) ---

319 pattr->flags |= THR_STACK_USER;
320 ret = 0;
321 }
322 else
323 ret = _thr_stack_alloc(pattr);
324 return (ret);
325}
326
327static void
328free_stack(struct pthread_attr *pattr)
329{
330 struct kse *curkse;
331 kse_critical_t crit;
335
332
333 if ((pattr->flags & THR_STACK_USER) == 0) {
334 crit = _kse_critical_enter();
335 curkse = _get_curkse();
336 KSE_LOCK_ACQUIRE(curkse, &_thread_list_lock);
337 /* Stack routines don't use malloc/free. */
338 _thr_stack_free(pattr);
339 KSE_LOCK_RELEASE(curkse, &_thread_list_lock);
340 _kse_critical_leave(crit);
341 }
342}
343
336static void
337thread_start(struct pthread *curthread, void *(*start_routine) (void *),
338 void *arg)
339{
340 /* Run the current thread's start routine with argument: */
341 pthread_exit(start_routine(arg));
342
343 /* This point should never be reached. */
344 PANIC("Thread has resumed after exit");
345}
344static void
345thread_start(struct pthread *curthread, void *(*start_routine) (void *),
346 void *arg)
347{
348 /* Run the current thread's start routine with argument: */
349 pthread_exit(start_routine(arg));
350
351 /* This point should never be reached. */
352 PANIC("Thread has resumed after exit");
353}