Revert "Use strictly-typed Microseconds for Libc timeout scheduling"

This reverts commit 4808565a28afe9ff248fb5c98aceb6f8d3e791c1.
This commit is contained in:
Christian Helmuth 2018-12-03 14:37:54 +01:00 committed by Norman Feske
parent e1b27885f9
commit 8236a18260
5 changed files with 58 additions and 66 deletions

View File

@ -948,7 +948,6 @@ _ZN16Pthread_registry6insertEP7pthread T
_ZN16Pthread_registry6removeEP7pthread T _ZN16Pthread_registry6removeEP7pthread T
_ZN16Pthread_registry8containsEP7pthread T _ZN16Pthread_registry8containsEP7pthread T
_ZN4Libc14pthread_createEPP7pthreadPFPvS3_ES3_mPKcPN6Genode11Cpu_sessionENS8_8Affinity8LocationE T _ZN4Libc14pthread_createEPP7pthreadPFPvS3_ES3_mPKcPN6Genode11Cpu_sessionENS8_8Affinity8LocationE T
_ZN4Libc7suspendERNS_15Suspend_functorEN6Genode12MicrosecondsE T
# #
# Libc plugin interface # Libc plugin interface

View File

@ -19,14 +19,12 @@
extern "C" __attribute__((weak)) extern "C" __attribute__((weak))
int _nanosleep(const struct timespec *req, struct timespec *rem) int _nanosleep(const struct timespec *req, struct timespec *rem)
{ {
using namespace Libc; unsigned long sleep_ms = req->tv_sec*1000 + req->tv_nsec/1000000;
Microseconds sleep_us(req->tv_sec*1000*1000 + req->tv_nsec/1000); if (!sleep_ms) return 0;
if (!sleep_us.value) return 0;
struct Check : Libc::Suspend_functor { bool suspend() override { return true; } } check; struct Check : Libc::Suspend_functor { bool suspend() override { return true; } } check;
do { sleep_us = Libc::suspend(check, sleep_us); } while (sleep_us.value); do { sleep_ms = Libc::suspend(check, sleep_ms); } while (sleep_ms);
if (rem) { if (rem) {
rem->tv_sec = 0; rem->tv_sec = 0;

View File

@ -220,8 +220,6 @@ __attribute__((weak))
_select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds, _select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
struct timeval *tv) struct timeval *tv)
{ {
using namespace Libc;
fd_set in_readfds, in_writefds, in_exceptfds; fd_set in_readfds, in_writefds, in_exceptfds;
Genode::Constructible<Libc::Select_cb> select_cb; Genode::Constructible<Libc::Select_cb> select_cb;
@ -264,10 +262,10 @@ _select(int nfds, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
{ {
timeval const *_tv; timeval const *_tv;
bool const valid { _tv != nullptr }; bool const valid { _tv != nullptr };
Microseconds duration { unsigned long duration {
valid ? (unsigned long)_tv->tv_sec*1000 + _tv->tv_usec : 0UL }; valid ? (unsigned long)_tv->tv_sec*1000 + _tv->tv_usec/1000 : 0UL };
bool expired() const { return valid && duration.value == 0; }; bool expired() const { return valid && duration == 0; };
Timeout(timeval *tv) : _tv(tv) { } Timeout(timeval *tv) : _tv(tv) { }
} timeout { tv }; } timeout { tv };

View File

@ -49,7 +49,7 @@ namespace Libc {
class Timeout_handler; class Timeout_handler;
class Io_response_handler; class Io_response_handler;
using Genode::Duration; using Genode::Microseconds;
} }
@ -217,7 +217,7 @@ struct Libc::Timer
Timer(Genode::Env &env) : _timer(env) { } Timer(Genode::Env &env) : _timer(env) { }
Duration curr_time() Genode::Duration curr_time()
{ {
return _timer.curr_time(); return _timer.curr_time();
} }
@ -227,9 +227,9 @@ struct Libc::Timer
return Microseconds(1000*timeout_ms); return Microseconds(1000*timeout_ms);
} }
static Microseconds max_timeout() static unsigned long max_timeout()
{ {
return Microseconds(~0UL/(1000*1000)); return ~0UL/1000;
} }
}; };
@ -262,13 +262,13 @@ struct Libc::Timeout
Timeout_handler &_handler; Timeout_handler &_handler;
::Timer::One_shot_timeout<Timeout> _timeout; ::Timer::One_shot_timeout<Timeout> _timeout;
bool _expired = true; bool _expired = true;
Duration _absolute_timeout { Microseconds(0) }; unsigned long _absolute_timeout_ms = 0;
void _handle(Duration now) void _handle(Duration now)
{ {
_expired = true; _expired = true;
_absolute_timeout = Duration(Microseconds(0)); _absolute_timeout_ms = 0;
_handler.handle_timeout(); _handler.handle_timeout();
} }
@ -279,23 +279,24 @@ struct Libc::Timeout
_timeout(_timer_accessor.timer()._timer, *this, &Timeout::_handle) _timeout(_timer_accessor.timer()._timer, *this, &Timeout::_handle)
{ } { }
void start(Microseconds timeout_us) void start(unsigned long timeout_ms)
{ {
_absolute_timeout = _timer_accessor.timer().curr_time(); Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms();
_absolute_timeout.add(timeout_us);
_timeout.schedule(timeout_us); _expired = false;
_absolute_timeout_ms = now.value + timeout_ms;
_timeout.schedule(_timer_accessor.timer().microseconds(timeout_ms));
} }
Microseconds duration_left() const unsigned long duration_left() const
{ {
Duration const now = _timer_accessor.timer().curr_time(); Milliseconds const now = _timer_accessor.timer().curr_time().trunc_to_plain_ms();
if (_expired || _absolute_timeout.less_than(now)) if (_expired || _absolute_timeout_ms < now.value)
return Microseconds(0); return 0;
return Microseconds(_absolute_timeout.trunc_to_plain_us().value return _absolute_timeout_ms - now.value;
- now.trunc_to_plain_us().value);
} }
}; };
@ -316,16 +317,16 @@ struct Libc::Pthreads
_timeout.construct(_timer_accessor, *this); _timeout.construct(_timer_accessor, *this);
} }
Pthread(Timer_accessor &timer_accessor, Microseconds timeout) Pthread(Timer_accessor &timer_accessor, unsigned long timeout_ms)
: _timer_accessor(timer_accessor) : _timer_accessor(timer_accessor)
{ {
if (timeout.value > 0) { if (timeout_ms > 0) {
_construct_timeout_once(); _construct_timeout_once();
_timeout->start(timeout); _timeout->start(timeout_ms);
} }
} }
Microseconds duration_left() unsigned long duration_left()
{ {
_construct_timeout_once(); _construct_timeout_once();
return _timeout->duration_left(); return _timeout->duration_left();
@ -353,9 +354,9 @@ struct Libc::Pthreads
p->lock.unlock(); p->lock.unlock();
} }
Microseconds suspend_myself(Suspend_functor & check, Microseconds timeout_us) unsigned long suspend_myself(Suspend_functor & check, unsigned long timeout_ms)
{ {
Pthread myself { timer_accessor, timeout_us }; Pthread myself { timer_accessor, timeout_ms };
{ {
Genode::Lock::Guard g(mutex); Genode::Lock::Guard g(mutex);
@ -378,7 +379,7 @@ struct Libc::Pthreads
} }
} }
return timeout_us.value > 0 ? myself.duration_left() : Microseconds(0); return timeout_ms > 0 ? myself.duration_left() : 0;
} }
}; };
@ -502,13 +503,13 @@ struct Libc::Kernel
: _timer_accessor(timer_accessor), _kernel(kernel) : _timer_accessor(timer_accessor), _kernel(kernel)
{ } { }
void timeout(Microseconds timeout) void timeout(unsigned long timeout_ms)
{ {
_construct_timeout_once(); _construct_timeout_once();
_timeout->start(timeout); _timeout->start(timeout_ms);
} }
Microseconds duration_left() unsigned long duration_left()
{ {
_construct_timeout_once(); _construct_timeout_once();
return _timeout->duration_left(); return _timeout->duration_left();
@ -552,7 +553,7 @@ struct Libc::Kernel
kernel->_app_code->execute(); kernel->_app_code->execute();
kernel->_app_returned = true; kernel->_app_returned = true;
kernel->_suspend_main(check, Microseconds(0)); kernel->_suspend_main(check, 0);
} }
bool _main_context() const { return &_myself == Genode::Thread::myself(); } bool _main_context() const { return &_myself == Genode::Thread::myself(); }
@ -585,8 +586,8 @@ struct Libc::Kernel
_longjmp(_user_context, 1); _longjmp(_user_context, 1);
} }
Microseconds _suspend_main(Suspend_functor &check, unsigned long _suspend_main(Suspend_functor &check,
Microseconds timeout) unsigned long timeout_ms)
{ {
/* check that we're not running on libc kernel context */ /* check that we're not running on libc kernel context */
if (Thread::mystack().top == _kernel_stack) { if (Thread::mystack().top == _kernel_stack) {
@ -596,10 +597,10 @@ struct Libc::Kernel
} }
if (!check.suspend()) if (!check.suspend())
return Microseconds(0); return 0;
if (timeout.value > 0) if (timeout_ms > 0)
_main_timeout.timeout(timeout); _main_timeout.timeout(timeout_ms);
if (!_setjmp(_user_context)) { if (!_setjmp(_user_context)) {
_valid_user_context = true; _valid_user_context = true;
@ -627,8 +628,7 @@ struct Libc::Kernel
_longjmp(_kernel_context, 1); _longjmp(_kernel_context, 1);
} }
return timeout.value > 0 return timeout_ms > 0 ? _main_timeout.duration_left() : 0;
? _main_timeout.duration_left() : Microseconds(0);
} }
public: public:
@ -721,19 +721,19 @@ struct Libc::Kernel
/** /**
* Suspend this context (main or pthread) * Suspend this context (main or pthread)
*/ */
Microseconds suspend(Suspend_functor &check, Microseconds timeout_us) unsigned long suspend(Suspend_functor &check, unsigned long timeout_ms)
{ {
if (timeout_us.value > 0 if (timeout_ms > 0
&& timeout_us.value > _timer_accessor.timer().max_timeout().value) { && timeout_ms > _timer_accessor.timer().max_timeout()) {
Genode::warning("libc: limiting exceeding timeout of ", Genode::warning("libc: limiting exceeding timeout of ",
timeout_us, " us to maximum of ", timeout_ms, " ms to maximum of ",
_timer_accessor.timer().max_timeout(), " us"); _timer_accessor.timer().max_timeout(), " ms");
timeout_us = min(timeout_us, _timer_accessor.timer().max_timeout()); timeout_ms = min(timeout_ms, _timer_accessor.timer().max_timeout());
} }
return _main_context() ? _suspend_main(check, timeout_us) return _main_context() ? _suspend_main(check, timeout_ms)
: _pthreads.suspend_myself(check, timeout_us); : _pthreads.suspend_myself(check, timeout_ms);
} }
void dispatch_pending_io_signals() void dispatch_pending_io_signals()
@ -751,7 +751,7 @@ struct Libc::Kernel
} }
} }
Duration current_time() Genode::Duration current_time()
{ {
return _timer_accessor.timer().curr_time(); return _timer_accessor.timer().curr_time();
} }
@ -873,13 +873,13 @@ static void resumed_callback() { kernel->entrypoint_resumed(); }
void Libc::resume_all() { kernel->resume_all(); } void Libc::resume_all() { kernel->resume_all(); }
Libc::Microseconds Libc::suspend(Suspend_functor &s, Microseconds timeout_us) unsigned long Libc::suspend(Suspend_functor &s, unsigned long timeout_ms)
{ {
if (!kernel) { if (!kernel) {
error("libc kernel not initialized, needed for suspend()"); error("libc kernel not initialized, needed for suspend()");
exit(1); exit(1);
} }
return kernel->suspend(s, timeout_us); return kernel->suspend(s, timeout_ms);
} }

View File

@ -26,8 +26,6 @@
namespace Libc { namespace Libc {
using Genode::Microseconds;
/** /**
* Resume all user contexts * Resume all user contexts
* *
@ -38,19 +36,18 @@ namespace Libc {
/** /**
* Suspend the execution of the calling user context * Suspend the execution of the calling user context
* *
* \param timeout maximum time to stay suspended in microseconds, * \param timeout_ms maximum time to stay suspended in milliseconds,
* 0 for infinite suspend * 0 for infinite suspend
* *
* \return remaining duration until timeout, * \return remaining duration until timeout,
* 0 if the timeout expired * 0 if the timeout expired
* *
* The context could be running on the component entrypoint as main context * The context could be running on the component entrypoint as main context
* or as separate pthread. This function returns after the libc kernel * or as separate pthread. This function returns after the libc kernel
* resumed the user context execution. * resumed the user context execution.
*/ */
struct Suspend_functor { virtual bool suspend() = 0; }; struct Suspend_functor { virtual bool suspend() = 0; };
Microseconds suspend(Suspend_functor &, unsigned long suspend(Suspend_functor &, unsigned long timeout_ms = 0UL);
Microseconds timeout = Microseconds(0UL));
void dispatch_pending_io_signals(); void dispatch_pending_io_signals();