Skip to content
Snippets Groups Projects
Commit b03f081c authored by Dmitry Fleytman's avatar Dmitry Fleytman Committed by Pekka Enberg
Browse files

msleep: prepare for interruptible sleep implementation


synch_port::msleep: merge time-out and non-time-out cases
into one conditional branch to avoid code duplication.

This both simplifies the code and makes future implementation of
interruption handling code for interruptable sleeps easier.

Signed-off-by: default avatarDmitry Fleytman <dmitry@daynix.com>
Signed-off-by: default avatarPekka Enberg <penberg@cloudius-systems.com>
parent 530d00cc
No related branches found
No related tags found
No related merge requests found
......@@ -18,8 +18,7 @@
#include <bsd/sys/sys/param.h>
TRACEPOINT(trace_synch_msleep, "chan=%p mtx=%p timo_hz=%d", void *, void *, int);
TRACEPOINT(trace_synch_msleep_wait, "chan=%p", void *);
TRACEPOINT(trace_synch_msleep_timeout_wait, "chan=%p", void *);
TRACEPOINT(trace_synch_msleep_wait, "chan=%p timo_hz=%d", void *, int);
TRACEPOINT(trace_synch_msleep_expired, "chan=%p", void *);
TRACEPOINT(trace_synch_wakeup, "chan=%p", void *);
TRACEPOINT(trace_synch_wakeup_waking, "chan=%p thread=%p", void *, void *);
......@@ -83,57 +82,48 @@ int synch_port::msleep(void *chan, struct mtx *mtx,
mutex_unlock(&_lock);
}
sched::timer t(*sched::thread::current());
if (timo_hz) {
u64 nanoseconds = ticks2ns(timo_hz);
u64 cur_time = clock::get()->time();
sched::timer t(*sched::thread::current());
t.set(cur_time + nanoseconds);
}
trace_synch_msleep_timeout_wait(chan);
if (wait_lock) {
mutex_unlock(wait_lock);
}
sched::thread::wait_until([&] {
return ( (t.expired()) || (wait._awake) );
});
if (!(priority & PDROP) && wait_lock) {
mutex_lock(wait_lock);
}
// msleep timeout
if (!wait._awake) {
trace_synch_msleep_expired(chan);
if (chan) {
// A pointer to the local "wait" may still be on the list -
// need to remove it before we can return:
mutex_lock(&_lock);
auto ppp = _evlist.equal_range(chan);
for (auto it=ppp.first; it!=ppp.second; ++it) {
if ((*it).second == &wait) {
_evlist.erase(it);
break;
}
}
mutex_unlock(&_lock);
}
return (EWOULDBLOCK);
}
trace_synch_msleep_wait(chan, timo_hz);
} else {
if (wait_lock) {
mutex_unlock(wait_lock);
}
trace_synch_msleep_wait(chan);
if (wait_lock) {
mutex_unlock(wait_lock);
}
sched::thread::wait_until([&] {
return (wait._awake);
});
sched::thread::wait_until([&] {
return ( (timo_hz && t.expired()) ||
(wait._awake) );
});
if (!(priority & PDROP) && wait_lock) {
mutex_lock(wait_lock);
if (!(priority & PDROP) && wait_lock) {
mutex_lock(wait_lock);
}
// msleep timeout
if (!wait._awake) {
trace_synch_msleep_expired(chan);
if (chan) {
// A pointer to the local "wait" may still be on the list -
// need to remove it before we can return:
// A pointer to the local "wait" may still be on the list -
// need to remove it before we can return:
mutex_lock(&_lock);
auto ppp = _evlist.equal_range(chan);
for (auto it=ppp.first; it!=ppp.second; ++it) {
if ((*it).second == &wait) {
_evlist.erase(it);
break;
}
}
mutex_unlock(&_lock);
}
return (EWOULDBLOCK);
}
return (0);
......
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