diff options
Diffstat (limited to 'platform/linux-generic/odp_timer.c')
-rw-r--r-- | platform/linux-generic/odp_timer.c | 217 |
1 files changed, 107 insertions, 110 deletions
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c index a28d31245..cd98fcc7d 100644 --- a/platform/linux-generic/odp_timer.c +++ b/platform/linux-generic/odp_timer.c @@ -51,6 +51,7 @@ #include <odp_timer_internal.h> #include <odp/api/plat/queue_inlines.h> #include <odp_global_data.h> +#include <odp_event_internal.h> /* Inlined API functions */ #include <odp/api/plat/event_inlines.h> @@ -92,8 +93,8 @@ tick_buf_s { #endif union { - /* ODP_BUFFER_INVALID if timer not active */ - odp_buffer_t tmo_buf; + /* ODP_EVENT_INVALID if timer not active */ + odp_event_t tmo_event; /* Ensures that tick_buf_t is 128 bits */ uint64_t tmo_u64; @@ -192,7 +193,7 @@ static void timer_init(_odp_timer_t *tim, tick_buf_t *tb, odp_queue_t _q, const tim->queue = _q; tim->user_ptr = _up; tb->tmo_u64 = 0; - tb->tmo_buf = ODP_BUFFER_INVALID; + tb->tmo_event = ODP_EVENT_INVALID; /* Release the timer by setting timer state to inactive */ #if __GCC_ATOMIC_LLONG_LOCK_FREE < 2 @@ -206,7 +207,7 @@ static void timer_init(_odp_timer_t *tim, tick_buf_t *tb, odp_queue_t _q, const static void timer_fini(_odp_timer_t *tim, tick_buf_t *tb) { ODP_ASSERT(tb->exp_tck.v == TMO_UNUSED); - ODP_ASSERT(tb->tmo_buf == ODP_BUFFER_INVALID); + ODP_ASSERT(tb->tmo_event == ODP_EVENT_INVALID); tim->queue = ODP_QUEUE_INVALID; tim->user_ptr = NULL; } @@ -266,16 +267,14 @@ static inline odp_timer_t tp_idx_to_handle(timer_pool_t *tp, (idx + 1)); } -static odp_timeout_hdr_t *timeout_hdr_from_buf(odp_buffer_t buf) +static inline odp_timeout_hdr_t *timeout_hdr_from_event(odp_event_t event) { - return (odp_timeout_hdr_t *)(void *)buf_hdl_to_hdr(buf); + return (odp_timeout_hdr_t *)(uintptr_t)event; } -static odp_timeout_hdr_t *timeout_hdr(odp_timeout_t tmo) +static inline odp_timeout_hdr_t *timeout_hdr(odp_timeout_t tmo) { - odp_buffer_t buf = odp_buffer_from_event(odp_timeout_to_event(tmo)); - - return timeout_hdr_from_buf(buf); + return (odp_timeout_hdr_t *)(uintptr_t)tmo; } static odp_timer_pool_t timer_pool_new(const char *name, @@ -286,7 +285,7 @@ static odp_timer_pool_t timer_pool_new(const char *name, size_t sz0, sz1, sz2; uint64_t tp_size; uint64_t res_ns, nsec_per_scan; - uint32_t flags = ODP_SHM_SW_ONLY; + uint32_t flags = 0; if (odp_global_ro.shm_single_va) flags |= ODP_SHM_SINGLE_VA; @@ -376,7 +375,7 @@ static odp_timer_pool_t timer_pool_new(const char *name, #else odp_atomic_init_u64(&tp->tick_buf[i].exp_tck, TMO_UNUSED); #endif - tp->tick_buf[i].tmo_buf = ODP_BUFFER_INVALID; + tp->tick_buf[i].tmo_event = ODP_EVENT_INVALID; } tp->tp_idx = tp_idx; odp_spinlock_init(&tp->lock); @@ -517,16 +516,15 @@ static inline odp_timer_t timer_alloc(timer_pool_t *tp, odp_queue_t queue, const return hdl; } -static odp_buffer_t timer_set_unused(timer_pool_t *tp, - uint32_t idx); +static odp_event_t timer_set_unused(timer_pool_t *tp, uint32_t idx); -static inline odp_buffer_t timer_free(timer_pool_t *tp, uint32_t idx) +static inline odp_event_t timer_free(timer_pool_t *tp, uint32_t idx) { _odp_timer_t *tim = &tp->timers[idx]; /* Free the timer by setting timer state to unused and - * grab any timeout buffer */ - odp_buffer_t old_buf = timer_set_unused(tp, idx); + * grab any timeout event */ + odp_event_t old_event = timer_set_unused(tp, idx); /* Remove timer from queue */ _odp_queue_fn->timer_rem(tim->queue); @@ -542,7 +540,7 @@ static inline odp_buffer_t timer_free(timer_pool_t *tp, uint32_t idx) tp->num_alloc--; odp_spinlock_unlock(&tp->lock); - return old_buf; + return old_event; } /****************************************************************************** @@ -550,36 +548,36 @@ static inline odp_buffer_t timer_free(timer_pool_t *tp, uint32_t idx) * expire/reset/cancel timer *****************************************************************************/ -static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf, +static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_event_t *tmo_event, timer_pool_t *tp) { bool success = true; tick_buf_t *tb = &tp->tick_buf[idx]; - if (tmo_buf == NULL || *tmo_buf == ODP_BUFFER_INVALID) { + if (tmo_event == NULL || *tmo_event == ODP_EVENT_INVALID) { #ifdef ODP_ATOMIC_U128 /* Target supports 128-bit atomic operations */ tick_buf_t new, old; - /* Init all bits, also when tmo_buf is less than 64 bits */ + /* Init all bits, also when tmo_event is less than 64 bits */ new.tmo_u64 = 0; old.tmo_u64 = 0; do { /* Relaxed and non-atomic read of current values */ old.exp_tck.v = tb->exp_tck.v; - old.tmo_buf = tb->tmo_buf; + old.tmo_event = tb->tmo_event; - /* Check if there actually is a timeout buffer + /* Check if there actually is a timeout event * present */ - if (old.tmo_buf == ODP_BUFFER_INVALID) { + if (old.tmo_event == ODP_EVENT_INVALID) { /* Cannot reset a timer with neither old nor - * new timeout buffer */ + * new timeout event */ success = false; break; } /* Set up new values */ new.exp_tck.v = abs_tck; - new.tmo_buf = old.tmo_buf; + new.tmo_event = old.tmo_event; /* Atomic CAS will fail if we experienced torn reads, * retry update sequence until CAS succeeds */ @@ -598,7 +596,7 @@ static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf, if ((old & TMO_INACTIVE) != 0) { /* Timer was inactive (cancelled or expired), - * we can't reset a timer without a timeout buffer. + * we can't reset a timer without a timeout event. * Attempt to restore inactive state, we don't * want this timer to continue as active without * timeout as this will trigger unnecessary and @@ -617,13 +615,13 @@ static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf, while (_odp_atomic_flag_load(IDX2LOCK(idx))) odp_cpu_pause(); - /* Only if there is a timeout buffer can be reset the timer */ - if (odp_likely(tb->tmo_buf != ODP_BUFFER_INVALID)) { + /* Only if there is a timeout event can the timer be reset */ + if (odp_likely(tb->tmo_event != ODP_EVENT_INVALID)) { /* Write the new expiration tick */ tb->exp_tck.v = abs_tck; } else { /* Cannot reset a timer with neither old nor new - * timeout buffer */ + * timeout event */ success = false; } @@ -631,35 +629,34 @@ static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf, _odp_atomic_flag_clear(IDX2LOCK(idx)); #endif } else { - /* We have a new timeout buffer which replaces any old one */ + /* We have a new timeout event which replaces any old one */ /* Fill in some (constant) header fields for timeout events */ - if (odp_event_type(odp_buffer_to_event(*tmo_buf)) == - ODP_EVENT_TIMEOUT) { - /* Convert from buffer to timeout hdr */ + if (odp_event_type(*tmo_event) == ODP_EVENT_TIMEOUT) { + /* Convert from event to timeout hdr */ odp_timeout_hdr_t *tmo_hdr = - timeout_hdr_from_buf(*tmo_buf); + timeout_hdr_from_event(*tmo_event); tmo_hdr->timer = tp_idx_to_handle(tp, idx); tmo_hdr->user_ptr = tp->timers[idx].user_ptr; /* expiration field filled in when timer expires */ } - /* Else ignore buffers of other types */ - odp_buffer_t old_buf = ODP_BUFFER_INVALID; + /* Else ignore events of other types */ + odp_event_t old_event = ODP_EVENT_INVALID; #ifdef ODP_ATOMIC_U128 tick_buf_t new, old; - /* Init all bits, also when tmo_buf is less than 64 bits */ + /* Init all bits, also when tmo_event is less than 64 bits */ new.tmo_u64 = 0; new.exp_tck.v = abs_tck; - new.tmo_buf = *tmo_buf; + new.tmo_event = *tmo_event; - /* We are releasing the new timeout buffer to some other + /* We are releasing the new timeout event to some other * thread */ _odp_atomic_u128_xchg_mm((_odp_atomic_u128_t *)tb, (_uint128_t *)&new, (_uint128_t *)&old, _ODP_MEMMODEL_ACQ_RLS); - old_buf = old.tmo_buf; + old_event = old.tmo_event; #else /* Take a related lock */ while (_odp_atomic_flag_tas(IDX2LOCK(idx))) @@ -667,9 +664,9 @@ static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf, while (_odp_atomic_flag_load(IDX2LOCK(idx))) odp_cpu_pause(); - /* Swap in new buffer, save any old buffer */ - old_buf = tb->tmo_buf; - tb->tmo_buf = *tmo_buf; + /* Swap in new event, save any old event */ + old_event = tb->tmo_event; + tb->tmo_event = *tmo_event; /* Write the new expiration tick */ tb->exp_tck.v = abs_tck; @@ -677,33 +674,32 @@ static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf, /* Release the lock */ _odp_atomic_flag_clear(IDX2LOCK(idx)); #endif - /* Return old timeout buffer */ - *tmo_buf = old_buf; + /* Return old timeout event */ + *tmo_event = old_event; } return success; } -static odp_buffer_t timer_set_unused(timer_pool_t *tp, - uint32_t idx) +static odp_event_t timer_set_unused(timer_pool_t *tp, uint32_t idx) { tick_buf_t *tb = &tp->tick_buf[idx]; - odp_buffer_t old_buf; + odp_event_t old_event; #ifdef ODP_ATOMIC_U128 tick_buf_t new, old; - /* Init all bits, also when tmo_buf is less than 64 bits */ + /* Init all bits, also when tmo_event is less than 64 bits */ new.tmo_u64 = 0; /* Update the timer state (e.g. cancel the current timeout) */ new.exp_tck.v = TMO_UNUSED; - /* Swap out the old buffer */ - new.tmo_buf = ODP_BUFFER_INVALID; + /* Swap out the old event */ + new.tmo_event = ODP_EVENT_INVALID; _odp_atomic_u128_xchg_mm((_odp_atomic_u128_t *)tb, (_uint128_t *)&new, (_uint128_t *)&old, _ODP_MEMMODEL_RLX); - old_buf = old.tmo_buf; + old_event = old.tmo_event; #else /* Take a related lock */ while (_odp_atomic_flag_tas(IDX2LOCK(idx))) @@ -714,44 +710,43 @@ static odp_buffer_t timer_set_unused(timer_pool_t *tp, /* Update the timer state (e.g. cancel the current timeout) */ tb->exp_tck.v = TMO_UNUSED; - /* Swap out the old buffer */ - old_buf = tb->tmo_buf; - tb->tmo_buf = ODP_BUFFER_INVALID; + /* Swap out the old event */ + old_event = tb->tmo_event; + tb->tmo_event = ODP_EVENT_INVALID; /* Release the lock */ _odp_atomic_flag_clear(IDX2LOCK(idx)); #endif - /* Return the old buffer */ - return old_buf; + /* Return the old event */ + return old_event; } -static odp_buffer_t timer_cancel(timer_pool_t *tp, - uint32_t idx) +static odp_event_t timer_cancel(timer_pool_t *tp, uint32_t idx) { tick_buf_t *tb = &tp->tick_buf[idx]; - odp_buffer_t old_buf; + odp_event_t old_event; #ifdef ODP_ATOMIC_U128 tick_buf_t new, old; - /* Init all bits, also when tmo_buf is less than 64 bits */ + /* Init all bits, also when tmo_event is less than 64 bits */ new.tmo_u64 = 0; old.tmo_u64 = 0; do { /* Relaxed and non-atomic read of current values */ old.exp_tck.v = tb->exp_tck.v; - old.tmo_buf = tb->tmo_buf; + old.tmo_event = tb->tmo_event; /* Check if it is not expired already */ if (old.exp_tck.v & TMO_INACTIVE) { - old.tmo_buf = ODP_BUFFER_INVALID; + old.tmo_event = ODP_EVENT_INVALID; break; } /* Set up new values */ new.exp_tck.v = TMO_INACTIVE; - new.tmo_buf = ODP_BUFFER_INVALID; + new.tmo_event = ODP_EVENT_INVALID; /* Atomic CAS will fail if we experienced torn reads, * retry update sequence until CAS succeeds */ @@ -760,7 +755,7 @@ static odp_buffer_t timer_cancel(timer_pool_t *tp, (_uint128_t *)&new, _ODP_MEMMODEL_RLS, _ODP_MEMMODEL_RLX)); - old_buf = old.tmo_buf; + old_event = old.tmo_event; #else /* Take a related lock */ while (_odp_atomic_flag_tas(IDX2LOCK(idx))) @@ -768,56 +763,56 @@ static odp_buffer_t timer_cancel(timer_pool_t *tp, while (_odp_atomic_flag_load(IDX2LOCK(idx))) odp_cpu_pause(); - /* Swap in new buffer, save any old buffer */ - old_buf = tb->tmo_buf; - tb->tmo_buf = ODP_BUFFER_INVALID; + /* Swap in new event, save any old event */ + old_event = tb->tmo_event; + tb->tmo_event = ODP_EVENT_INVALID; /* Write the new expiration tick if it not cancelled */ if (tb->exp_tck.v & TMO_INACTIVE) - old_buf = ODP_BUFFER_INVALID; + old_event = ODP_EVENT_INVALID; else tb->exp_tck.v = TMO_INACTIVE; /* Release the lock */ _odp_atomic_flag_clear(IDX2LOCK(idx)); #endif - /* Return the old buffer */ - return old_buf; + /* Return the old event */ + return old_event; } static inline void timer_expire(timer_pool_t *tp, uint32_t idx, uint64_t tick) { _odp_timer_t *tim = &tp->timers[idx]; tick_buf_t *tb = &tp->tick_buf[idx]; - odp_buffer_t tmo_buf = ODP_BUFFER_INVALID; + odp_event_t tmo_event = ODP_EVENT_INVALID; uint64_t exp_tck; #ifdef ODP_ATOMIC_U128 /* Atomic re-read for correctness */ exp_tck = odp_atomic_load_u64(&tb->exp_tck); /* Re-check exp_tck */ if (odp_likely(exp_tck <= tick)) { - /* Attempt to grab timeout buffer, replace with inactive timer - * and invalid buffer */ + /* Attempt to grab timeout event, replace with inactive timer + * and invalid event. */ tick_buf_t new, old; - /* Init all bits, also when tmo_buf is less than 64 bits */ + /* Init all bits, also when tmo_event is less than 64 bits. */ new.tmo_u64 = 0; old.tmo_u64 = 0; old.exp_tck.v = exp_tck; - old.tmo_buf = tb->tmo_buf; + old.tmo_event = tb->tmo_event; /* Set the inactive/expired bit keeping the expiration tick so * that we can check against the expiration tick of the timeout * when it is received */ new.exp_tck.v = exp_tck | TMO_INACTIVE; - new.tmo_buf = ODP_BUFFER_INVALID; + new.tmo_event = ODP_EVENT_INVALID; int succ = _odp_atomic_u128_cmp_xchg_mm((_odp_atomic_u128_t *)tb, (_uint128_t *)&old, (_uint128_t *)&new, _ODP_MEMMODEL_RLS, _ODP_MEMMODEL_RLX); if (succ) - tmo_buf = old.tmo_buf; + tmo_event = old.tmo_event; /* Else CAS failed, something changed => skip timer * this tick, it will be checked again next tick */ } @@ -831,41 +826,40 @@ static inline void timer_expire(timer_pool_t *tp, uint32_t idx, uint64_t tick) /* Proper check for timer expired */ exp_tck = tb->exp_tck.v; if (odp_likely(exp_tck <= tick)) { - /* Verify that there is a timeout buffer */ - if (odp_likely(tb->tmo_buf != ODP_BUFFER_INVALID)) { - /* Grab timeout buffer, replace with inactive timer - * and invalid buffer */ - tmo_buf = tb->tmo_buf; - tb->tmo_buf = ODP_BUFFER_INVALID; + /* Verify that there is a timeout event */ + if (odp_likely(tb->tmo_event != ODP_EVENT_INVALID)) { + /* Grab timeout event, replace with inactive timer + * and invalid event. */ + tmo_event = tb->tmo_event; + tb->tmo_event = ODP_EVENT_INVALID; /* Set the inactive/expired bit keeping the expiration * tick so that we can check against the expiration * tick of the timeout when it is received */ tb->exp_tck.v |= TMO_INACTIVE; } - /* Else somehow active timer without user buffer */ + /* Else somehow active timer without user event */ } /* Else false positive, ignore */ /* Release the lock */ _odp_atomic_flag_clear(IDX2LOCK(idx)); #endif - if (odp_likely(tmo_buf != ODP_BUFFER_INVALID)) { + if (odp_likely(tmo_event != ODP_EVENT_INVALID)) { /* Fill in expiration tick for timeout events */ - if (odp_event_type(odp_buffer_to_event(tmo_buf)) == - ODP_EVENT_TIMEOUT) { - /* Convert from buffer to timeout hdr */ + if (odp_event_type(tmo_event) == ODP_EVENT_TIMEOUT) { + /* Convert from event to timeout hdr */ odp_timeout_hdr_t *tmo_hdr = - timeout_hdr_from_buf(tmo_buf); + timeout_hdr_from_event(tmo_event); tmo_hdr->expiration = exp_tck; /* timer and user_ptr fields filled in when timer * was set */ } /* Else ignore events of other types */ /* Post the timeout to the destination queue */ - int rc = odp_queue_enq(tim->queue, - odp_buffer_to_event(tmo_buf)); + int rc = odp_queue_enq(tim->queue, tmo_event); + if (odp_unlikely(rc != 0)) { - odp_buffer_free(tmo_buf); - ODP_ABORT("Failed to enqueue timeout buffer (%d)\n", + _odp_event_free(tmo_event); + ODP_ABORT("Failed to enqueue timeout event (%d)\n", rc); } } @@ -1270,6 +1264,12 @@ int odp_timer_res_capability(odp_timer_clk_src_t clk_src, return 0; } +void odp_timer_pool_param_init(odp_timer_pool_param_t *param) +{ + memset(param, 0, sizeof(odp_timer_pool_param_t)); + param->clk_src = ODP_CLOCK_DEFAULT; +} + odp_timer_pool_t odp_timer_pool_create(const char *name, const odp_timer_pool_param_t *param) { @@ -1384,9 +1384,8 @@ odp_event_t odp_timer_free(odp_timer_t hdl) { timer_pool_t *tp = handle_to_tp(hdl); uint32_t idx = handle_to_idx(hdl, tp); - odp_buffer_t old_buf = timer_free(tp, idx); - return odp_buffer_to_event(old_buf); + return timer_free(tp, idx); } int odp_timer_set_abs(odp_timer_t hdl, @@ -1401,7 +1400,7 @@ int odp_timer_set_abs(odp_timer_t hdl, return ODP_TIMER_TOO_NEAR; if (odp_unlikely(abs_tck > cur_tick + tp->max_rel_tck)) return ODP_TIMER_TOO_FAR; - if (timer_reset(idx, abs_tck, (odp_buffer_t *)tmo_ev, tp)) + if (timer_reset(idx, abs_tck, tmo_ev, tp)) return ODP_TIMER_SUCCESS; else return ODP_TIMER_FAIL; @@ -1420,7 +1419,7 @@ int odp_timer_set_rel(odp_timer_t hdl, return ODP_TIMER_TOO_NEAR; if (odp_unlikely(rel_tck > tp->max_rel_tck)) return ODP_TIMER_TOO_FAR; - if (timer_reset(idx, abs_tck, (odp_buffer_t *)tmo_ev, tp)) + if (timer_reset(idx, abs_tck, tmo_ev, tp)) return ODP_TIMER_SUCCESS; else return ODP_TIMER_FAIL; @@ -1431,10 +1430,10 @@ int odp_timer_cancel(odp_timer_t hdl, odp_event_t *tmo_ev) timer_pool_t *tp = handle_to_tp(hdl); uint32_t idx = handle_to_idx(hdl, tp); /* Set the expiration tick of the timer to TMO_INACTIVE */ - odp_buffer_t old_buf = timer_cancel(tp, idx); + odp_event_t old_event = timer_cancel(tp, idx); - if (old_buf != ODP_BUFFER_INVALID) { - *tmo_ev = odp_buffer_to_event(old_buf); + if (old_event != ODP_EVENT_INVALID) { + *tmo_ev = old_event; return 0; /* Active timer cancelled, timeout returned */ } else { return -1; /* Timer already expired, no timeout returned */ @@ -1498,9 +1497,8 @@ void *odp_timeout_user_ptr(odp_timeout_t tmo) odp_timeout_t odp_timeout_alloc(odp_pool_t pool_hdl) { - odp_timeout_t tmo; + odp_event_t event; pool_t *pool; - int ret; ODP_ASSERT(pool_hdl != ODP_POOL_INVALID); @@ -1508,17 +1506,16 @@ odp_timeout_t odp_timeout_alloc(odp_pool_t pool_hdl) ODP_ASSERT(pool->type == ODP_POOL_TIMEOUT); - ret = _odp_buffer_alloc_multi(pool, (odp_buffer_hdr_t **)&tmo, 1); - - if (odp_likely(ret == 1)) - return tmo; + event = _odp_event_alloc(pool); + if (odp_unlikely(event == ODP_EVENT_INVALID)) + return ODP_TIMEOUT_INVALID; - return ODP_TIMEOUT_INVALID; + return odp_timeout_from_event(event); } void odp_timeout_free(odp_timeout_t tmo) { - _odp_buffer_free_multi((odp_buffer_hdr_t **)&tmo, 1); + _odp_event_free(odp_timeout_to_event(tmo)); } void odp_timer_pool_print(odp_timer_pool_t timer_pool) |