1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20: #include <errno.h>
21: #include <stdbool.h>
22: #include <stdlib.h>
23: #include <string.h>
24: #include "pthreadP.h"
25: #include <hp-timing.h>
26: #include <ldsodefs.h>
27: #include <atomic.h>
28: #include <libc-internal.h>
29: #include <resolv.h>
30: #include <kernel-features.h>
31:
32: #include <shlib-compat.h>
33:
34:
35:
36: static int start_thread (void *arg);
37:
38:
39:
40: int __pthread_debug;
41:
42:
43: static td_thr_events_t __nptl_threads_events;
44:
45:
46: static struct pthread *__nptl_last_event;
47:
48:
49: unsigned int __nptl_nthreads = 1;
50:
51:
52:
53: #include "allocatestack.c"
54:
55:
56: #include <createthread.c>
57:
58:
59: struct pthread *
60: internal_function
61: __find_in_stack_list (pd)
62: struct pthread *pd;
63: {
64: list_t *entry;
65: struct pthread *result = NULL;
66:
67: lll_lock (stack_cache_lock, LLL_PRIVATE);
68:
69: list_for_each (entry, &stack_used)
70: {
71: struct pthread *curp;
72:
73: curp = list_entry (entry, struct pthread, list);
74: if (curp == pd)
75: {
76: result = curp;
77: break;
78: }
79: }
80:
81: if (result == NULL)
82: list_for_each (entry, &__stack_user)
83: {
84: struct pthread *curp;
85:
86: curp = list_entry (entry, struct pthread, list);
87: if (curp == pd)
88: {
89: result = curp;
90: break;
91: }
92: }
93:
94: lll_unlock (stack_cache_lock, LLL_PRIVATE);
95:
96: return result;
97: }
98:
99:
100:
101: void
102: attribute_hidden
103: __nptl_deallocate_tsd (void)
104: {
105: struct pthread *self = THREAD_SELF;
106:
107:
108:
109: if (THREAD_GETMEM (self, specific_used))
110: {
111: size_t round;
112: size_t cnt;
113:
114: round = 0;
115: do
116: {
117: size_t idx;
118:
119:
120: THREAD_SETMEM (self, specific_used, false);
121:
122: for (cnt = idx = 0; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
123: {
124: struct pthread_key_data *level2;
125:
126: level2 = THREAD_GETMEM_NC (self, specific, cnt);
127:
128: if (level2 != NULL)
129: {
130: size_t inner;
131:
132: for (inner = 0; inner < PTHREAD_KEY_2NDLEVEL_SIZE;
133: ++inner, ++idx)
134: {
135: void *data = level2[inner].data;
136:
137: if (data != NULL)
138: {
139:
140: level2[inner].data = NULL;
141:
142:
143:
144:
145:
146:
147:
148: if (level2[inner].seq
149: == __pthread_keys[idx].seq
150:
151:
152: && __pthread_keys[idx].destr != NULL)
153:
154: __pthread_keys[idx].destr (data);
155: }
156: }
157: }
158: else
159: idx += PTHREAD_KEY_1STLEVEL_SIZE;
160: }
161:
162: if (THREAD_GETMEM (self, specific_used) == 0)
163:
164: goto just_free;
165: }
166:
167: while (__builtin_expect (++round < PTHREAD_DESTRUCTOR_ITERATIONS, 0));
168:
169:
170: memset (&THREAD_SELF->specific_1stblock, '\0',
171: sizeof (self->specific_1stblock));
172:
173: just_free:
174:
175: for (cnt = 1; cnt < PTHREAD_KEY_1STLEVEL_SIZE; ++cnt)
176: {
177: struct pthread_key_data *level2;
178:
179: level2 = THREAD_GETMEM_NC (self, specific, cnt);
180: if (level2 != NULL)
181: {
182:
183:
184: free (level2);
185: THREAD_SETMEM_NC (self, specific, cnt, NULL);
186: }
187: }
188:
189: THREAD_SETMEM (self, specific_used, false);
190: }
191: }
192:
193:
194:
195:
196: void
197: internal_function
198: __free_tcb (struct pthread *pd)
199: {
200:
201: if (__builtin_expect (atomic_bit_test_set (&pd->cancelhandling,
202: TERMINATED_BIT) == 0, 1))
203: {
204:
205: if (DEBUGGING_P && __find_in_stack_list (pd) == NULL)
206:
207:
208: abort ();
209:
210:
211: if (__builtin_expect (pd->tpp != NULL, 0))
212: {
213: struct priority_protection_data *tpp = pd->tpp;
214:
215: pd->tpp = NULL;
216: free (tpp);
217: }
218:
219:
220:
221:
222: __deallocate_stack (pd);
223: }
224: }
225:
226:
227: static int
228: start_thread (void *arg)
229: {
230: struct pthread *pd = (struct pthread *) arg;
231:
232: #if HP_TIMING_AVAIL
233:
234: hp_timing_t now;
235: HP_TIMING_NOW (now);
236: THREAD_SETMEM (pd, cpuclock_offset, now);
237: #endif
238:
239:
240: __resp = &pd->res;
241:
242: #ifdef __NR_set_robust_list
243: # ifndef __ASSUME_SET_ROBUST_LIST
244: if (__set_robust_list_avail >= 0)
245: # endif
246: {
247: INTERNAL_SYSCALL_DECL (err);
248:
249:
250: INTERNAL_SYSCALL (set_robust_list, err, 2, &pd->robust_head,
251: sizeof (struct robust_list_head));
252: }
253: #endif
254:
255:
256:
257:
258: if (__builtin_expect (pd->parent_cancelhandling & CANCELING_BITMASK, 0))
259: {
260: INTERNAL_SYSCALL_DECL (err);
261: sigset_t mask;
262: __sigemptyset (&mask);
263: __sigaddset (&mask, SIGCANCEL);
264: (void) INTERNAL_SYSCALL (rt_sigprocmask, err, 4, SIG_UNBLOCK, &mask,
265: NULL, _NSIG / 8);
266: }
267:
268:
269:
270: struct pthread_unwind_buf unwind_buf;
271:
272:
273: unwind_buf.priv.data.prev = NULL;
274: unwind_buf.priv.data.cleanup = NULL;
275:
276: int not_first_call;
277: not_first_call = setjmp ((struct __jmp_buf_tag *) unwind_buf.cancel_jmp_buf);
278: if (__builtin_expect (! not_first_call, 1))
279: {
280:
281: THREAD_SETMEM (pd, cleanup_jmp_buf, &unwind_buf);
282:
283: if (__builtin_expect (pd->stopped_start, 0))
284: {
285: int oldtype = CANCEL_ASYNC ();
286:
287:
288: lll_lock (pd->lock, LLL_PRIVATE);
289:
290: lll_unlock (pd->lock, LLL_PRIVATE);
291:
292: CANCEL_RESET (oldtype);
293: }
294:
295:
296: #ifdef CALL_THREAD_FCT
297: THREAD_SETMEM (pd, result, CALL_THREAD_FCT (pd));
298: #else
299: THREAD_SETMEM (pd, result, pd->start_routine (pd->arg));
300: #endif
301: }
302:
303:
304: __nptl_deallocate_tsd ();
305:
306:
307: __libc_thread_freeres ();
308:
309:
310:
311:
312: if (__builtin_expect (atomic_decrement_and_test (&__nptl_nthreads), 0))
313:
314: exit (0);
315:
316:
317: if (__builtin_expect (pd->report_events, 0))
318: {
319:
320: const int idx = __td_eventword (TD_DEATH);
321: const uint32_t mask = __td_eventmask (TD_DEATH);
322:
323: if ((mask & (__nptl_threads_events.event_bits[idx]
324: | pd->eventbuf.eventmask.event_bits[idx])) != 0)
325: {
326:
327:
328: if (pd->nextevent == NULL)
329: {
330: pd->eventbuf.eventnum = TD_DEATH;
331: pd->eventbuf.eventdata = pd;
332:
333: do
334: pd->nextevent = __nptl_last_event;
335: while (atomic_compare_and_exchange_bool_acq (&__nptl_last_event,
336: pd, pd->nextevent));
337: }
338:
339:
340: __nptl_death_event ();
341: }
342: }
343:
344:
345:
346:
347: atomic_bit_set (&pd->cancelhandling, EXITING_BIT);
348:
349: #ifndef __ASSUME_SET_ROBUST_LIST
350:
351: # if __WORDSIZE == 64
352: void *robust = pd->robust_head.list;
353: # else
354: __pthread_slist_t *robust = pd->robust_list.__next;
355: # endif
356:
357:
358:
359: if (__set_robust_list_avail < 0
360: && __builtin_expect (robust != (void *) &pd->robust_head, 0))
361: {
362: do
363: {
364: struct __pthread_mutex_s *this = (struct __pthread_mutex_s *)
365: ((char *) robust - offsetof (struct __pthread_mutex_s,
366: __list.__next));
367: robust = *((void **) robust);
368:
369: # ifdef __PTHREAD_MUTEX_HAVE_PREV
370: this->__list.__prev = NULL;
371: # endif
372: this->__list.__next = NULL;
373:
374: lll_robust_dead (this->__lock, LLL_SHARED);
375: }
376: while (robust != (void *) &pd->robust_head);
377: }
378: #endif
379:
380:
381: if (IS_DETACHED (pd))
382:
383: __free_tcb (pd);
384: else if (__builtin_expect (pd->cancelhandling & SETXID_BITMASK, 0))
385: {
386:
387:
388: do
389: lll_futex_wait (&pd->setxid_futex, 0, LLL_PRIVATE);
390: while (pd->cancelhandling & SETXID_BITMASK);
391:
392:
393: pd->setxid_futex = 0;
394: }
395:
396:
397:
398:
399:
400:
401:
402:
403:
404: __exit_thread_inline (0);
405:
406:
407: return 0;
408: }
409:
410:
411:
412:
413: static const struct pthread_attr default_attr =
414: {
415:
416: .guardsize = 1,
417: };
418:
419:
420: int
421: __pthread_create_2_1 (newthread, attr, start_routine, arg)
422: pthread_t *newthread;
423: const pthread_attr_t *attr;
424: void *(*start_routine) (void *);
425: void *arg;
426: {
427: STACK_VARIABLES;
428:
429: const struct pthread_attr *iattr = (struct pthread_attr *) attr;
430: if (iattr == NULL)
431:
432:
433: iattr = &default_attr;
434:
435: struct pthread *pd = NULL;
436: int err = ALLOCATE_STACK (iattr, &pd);
437: if (__builtin_expect (err != 0, 0))
438:
439:
440: return err;
441:
442:
443:
444:
445:
446:
447: #ifdef TLS_TCB_AT_TP
448:
449: pd->header.self = pd;
450:
451:
452: pd->header.tcb = pd;
453: #endif
454:
455:
456:
457:
458: pd->start_routine = start_routine;
459: pd->arg = arg;
460:
461:
462: struct pthread *self = THREAD_SELF;
463: pd->flags = ((iattr->flags & ~(ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET))
464: | (self->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)));
465:
466:
467:
468:
469: pd->joinid = iattr->flags & ATTR_FLAG_DETACHSTATE ? pd : NULL;
470:
471:
472: pd->eventbuf = self->eventbuf;
473:
474:
475:
476:
477: pd->schedpolicy = self->schedpolicy;
478: pd->schedparam = self->schedparam;
479:
480:
481: #ifdef THREAD_COPY_STACK_GUARD
482: THREAD_COPY_STACK_GUARD (pd);
483: #endif
484:
485:
486: #ifdef THREAD_COPY_POINTER_GUARD
487: THREAD_COPY_POINTER_GUARD (pd);
488: #endif
489:
490:
491: if (attr != NULL
492: && __builtin_expect ((iattr->flags & ATTR_FLAG_NOTINHERITSCHED) != 0, 0)
493: && (iattr->flags & (ATTR_FLAG_SCHED_SET | ATTR_FLAG_POLICY_SET)) != 0)
494: {
495: INTERNAL_SYSCALL_DECL (scerr);
496:
497:
498: if (iattr->flags & ATTR_FLAG_POLICY_SET)
499: pd->schedpolicy = iattr->schedpolicy;
500: else if ((pd->flags & ATTR_FLAG_POLICY_SET) == 0)
501: {
502: pd->schedpolicy = INTERNAL_SYSCALL (sched_getscheduler, scerr, 1, 0);
503: pd->flags |= ATTR_FLAG_POLICY_SET;
504: }
505:
506: if (iattr->flags & ATTR_FLAG_SCHED_SET)
507: memcpy (&pd->schedparam, &iattr->schedparam,
508: sizeof (struct sched_param));
509: else if ((pd->flags & ATTR_FLAG_SCHED_SET) == 0)
510: {
511: INTERNAL_SYSCALL (sched_getparam, scerr, 2, 0, &pd->schedparam);
512: pd->flags |= ATTR_FLAG_SCHED_SET;
513: }
514:
515:
516: int minprio = INTERNAL_SYSCALL (sched_get_priority_min, scerr, 1,
517: iattr->schedpolicy);
518: int maxprio = INTERNAL_SYSCALL (sched_get_priority_max, scerr, 1,
519: iattr->schedpolicy);
520: if (pd->schedparam.sched_priority < minprio
521: || pd->schedparam.sched_priority > maxprio)
522: {
523: err = EINVAL;
524: goto errout;
525: }
526: }
527:
528:
529: *newthread = (pthread_t) pd;
530:
531:
532:
533:
534: bool is_detached = IS_DETACHED (pd);
535:
536:
537: err = create_thread (pd, iattr, STACK_VARIABLES_ARGS);
538: if (err != 0)
539: {
540:
541: if (!is_detached)
542: {
543: errout:
544: __deallocate_stack (pd);
545: }
546: return err;
547: }
548:
549: return 0;
550: }
551: versioned_symbol (libpthread, __pthread_create_2_1, pthread_create, GLIBC_2_1);
552:
553:
554: #if SHLIB_COMPAT(libpthread, GLIBC_2_0, GLIBC_2_1)
555: int
556: __pthread_create_2_0 (newthread, attr, start_routine, arg)
557: pthread_t *newthread;
558: const pthread_attr_t *attr;
559: void *(*start_routine) (void *);
560: void *arg;
561: {
562:
563:
564:
565: struct pthread_attr new_attr;
566:
567: if (attr != NULL)
568: {
569: struct pthread_attr *iattr = (struct pthread_attr *) attr;
570: size_t ps = __getpagesize ();
571:
572:
573: new_attr.schedparam = iattr->schedparam;
574: new_attr.schedpolicy = iattr->schedpolicy;
575: new_attr.flags = iattr->flags;
576:
577:
578:
579: new_attr.guardsize = ps;
580: new_attr.stackaddr = NULL;
581: new_attr.stacksize = 0;
582: new_attr.cpuset = NULL;
583:
584:
585: attr = (pthread