summaryrefslogtreecommitdiffstats
path: root/libexec/rtld-elf/i386
diff options
context:
space:
mode:
authorkan <kan@FreeBSD.org>2003-05-29 22:58:26 +0000
committerkan <kan@FreeBSD.org>2003-05-29 22:58:26 +0000
commit949c40c5fd683b40f39ebfa2783d06b8226148ab (patch)
treeb9989a6b77c2c503eafdb3cf6bf13370f5c6396b /libexec/rtld-elf/i386
parentb292a2679ee1e9385409c38e0e898f0c2f4cb41c (diff)
downloadFreeBSD-src-949c40c5fd683b40f39ebfa2783d06b8226148ab.zip
FreeBSD-src-949c40c5fd683b40f39ebfa2783d06b8226148ab.tar.gz
Allow threading libraries to register their own locking
implementation in case default one provided by rtld is not suitable. Consolidate various identical MD lock implementation into a single file using appropriate machine/atomic.h. Approved by: re (scottl)
Diffstat (limited to 'libexec/rtld-elf/i386')
-rw-r--r--libexec/rtld-elf/i386/lockdflt.c132
-rw-r--r--libexec/rtld-elf/i386/rtld_machdep.h26
2 files changed, 5 insertions, 153 deletions
diff --git a/libexec/rtld-elf/i386/lockdflt.c b/libexec/rtld-elf/i386/lockdflt.c
index 46f8922..42dc7fe 100644
--- a/libexec/rtld-elf/i386/lockdflt.c
+++ b/libexec/rtld-elf/i386/lockdflt.c
@@ -50,23 +50,6 @@
#include <setjmp.h>
#include <signal.h>
-#include <stdlib.h>
-#include <time.h>
-
-#include "debug.h"
-#include "rtld.h"
-
-#define CACHE_LINE_SIZE 32
-
-#define WAFLAG 0x1 /* A writer holds the lock */
-#define RC_INCR 0x2 /* Adjusts count of readers desiring lock */
-
-typedef struct Struct_Lock {
- volatile int lock;
- void *base;
-} Lock;
-
-static sigset_t fullsigmask, oldsigmask;
static inline int
cmpxchgl(int old, int new, volatile int *m)
@@ -93,44 +76,6 @@ xchgl(int v, volatile int *m)
return result;
}
-static void *
-lock_create(void *context)
-{
- void *base;
- char *p;
- uintptr_t r;
- Lock *l;
-
- /*
- * Arrange for the lock to occupy its own cache line. First, we
- * optimistically allocate just a cache line, hoping that malloc
- * will give us a well-aligned block of memory. If that doesn't
- * work, we allocate a larger block and take a well-aligned cache
- * line from it.
- */
- base = xmalloc(CACHE_LINE_SIZE);
- p = (char *)base;
- if ((uintptr_t)p % CACHE_LINE_SIZE != 0) {
- free(base);
- base = xmalloc(2 * CACHE_LINE_SIZE);
- p = (char *)base;
- if ((r = (uintptr_t)p % CACHE_LINE_SIZE) != 0)
- p += CACHE_LINE_SIZE - r;
- }
- l = (Lock *)p;
- l->base = base;
- l->lock = 0;
- return l;
-}
-
-static void
-lock_destroy(void *lock)
-{
- Lock *l = (Lock *)lock;
-
- free(l->base);
-}
-
/*
* Crude exclusive locks for the 80386, which does not support the
* cmpxchg instruction.
@@ -162,51 +107,6 @@ lock80386_release(void *lock)
}
/*
- * Better reader/writer locks for the 80486 and later CPUs.
- */
-static void
-rlock_acquire(void *lock)
-{
- Lock *l = (Lock *)lock;
-
- atomic_add_int(&l->lock, RC_INCR);
- while (l->lock & WAFLAG)
- ; /* Spin */
-}
-
-static void
-wlock_acquire(void *lock)
-{
- Lock *l = (Lock *)lock;
- sigset_t tmp_oldsigmask;
-
- for ( ; ; ) {
- sigprocmask(SIG_BLOCK, &fullsigmask, &tmp_oldsigmask);
- if (cmpxchgl(0, WAFLAG, &l->lock) == 0)
- break;
- sigprocmask(SIG_SETMASK, &tmp_oldsigmask, NULL);
- }
- oldsigmask = tmp_oldsigmask;
-}
-
-static void
-rlock_release(void *lock)
-{
- Lock *l = (Lock *)lock;
-
- atomic_add_int(&l->lock, -RC_INCR);
-}
-
-static void
-wlock_release(void *lock)
-{
- Lock *l = (Lock *)lock;
-
- atomic_add_int(&l->lock, -WAFLAG);
- sigprocmask(SIG_SETMASK, &oldsigmask, NULL);
-}
-
-/*
* Code to determine at runtime whether the CPU supports the cmpxchg
* instruction. This instruction allows us to use locks that are more
* efficient, but it didn't exist on the 80386.
@@ -242,35 +142,3 @@ cpu_supports_cmpxchg(void)
return result;
}
-void
-lockdflt_init(LockInfo *li)
-{
- li->context = NULL;
- li->context_destroy = NULL;
- li->lock_create = lock_create;
- li->lock_destroy = lock_destroy;
- if (cpu_supports_cmpxchg()) {
- /* Use fast locks that require an 80486 or later. */
- li->rlock_acquire = rlock_acquire;
- li->wlock_acquire = wlock_acquire;
- li->rlock_release = rlock_release;
- li->wlock_release = wlock_release;
- } else {
- /* It's a cruddy old 80386. */
- li->rlock_acquire = li->wlock_acquire = lock80386_acquire;
- li->rlock_release = li->wlock_release = lock80386_release;
- }
- /*
- * Construct a mask to block all signals except traps which might
- * conceivably be generated within the dynamic linker itself.
- */
- sigfillset(&fullsigmask);
- sigdelset(&fullsigmask, SIGILL);
- sigdelset(&fullsigmask, SIGTRAP);
- sigdelset(&fullsigmask, SIGABRT);
- sigdelset(&fullsigmask, SIGEMT);
- sigdelset(&fullsigmask, SIGFPE);
- sigdelset(&fullsigmask, SIGBUS);
- sigdelset(&fullsigmask, SIGSEGV);
- sigdelset(&fullsigmask, SIGSYS);
-}
diff --git a/libexec/rtld-elf/i386/rtld_machdep.h b/libexec/rtld-elf/i386/rtld_machdep.h
index 4bd7ae2..953e289 100644
--- a/libexec/rtld-elf/i386/rtld_machdep.h
+++ b/libexec/rtld-elf/i386/rtld_machdep.h
@@ -29,6 +29,11 @@
#ifndef RTLD_MACHDEP_H
#define RTLD_MACHDEP_H 1
+#include <sys/types.h>
+#include <machine/atomic.h>
+
+#define CACHE_LINE_SIZE 32
+
struct Struct_Obj_Entry;
/* Return the address of the .dynamic section in the dynamic linker. */
@@ -53,25 +58,4 @@ reloc_jmpslot(Elf_Addr *where, Elf_Addr target,
#define call_initfini_pointer(obj, target) \
(((InitFunc)(target))())
-static inline void
-atomic_decr_int(volatile int *p)
-{
- __asm __volatile ("lock; decl %0" : "+m"(*p) : : "cc");
-}
-
-static inline void
-atomic_incr_int(volatile int *p)
-{
- __asm __volatile ("lock; incl %0" : "+m"(*p) : : "cc");
-}
-
-static inline void
-atomic_add_int(volatile int *p, int val)
-{
- __asm __volatile ("lock; addl %1, %0"
- : "+m"(*p)
- : "ri"(val)
- : "cc");
-}
-
#endif
OpenPOWER on IntegriCloud