Skip to content
Snippets Groups Projects
Commit 7890e39a authored by Nadav Har'El's avatar Nadav Har'El
Browse files

Added timeout parameter to semaphore::wait()

Added a timeout parameter to semaphore::wait(), which defaults to no
timeout.

semaphore:wait() is now a boolean, just like trywait(), and likewise can
return false when the semaphore has not actually been decremented but
rather we had a timeout.

Because we need the mutex again after the wait, I replaced the "with_lock"
mechanism by the better-looking lock_guard and mutex parameter to
wait_until.
parent 9c9416cd
No related branches found
No related tags found
No related merge requests found
...@@ -22,25 +22,30 @@ void semaphore::post(unsigned units) ...@@ -22,25 +22,30 @@ void semaphore::post(unsigned units)
}); });
} }
void semaphore::wait(unsigned units) bool semaphore::wait(unsigned units, sched::timer* tmr)
{ {
bool wait = false;
wait_record wr; wait_record wr;
wr.owner = nullptr; wr.owner = nullptr;
with_lock(_mtx, [&] {
if (_val >= units) {
_val -= units;
} else {
wr.owner = sched::thread::current();
wr.units = units;
_waiters.push_back(wr);
wait = true;
}
});
if (wait) std::lock_guard<mutex> guard(_mtx);
sched::thread::wait_until([&] { return !wr.owner; });
} if (_val >= units) {
_val -= units;
return true;
} else {
wr.owner = sched::thread::current();
wr.units = units;
_waiters.push_back(wr);
}
sched::thread::wait_until(_mtx,
[&] { return (tmr && tmr->expired()) || !wr.owner; });
// if wr.owner, it's a timeout - post() didn't wake us and didn't decrease
// the semaphore's value for us. Note we are holding the mutex, so there
// can be no race with post().
return !wr.owner;
}
bool semaphore::trywait(unsigned units) bool semaphore::trywait(unsigned units)
{ {
......
...@@ -9,7 +9,7 @@ class semaphore { ...@@ -9,7 +9,7 @@ class semaphore {
public: public:
explicit semaphore(unsigned val); explicit semaphore(unsigned val);
void post(unsigned units = 1); void post(unsigned units = 1);
void wait(unsigned units = 1); bool wait(unsigned units = 1, sched::timer* tmr = nullptr);
bool trywait(unsigned units = 1); bool trywait(unsigned units = 1);
private: private:
unsigned _val; unsigned _val;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment