Merged, thanks!

Maxim.

On 08/21/2014 03:58 PM, Petri Savolainen wrote:
- Start POSIX timer in odp_timer_create
- return correct value int odp_timeout_tick

Signed-off-by: Petri Savolainen <[email protected]>
---
  platform/linux-generic/odp_timer.c | 127 ++++++++++++++++++++++++-------------
  1 file changed, 83 insertions(+), 44 deletions(-)

diff --git a/platform/linux-generic/odp_timer.c 
b/platform/linux-generic/odp_timer.c
index 73a690b..1bf37f9 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -29,9 +29,11 @@ typedef struct {
  } tick_t;
typedef struct {
+       int               allocated;
        volatile int      active;
        volatile uint64_t cur_tick;
        timer_t           timerid;
+       odp_timer_t       timer_hdl;
        odp_buffer_pool_t pool;
        uint64_t          resolution_ns;
        uint64_t          max_ticks;
@@ -40,8 +42,10 @@ typedef struct {
  } timer_ring_t;
typedef struct {
-       timer_ring_t     timer[NUM_TIMERS];
-       odp_atomic_int_t num_timers;
+       odp_spinlock_t lock;
+       int            num_timers;
+       timer_ring_t   timer[NUM_TIMERS];
+
  } timer_global_t;
/* Global */
@@ -105,7 +109,7 @@ static int find_and_del_tmo(timeout_t **tmo, 
odp_timer_tmo_t handle)
        return 0;
  }
-int odp_timer_cancel_tmo(odp_timer_t timer, odp_timer_tmo_t tmo)
+int odp_timer_cancel_tmo(odp_timer_t timer_hdl, odp_timer_tmo_t tmo)
  {
        int id;
        uint64_t tick_idx;
@@ -114,7 +118,7 @@ int odp_timer_cancel_tmo(odp_timer_t timer, odp_timer_tmo_t 
tmo)
        tick_t *tick;
/* get id */
-       id = timer - 1;
+       id = timer_hdl - 1;
tmo_hdr = odp_timeout_hdr((odp_timeout_t) tmo);
        /* get tmo_buf to cancel */
@@ -137,19 +141,25 @@ int odp_timer_cancel_tmo(odp_timer_t timer, 
odp_timer_tmo_t tmo)
static void notify_function(union sigval sigval)
  {
-       (void) sigval;
        uint64_t cur_tick;
        timeout_t *tmo;
        tick_t *tick;
+       timer_ring_t *timer;
+
+       timer = sigval.sival_ptr;
- if (odp_timer.timer[0].active == 0)
+       if (timer->active == 0) {
+               ODP_DBG("Timer (%u) not active\n", timer->timer_hdl);
                return;
+       }
/* ODP_DBG("Tick\n"); */ - cur_tick = odp_timer.timer[0].cur_tick++;
+       cur_tick = timer->cur_tick++;
+
+       odp_sync_stores();
- tick = &odp_timer.timer[0].tick[cur_tick % MAX_TICKS];
+       tick = &timer->tick[cur_tick % MAX_TICKS];
while ((tmo = rem_tmo(tick)) != NULL) {
                odp_queue_t  queue;
@@ -165,21 +175,21 @@ static void notify_function(union sigval sigval)
        }
  }
-static void timer_init(void)
+static void timer_start(timer_ring_t *timer)
  {
        struct sigevent   sigev;
        struct itimerspec ispec;
- ODP_DBG("Timer thread starts\n");
+       ODP_DBG("\nTimer (%u) starts\n", timer->timer_hdl);
memset(&sigev, 0, sizeof(sigev));
        memset(&ispec, 0, sizeof(ispec));
sigev.sigev_notify = SIGEV_THREAD;
        sigev.sigev_notify_function = notify_function;
+       sigev.sigev_value.sival_ptr = timer;
- if (timer_create(CLOCK_MONOTONIC, &sigev,
-                        &odp_timer.timer[0].timerid)) {
+       if (timer_create(CLOCK_MONOTONIC, &sigev, &timer->timerid)) {
                ODP_DBG("Timer create failed\n");
                return;
        }
@@ -189,7 +199,7 @@ static void timer_init(void)
        ispec.it_value.tv_sec     = 0;
        ispec.it_value.tv_nsec    = RESOLUTION_NS;
- if (timer_settime(odp_timer.timer[0].timerid, 0, &ispec, NULL)) {
+       if (timer_settime(timer->timerid, 0, &ispec, NULL)) {
                ODP_DBG("Timer set failed\n");
                return;
        }
@@ -199,14 +209,13 @@ static void timer_init(void)
int odp_timer_init_global(void)
  {
-       int i;
+       ODP_DBG("Timer init ...");
memset(&odp_timer, 0, sizeof(timer_global_t)); - for (i = 0; i < MAX_TICKS; i++)
-               odp_spinlock_init(&odp_timer.timer[0].tick[i].lock);
+       odp_spinlock_init(&odp_timer.lock);
- timer_init();
+       ODP_DBG("done\n");
return 0;
  }
@@ -216,7 +225,9 @@ int odp_timer_disarm_all(void)
        int timers;
        struct itimerspec ispec;
- timers = odp_atomic_load_int(&odp_timer.num_timers);
+       odp_spinlock_lock(&odp_timer.lock);
+
+       timers = odp_timer.num_timers;
ispec.it_interval.tv_sec = 0;
        ispec.it_interval.tv_nsec = 0;
@@ -227,11 +238,14 @@ int odp_timer_disarm_all(void)
                if (timer_settime(odp_timer.timer[timers].timerid,
                                  0, &ispec, NULL)) {
                        ODP_DBG("Timer reset failed\n");
+                       odp_spinlock_unlock(&odp_timer.lock);
                        return -1;
                }
-               odp_atomic_fetch_sub_int(&odp_timer.num_timers, 1);
+               odp_timer.num_timers--;
        }
+ odp_spinlock_unlock(&odp_timer.lock);
+
        return 0;
  }
@@ -240,27 +254,50 @@ odp_timer_t odp_timer_create(const char *name, odp_buffer_pool_t pool,
                             uint64_t max_tmo)
  {
        uint32_t id;
+       timer_ring_t *timer;
+       odp_timer_t timer_hdl;
+       int i;
        (void) name; (void) resolution; (void) min_tmo; (void) max_tmo;
- if (odp_timer.num_timers >= NUM_TIMERS)
-               return ODP_TIMER_INVALID;
+       odp_spinlock_lock(&odp_timer.lock);
- id = odp_atomic_fetch_inc_int(&odp_timer.num_timers);
-       if (id >= NUM_TIMERS)
+       if (odp_timer.num_timers >= NUM_TIMERS) {
+               odp_spinlock_unlock(&odp_timer.lock);
                return ODP_TIMER_INVALID;
+       }
+
+       for (id = 0; id < NUM_TIMERS; id++) {
+               if (odp_timer.timer[id].allocated == 0)
+                       break;
+       }
- odp_timer.timer[id].pool = pool;
-       odp_timer.timer[id].resolution_ns = RESOLUTION_NS;
-       odp_timer.timer[id].max_ticks     = MAX_TICKS;
+       timer = &odp_timer.timer[id];
+       timer->allocated = 1;
+       odp_timer.num_timers++;
+
+       odp_spinlock_unlock(&odp_timer.lock);
+
+       timer_hdl = id + 1;
+
+       timer->timer_hdl     = timer_hdl;
+       timer->pool          = pool;
+       timer->resolution_ns = RESOLUTION_NS;
+       timer->max_ticks     = MAX_TICKS;
+
+       for (i = 0; i < MAX_TICKS; i++) {
+               odp_spinlock_init(&timer->tick[i].lock);
+               timer->tick[i].list = NULL;
+       }
+ timer->active = 1;
        odp_sync_stores();
- odp_timer.timer[id].active = 1;
+       timer_start(timer);
- return id + 1;
+       return timer_hdl;
  }
-odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, uint64_t tmo_tick,
+odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer_hdl, uint64_t 
tmo_tick,
                                       odp_queue_t queue, odp_buffer_t buf)
  {
        int id;
@@ -269,10 +306,12 @@ odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, 
uint64_t tmo_tick,
        timeout_t *new_tmo;
        odp_buffer_t tmo_buf;
        odp_timeout_hdr_t *tmo_hdr;
+       timer_ring_t *timer;
- id = timer - 1;
+       id = timer_hdl - 1;
+       timer = &odp_timer.timer[id];
- cur_tick = odp_timer.timer[id].cur_tick;
+       cur_tick = timer->cur_tick;
        if (tmo_tick <= cur_tick) {
                ODP_DBG("timeout too close\n");
                return ODP_TIMER_TMO_INVALID;
@@ -286,7 +325,7 @@ odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, 
uint64_t tmo_tick,
tick = (cur_tick + tick) % MAX_TICKS; - tmo_buf = odp_buffer_alloc(odp_timer.timer[id].pool);
+       tmo_buf = odp_buffer_alloc(timer->pool);
        if (tmo_buf == ODP_BUFFER_INVALID) {
                ODP_DBG("alloc failed\n");
                return ODP_TIMER_TMO_INVALID;
@@ -306,48 +345,48 @@ odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer, 
uint64_t tmo_tick,
        else
                new_tmo->buf = tmo_buf;
- add_tmo(&odp_timer.timer[id].tick[tick], new_tmo);
+       add_tmo(&timer->tick[tick], new_tmo);
return tmo_buf;
  }
-uint64_t odp_timer_tick_to_ns(odp_timer_t timer, uint64_t ticks)
+uint64_t odp_timer_tick_to_ns(odp_timer_t timer_hdl, uint64_t ticks)
  {
        uint32_t id;
- id = timer - 1;
+       id = timer_hdl - 1;
        return ticks * odp_timer.timer[id].resolution_ns;
  }
-uint64_t odp_timer_ns_to_tick(odp_timer_t timer, uint64_t ns)
+uint64_t odp_timer_ns_to_tick(odp_timer_t timer_hdl, uint64_t ns)
  {
        uint32_t id;
- id = timer - 1;
+       id = timer_hdl - 1;
        return ns / odp_timer.timer[id].resolution_ns;
  }
-uint64_t odp_timer_resolution(odp_timer_t timer)
+uint64_t odp_timer_resolution(odp_timer_t timer_hdl)
  {
        uint32_t id;
- id = timer - 1;
+       id = timer_hdl - 1;
        return odp_timer.timer[id].resolution_ns;
  }
-uint64_t odp_timer_maximum_tmo(odp_timer_t timer)
+uint64_t odp_timer_maximum_tmo(odp_timer_t timer_hdl)
  {
        uint32_t id;
- id = timer - 1;
+       id = timer_hdl - 1;
        return odp_timer.timer[id].max_ticks;
  }
-uint64_t odp_timer_current_tick(odp_timer_t timer)
+uint64_t odp_timer_current_tick(odp_timer_t timer_hdl)
  {
        uint32_t id;
- id = timer - 1;
+       id = timer_hdl - 1;
        return odp_timer.timer[id].cur_tick;
  }
@@ -359,5 +398,5 @@ odp_timeout_t odp_timeout_from_buffer(odp_buffer_t buf)
  uint64_t odp_timeout_tick(odp_timeout_t tmo)
  {
        odp_timeout_hdr_t *tmo_hdr = odp_timeout_hdr(tmo);
-       return tmo_hdr->meta.tick;
+       return tmo_hdr->meta.tmo_tick;
  }


_______________________________________________
lng-odp mailing list
[email protected]
http://lists.linaro.org/mailman/listinfo/lng-odp

Reply via email to