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
 {
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "[EMAIL PROTECTED]"

Reply via email to