projects
/
musl
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
add _ALL_SOURCE as an alias for _GNU_SOURCE/enable-everything
[musl]
/
src
/
thread
/
pthread_create.c
diff --git
a/src/thread/pthread_create.c
b/src/thread/pthread_create.c
index
6327a94
..
a65e88e
100644
(file)
--- a/
src/thread/pthread_create.c
+++ b/
src/thread/pthread_create.c
@@
-1,5
+1,6
@@
#include "pthread_impl.h"
#include "stdio_impl.h"
#include "pthread_impl.h"
#include "stdio_impl.h"
+#include <sys/mman.h>
static void dummy_0()
{
static void dummy_0()
{
@@
-61,6
+62,15
@@
void __do_cleanup_pop(struct __ptcb *cb)
static int start(void *p)
{
pthread_t self = p;
static int start(void *p)
{
pthread_t self = p;
+ if (self->startlock[0]) {
+ __wait(self->startlock, 0, 1, 1);
+ if (self->startlock[0]) {
+ self->detached = 2;
+ pthread_exit(0);
+ }
+ __syscall(SYS_rt_sigprocmask, SIG_SETMASK,
+ self->sigmask, 0, __SYSCALL_SSLEN);
+ }
if (self->unblock_cancel)
__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
SIGPT_SET, 0, __SYSCALL_SSLEN);
if (self->unblock_cancel)
__syscall(SYS_rt_sigprocmask, SIG_UNBLOCK,
SIGPT_SET, 0, __SYSCALL_SSLEN);
@@
-94,6
+104,7
@@
int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
struct pthread *self = pthread_self(), *new;
unsigned char *map, *stack, *tsd;
unsigned flags = 0x7d8f00;
struct pthread *self = pthread_self(), *new;
unsigned char *map, *stack, *tsd;
unsigned flags = 0x7d8f00;
+ int do_sched = 0;
if (!self) return ENOSYS;
if (!libc.threaded) {
if (!self) return ENOSYS;
if (!libc.threaded) {
@@
-130,7
+141,7
@@
int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
}
tsd = map + size - __pthread_tsd_size;
}
}
tsd = map + size - __pthread_tsd_size;
}
- new = __copy_tls(tsd - libc.tls_size);
+ new = __copy_tls(
stack =
tsd - libc.tls_size);
new->map_base = map;
new->map_size = size;
new->pid = self->pid;
new->map_base = map;
new->map_size = size;
new->pid = self->pid;
@@
-143,20
+154,38
@@
int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
new->detached = 1;
flags -= 0x200000;
}
new->detached = 1;
flags -= 0x200000;
}
+ if (attr && attr->_a_sched) {
+ do_sched = new->startlock[0] = 1;
+ __syscall(SYS_rt_sigprocmask, SIG_BLOCK,
+ SIGALL_SET, self->sigmask, __SYSCALL_SSLEN);
+ }
new->unblock_cancel = self->cancel;
new->canary = self->canary;
new->unblock_cancel = self->cancel;
new->canary = self->canary;
- stack = (void *)new;
a_inc(&libc.threads_minus_1);
a_inc(&libc.threads_minus_1);
- ret = __clone(start, stack, flags, new, &new->tid,
new
, &new->tid);
+ ret = __clone(start, stack, flags, new, &new->tid,
TP_ADJ(new)
, &new->tid);
__release_ptc();
__release_ptc();
+ if (do_sched) {
+ __syscall(SYS_rt_sigprocmask, SIG_SETMASK,
+ new->sigmask, 0, __SYSCALL_SSLEN);
+ }
+
if (ret < 0) {
a_dec(&libc.threads_minus_1);
munmap(map, size);
return EAGAIN;
}
if (ret < 0) {
a_dec(&libc.threads_minus_1);
munmap(map, size);
return EAGAIN;
}
+
+ if (do_sched) {
+ ret = __syscall(SYS_sched_setscheduler, new->tid,
+ attr->_a_policy, &attr->_a_prio);
+ a_store(new->startlock, ret<0 ? 2 : 0);
+ __wake(new->startlock, 1, 1);
+ if (ret < 0) return -ret;
+ }
+
*res = new;
return 0;
}
*res = new;
return 0;
}