svn commit: r185558 - in head: lib/libthr/thread libexec/rtld-elf

Konstantin Belousov kib at FreeBSD.org
Tue Dec 2 03:58:32 PST 2008


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
 {


More information about the svn-src-head mailing list