tech-kern archive
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]
nanosecond debiting cv_timedwait
cv_timedwait can't handle sub-tick waits, which we can't do now but
when we go tickless will be handy.
It's also a pain to use in a loop with a maximum timeout -- it doesn't
tell you how many ticks passed, so you have to maintain that yourself:
unsigned timeout = mstohz(1000);
unsigned now, end;
now = hardclock_ticks;
end = now + timeout;
while (!condition) {
error = cv_timedwait_sig(&sc->sc_cv, &sc->sc_lock,
timeout);
if (error)
goto fail;
now = hardclock_ticks;
if (end < now) {
error = EWOULDBLOCK;
goto fail;
}
timeout = end - now;
}
I propose to add the following routines to address these shortcomings:
int cv_timedwaitns(kcondvar_t *, kmutex_t *, struct timespec *);
int cv_timedwaitns_sig(kcondvar_t *, kmutex_t *, struct timespec *);
cv_timedwaitns(cv, lock, timeout) waits a duration at most timeout for
cv. When it returns, it stores in timeout the remaining time, so that
you can safely write loops like:
struct timespec timeout = { .tv_sec = 1, .tv_nsec = 0 };
int error;
while (!condition) {
error = cv_timedwaitns_sig(&sc->sc_cv, &sc->sc_lock,
&timeout);
if (error)
goto fail;
}
Objections?
int
cv_timedwaitns(kcondvar_t *cv, kmutex_t *lock, struct timespec *wait)
{
struct timespec now, end;
unsigned ticks;
int error;
getnanouptime(&now);
timespecadd(&now, wait, &end);
ticks = mstohz(timespec2ns(wait) / 1000000);
error = cv_timedwait(cv, lock, ticks);
getnanouptime(&now);
if (timespeccmp(&now, &end, <))
timespecsub(&end, &now, wait);
else
timespecclear(wait);
return error;
}
int
cv_timedwaitns_sig(kcondvar_t *cv, kmutex_t *lock, struct timespec *wait)
{
struct timespec now, end;
unsigned ticks;
int error;
getnanouptime(&now);
timespecadd(&now, wait, &end);
ticks = mstohz(timespec2ns(wait) / 1000000);
error = cv_timedwait_sig(cv, lock, ticks);
getnanouptime(&now);
if (timespeccmp(&now, &end, <))
timespecsub(&end, &now, wait);
else
timespecclear(wait);
return error;
}
Home |
Main Index |
Thread Index |
Old Index