[Glibc-bsd-commits] r1942 - in trunk/glibc-ports/kfreebsd: . i386/linuxthreads x86_64/linuxthreads
ps-guest at alioth.debian.org
ps-guest at alioth.debian.org
Tue May 22 20:24:43 UTC 2007
Author: ps-guest
Date: 2007-05-22 20:24:43 +0000 (Tue, 22 May 2007)
New Revision: 1942
Added:
trunk/glibc-ports/kfreebsd/rtld-lowlevel.h
Modified:
trunk/glibc-ports/kfreebsd/Makefile
trunk/glibc-ports/kfreebsd/i386/linuxthreads/sysdep-cancel.h
trunk/glibc-ports/kfreebsd/syscalls.list
trunk/glibc-ports/kfreebsd/x86_64/linuxthreads/sysdep-cancel.h
Log:
* add glibc bits needed by version 2.6
Modified: trunk/glibc-ports/kfreebsd/Makefile
===================================================================
--- trunk/glibc-ports/kfreebsd/Makefile 2007-05-22 18:58:50 UTC (rev 1941)
+++ trunk/glibc-ports/kfreebsd/Makefile 2007-05-22 20:24:43 UTC (rev 1942)
@@ -111,6 +111,7 @@
# Special ELF hacks.
ifeq ($(subdir),elf)
sysdep-rtld-routines += dl-brk dl-sbrk
+sysdep_routines += sys_umtx
endif
ifeq ($(subdir),sunrpc)
Modified: trunk/glibc-ports/kfreebsd/i386/linuxthreads/sysdep-cancel.h
===================================================================
--- trunk/glibc-ports/kfreebsd/i386/linuxthreads/sysdep-cancel.h 2007-05-22 18:58:50 UTC (rev 1941)
+++ trunk/glibc-ports/kfreebsd/i386/linuxthreads/sysdep-cancel.h 2007-05-22 20:24:43 UTC (rev 1942)
@@ -154,5 +154,13 @@
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ p_header.data.multiple_threads) == 0, 1)
+#endif
+
Added: trunk/glibc-ports/kfreebsd/rtld-lowlevel.h
===================================================================
--- trunk/glibc-ports/kfreebsd/rtld-lowlevel.h (rev 0)
+++ trunk/glibc-ports/kfreebsd/rtld-lowlevel.h 2007-05-22 20:24:43 UTC (rev 1942)
@@ -0,0 +1,153 @@
+/* Definitions for lowlevel handling in ld.so, FreeBSD variant
+ Copyright (C) 2006-2007 Free Software Foundation, Inc.
+ This file is part of the GNU C Library.
+
+ The GNU C Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Lesser General Public
+ License as published by the Free Software Foundation; either
+ version 2.1 of the License, or (at your option) any later version.
+
+ The GNU C Library is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ Lesser General Public License for more details.
+
+ You should have received a copy of the GNU Lesser General Public
+ License along with the GNU C Library; if not, write to the Free
+ Software Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA
+ 02111-1307 USA. */
+
+#ifndef _RTLD_LOWLEVEL_H
+#define _RTLD_LOWLEVEL_H 1
+
+#include <atomic.h>
+
+typedef union
+{
+ volatile void * uv; /* in fact struct umtx from <sys/umtx.h> */
+ volatile int iv;
+ volatile long lv;
+
+} __rtld_mrlock_t;
+
+#define UMTX_OP_WAIT 2 /* <sys/umtx.h> */
+#define UMTX_OP_WAKE 3 /* <sys/umtx.h> */
+
+extern int __syscall__umtx_op(void *, int, long, void*, void*);
+
+static inline void lll_rtld_wake(__rtld_mrlock_t *umtx, int nr_wakeup)
+{
+ __syscall__umtx_op(umtx, UMTX_OP_WAKE, (long) nr_wakeup, NULL, NULL);
+};
+
+static inline void lll_rtld_wait(__rtld_mrlock_t *umtx, int old_val)
+{
+ __syscall__umtx_op(umtx, UMTX_OP_WAIT, (long) old_val, NULL, NULL);
+};
+
+/* Special multi-reader lock used in ld.so. */
+#define __RTLD_MRLOCK_WRITER 1
+#define __RTLD_MRLOCK_RWAIT 2
+#define __RTLD_MRLOCK_WWAIT 4
+#define __RTLD_MRLOCK_RBITS \
+ ~(__RTLD_MRLOCK_WRITER | __RTLD_MRLOCK_RWAIT | __RTLD_MRLOCK_WWAIT)
+#define __RTLD_MRLOCK_INC 8
+#define __RTLD_MRLOCK_TRIES 5
+
+#define __rtld_mrlock_define(CLASS,NAME) \
+ CLASS __rtld_mrlock_t NAME;
+
+
+#define _RTLD_MRLOCK_INITIALIZER 0
+#define __rtld_mrlock_initialize(NAME) \
+ (void) ((NAME).lv = 0)
+
+
+#define __rtld_mrlock_lock(lock) \
+ do { \
+ __label__ out; \
+ while (1) \
+ { \
+ int oldval; \
+ for (int tries = 0; tries < __RTLD_MRLOCK_TRIES; ++tries) \
+ { \
+ oldval = (lock).iv; \
+ while (__builtin_expect ((oldval \
+ & (__RTLD_MRLOCK_WRITER \
+ | __RTLD_MRLOCK_WWAIT)) \
+ == 0, 1)) \
+ { \
+ int newval = ((oldval & __RTLD_MRLOCK_RBITS) \
+ + __RTLD_MRLOCK_INC); \
+ int ret = atomic_compare_and_exchange_val_acq (&(lock.iv), \
+ newval, \
+ oldval); \
+ if (__builtin_expect (ret == oldval, 1)) \
+ goto out; \
+ oldval = ret; \
+ } \
+ atomic_delay (); \
+ } \
+ if ((oldval & __RTLD_MRLOCK_RWAIT) == 0) \
+ { \
+ atomic_or (&(lock.iv), __RTLD_MRLOCK_RWAIT); \
+ oldval |= __RTLD_MRLOCK_RWAIT; \
+ } \
+ lll_rtld_wait (&(lock), oldval); \
+ } \
+ out:; \
+ } while (0)
+
+
+#define __rtld_mrlock_unlock(lock) \
+ do { \
+ int oldval = atomic_exchange_and_add (&(lock.iv), -__RTLD_MRLOCK_INC); \
+ if (__builtin_expect ((oldval \
+ & (__RTLD_MRLOCK_RBITS | __RTLD_MRLOCK_WWAIT)) \
+ == (__RTLD_MRLOCK_INC | __RTLD_MRLOCK_WWAIT), 0)) \
+ /* We have to wake all threads since there might be some queued \
+ readers already. */ \
+ lll_rtld_wake (&(lock), 0x7fffffff); \
+ } while (0)
+
+
+/* There can only ever be one thread trying to get the exclusive lock. */
+#define __rtld_mrlock_change(lock) \
+ do { \
+ __label__ out; \
+ while (1) \
+ { \
+ int oldval; \
+ for (int tries = 0; tries < __RTLD_MRLOCK_TRIES; ++tries) \
+ { \
+ oldval = lock.iv; \
+ while (__builtin_expect ((oldval & __RTLD_MRLOCK_RBITS) == 0, 1)) \
+ { \
+ int newval = ((oldval & __RTLD_MRLOCK_RWAIT) \
+ + __RTLD_MRLOCK_WRITER); \
+ int ret = atomic_compare_and_exchange_val_acq (&(lock.iv), \
+ newval, \
+ oldval); \
+ if (__builtin_expect (ret == oldval, 1)) \
+ goto out; \
+ oldval = ret; \
+ } \
+ atomic_delay (); \
+ } \
+ atomic_or (&(lock.iv), __RTLD_MRLOCK_WWAIT); \
+ oldval |= __RTLD_MRLOCK_WWAIT; \
+ lll_rtld_wait (&(lock), oldval); \
+ } \
+ out:; \
+ } while (0)
+
+
+#define __rtld_mrlock_done(lock) \
+ do { \
+ int oldval = atomic_exchange_and_add (&(lock.iv), -__RTLD_MRLOCK_WRITER); \
+ if (__builtin_expect ((oldval & __RTLD_MRLOCK_RWAIT) != 0, 0)) \
+ lll_rtld_wake (&(lock), 0x7fffffff); \
+ } while (0)
+
+
+#endif
Modified: trunk/glibc-ports/kfreebsd/syscalls.list
===================================================================
--- trunk/glibc-ports/kfreebsd/syscalls.list 2007-05-22 18:58:50 UTC (rev 1941)
+++ trunk/glibc-ports/kfreebsd/syscalls.list 2007-05-22 20:24:43 UTC (rev 1942)
@@ -153,3 +153,5 @@
setcontext - setcontext i:p __setcontext setcontext
kqueue EXTRA kqueue i: __kqueue kqueue
kevent EXTRA kevent i:ipipip __kevent kevent
+sys_umtx - _umtx_op i:piipp __syscall__umtx_op
+
Modified: trunk/glibc-ports/kfreebsd/x86_64/linuxthreads/sysdep-cancel.h
===================================================================
--- trunk/glibc-ports/kfreebsd/x86_64/linuxthreads/sysdep-cancel.h 2007-05-22 18:58:50 UTC (rev 1941)
+++ trunk/glibc-ports/kfreebsd/x86_64/linuxthreads/sysdep-cancel.h 2007-05-22 20:24:43 UTC (rev 1942)
@@ -134,5 +134,12 @@
/* This code should never be used but we define it anyhow. */
# define SINGLE_THREAD_P (1)
+# define NO_CANCELLATION 1
#endif
+
+#ifndef __ASSEMBLER__
+# define RTLD_SINGLE_THREAD_P \
+ __builtin_expect (THREAD_GETMEM (THREAD_SELF, \
+ p_header.data.multiple_threads) == 0, 1)
+#endif
More information about the Glibc-bsd-commits
mailing list