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} |