bug-hurd
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[ PATCH ] Replace glibc spin-locks with gsync-based locks


From: Agustina Arzille
Subject: [ PATCH ] Replace glibc spin-locks with gsync-based locks
Date: Thu, 05 May 2016 23:02:35 -0300

Hello, everyone.

Here's the first of the patches to replace spin-locks in glibc with locks based
on gnumach's gsync.

I ran into a lot of troubles to compile glibc, mostly because the filesystem
kept freezing and / or crashing.

I had to modify several makefiles for a few libs because the new locks use RPCs
that are implemented in libmachuser. This is strictly for gnumach, obviously,
so it should be probably be edited out for other platforms (Linux), or be
included as a patch in Debian's package. Any help with this will be greatly
appreciated :)

I followed glibc's convention of naming these locks "low-level locks" and using
the lll_* namespace. I suggest we use these for any further locking in glibc,
instead of jumping through hoops with the old spin locks.

Anyway, here's the patch. For the next one, I'm thinking of replacing all
instances of __mutex_* calls in hurd/ and sysdeps/mach/hurd/, but if you have a
better idea, I'm all ears :)

=========================================

diff --git a/crypt/Makefile b/crypt/Makefile
index 9f69ecb..0e692a4 100644
--- a/crypt/Makefile
+++ b/crypt/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2016 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
@@ -40,7 +40,7 @@ ifeq ($(nss-crypt),yes)
 CPPFLAGS-sha256-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
 CPPFLAGS-sha512-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
 CPPFLAGS-md5-crypt.c = -DUSE_NSS -I$(shell nss-config --includedir)
-LDLIBS-crypt.so = -lfreebl3
+LDLIBS-crypt.so = -lfreebl3 -lmachuser
 else
 libcrypt-routines += md5 sha256 sha512

@@ -49,6 +49,7 @@ tests += md5test sha256test sha512test
 # The test md5test-giant uses up to 400 MB of RSS and runs on a fast
 # machine over a minute.
 xtests = md5test-giant
+LDLIBS-crypt.so = -lmachuser
 endif

 include ../Rules
diff --git a/dlfcn/Makefile b/dlfcn/Makefile
index bf20063..9fd8332 100644
--- a/dlfcn/Makefile
+++ b/dlfcn/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1995-2014 Free Software Foundation, Inc.
+# Copyright (C) 1995-2016 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
@@ -61,6 +61,8 @@ endif
 extra-test-objs += $(modules-names:=.os)
 generated := $(modules-names:=.so)

+LDLIBS-dl.so = -lmachuser
+
 include ../Rules

 test-modules = $(addprefix $(objpfx),$(addsuffix .so,$(modules-names)))
diff --git a/mach/Makefile b/mach/Makefile
index 5131e26..10b3cc9 100644
--- a/mach/Makefile
+++ b/mach/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1991-2014 Free Software Foundation, Inc.
+# Copyright (C) 1991-2016 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
@@ -27,7 +27,7 @@ headers = mach_init.h mach.h mach_error.h mach-shortcuts.h mach/mach_traps.h \
       $(interface-headers) mach/mach.h mach/mig_support.h mach/error.h \
       $(lock-headers) machine-sp.h
 lock = spin-solid spin-lock mutex-init mutex-solid
-lock-headers = lock-intern.h machine-lock.h spin-lock.h
+lock-headers = lock-intern.h machine-lock.h spin-lock.h lowlevellock
 routines = $(mach-syscalls) $(mach-shortcuts) \
        mach_init mig_strncpy msg \
        mig-alloc mig-dealloc mig-reply \
diff --git a/mach/lock-intern.h b/mach/lock-intern.h
index 6d315bb..5fae003 100644
--- a/mach/lock-intern.h
+++ b/mach/lock-intern.h
@@ -1,10 +1,10 @@
-/* Copyright (C) 1994-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2016 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.
+   version 3 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
@@ -20,6 +20,7 @@

 #include <sys/cdefs.h>
 #include <machine-lock.h>
+#include <lowlevellock.h>

 #ifndef _EXTERN_INLINE
 #define _EXTERN_INLINE __extern_inline
@@ -34,7 +35,7 @@ void __spin_lock_init (__spin_lock_t *__lock);
 _EXTERN_INLINE void
 __spin_lock_init (__spin_lock_t *__lock)
 {
-  *__lock = __SPIN_LOCK_INITIALIZER;
+  *__lock = LLL_INITIALIZER;
 }
 #endif

@@ -50,21 +51,11 @@ void __spin_lock (__spin_lock_t *__lock);
 _EXTERN_INLINE void
 __spin_lock (__spin_lock_t *__lock)
 {
-  if (! __spin_try_lock (__lock))
-    __spin_lock_solid (__lock);
+  lll_lock (__lock, 0);
 }
 #endif
 
-/* Name space-clean internal interface to mutex locks.
-
-   Code internal to the C library uses these functions to lock and unlock
-   mutex locks.  These locks are of type `struct mutex', defined in
-   <cthreads.h>.  The functions here are name space-clean. If the program
-   is linked with the cthreads library, `__mutex_lock_solid' and
-   `__mutex_unlock_solid' will invoke the corresponding cthreads functions
-   to implement real mutex locks.  If not, simple stub versions just use
-   spin locks.  */
-
+/* Name space-clean internal interface to mutex locks. */

 /* Initialize the newly allocated mutex lock LOCK for further use. */
 extern void __mutex_init (void *__lock);
@@ -84,8 +75,7 @@ void __mutex_lock (void *__lock);
 _EXTERN_INLINE void
 __mutex_lock (void *__lock)
 {
-  if (! __spin_try_lock ((__spin_lock_t *) __lock))
-    __mutex_lock_solid (__lock);
+  lll_lock (__lock, 0);
 }
 #endif

@@ -97,8 +87,7 @@ void __mutex_unlock (void *__lock);
 _EXTERN_INLINE void
 __mutex_unlock (void *__lock)
 {
-  __spin_unlock ((__spin_lock_t *) __lock);
-  __mutex_unlock_solid (__lock);
+  lll_unlock (__lock, 0);
 }
 #endif

@@ -109,7 +98,7 @@ int __mutex_trylock (void *__lock);
 _EXTERN_INLINE int
 __mutex_trylock (void *__lock)
 {
-  return __spin_try_lock ((__spin_lock_t *) __lock);
+  return (lll_trylock (__lock) == 0);
 }
 #endif

diff --git a/mach/lowlevellock.h b/mach/lowlevellock.h
new file mode 100644
index 0000000..bc56f80
--- /dev/null
+++ b/mach/lowlevellock.h
@@ -0,0 +1,78 @@
+/* Copyright (C) 1994-2016 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 3 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, see
+   <http://www.gnu.org/licenses/>.  */
+
+#ifndef __MACH_LOWLEVELLOCK_H__
+#define __MACH_LOWLEVELLOCK_H__   1
+
+#include <mach/gnumach.h>
+#include <atomic.h>
+
+/* Gsync flags. */
+#define GSYNC_SHARED      0x01
+#define GSYNC_QUAD        0x02
+#define GSYNC_TIMED       0x04
+#define GSYNC_BROADCAST   0x08
+#define GSYNC_MUTATE      0x10
+
+/* Static initializer for low-level locks. */
+#define LLL_INITIALIZER   0
+
+/* Wait on address PTR, without blocking if its contents
+ * are different from VAL. */
+#define lll_wait(ptr, val, flags)   \
+  __gsync_wait (__mach_task_self (),   \
+    (vm_offset_t)(ptr), (val), 0, 0, (flags))
+
+/* Wake one or more threads waiting on address PTR. */
+#define lll_wake(ptr, flags)   \
+  __gsync_wake (__mach_task_self (), (vm_offset_t)(ptr), 0, (flags))
+
+/* Acquire the lock at PTR. */
+#define lll_lock(ptr, flags)   \
+  ({   \
+     int *__iptr = (int *)(ptr);   \
+     int __flags = (flags);   \
+     if (*__iptr!= 0 ||   \
+         atomic_compare_and_exchange_bool_acq (__iptr, 1, 0) != 0)   \
+       while (1)   \
+         {   \
+           if (atomic_exchange_acq (__iptr, 2) == 0)   \
+             break;   \
+           lll_wait (__iptr, 2, __flags);   \
+         }   \
+     (void)0;   \
+   })
+
+/* Try to acquire the lock at PTR, without blocking.
+ * Evaluates to zero on success. */
+#define lll_trylock(ptr)   \
+  ({   \
+     int *__iptr = (int *)(ptr);   \
+     *__iptr == 0 &&   \
+       atomic_compare_and_exchange_bool_acq (__iptr, 1, 0) == 0 ? 0 : -1;   \
+   })
+
+/* Release the lock at PTR. */
+#define lll_unlock(ptr, flags)   \
+  ({   \
+     int *__iptr = (int *)(ptr);   \
+     if (atomic_exchange_rel (__iptr, 0) == 2)   \
+       lll_wake (__iptr, (flags));   \
+     (void)0;   \
+   })
+
+#endif
diff --git a/mach/mutex-init.c b/mach/mutex-init.c
index fc3a5e5..24703da 100644
--- a/mach/mutex-init.c
+++ b/mach/mutex-init.c
@@ -1,11 +1,11 @@
-/* Initialize a cthreads mutex structure.
-   Copyright (C) 1995-2014 Free Software Foundation, Inc.
+/* Initialize a mutex.
+   Copyright (C) 1995-2016 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.
+   version 3 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
@@ -17,13 +17,10 @@
    <http://www.gnu.org/licenses/>.  */

 #include <lock-intern.h>
-#include <cthreads.h>
+#include <lowlevellock.h>

 void
 __mutex_init (void *lock)
 {
-  /* This happens to be name space-safe because it is a macro.
-     It invokes only spin_lock_init, which is a macro for __spin_lock_init;
-     and cthread_queue_init, which is a macro for some simple code.  */
-  mutex_init ((struct mutex *) lock);
+  *(int *)lock = LLL_INITIALIZER;
 }
diff --git a/mach/mutex-solid.c b/mach/mutex-solid.c
index 70e8333..ca0c791 100644
--- a/mach/mutex-solid.c
+++ b/mach/mutex-solid.c
@@ -1,11 +1,11 @@
 /* Stub versions of mutex_lock_solid/mutex_unlock_solid for no -lthreads.
-   Copyright (C) 1995-2014 Free Software Foundation, Inc.
+   Copyright (C) 1995-2016 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.
+   version 3 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
@@ -17,17 +17,12 @@
    <http://www.gnu.org/licenses/>.  */

 #include <lock-intern.h>
-#include <cthreads.h>
-
-/* If cthreads is linked in, it will define these functions itself to do
-   real cthreads mutex locks.  This file will only be linked in when
-   cthreads is not used, and `mutexes' are in fact just spin locks (and
-   some unused storage).  */
+#include <lowlevellock.h>

 void
 __mutex_lock_solid (void *lock)
 {
-  __spin_lock_solid (lock);
+  lll_lock (lock, 0);
 }

 void
diff --git a/mach/spin-lock.h b/mach/spin-lock.h
index fc21b1e..535191a 100644
--- a/mach/spin-lock.h
+++ b/mach/spin-lock.h
@@ -1,5 +1,5 @@
 /* Definitions of user-visible names for spin locks.
-   Copyright (C) 1994-2014 Free Software Foundation, Inc.
+   Copyright (C) 1994-2016 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
diff --git a/mach/spin-solid.c b/mach/spin-solid.c
index e1e154b..415636e 100644
--- a/mach/spin-solid.c
+++ b/mach/spin-solid.c
@@ -1,4 +1,4 @@
-/* Copyright (C) 1994-2014 Free Software Foundation, Inc.
+/* Copyright (C) 1994-2015 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
@@ -16,13 +16,11 @@
    <http://www.gnu.org/licenses/>.  */

 #include <spin-lock.h>
-#include <mach/mach_traps.h>
+#include <lowlevellock.h>

 void
 __spin_lock_solid (spin_lock_t *lock)
 {
-  while (__spin_lock_locked (lock) || ! __spin_try_lock (lock))
-    /* Yield to another thread (system call).  */
-    __swtch_pri (0);
+  lll_lock (lock, 0);
 }
 weak_alias (__spin_lock_solid, spin_lock_solid);
diff --git a/nis/Makefile b/nis/Makefile
index 15f86ba..d1ffee0 100644
--- a/nis/Makefile
+++ b/nis/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2016 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
@@ -41,6 +41,11 @@ extra-libs        = libnsl $(services:%=libnss_%)
 # the `lib' pass, because they depend on libc.so being built already.
 extra-libs-others    = $(extra-libs)

+LDLIBS-nsl.so = -lmachuser
+LDLIBS-nss_nis.so = -lmachuser
+LDLIBS-nss_nisplus.so = -lmachuser
+LDLIBS-nss_compat.so = -lmachuser
+
 # The sources are found in the appropriate subdir.
 subdir-dirs = $(services:%=nss_%)
 vpath %.c $(subdir-dirs)
diff --git a/nss/Makefile b/nss/Makefile
index c8880c0..fe603fd 100644
--- a/nss/Makefile
+++ b/nss/Makefile
@@ -1,4 +1,4 @@
-# Copyright (C) 1996-2014 Free Software Foundation, Inc.
+# Copyright (C) 1996-2016 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
@@ -50,6 +50,8 @@ extra-libs        = $(services:%=libnss_%)
 # the `lib' pass, because they depend on libc.so being built already.
 extra-libs-others    = $(extra-libs)

+LDLIBS-$(services:%=nss_%).so = -lmachuser
+
 # The sources are found in the appropriate subdir.
 subdir-dirs = $(services:%=nss_%)
 vpath %.c $(subdir-dirs) ../locale/programs ../intl
diff --git a/sysdeps/mach/bits/libc-lock.h b/sysdeps/mach/bits/libc-lock.h
index 40b7f2b..dbd9fd6 100644
--- a/sysdeps/mach/bits/libc-lock.h
+++ b/sysdeps/mach/bits/libc-lock.h
@@ -1,11 +1,11 @@
-/* libc-internal interface for mutex locks.  Mach cthreads version.
-   Copyright (C) 1996-2014 Free Software Foundation, Inc.
+/* libc-internal interface for mutex locks.  Hurd version using gnumach gsync.
+   Copyright (C) 1996-2016 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.
+   version 3 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
@@ -19,16 +19,36 @@
 #ifndef _BITS_LIBC_LOCK_H
 #define _BITS_LIBC_LOCK_H 1

-#ifdef _LIBC
+#if (_LIBC - 0) || (_CTHREADS_ - 0)
+#if (_LIBC - 0)
+#include <tls.h>
+#endif
+
 #include <cthreads.h>
-#define __libc_lock_t struct mutex
+#include <lowlevellock.h>
+
+/* The locking here is very inexpensive, even for inlining. */
+#define _IO_lock_inexpensive   1
+
+typedef unsigned int __libc_lock_t;
+typedef struct
+{
+  __libc_lock_t lock;
+  void *owner;
+  int cnt;
+} __libc_lock_recursive_t;
+
+typedef __libc_lock_recursive_t __rtld_lock_recursive_t;
+
+extern char __libc_lock_self0[0];
+#define __libc_lock_owner_self()   \
+  (__LIBC_NO_TLS() ? (void *)&__libc_lock_self0 : THREAD_SELF)
+
 #else
 typedef struct __libc_lock_opaque__ __libc_lock_t;
+typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
 #endif

-/* Type for key of thread specific data.  */
-typedef cthread_key_t __libc_key_t;
-
 /* Define a lock variable NAME with storage class CLASS.  The lock must be
    initialized with __libc_lock_init before it can be used (or define it
    with __libc_lock_define_initialized, below).  Use `extern' for CLASS to
@@ -41,25 +61,92 @@ typedef cthread_key_t __libc_key_t;

 /* Define an initialized lock variable NAME with storage class CLASS.  */
 #define __libc_lock_define_initialized(CLASS,NAME) \
-  CLASS __libc_lock_t NAME = MUTEX_INITIALIZER;
+  CLASS __libc_lock_t NAME = LLL_INITIALIZER;

 /* Initialize the named lock variable, leaving it in a consistent, unlocked
    state.  */
-#define __libc_lock_init(NAME) __mutex_init (&(NAME))
+#define __libc_lock_init(NAME) (NAME) = LLL_INITIALIZER

 /* Finalize the named lock variable, which must be locked.  It cannot be
    used again until __libc_lock_init is called again on it.  This must be
    called on a lock variable before the containing storage is reused.  */
-#define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
+#define __libc_lock_fini             __libc_lock_unlock
+#define __libc_lock_fini_recursive   __libc_lock_unlock_recursive
+#define __rtld_lock_fini_recursive   __rtld_lock_unlock_recursive

 /* Lock the named lock variable.  */
-#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
+#define __libc_lock_lock(NAME)   \
+  ({ lll_lock (&(NAME), 0); 0; })

 /* Lock the named lock variable.  */
-#define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME)))
+#define __libc_lock_trylock(NAME) lll_trylock (&(NAME))

 /* Unlock the named lock variable.  */
-#define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
+#define __libc_lock_unlock(NAME)   \
+  ({ lll_unlock (&(NAME), 0); 0; })
+
+#define __libc_lock_define_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME;
+
+#define _LIBC_LOCK_RECURSIVE_INITIALIZER { LLL_INITIALIZER, 0, 0 }
+
+#define __libc_lock_define_initialized_recursive(CLASS,NAME) \
+  CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
+
+#define __rtld_lock_define_recursive(CLASS,NAME) \
+  __libc_lock_define_recursive (CLASS, NAME)
+#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
+  _LIBC_LOCK_RECURSIVE_INITIALIZER
+#define __rtld_lock_define_initialized_recursive(CLASS,NAME) \
+  __libc_lock_define_initialized_recursive (CLASS, NAME)
+
+#define __libc_lock_init_recursive(NAME)   \
+  ((NAME) = (__libc_lock_recursive_t)_LIBC_LOCK_RECURSIVE_INITIALIZER, 0)
+
+#define __libc_lock_trylock_recursive(NAME)   \
+  ({   \
+     __libc_lock_recursive_t *const __lock = &(NAME);   \
+     void *__self = __libc_lock_owner_self ();   \
+     int __r = 0;   \
+     if (__self == __lock->owner)   \
+       ++__lock->cnt;   \
+     else if ((__r = lll_trylock (&__lock->lock)) == 0)   \
+       __lock->owner = __self, __lock->cnt = 1;   \
+     __r;   \
+   })
+
+#define __libc_lock_lock_recursive(NAME)   \
+  ({   \
+     __libc_lock_recursive_t *const __lock = &(NAME);   \
+     void *__self = __libc_lock_owner_self ();   \
+     if (__self != __lock->owner)   \
+       {   \
+         lll_lock (&__lock->lock, 0);   \
+         __lock->owner = __self;   \
+       }   \
+     ++__lock->cnt;   \
+     (void)0;   \
+   })
+
+#define __libc_lock_unlock_recursive(NAME)   \
+  ({   \
+     __libc_lock_recursive_t *const __lock = &(NAME);   \
+     if (--__lock->cnt == 0)   \
+       {   \
+         __lock->owner = 0;   \
+         lll_unlock (&__lock->lock, 0);   \
+       }   \
+   })
+
+
+#define __rtld_lock_initialize(NAME) \
+  (void) ((NAME) = (__rtld_lock_recursive_t) _RTLD_LOCK_RECURSIVE_INITIALIZER)
+#define __rtld_lock_trylock_recursive(NAME) \
+  __libc_lock_trylock_recursive (NAME)
+#define __rtld_lock_lock_recursive(NAME) \
+  __libc_lock_lock_recursive(NAME)
+#define __rtld_lock_unlock_recursive(NAME) \
+  __libc_lock_unlock_recursive (NAME)


 /* XXX for now */
@@ -92,6 +179,10 @@ typedef cthread_key_t __libc_key_t;
   if ((DOIT) && __save_FCT != 0)                        \
     (*__save_FCT)(__save_ARG);                            \

+#define __libc_cleanup_push(fct, arg) __libc_cleanup_region_start (1, fct, arg)
+#define __libc_cleanup_pop(execute) __libc_cleanup_region_end (execute)
+
+#if (_CTHREADS_ - 0)

 /* Use mutexes as once control variables. */

@@ -104,7 +195,6 @@ struct __libc_once
 #define __libc_once_define(CLASS,NAME) \
   CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 }

-
 /* Call handler iff the first call.  */
 #define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
   do {                                          \
@@ -121,25 +211,22 @@ struct __libc_once
 #ifdef _LIBC
 /* We need portable names for some functions.  E.g., when they are
    used as argument to __libc_cleanup_region_start.  */
-#define __libc_mutex_unlock __mutex_unlock
+#define __libc_mutex_unlock __libc_lock_unlock
 #endif

+/* Type for key of thread specific data.  */
+typedef cthread_key_t __libc_key_t;
+
 #define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
 #define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
 void *__libc_getspecific (__libc_key_t key);

-/* XXX until cthreads supports recursive locks */
-#define __libc_lock_define_initialized_recursive __libc_lock_define_initialized
-#define __libc_lock_init_recursive __libc_lock_init
-#define __libc_lock_fini_recursive __libc_lock_fini
-#define __libc_lock_trylock_recursive __libc_lock_trylock
-#define __libc_lock_unlock_recursive __libc_lock_unlock
-#define __libc_lock_lock_recursive __libc_lock_lock
-
-#define __rtld_lock_define_initialized_recursive __libc_lock_define_initialized
-#define __rtld_lock_fini_recursive __libc_lock_fini
-#define __rtld_lock_trylock_recursive __libc_lock_trylock
-#define __rtld_lock_unlock_recursive __libc_lock_unlock
-#define __rtld_lock_lock_recursive __libc_lock_lock
+#endif /* _CTHREADS_ */
+
+/* Hide the definitions which are only supposed to be used inside libc in
+   a separate file.  This file is not present in the installation! */
+#ifdef _LIBC
+# include <bits/libc-lockP.h>
+#endif

 #endif    /* bits/libc-lock.h */
diff --git a/sysdeps/mach/hurd/bits/libc-lock.h 
b/sysdeps/mach/hurd/bits/libc-lock.h
deleted file mode 100644
index c9872c6..0000000
--- a/sysdeps/mach/hurd/bits/libc-lock.h
+++ /dev/null
@@ -1,215 +0,0 @@
-/* libc-internal interface for mutex locks.  Hurd version using Mach cthreads.
-   Copyright (C) 1996-2014 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, see
-   <http://www.gnu.org/licenses/>.  */
-
-#ifndef _BITS_LIBC_LOCK_H
-#define _BITS_LIBC_LOCK_H 1
-
-#if (_LIBC - 0) || (_CTHREADS_ - 0)
-# if (_LIBC - 0)
-#  include <tls.h>
-# endif
-#include <cthreads.h>
-
-typedef struct mutex __libc_lock_t;
-typedef struct
-{
-  struct mutex mutex;
-  void *owner;
-  int count;
-} __libc_lock_recursive_t;
-typedef __libc_lock_recursive_t __rtld_lock_recursive_t;
-
-extern char __libc_lock_self0[0];
-#define __libc_lock_owner_self() (__LIBC_NO_TLS() ? &__libc_lock_self0 : THREAD_SELF)
-
-#else
-typedef struct __libc_lock_opaque__ __libc_lock_t;
-typedef struct __libc_lock_recursive_opaque__ __libc_lock_recursive_t;
-#endif
-
-/* Define a lock variable NAME with storage class CLASS.  The lock must be
-   initialized with __libc_lock_init before it can be used (or define it
-   with __libc_lock_define_initialized, below).  Use `extern' for CLASS to
-   declare a lock defined in another module.  In public structure
-   definitions you must use a pointer to the lock structure (i.e., NAME
-   begins with a `*'), because its storage size will not be known outside
-   of libc.  */
-#define __libc_lock_define(CLASS,NAME) \
-  CLASS __libc_lock_t NAME;
-
-/* Define an initialized lock variable NAME with storage class CLASS.  */
-#define __libc_lock_define_initialized(CLASS,NAME) \
-  CLASS __libc_lock_t NAME = MUTEX_INITIALIZER;
-
-/* Initialize the named lock variable, leaving it in a consistent, unlocked
-   state.  */
-#define __libc_lock_init(NAME) __mutex_init (&(NAME))
-
-/* Finalize the named lock variable, which must be locked.  It cannot be
-   used again until __libc_lock_init is called again on it.  This must be
-   called on a lock variable before the containing storage is reused.  */
-#define __libc_lock_fini(NAME) __mutex_unlock (&(NAME))
-#define __libc_lock_fini_recursive(NAME) __mutex_unlock (&(NAME).mutex)
-#define __rtld_lock_fini_recursive(NAME) __mutex_unlock (&(NAME).mutex)
-
-
-/* Lock the named lock variable.  */
-#define __libc_lock_lock(NAME) __mutex_lock (&(NAME))
-
-/* Lock the named lock variable.  */
-#define __libc_lock_trylock(NAME) (!__mutex_trylock (&(NAME)))
-
-/* Unlock the named lock variable.  */
-#define __libc_lock_unlock(NAME) __mutex_unlock (&(NAME))
-
-
-#define __libc_lock_define_recursive(CLASS,NAME) \
-  CLASS __libc_lock_recursive_t NAME;
-#define _LIBC_LOCK_RECURSIVE_INITIALIZER { MUTEX_INITIALIZER, 0, 0 }
-#define __libc_lock_define_initialized_recursive(CLASS,NAME) \
-  CLASS __libc_lock_recursive_t NAME = _LIBC_LOCK_RECURSIVE_INITIALIZER;
-
-#define __rtld_lock_define_recursive(CLASS,NAME) \
-  __libc_lock_define_recursive (CLASS, NAME)
-#define _RTLD_LOCK_RECURSIVE_INITIALIZER \
-  _LIBC_LOCK_RECURSIVE_INITIALIZER
-#define __rtld_lock_define_initialized_recursive(CLASS,NAME) \
-  __libc_lock_define_initialized_recursive (CLASS, NAME)
-
-#define __libc_lock_init_recursive(NAME) \
-  ({ __libc_lock_recursive_t *const __lock = &(NAME); \
-     __lock->owner = 0; mutex_init (&__lock->mutex); })
-
-#define __libc_lock_trylock_recursive(NAME)                      \
-  ({ __libc_lock_recursive_t *const __lock = &(NAME);        \
-     void *__self = __libc_lock_owner_self (); \
-     __mutex_trylock (&__lock->mutex)        \
-     ? (__lock->owner = __self, __lock->count = 1, 0)            \
-     : __lock->owner == __self ? (++__lock->count, 0) : 1; })
-
-#define __libc_lock_lock_recursive(NAME)                      \
-  ({ __libc_lock_recursive_t *const __lock = &(NAME);        \
-     void *__self = __libc_lock_owner_self (); \
-     if (__mutex_trylock (&__lock->mutex)        \
-     || (__lock->owner != __self                          \
-         && (__mutex_lock (&__lock->mutex), 1)))                \
-       __lock->owner = __self, __lock->count = 1;        \
-     else                                      \
-       ++__lock->count;                                  \
-  })
-#define __libc_lock_unlock_recursive(NAME)                      \
-  ({ __libc_lock_recursive_t *const __lock = &(NAME);        \
-     if (--__lock->count == 0)                              \
-       {                                      \
-     __lock->owner = 0;                              \
-     __mutex_unlock (&__lock->mutex);                      \
-       }                                      \
-  })
-
-
-#define __rtld_lock_initialize(NAME) \
-  (void) ((NAME) = (__rtld_lock_recursive_t) _RTLD_LOCK_RECURSIVE_INITIALIZER)
-#define __rtld_lock_trylock_recursive(NAME) \
-  __libc_lock_trylock_recursive (NAME)
-#define __rtld_lock_lock_recursive(NAME) \
-  __libc_lock_lock_recursive(NAME)
-#define __rtld_lock_unlock_recursive(NAME) \
-  __libc_lock_unlock_recursive (NAME)
-
-
-/* XXX for now */
-#define __libc_rwlock_define        __libc_lock_define
-#define __libc_rwlock_define_initialized __libc_lock_define_initialized
-#define __libc_rwlock_init        __libc_lock_init
-#define __libc_rwlock_fini        __libc_lock_fini
-#define __libc_rwlock_rdlock        __libc_lock_lock
-#define __libc_rwlock_wrlock        __libc_lock_lock
-#define __libc_rwlock_tryrdlock        __libc_lock_trylock
-#define __libc_rwlock_trywrlock        __libc_lock_trylock
-#define __libc_rwlock_unlock        __libc_lock_unlock
-
-
-/* Start a critical region with a cleanup function */
-#define __libc_cleanup_region_start(DOIT, FCT, ARG) \
-{                                        \
-  typeof (***(FCT)) *__save_FCT = (DOIT) ? (FCT) : 0;      \
-  typeof (ARG) __save_ARG = ARG;                        \
-  /* close brace is in __libc_cleanup_region_end below. */
-
-/* End a critical region started with __libc_cleanup_region_start. */
-#define __libc_cleanup_region_end(DOIT)                        \
-  if ((DOIT) && __save_FCT != 0)                        \
-    (*__save_FCT)(__save_ARG);                            \
-}
-
-/* Sometimes we have to exit the block in the middle.  */
-#define __libc_cleanup_end(DOIT)                        \
-  if ((DOIT) && __save_FCT != 0)                        \
-    (*__save_FCT)(__save_ARG);                            \
-
-#define __libc_cleanup_push(fct, arg) __libc_cleanup_region_start (1, fct, arg)
-#define __libc_cleanup_pop(execute) __libc_cleanup_region_end (execute)
-
-#if (_CTHREADS_ - 0)
-
-/* Use mutexes as once control variables. */
-
-struct __libc_once
-  {
-    __libc_lock_t lock;
-    int done;
-  };
-
-#define __libc_once_define(CLASS,NAME) \
-  CLASS struct __libc_once NAME = { MUTEX_INITIALIZER, 0 }
-
-/* Call handler iff the first call.  */
-#define __libc_once(ONCE_CONTROL, INIT_FUNCTION) \
-  do {                                          \
-    __libc_lock_lock (ONCE_CONTROL.lock);                      \
-    if (!ONCE_CONTROL.done)                              \
-      (INIT_FUNCTION) ();                              \
-    ONCE_CONTROL.done = 1;                              \
-    __libc_lock_unlock (ONCE_CONTROL.lock);                      \
-  } while (0)
-
-/* Get once control variable.  */
-#define __libc_once_get(ONCE_CONTROL)    ((ONCE_CONTROL).done != 0)
-
-#ifdef _LIBC
-/* We need portable names for some functions.  E.g., when they are
-   used as argument to __libc_cleanup_region_start.  */
-#define __libc_mutex_unlock __mutex_unlock
-#endif
-
-/* Type for key of thread specific data.  */
-typedef cthread_key_t __libc_key_t;
-
-#define __libc_key_create(KEY,DEST) cthread_keycreate (KEY)
-#define __libc_setspecific(KEY,VAL) cthread_setspecific (KEY, VAL)
-void *__libc_getspecific (__libc_key_t key);
-
-#endif /* _CTHREADS_ */
-
-/* Hide the definitions which are only supposed to be used inside libc in
-   a separate file.  This file is not present in the installation! */
-#ifdef _LIBC
-# include <bits/libc-lockP.h>
-#endif
-
-#endif    /* bits/libc-lock.h */



reply via email to

[Prev in Thread] Current Thread [Next in Thread]