diff --git a/lib/libthr/thread/thr_fork.c b/lib/libthr/thread/thr_fork.c index 18a9a05..59ca797 100644 --- a/lib/libthr/thread/thr_fork.c +++ b/lib/libthr/thread/thr_fork.c @@ -106,7 +106,7 @@ _fork(void) pid_t ret; int errsave; int unlock_malloc; - int rtld_locks[16]; + int rtld_locks[MAX_RTLD_LOCKS]; if (!_thr_is_inited()) return (__sys_fork()); diff --git a/lib/libthr/thread/thr_rtld.c b/lib/libthr/thread/thr_rtld.c index a8cd61d..8e09494 100644 --- a/lib/libthr/thread/thr_rtld.c +++ b/lib/libthr/thread/thr_rtld.c @@ -50,42 +50,42 @@ static int _thr_rtld_set_flag(int); static void _thr_rtld_wlock_acquire(void *); struct rtld_lock { - struct urwlock lock; - void *base; + struct urwlock lock; + char _pad[CACHE_LINE_SIZE - sizeof(struct urwlock)]; }; +static struct rtld_lock lock_place[MAX_RTLD_LOCKS] __aligned(CACHE_LINE_SIZE); +static int busy_places; + static void * _thr_rtld_lock_create(void) { - void *base; - char *p; - uintptr_t r; - struct rtld_lock *l; - size_t size; - - size = CACHE_LINE_SIZE; - while (size < sizeof(struct rtld_lock)) - size <<= 1; - base = calloc(1, size); - p = (char *)base; - if ((uintptr_t)p % CACHE_LINE_SIZE != 0) { - free(base); - base = calloc(1, size + CACHE_LINE_SIZE); - p = (char *)base; - if ((r = (uintptr_t)p % CACHE_LINE_SIZE) != 0) - p += CACHE_LINE_SIZE - r; + int locki; + struct rtld_lock *l; + static const char fail[] = "_thr_rtld_lock_create failed\n"; + + for (locki = 0; locki < MAX_RTLD_LOCKS; locki++) { + if ((busy_places & (1 << locki)) == 0) + break; } - l = (struct rtld_lock *)p; + if (locki == MAX_RTLD_LOCKS) { + write(2, fail, sizeof(fail) - 1); + return (NULL); + } + busy_places |= (1 << locki); + + l = &lock_place[locki]; l->lock.rw_flags = URWLOCK_PREFER_READER; - l->base = base; return (l); } static void _thr_rtld_lock_destroy(void *lock) { - struct rtld_lock *l = (struct rtld_lock *)lock; - free(l->base); + int locki; + + locki = (struct rtld_lock *)lock - &lock_place[0]; + busy_places &= ~(1 << locki); } #define SAVE_ERRNO() { \ diff --git a/libexec/rtld-elf/rtld_lock.h b/libexec/rtld-elf/rtld_lock.h index 4c5d854..6c04e3b 100644 --- a/libexec/rtld-elf/rtld_lock.h +++ b/libexec/rtld-elf/rtld_lock.h @@ -29,6 +29,7 @@ #define _RTLD_LOCK_H_ #define RTLI_VERSION 0x01 +#define MAX_RTLD_LOCKS 8 struct RtldLockInfo {