|
|
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.