base: add 'wait_for_any' to 'Register_set'

This is the same as 'wait_for' with the difference that 'wait_for_any'
succeeds when *one* condition is met.

issue #3636
This commit is contained in:
Sebastian Sumpf 2020-01-08 12:58:17 +01:00 committed by Norman Feske
parent 57ea1dbdd3
commit de24035066
2 changed files with 41 additions and 0 deletions

View File

@ -103,6 +103,10 @@ class Genode::Register_set : Noncopyable
inline bool _conditions_met(CONDITION condition) {
return condition.met(read<typename CONDITION::Object>()); }
template <typename CONDITION>
inline bool _one_condition_met(CONDITION condition) {
return condition.met(read<typename CONDITION::Object>()); }
/**
* Return wether a list of IO conditions is met
*
@ -118,6 +122,14 @@ class Genode::Register_set : Noncopyable
inline bool _conditions_met(CONDITION head, CONDITIONS... tail) {
return _conditions_met(head) ? _conditions_met(tail...) : false; }
/**
* Same as '_conditions_met' but returns true if one condition in a list of
* IO conditions is met
*/
template <typename CONDITION, typename... CONDITIONS>
inline bool _one_condition_met(CONDITION head, CONDITIONS... tail) {
return _conditions_met(head) ? true : _one_condition_met(tail...); }
/**
* This template equips registers/bitfields with conditions for polling
*
@ -720,6 +732,35 @@ class Genode::Register_set : Noncopyable
wait_for<CONDITIONS...>(Attempts(500), Microseconds(1000),
delayer, conditions...);
}
/**
* Same as 'wait_for' but wait until one condition in a list of IO
* conditions is met
*/
template <typename... CONDITIONS>
inline void wait_for_any(Attempts attempts,
Microseconds us,
Delayer &delayer,
CONDITIONS... conditions)
{
for (unsigned i = 0; i < attempts.value; i++,
delayer.usleep(us.value))
{
if (_one_condition_met(conditions...)) {
return; }
}
throw Polling_timeout();
}
/**
* Shortcut for 'wait_for' with 'attempts = 500' and 'us = 1000'
*/
template <typename... CONDITIONS>
inline void wait_for_any(Delayer &delayer, CONDITIONS... conditions)
{
wait_for_any<CONDITIONS...>(Attempts(500), Microseconds(1000),
delayer, conditions...);
}
};
#endif /* _INCLUDE__UTIL__REGISTER_SET_H_ */