summaryrefslogtreecommitdiffstats
path: root/lib
diff options
context:
space:
mode:
authorkib <kib@FreeBSD.org>2008-12-02 11:58:31 +0000
committerkib <kib@FreeBSD.org>2008-12-02 11:58:31 +0000
commitaf7a67c13ca3d0aea828b69672928819ce3cafc1 (patch)
treeb23ed20daecc73be355f5025496a06fa66e978c8 /lib
parentade687809e3b9101f41cc7ab57fee5e8056b7381 (diff)
downloadFreeBSD-src-af7a67c13ca3d0aea828b69672928819ce3cafc1.zip
FreeBSD-src-af7a67c13ca3d0aea828b69672928819ce3cafc1.tar.gz
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
Diffstat (limited to 'lib')
-rw-r--r--lib/libthr/thread/thr_fork.c2
-rw-r--r--lib/libthr/thread/thr_rtld.c46
2 files changed, 24 insertions, 24 deletions
diff --git a/lib/libthr/thread/thr_fork.c b/lib/libthr/thread/thr_fork.c
index 0288dc2..bc410d1 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() { \
OpenPOWER on IntegriCloud