Date: Tue, 2 Dec 2008 11:58:32 +0000 (UTC) From: Konstantin Belousov <kib@FreeBSD.org> To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org Subject: svn commit: r185558 - in head: lib/libthr/thread libexec/rtld-elf Message-ID: <200812021158.mB2BwW5g059495@svn.freebsd.org>
next in thread | raw e-mail | index | archive | help
Author: kib Date: Tue Dec 2 11:58:31 2008 New Revision: 185558 URL: http://svn.freebsd.org/changeset/base/185558 Log: Provide custom simple allocator for rtld locks in libthr. The allocator does not use any external symbols, thus avoiding possible recursion into rtld to resolve symbols, when called. Reviewed by: kan, davidxu Tested by: rink MFC after: 1 month Modified: head/lib/libthr/thread/thr_fork.c head/lib/libthr/thread/thr_rtld.c head/libexec/rtld-elf/rtld_lock.h Modified: head/lib/libthr/thread/thr_fork.c ============================================================================== --- head/lib/libthr/thread/thr_fork.c Tue Dec 2 11:14:16 2008 (r185557) +++ head/lib/libthr/thread/thr_fork.c Tue Dec 2 11:58:31 2008 (r185558) @@ -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()); Modified: head/lib/libthr/thread/thr_rtld.c ============================================================================== --- head/lib/libthr/thread/thr_rtld.c Tue Dec 2 11:14:16 2008 (r185557) +++ head/lib/libthr/thread/thr_rtld.c Tue Dec 2 11:58:31 2008 (r185558) @@ -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() { \ Modified: head/libexec/rtld-elf/rtld_lock.h ============================================================================== --- head/libexec/rtld-elf/rtld_lock.h Tue Dec 2 11:14:16 2008 (r185557) +++ head/libexec/rtld-elf/rtld_lock.h Tue Dec 2 11:58:31 2008 (r185558) @@ -29,6 +29,7 @@ #define _RTLD_LOCK_H_ #define RTLI_VERSION 0x01 +#define MAX_RTLD_LOCKS 8 struct RtldLockInfo {
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?200812021158.mB2BwW5g059495>