Deleted Added
full compact
thr_create.c (144921) thr_create.c (145436)
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/libthr/thread/thr_create.c 144921 2005-04-12 03:00:28Z davidxu $
33 * $FreeBSD: head/lib/libthr/thread/thr_create.c 145436 2005-04-23 02:48:59Z davidxu $
34 */
35
36#include <errno.h>
37#include <stdlib.h>
38#include <string.h>
39#include <stddef.h>
40#include <pthread.h>
41#include <sys/signalvar.h>

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

48static void thread_start(struct pthread *curthread);
49
50__weak_reference(_pthread_create, pthread_create);
51
52int
53_pthread_create(pthread_t * thread, const pthread_attr_t * attr,
54 void *(*start_routine) (void *), void *arg)
55{
34 */
35
36#include <errno.h>
37#include <stdlib.h>
38#include <string.h>
39#include <stddef.h>
40#include <pthread.h>
41#include <sys/signalvar.h>

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

48static void thread_start(struct pthread *curthread);
49
50__weak_reference(_pthread_create, pthread_create);
51
52int
53_pthread_create(pthread_t * thread, const pthread_attr_t * attr,
54 void *(*start_routine) (void *), void *arg)
55{
56 ucontext_t uc;
57 sigset_t sigmask, oldsigmask;
58 struct pthread *curthread, *new_thread;
56 struct pthread *curthread, *new_thread;
57 struct thr_param param;
59 int ret = 0, locked;
60
61 _thr_check_init();
62
63 /*
64 * Tell libc and others now they need lock to protect their data.
65 */
66 if (_thr_isthreaded() == 0 && _thr_setthreaded(1))
67 return (EAGAIN);
68
69 curthread = _get_curthread();
70 if ((new_thread = _thr_alloc(curthread)) == NULL)
71 return (EAGAIN);
72
58 int ret = 0, locked;
59
60 _thr_check_init();
61
62 /*
63 * Tell libc and others now they need lock to protect their data.
64 */
65 if (_thr_isthreaded() == 0 && _thr_setthreaded(1))
66 return (EAGAIN);
67
68 curthread = _get_curthread();
69 if ((new_thread = _thr_alloc(curthread)) == NULL)
70 return (EAGAIN);
71
72 memset(&param, 0, sizeof(param));
73
73 if (attr == NULL || *attr == NULL)
74 /* Use the default thread attributes: */
75 new_thread->attr = _pthread_attr_default;
76 else
77 new_thread->attr = *(*attr);
78 if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) {
79 /* inherit scheduling contention scope */
80 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)

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

103 * Write a magic value to the thread structure
104 * to help identify valid ones:
105 */
106 new_thread->magic = THR_MAGIC;
107 new_thread->start_routine = start_routine;
108 new_thread->arg = arg;
109 new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
110 PTHREAD_CANCEL_DEFERRED;
74 if (attr == NULL || *attr == NULL)
75 /* Use the default thread attributes: */
76 new_thread->attr = _pthread_attr_default;
77 else
78 new_thread->attr = *(*attr);
79 if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) {
80 /* inherit scheduling contention scope */
81 if (curthread->attr.flags & PTHREAD_SCOPE_SYSTEM)

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

104 * Write a magic value to the thread structure
105 * to help identify valid ones:
106 */
107 new_thread->magic = THR_MAGIC;
108 new_thread->start_routine = start_routine;
109 new_thread->arg = arg;
110 new_thread->cancelflags = PTHREAD_CANCEL_ENABLE |
111 PTHREAD_CANCEL_DEFERRED;
111 getcontext(&uc);
112 SIGFILLSET(uc.uc_sigmask);
113 uc.uc_stack.ss_sp = new_thread->attr.stackaddr_attr;
114 uc.uc_stack.ss_size = new_thread->attr.stacksize_attr;
115 makecontext(&uc, (void (*)(void))thread_start, 1, new_thread);
116
117 /*
118 * Check if this thread is to inherit the scheduling
119 * attributes from its parent:
120 */
121 if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) {
122 /*
123 * Copy the scheduling attributes. Lock the scheduling
124 * lock to get consistent scheduling parameters.

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

141 /* Initialize the mutex queue: */
142 TAILQ_INIT(&new_thread->mutexq);
143 TAILQ_INIT(&new_thread->pri_mutexq);
144
145 /* Initialise hooks in the thread structure: */
146 if (new_thread->attr.suspend == THR_CREATE_SUSPENDED)
147 new_thread->flags = THR_FLAGS_SUSPENDED;
148 new_thread->state = PS_RUNNING;
112 /*
113 * Check if this thread is to inherit the scheduling
114 * attributes from its parent:
115 */
116 if (new_thread->attr.sched_inherit == PTHREAD_INHERIT_SCHED) {
117 /*
118 * Copy the scheduling attributes. Lock the scheduling
119 * lock to get consistent scheduling parameters.

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

136 /* Initialize the mutex queue: */
137 TAILQ_INIT(&new_thread->mutexq);
138 TAILQ_INIT(&new_thread->pri_mutexq);
139
140 /* Initialise hooks in the thread structure: */
141 if (new_thread->attr.suspend == THR_CREATE_SUSPENDED)
142 new_thread->flags = THR_FLAGS_SUSPENDED;
143 new_thread->state = PS_RUNNING;
149 /*
150 * Thread created by thr_create() inherits currrent thread
151 * sigmask, however, before new thread setup itself correctly,
152 * it can not handle signal, so we should masks all signals here.
153 */
154 SIGFILLSET(sigmask);
155 SIGDELSET(sigmask, SIGTRAP);
156 __sys_sigprocmask(SIG_SETMASK, &sigmask, &oldsigmask);
157 new_thread->sigmask = oldsigmask;
144
158 /* Add the new thread. */
159 _thr_link(curthread, new_thread);
160 /* Return thread pointer eariler so that new thread can use it. */
161 (*thread) = new_thread;
162 if (SHOULD_REPORT_EVENT(curthread, TD_CREATE)) {
163 THR_THREAD_LOCK(curthread, new_thread);
164 locked = 1;
165 } else
166 locked = 0;
145 /* Add the new thread. */
146 _thr_link(curthread, new_thread);
147 /* Return thread pointer eariler so that new thread can use it. */
148 (*thread) = new_thread;
149 if (SHOULD_REPORT_EVENT(curthread, TD_CREATE)) {
150 THR_THREAD_LOCK(curthread, new_thread);
151 locked = 1;
152 } else
153 locked = 0;
154 param.start_func = (void (*)(void *)) thread_start;
155 param.arg = new_thread;
156 param.stack_base = new_thread->attr.stackaddr_attr;
157 param.stack_size = new_thread->attr.stacksize_attr;
158 param.tls_base = (char *)new_thread->tcb;
159 param.tls_size = sizeof(struct tcb);
160 param.child_tid = &new_thread->tid;
161 param.parent_tid = &new_thread->tid;
162 param.flags = 0;
163 if (new_thread->attr.flags & PTHREAD_SCOPE_SYSTEM)
164 param.flags |= THR_SYSTEM_SCOPE;
167 /* Schedule the new thread. */
165 /* Schedule the new thread. */
168 ret = thr_create(&uc, &new_thread->tid, 0);
169 __sys_sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
166 ret = thr_new(&param, sizeof(param));
170 if (ret != 0) {
171 if (locked)
172 THR_THREAD_UNLOCK(curthread, new_thread);
173 _thr_unlink(curthread, new_thread);
174 free_thread(curthread, new_thread);
175 (*thread) = 0;
176 ret = EAGAIN;
177 } else if (locked) {

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

214 _thr_stack_free(pattr);
215 THREAD_LIST_UNLOCK(curthread);
216 }
217}
218
219static void
220thread_start(struct pthread *curthread)
221{
167 if (ret != 0) {
168 if (locked)
169 THR_THREAD_UNLOCK(curthread, new_thread);
170 _thr_unlink(curthread, new_thread);
171 free_thread(curthread, new_thread);
172 (*thread) = 0;
173 ret = EAGAIN;
174 } else if (locked) {

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

211 _thr_stack_free(pattr);
212 THREAD_LIST_UNLOCK(curthread);
213 }
214}
215
216static void
217thread_start(struct pthread *curthread)
218{
222 _tcb_set(curthread->tcb);
223
224 /* Thread was created with all signals blocked, unblock them. */
225 __sys_sigprocmask(SIG_SETMASK, &curthread->sigmask, NULL);
226
227 if (curthread->flags & THR_FLAGS_NEED_SUSPEND)
228 _thr_suspend_check(curthread);
229
230 THR_LOCK(curthread);
231 THR_UNLOCK(curthread);
232
233 /* Run the current thread's start routine with argument: */
234 pthread_exit(curthread->start_routine(curthread->arg));
235
236 /* This point should never be reached. */
237 PANIC("Thread has resumed after exit");
238}
219 if (curthread->flags & THR_FLAGS_NEED_SUSPEND)
220 _thr_suspend_check(curthread);
221
222 THR_LOCK(curthread);
223 THR_UNLOCK(curthread);
224
225 /* Run the current thread's start routine with argument: */
226 pthread_exit(curthread->start_routine(curthread->arg));
227
228 /* This point should never be reached. */
229 PANIC("Thread has resumed after exit");
230}