job/semaphore: add multi-acquire

This commit is contained in:
Danny Robson 2018-03-22 13:37:28 +11:00
parent 804b2263b8
commit 848b9951e8
2 changed files with 19 additions and 8 deletions

View File

@ -32,6 +32,7 @@ namespace util::job {
semaphore& operator= (semaphore&&) = delete;
int acquire (void);
int acquire (int count);
int release (void);
auto lock (void) { return acquire (); }

View File

@ -50,16 +50,18 @@ semaphore::semaphore (int initial):
///////////////////////////////////////////////////////////////////////////////
int
semaphore::acquire (void)
semaphore::acquire (int count)
{
CHECK_GE (count, 0);
do {
int now = m_value;
// if our value is positive then attempt to decrement it and return,
// else retry because someone interfered with us.
if (now > 0) {
if (m_value.compare_exchange_weak (now, now - 1))
return now - 1;
if (now - count >= 0) {
if (m_value.compare_exchange_weak (now, now - count))
return now - count;
continue;
}
@ -67,16 +69,24 @@ semaphore::acquire (void)
// there's been a modification and retry.
if (-1 == sys_futex (&m_value, FUTEX_WAIT, now, nullptr, nullptr, 0)) {
switch (errno) {
case EAGAIN: break;
case EINTR: break;
default:
posix::error::throw_code ();
case EAGAIN: break;
case EINTR: break;
default:
posix::error::throw_code ();
}
}
} while (1);
}
//-----------------------------------------------------------------------------
int
semaphore::acquire (void)
{
return acquire (1);
}
//-----------------------------------------------------------------------------
int
semaphore::release (void)