mirror of
https://github.com/fluencelabs/musl
synced 2025-06-26 05:02:02 +00:00
new internal locking primitive; drop spinlocks
we use priority inheritance futexes if possible so that the library cannot hit internal priority inversion deadlocks in the presence of realtime priority scheduling (full support to be added later).
This commit is contained in:
@ -45,10 +45,11 @@ extern struct __libc *__libc_loc(void) __attribute__((const));
|
|||||||
|
|
||||||
/* Designed to avoid any overhead in non-threaded processes */
|
/* Designed to avoid any overhead in non-threaded processes */
|
||||||
void __lock(volatile int *);
|
void __lock(volatile int *);
|
||||||
|
void __unlock(volatile int *);
|
||||||
int __lockfile(FILE *);
|
int __lockfile(FILE *);
|
||||||
void __unlockfile(FILE *);
|
void __unlockfile(FILE *);
|
||||||
#define LOCK(x) (libc.threads_minus_1 ? (__lock(x),1) : ((void)(x),1))
|
#define LOCK(x) (libc.threads_minus_1 ? (__lock(x),1) : ((void)(x),1))
|
||||||
#define UNLOCK(x) (*(volatile int *)(x)=0)
|
#define UNLOCK(x) (libc.threads_minus_1 ? (__unlock(x),1) : ((void)(x),1))
|
||||||
|
|
||||||
void __synccall(void (*)(void *), void *);
|
void __synccall(void (*)(void *), void *);
|
||||||
void __synccall_wait(void);
|
void __synccall_wait(void);
|
||||||
|
@ -1,11 +1,32 @@
|
|||||||
#include "pthread_impl.h"
|
#include "pthread_impl.h"
|
||||||
|
|
||||||
|
void __lock_2(volatile int *l)
|
||||||
|
{
|
||||||
|
if (!__syscall(SYS_futex, l, FUTEX_LOCK_PI, 0, 0))
|
||||||
|
return;
|
||||||
|
int old, tid = __pthread_self()->tid;
|
||||||
|
while ((old = a_cas(l, 0, tid))) {
|
||||||
|
a_cas(l, old, old|INT_MIN);
|
||||||
|
__syscall(SYS_futex, l, FUTEX_WAIT, old|INT_MIN, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void __lock(volatile int *l)
|
void __lock(volatile int *l)
|
||||||
{
|
{
|
||||||
int spins=10000;
|
if (a_cas(l, 0, __pthread_self()->tid)) __lock_2(l);
|
||||||
/* Do not use futexes because we insist that unlocking is a simple
|
}
|
||||||
* assignment to optimize non-pathological code with no contention. */
|
|
||||||
while (a_swap(l, 1))
|
void __unlock_2(volatile int *l)
|
||||||
if (spins) spins--, a_spin();
|
{
|
||||||
else __syscall(SYS_sched_yield);
|
if (__syscall(SYS_futex, l, FUTEX_UNLOCK_PI)) {
|
||||||
|
*l = 0;
|
||||||
|
__syscall(SYS_futex, l, FUTEX_WAKE, 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void __unlock(volatile int *l)
|
||||||
|
{
|
||||||
|
int old = *l;
|
||||||
|
if (!(old & INT_MIN) && a_cas(l, old, 0)==old) return;
|
||||||
|
__unlock_2(l);
|
||||||
}
|
}
|
||||||
|
Reference in New Issue
Block a user