From: Rich Felker Date: Sun, 17 Apr 2011 20:53:54 +0000 (-0400) Subject: clean up handling of thread/nothread mode, locking X-Git-Url: http://nsz.repo.hu/git/?p=musl;a=commitdiff_plain;h=9080cc153cc2b09881c3245becbd68534db18d7c clean up handling of thread/nothread mode, locking --- diff --git a/src/internal/libc.h b/src/internal/libc.h index d6df93d0..06ba73e7 100644 --- a/src/internal/libc.h +++ b/src/internal/libc.h @@ -7,8 +7,8 @@ struct __libc { int *(*errno_location)(void); void (*testcancel)(void); - void (*lock)(volatile int *); - void (*lockfile)(FILE *); + int threaded; + int canceldisable; void (*fork_handler)(int); int (*atexit)(void (*)(void)); void (*fini)(void); @@ -16,7 +16,6 @@ struct __libc { volatile int threads_minus_1; int ofl_lock; FILE *ofl_head; - int canceldisable; }; @@ -40,7 +39,7 @@ extern struct __libc *__libc_loc(void) __attribute__((const)); void __lock(volatile int *); void __lockfile(FILE *); #define LOCK(x) (libc.threads_minus_1 ? (__lock(x),1) : ((void)(x),1)) -#define UNLOCK(x) (*(x)=0) +#define UNLOCK(x) (*(volatile int *)(x)=0) int __rsyscall(int, long, long, long, long, long, long); diff --git a/src/internal/stdio_impl.h b/src/internal/stdio_impl.h index 90a8214b..76b58be9 100644 --- a/src/internal/stdio_impl.h +++ b/src/internal/stdio_impl.h @@ -24,7 +24,7 @@ #define UNGET 8 -#define FLOCK(f) ((libc.lockfile && (f)->lock>=0) ? (libc.lockfile((f)),0) : 0) +#define FLOCK(f) ((libc.threads_minus_1 && (f)->lock>=0) ? (__lockfile((f)),0) : 0) #define FUNLOCK(f) ((f)->lockcount && (--(f)->lockcount || ((f)->lock=0))) #define F_PERM 1 diff --git a/src/process/fork.c b/src/process/fork.c index 07fb79ed..bcd47c97 100644 --- a/src/process/fork.c +++ b/src/process/fork.c @@ -8,7 +8,7 @@ pid_t fork(void) pid_t ret; if (libc.fork_handler) libc.fork_handler(-1); ret = syscall(SYS_fork); - if (libc.lock && !ret) { + if (libc.threaded && !ret) { pthread_t self = __pthread_self(); self->tid = self->pid = syscall(SYS_getpid); libc.threads_minus_1 = 0; diff --git a/src/stdio/flockfile.c b/src/stdio/flockfile.c index 440a36a9..0d4c92c2 100644 --- a/src/stdio/flockfile.c +++ b/src/stdio/flockfile.c @@ -3,9 +3,6 @@ void flockfile(FILE *f) { - if (!libc.lockfile) { - pthread_self(); - libc.lockfile = __lockfile; - } + if (!libc.threaded) pthread_self(); __lockfile(f); } diff --git a/src/stdio/ftrylockfile.c b/src/stdio/ftrylockfile.c index 67f4b6a0..0b0e44aa 100644 --- a/src/stdio/ftrylockfile.c +++ b/src/stdio/ftrylockfile.c @@ -4,7 +4,6 @@ int ftrylockfile(FILE *f) { int tid = pthread_self()->tid; - if (!libc.lockfile) libc.lockfile = __lockfile; if (f->lock == tid) { if (f->lockcount == INT_MAX) return -1; diff --git a/src/thread/cancel_impl.c b/src/thread/cancel_impl.c index 2d2bb572..1f4ff90c 100644 --- a/src/thread/cancel_impl.c +++ b/src/thread/cancel_impl.c @@ -17,7 +17,7 @@ long (__syscall_cp)(long nr, long u, long v, long w, long x, long y, long z) uintptr_t old_sp, old_ip; long r; - if (!libc.lock || (self = __pthread_self())->canceldisable) + if (!libc.threaded || (self = __pthread_self())->canceldisable) return __syscall(nr, u, v, w, x, y, z); old_sp = self->cp_sp; diff --git a/src/thread/pthread_create.c b/src/thread/pthread_create.c index 844d7bf9..8e3a4a26 100644 --- a/src/thread/pthread_create.c +++ b/src/thread/pthread_create.c @@ -44,18 +44,6 @@ void __pthread_unwind_next(struct __ptcb *cb) __syscall(SYS_exit, 0); } -static void init_threads() -{ - sigset_t set; - libc.lock = __lock; - libc.lockfile = __lockfile; - - sigemptyset(&set); - sigaddset(&set, SIGSYSCALL); - sigaddset(&set, SIGCANCEL); - __libc_sigprocmask(SIG_UNBLOCK, &set, 0); -} - static int start(void *p) { struct pthread *self = p; @@ -79,7 +67,6 @@ weak_alias(dummy, __pthread_tsd_size); int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(void *), void *arg) { - static int init; int ret; size_t size, guard; struct pthread *self = pthread_self(), *new; @@ -87,7 +74,14 @@ int pthread_create(pthread_t *res, const pthread_attr_t *attr, void *(*entry)(vo const pthread_attr_t default_attr = { 0 }; if (!self) return ENOSYS; - if (!init && ++init) init_threads(); + if (!libc.threaded) { + sigset_t set; + sigemptyset(&set); + sigaddset(&set, SIGSYSCALL); + sigaddset(&set, SIGCANCEL); + __libc_sigprocmask(SIG_UNBLOCK, &set, 0); + libc.threaded = 1; + } if (!attr) attr = &default_attr; guard = ROUND(attr->_a_guardsize + DEFAULT_GUARD_SIZE); diff --git a/src/thread/pthread_setcancelstate.c b/src/thread/pthread_setcancelstate.c index 6722541a..ebb6eba4 100644 --- a/src/thread/pthread_setcancelstate.c +++ b/src/thread/pthread_setcancelstate.c @@ -3,7 +3,7 @@ int pthread_setcancelstate(int new, int *old) { if (new > 1U) return EINVAL; - if (libc.lock) { + if (libc.threaded) { struct pthread *self = __pthread_self(); if (old) *old = self->canceldisable; self->canceldisable = new;