mirror of
https://github.com/Ardour/ardour.git
synced 2025-12-06 06:44:57 +01:00
Improve PBD::Semaphore performance
Skip syscall if no threads are waiting and decouple atomic value from futex address so that FUTEX_WAIT does not fail.
This commit is contained in:
parent
f849f3ce2c
commit
40fa6e2023
2 changed files with 14 additions and 23 deletions
|
|
@ -47,7 +47,8 @@ class LIBPBD_API Semaphore {
|
|||
sem_t* _sem;
|
||||
sem_t* ptr_to_sem() const { return _sem; }
|
||||
#elif defined USE_FUTEX_SEMAPHORE
|
||||
std::atomic<unsigned int> _value;
|
||||
int _futex;
|
||||
std::atomic<int> _value;
|
||||
#else
|
||||
mutable sem_t _sem;
|
||||
sem_t* ptr_to_sem() const { return &_sem; }
|
||||
|
|
|
|||
|
|
@ -23,6 +23,7 @@
|
|||
#ifdef USE_FUTEX_SEMAPHORE
|
||||
#include <errno.h>
|
||||
#include <linux/futex.h>
|
||||
#include <sched.h>
|
||||
#include <syscall.h>
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
|
|
@ -103,23 +104,19 @@ Semaphore::reset ()
|
|||
int
|
||||
Semaphore::signal ()
|
||||
{
|
||||
std::atomic_fetch_add_explicit (&_value, 1, std::memory_order_release);
|
||||
return syscall (__NR_futex, &_value, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0);
|
||||
if (std::atomic_fetch_add_explicit (&_value, 1, std::memory_order_relaxed) < 0) {
|
||||
while (syscall (__NR_futex, &_futex, FUTEX_WAKE_PRIVATE, 1, NULL, NULL, 0) < 1) {
|
||||
sched_yield();
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
Semaphore::wait ()
|
||||
{
|
||||
unsigned int value = 1;
|
||||
while (!std::atomic_compare_exchange_weak_explicit (&_value, &value, value - 1, std::memory_order_acquire, std::memory_order_relaxed)) {
|
||||
if (value == 0) {
|
||||
if (syscall (__NR_futex, &_value, FUTEX_WAIT_PRIVATE, 0, NULL, NULL, 0)) {
|
||||
if (errno != EAGAIN && errno != EINTR) {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
value = 1;
|
||||
}
|
||||
if (std::atomic_fetch_sub_explicit (&_value, 1, std::memory_order_relaxed) <= 0) {
|
||||
syscall(__NR_futex, &_futex, FUTEX_WAIT_PRIVATE, _futex, NULL, 0, 0);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
@ -127,16 +124,9 @@ Semaphore::wait ()
|
|||
int
|
||||
Semaphore::reset ()
|
||||
{
|
||||
int rv = 0;
|
||||
unsigned int value = 1;
|
||||
|
||||
while (!std::atomic_compare_exchange_weak_explicit (&_value, &value, value - 1, std::memory_order_acquire, std::memory_order_relaxed)) {
|
||||
if (value == 0) {
|
||||
break;
|
||||
}
|
||||
++rv;
|
||||
}
|
||||
return rv;
|
||||
int value = _value;
|
||||
_value = 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue