diff options
-rw-r--r-- | include/sbi/sbi_timer.h | 18 | ||||
-rw-r--r-- | lib/sbi/sbi_timer.c | 13 |
2 files changed, 31 insertions, 0 deletions
diff --git a/include/sbi/sbi_timer.h b/include/sbi/sbi_timer.h index 63ef1af..ac48e2b 100644 --- a/include/sbi/sbi_timer.h +++ b/include/sbi/sbi_timer.h @@ -48,6 +48,24 @@ static inline void sbi_timer_udelay(ulong usecs) sbi_timer_delay_loop(usecs, 1000000, NULL, NULL); } +/** + * A blocking function that will wait until @p predicate returns true or + * @p timeout_ms milliseconds elapsed. @p arg will be passed as argument to + * @p predicate function. + * + * @param predicate Pointer to a function that returns true if certain + * condition is met. It shouldn't block the code execution. + * @param arg Argument to pass to @p predicate. + * @param timeout_ms Timeout value in milliseconds. The function will return + * false if @p timeout_ms time period elapsed but still @p predicate doesn't + * return true. + * + * @return true if @p predicate returns true within @p timeout_ms, false + * otherwise. + */ +bool sbi_timer_waitms_until(bool (*predicate)(void *), void *arg, + uint64_t timeout_ms); + /** Get timer value for current HART */ u64 sbi_timer_value(void); diff --git a/lib/sbi/sbi_timer.c b/lib/sbi/sbi_timer.c index b0a6e63..4b24cbe 100644 --- a/lib/sbi/sbi_timer.c +++ b/lib/sbi/sbi_timer.c @@ -76,6 +76,19 @@ void sbi_timer_delay_loop(ulong units, u64 unit_freq, delay_fn(opaque); } +bool sbi_timer_waitms_until(bool (*predicate)(void *), void *arg, + uint64_t timeout_ms) +{ + uint64_t start_time = sbi_timer_value(); + uint64_t ticks = + (sbi_timer_get_device()->timer_freq / 1000) * + timeout_ms; + while(!predicate(arg)) + if (sbi_timer_value() - start_time >= ticks) + return false; + return true; +} + u64 sbi_timer_value(void) { if (get_time_val) |