aboutsummaryrefslogtreecommitdiff
path: root/platform/linux-generic/odp_timer.c
diff options
context:
space:
mode:
Diffstat (limited to 'platform/linux-generic/odp_timer.c')
-rw-r--r--platform/linux-generic/odp_timer.c120
1 files changed, 91 insertions, 29 deletions
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index ce33c6787..8b2ba16c2 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -26,6 +26,7 @@
#include <odp/api/align.h>
#include <odp_align_internal.h>
#include <odp/api/atomic.h>
+#include <odp/api/plat/atomic_inlines.h>
#include <odp_atomic_internal.h>
#include <odp/api/buffer.h>
#include <odp/api/cpu.h>
@@ -106,7 +107,7 @@ ODP_STATIC_ASSERT(sizeof(tick_buf_t) == 16, "sizeof(tick_buf_t) == 16");
#endif
typedef struct {
- void *user_ptr;
+ const void *user_ptr;
odp_queue_t queue;/* Used for free list when timer is free */
} _odp_timer_t;
@@ -186,10 +187,7 @@ static __thread timer_local_t timer_local;
static void itimer_init(timer_pool_t *tp);
static void itimer_fini(timer_pool_t *tp);
-static void timer_init(_odp_timer_t *tim,
- tick_buf_t *tb,
- odp_queue_t _q,
- void *_up)
+static void timer_init(_odp_timer_t *tim, tick_buf_t *tb, odp_queue_t _q, const void *_up)
{
tim->queue = _q;
tim->user_ptr = _up;
@@ -200,7 +198,7 @@ static void timer_init(_odp_timer_t *tim,
#if __GCC_ATOMIC_LLONG_LOCK_FREE < 2
tb->exp_tck.v = TMO_INACTIVE;
#else
- _odp_atomic_u64_store_mm(&tb->exp_tck, TMO_INACTIVE, _ODP_MEMMODEL_RLS);
+ odp_atomic_store_rel_u64(&tb->exp_tck, TMO_INACTIVE);
#endif
}
@@ -487,9 +485,7 @@ static void odp_timer_pool_del(timer_pool_t *tp)
ODP_ABORT("Failed to free shared memory (%d)\n", rc);
}
-static inline odp_timer_t timer_alloc(timer_pool_t *tp,
- odp_queue_t queue,
- void *user_ptr)
+static inline odp_timer_t timer_alloc(timer_pool_t *tp, odp_queue_t queue, const void *user_ptr)
{
odp_timer_t hdl;
@@ -504,13 +500,12 @@ static inline odp_timer_t timer_alloc(timer_pool_t *tp,
tp->first_free = get_next_free(tim);
/* Initialize timer */
timer_init(tim, &tp->tick_buf[idx], queue, user_ptr);
- if (odp_unlikely(tp->num_alloc >
- odp_atomic_load_u32(&tp->high_wm)))
+ if (odp_unlikely(tp->num_alloc > odp_atomic_load_u32(&tp->high_wm))) {
/* Update high_wm last with release model to
* ensure timer initialization is visible */
- _odp_atomic_u32_store_mm(&tp->high_wm,
- tp->num_alloc,
- _ODP_MEMMODEL_RLS);
+ odp_atomic_store_rel_u32(&tp->high_wm, tp->num_alloc);
+ }
+
hdl = tp_idx_to_handle(tp, idx);
/* Add timer to queue */
_odp_queue_fn->timer_add(queue);
@@ -602,8 +597,8 @@ static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf,
uint64_t old;
/* Swap in new expiration tick, get back old tick which
* will indicate active/inactive timer state */
- old = _odp_atomic_u64_xchg_mm(&tb->exp_tck, abs_tck,
- _ODP_MEMMODEL_RLX);
+ old = odp_atomic_xchg_u64(&tb->exp_tck, abs_tck);
+
if ((old & TMO_INACTIVE) != 0) {
/* Timer was inactive (cancelled or expired),
* we can't reset a timer without a timeout buffer.
@@ -615,12 +610,7 @@ static bool timer_reset(uint32_t idx, uint64_t abs_tck, odp_buffer_t *tmo_buf,
* reset or cancelled the timer. Without any
* synchronization between the threads, we have a
* data race and the behavior is undefined */
- (void)_odp_atomic_u64_cmp_xchg_strong_mm(
- &tb->exp_tck,
- &abs_tck,
- old,
- _ODP_MEMMODEL_RLX,
- _ODP_MEMMODEL_RLX);
+ (void)odp_atomic_cas_u64(&tb->exp_tck, &abs_tck, old);
success = false;
}
#else /* Target supports neither 128-bit nor 64-bit CAS => use lock */
@@ -806,7 +796,7 @@ static inline void timer_expire(timer_pool_t *tp, uint32_t idx, uint64_t tick)
uint64_t exp_tck;
#ifdef ODP_ATOMIC_U128
/* Atomic re-read for correctness */
- exp_tck = _odp_atomic_u64_load_mm(&tb->exp_tck, _ODP_MEMMODEL_RLX);
+ 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
@@ -888,8 +878,7 @@ static inline void timer_expire(timer_pool_t *tp, uint32_t idx, uint64_t tick)
static inline void timer_pool_scan(timer_pool_t *tp, uint64_t tick)
{
tick_buf_t *array = &tp->tick_buf[0];
- uint32_t high_wm = _odp_atomic_u32_load_mm(&tp->high_wm,
- _ODP_MEMMODEL_ACQ);
+ uint32_t high_wm = odp_atomic_load_acq_u32(&tp->high_wm);
uint32_t i;
ODP_ASSERT(high_wm <= tp->param.num_timers);
@@ -1364,9 +1353,7 @@ uint64_t odp_timer_pool_to_u64(odp_timer_pool_t tpid)
return _odp_pri(tpid);
}
-odp_timer_t odp_timer_alloc(odp_timer_pool_t tpid,
- odp_queue_t queue,
- void *user_ptr)
+odp_timer_t odp_timer_alloc(odp_timer_pool_t tpid, odp_queue_t queue, const void *user_ptr)
{
timer_pool_t *tp = timer_pool_from_hdl(tpid);
@@ -1497,7 +1484,7 @@ uint64_t odp_timeout_tick(odp_timeout_t tmo)
void *odp_timeout_user_ptr(odp_timeout_t tmo)
{
- return timeout_hdr(tmo)->user_ptr;
+ return (void *)(uintptr_t)timeout_hdr(tmo)->user_ptr;
}
odp_timeout_t odp_timeout_alloc(odp_pool_t pool)
@@ -1516,6 +1503,81 @@ void odp_timeout_free(odp_timeout_t tmo)
odp_buffer_free(odp_buffer_from_event(ev));
}
+void odp_timer_pool_print(odp_timer_pool_t timer_pool)
+{
+ timer_pool_t *tp;
+
+ if (timer_pool == ODP_TIMER_POOL_INVALID) {
+ ODP_ERR("Bad timer pool handle\n");
+ return;
+ }
+
+ tp = timer_pool_from_hdl(timer_pool);
+
+ ODP_PRINT("\nTimer pool info\n");
+ ODP_PRINT("---------------\n");
+ ODP_PRINT(" timer pool %p\n", tp);
+ ODP_PRINT(" tp index %u\n", tp->tp_idx);
+ ODP_PRINT(" num timers %u\n", tp->num_alloc);
+ ODP_PRINT(" num tp %i\n", timer_global->num_timer_pools);
+ ODP_PRINT(" inline timers %i\n", timer_global->use_inline_timers);
+ ODP_PRINT("\n");
+}
+
+void odp_timer_print(odp_timer_t timer)
+{
+ timer_pool_t *tp;
+ uint32_t idx;
+ _odp_timer_t *tim;
+
+ if (timer == ODP_TIMER_INVALID) {
+ ODP_ERR("Bad timer handle\n");
+ return;
+ }
+
+ tp = handle_to_tp(timer);
+ idx = handle_to_idx(timer, tp);
+ tim = &tp->timers[idx];
+
+ ODP_PRINT("\nTimer info\n");
+ ODP_PRINT("----------\n");
+ ODP_PRINT(" timer pool %p\n", tp);
+ ODP_PRINT(" timer index %u\n", idx);
+ ODP_PRINT(" dest queue 0x%" PRIx64 "\n", odp_queue_to_u64(tim->queue));
+ ODP_PRINT(" user ptr %p\n", tim->user_ptr);
+ ODP_PRINT("\n");
+}
+
+void odp_timeout_print(odp_timeout_t tmo)
+{
+ const odp_timeout_hdr_t *tmo_hdr;
+ odp_timer_t timer;
+ timer_pool_t *tp = NULL;
+ uint32_t idx = 0;
+
+ if (tmo == ODP_TIMEOUT_INVALID) {
+ ODP_ERR("Bad timeout handle\n");
+ return;
+ }
+
+ tmo_hdr = timeout_hdr(tmo);
+ timer = tmo_hdr->timer;
+
+ if (timer != ODP_TIMER_INVALID) {
+ tp = handle_to_tp(timer);
+ idx = handle_to_idx(timer, tp);
+ }
+
+ ODP_PRINT("\nTimeout info\n");
+ ODP_PRINT("------------\n");
+ ODP_PRINT(" tmo handle 0x%" PRIx64 "\n", odp_timeout_to_u64(tmo));
+ ODP_PRINT(" timer pool %p\n", tp);
+ ODP_PRINT(" timer index %u\n", idx);
+ ODP_PRINT(" expiration %" PRIu64 "\n", tmo_hdr->expiration);
+ ODP_PRINT(" user ptr %p\n", tmo_hdr->user_ptr);
+ ODP_PRINT("\n");
+}
+
int _odp_timer_init_global(const odp_init_t *params)
{
odp_shm_t shm;