summaryrefslogtreecommitdiff
path: root/src/thread
diff options
context:
space:
mode:
Diffstat (limited to 'src/thread')
-rw-r--r--src/thread/lock_ptc.c18
-rw-r--r--src/thread/pthread_create.c18
-rw-r--r--src/thread/synccall.c15
3 files changed, 28 insertions, 23 deletions
diff --git a/src/thread/lock_ptc.c b/src/thread/lock_ptc.c
new file mode 100644
index 00000000..7adedab7
--- /dev/null
+++ b/src/thread/lock_ptc.c
@@ -0,0 +1,18 @@
+#include <pthread.h>
+
+static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
+
+void __inhibit_ptc()
+{
+ pthread_rwlock_wrlock(&lock);
+}
+
+void __acquire_ptc()
+{
+ pthread_rwlock_rdlock(&lock);
+}
+
+void __release_ptc()
+{
+ pthread_rwlock_unlock(&lock);
+}
diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c
index f53fc1ba..92ce9ffb 100644
--- a/src/thread/pthread_create.c
+++ b/src/thread/pthread_create.c
@@ -4,8 +4,8 @@
static void dummy_0()
{
}
-weak_alias(dummy_0, __synccall_lock);
-weak_alias(dummy_0, __synccall_unlock);
+weak_alias(dummy_0, __acquire_ptc);
+weak_alias(dummy_0, __release_ptc);
weak_alias(dummy_0, __pthread_tsd_run_dtors);
_Noreturn void pthread_exit(void *result)
@@ -84,7 +84,7 @@ static void init_file_lock(FILE *f)
if (f && f->lock<0) f->lock = 0;
}
-void *__copy_tls(unsigned char *, size_t);
+void *__copy_tls(unsigned char *);
int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr, void *(*entry)(void *), void *restrict arg)
{
@@ -94,8 +94,6 @@ 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;
- size_t tls_cnt = libc.tls_cnt;
- size_t tls_size = libc.tls_size;
if (!self) return ENOSYS;
if (!libc.threaded) {
@@ -107,6 +105,8 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
libc.threaded = 1;
}
+ __acquire_ptc();
+
if (attr && attr->_a_stackaddr) {
map = 0;
tsd = (void *)(attr->_a_stackaddr-__pthread_tsd_size & -16);
@@ -114,7 +114,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
if (attr) {
guard = ROUND(attr->_a_guardsize + DEFAULT_GUARD_SIZE);
size = guard + ROUND(attr->_a_stacksize
- + DEFAULT_STACK_SIZE + tls_size);
+ + DEFAULT_STACK_SIZE + libc.tls_size);
}
size += __pthread_tsd_size;
if (guard) {
@@ -130,7 +130,7 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
}
tsd = map + size - __pthread_tsd_size;
}
- new = __copy_tls(tsd - tls_size, tls_cnt);
+ new = __copy_tls(tsd - libc.tls_size);
new->map_base = map;
new->map_size = size;
new->pid = self->pid;
@@ -147,12 +147,10 @@ int pthread_create(pthread_t *restrict res, const pthread_attr_t *restrict attr,
new->canary = self->canary ^ (uintptr_t)&new;
stack = (void *)new;
- __synccall_lock();
-
a_inc(&libc.threads_minus_1);
ret = __clone(start, stack, flags, new, &new->tid, new, &new->tid);
- __synccall_unlock();
+ __release_ptc();
if (ret < 0) {
a_dec(&libc.threads_minus_1);
diff --git a/src/thread/synccall.c b/src/thread/synccall.c
index fd377cb3..2b7eac25 100644
--- a/src/thread/synccall.c
+++ b/src/thread/synccall.c
@@ -9,7 +9,6 @@ static struct chain {
static void (*callback)(void *), *context;
static int chainlen;
static sem_t chainlock, chaindone;
-static pthread_rwlock_t lock = PTHREAD_RWLOCK_INITIALIZER;
static void handler(int sig, siginfo_t *si, void *ctx)
{
@@ -59,7 +58,7 @@ void __synccall(void (*func)(void *), void *ctx)
return;
}
- pthread_rwlock_wrlock(&lock);
+ __inhibit_ptc();
__syscall(SYS_rt_sigprocmask, SIG_BLOCK, SIGALL_SET,
&oldmask, __SYSCALL_SSLEN);
@@ -97,15 +96,5 @@ void __synccall(void (*func)(void *), void *ctx)
__syscall(SYS_rt_sigprocmask, SIG_SETMASK,
&oldmask, 0, __SYSCALL_SSLEN);
- pthread_rwlock_unlock(&lock);
-}
-
-void __synccall_lock()
-{
- pthread_rwlock_rdlock(&lock);
-}
-
-void __synccall_unlock()
-{
- pthread_rwlock_unlock(&lock);
+ __release_ptc();
}