|
Message-Id: <41048892c9aa47a6ebde97cd90f244981221a437.1514985618.git.Jens.Gustedt@inria.fr> Date: Wed, 3 Jan 2018 14:17:12 +0100 From: Jens Gustedt <Jens.Gustedt@...ia.fr> To: musl@...ts.openwall.com Subject: [PATCH 4/7] separate the fast parts of __lock and __unlock into a .h file that may be used by other TU This provides two interfaces __lock_fast and __unlock_fast that are both "static inline" and that should result in a better integration of the lock in place. The slow path of the lock algorithm remains centralized, here adding the overhead of a function call is not a big deal. This must only be used directly by a TU that encapsulates all LOCK and UNLOCK calls of a particular lock object. --- src/internal/__lock.h | 21 +++++++++++++++++++++ src/internal/libc.h | 1 + src/thread/__lock.c | 20 +++++--------------- 3 files changed, 27 insertions(+), 15 deletions(-) create mode 100644 src/internal/__lock.h diff --git a/src/internal/__lock.h b/src/internal/__lock.h new file mode 100644 index 00000000..f16d6176 --- /dev/null +++ b/src/internal/__lock.h @@ -0,0 +1,21 @@ +#include "pthread_impl.h" + +static inline void __lock_fast(volatile int *l) +{ + extern void __lock_slow(volatile int*, int); + if (!libc.threads_minus_1) return; + /* fast path: INT_MIN for the lock, +1 for the congestion */ + int current = a_cas(l, 0, INT_MIN + 1); + if (!current) return; + __lock_slow(l, current); +} + +static inline void __unlock_fast(volatile int *l) +{ + /* Check l[0] to see if we are multi-threaded. */ + if (l[0] < 0) { + if (a_fetch_add(l, -(INT_MIN + 1)) != (INT_MIN + 1)) { + __wake(l, 1, 1); + } + } +} diff --git a/src/internal/libc.h b/src/internal/libc.h index 5e145183..a594d0c5 100644 --- a/src/internal/libc.h +++ b/src/internal/libc.h @@ -47,6 +47,7 @@ extern size_t __sysinfo ATTR_LIBC_VISIBILITY; extern char *__progname, *__progname_full; /* Designed to avoid any overhead in non-threaded processes */ +void __lock_slow(volatile int *, int) ATTR_LIBC_VISIBILITY; void __lock(volatile int *) ATTR_LIBC_VISIBILITY; void __unlock(volatile int *) ATTR_LIBC_VISIBILITY; int __lockfile(FILE *) ATTR_LIBC_VISIBILITY; diff --git a/src/thread/__lock.c b/src/thread/__lock.c index 45557c88..a3d8d4d0 100644 --- a/src/thread/__lock.c +++ b/src/thread/__lock.c @@ -1,4 +1,5 @@ #include "pthread_impl.h" +#include "__lock.h" /* This lock primitive combines a flag (in the sign bit) and a * congestion count (= threads inside the critical section, CS) in a @@ -16,12 +17,11 @@ * with INT_MIN as a lock flag. */ -void __lock(volatile int *l) +weak_alias(__lock_fast, __lock); +weak_alias(__unlock_fast, __unlock); + +void __lock_slow(volatile int *l, int current) { - if (!libc.threads_minus_1) return; - /* fast path: INT_MIN for the lock, +1 for the congestion */ - int current = a_cas(l, 0, INT_MIN + 1); - if (!current) return; /* A first spin loop, for medium congestion. */ for (unsigned i = 0; i < 10; ++i) { if (current < 0) current -= INT_MIN + 1; @@ -48,13 +48,3 @@ void __lock(volatile int *l) current = val; } } - -void __unlock(volatile int *l) -{ - /* Check l[0] to see if we are multi-threaded. */ - if (l[0] < 0) { - if (a_fetch_add(l, -(INT_MIN + 1)) != (INT_MIN + 1)) { - __wake(l, 1, 1); - } - } -} -- 2.15.1
Powered by blists - more mailing lists
Confused about mailing lists and their use? Read about mailing lists on Wikipedia and check out these guidelines on proper formatting of your messages.