diff mbox

[v3,1/2] Use timer resolution

Message ID 1409751302-3904-1-git-send-email-petri.savolainen@linaro.org
State New
Headers show

Commit Message

Petri Savolainen Sept. 3, 2014, 1:35 p.m. UTC
Use resolution and min/max tmo values from timer create call.
Use common nanosec time defines.

Signed-off-by: Petri Savolainen <petri.savolainen@linaro.org>
---
 platform/linux-generic/include/api/odp_time.h |  5 ++
 platform/linux-generic/odp_timer.c            | 66 ++++++++++++++++++++-------
 2 files changed, 54 insertions(+), 17 deletions(-)

Comments

Maxim Uvarov Sept. 3, 2014, 4:27 p.m. UTC | #1
On 09/03/2014 05:35 PM, Petri Savolainen wrote:
> +#define USEC ODP_TIME_USEC
> +#define SEC  ODP_TIME_SEC
> +
Are you defining them only to make lines short? Not critical but in 
example it's better to not redefine. In my opinion of course.

Maxim.
Wiles, Roger Keith Sept. 3, 2014, 6:30 p.m. UTC | #2
On Sep 3, 2014, at 11:27 AM, Maxim Uvarov <maxim.uvarov@linaro.org> wrote:

> On 09/03/2014 05:35 PM, Petri Savolainen wrote:
>> +#define USEC ODP_TIME_USEC
>> +#define SEC  ODP_TIME_SEC
>> +
> Are you defining them only to make lines short? Not critical but in example it's better to not redefine. In my opinion of course.

I agree with Maxim. Not critical can not useful just to have shorter defines.
> 
> Maxim.
> 
> _______________________________________________
> lng-odp mailing list
> lng-odp@lists.linaro.org
> http://lists.linaro.org/mailman/listinfo/lng-odp

Keith Wiles, Principal Technologist with CTO office, Wind River mobile 972-213-5533
diff mbox

Patch

diff --git a/platform/linux-generic/include/api/odp_time.h b/platform/linux-generic/include/api/odp_time.h
index 188d1fe..ecddb54 100644
--- a/platform/linux-generic/include/api/odp_time.h
+++ b/platform/linux-generic/include/api/odp_time.h
@@ -21,6 +21,11 @@  extern "C" {
 
 #include <odp_std_types.h>
 
+/* Time in nanoseconds */
+#define ODP_TIME_USEC 1000UL       /**< Microsecond in nsec */
+#define ODP_TIME_MSEC 1000000UL    /**< Millisecond in nsec */
+#define ODP_TIME_SEC  1000000000UL /**< Second in nsec */
+
 
 /**
  * Current time in CPU cycles
diff --git a/platform/linux-generic/odp_timer.c b/platform/linux-generic/odp_timer.c
index 1bf37f9..83e90e5 100644
--- a/platform/linux-generic/odp_timer.c
+++ b/platform/linux-generic/odp_timer.c
@@ -6,6 +6,7 @@ 
 
 #include <odp_timer.h>
 #include <odp_timer_internal.h>
+#include <odp_time.h>
 #include <odp_buffer_pool_internal.h>
 #include <odp_internal.h>
 #include <odp_atomic.h>
@@ -18,9 +19,13 @@ 
 
 #include <string.h>
 
+#define USEC ODP_TIME_USEC
+#define SEC  ODP_TIME_SEC
+
 #define NUM_TIMERS    1
 #define MAX_TICKS     1024
-#define RESOLUTION_NS 1000000
+#define MAX_RES       SEC
+#define MIN_RES       (100*USEC)
 
 
 typedef struct {
@@ -112,13 +117,13 @@  static int find_and_del_tmo(timeout_t **tmo, odp_timer_tmo_t handle)
 int odp_timer_cancel_tmo(odp_timer_t timer_hdl, odp_timer_tmo_t tmo)
 {
 	int id;
-	uint64_t tick_idx;
+	int tick_idx;
 	timeout_t *cancel_tmo;
 	odp_timeout_hdr_t *tmo_hdr;
 	tick_t *tick;
 
 	/* get id */
-	id = timer_hdl - 1;
+	id = (int)timer_hdl - 1;
 
 	tmo_hdr = odp_timeout_hdr((odp_timeout_t) tmo);
 	/* get tmo_buf to cancel */
@@ -179,6 +184,7 @@  static void timer_start(timer_ring_t *timer)
 {
 	struct sigevent   sigev;
 	struct itimerspec ispec;
+	uint64_t res, sec, nsec;
 
 	ODP_DBG("\nTimer (%u) starts\n", timer->timer_hdl);
 
@@ -194,10 +200,14 @@  static void timer_start(timer_ring_t *timer)
 		return;
 	}
 
-	ispec.it_interval.tv_sec  = 0;
-	ispec.it_interval.tv_nsec = RESOLUTION_NS;
-	ispec.it_value.tv_sec     = 0;
-	ispec.it_value.tv_nsec    = RESOLUTION_NS;
+	res  = timer->resolution_ns;
+	sec  = res / SEC;
+	nsec = res - sec*SEC;
+
+	ispec.it_interval.tv_sec  = (time_t)sec;
+	ispec.it_interval.tv_nsec = (long)nsec;
+	ispec.it_value.tv_sec     = (time_t)sec;
+	ispec.it_value.tv_nsec    = (long)nsec;
 
 	if (timer_settime(timer->timerid, 0, &ispec, NULL)) {
 		ODP_DBG("Timer set failed\n");
@@ -250,19 +260,41 @@  int odp_timer_disarm_all(void)
 }
 
 odp_timer_t odp_timer_create(const char *name, odp_buffer_pool_t pool,
-			     uint64_t resolution, uint64_t min_tmo,
-			     uint64_t max_tmo)
+			     uint64_t resolution_ns, uint64_t min_ns,
+			     uint64_t max_ns)
 {
 	uint32_t id;
 	timer_ring_t *timer;
 	odp_timer_t timer_hdl;
 	int i;
-	(void) name; (void) resolution; (void) min_tmo; (void) max_tmo;
+	uint64_t max_ticks;
+	(void) name;
+
+	if (resolution_ns < MIN_RES)
+		resolution_ns = MIN_RES;
+
+	if (resolution_ns > MAX_RES)
+		resolution_ns = MAX_RES;
+
+	max_ticks = max_ns / resolution_ns;
+
+	if (max_ticks > MAX_TICKS) {
+		ODP_DBG("Maximum timeout too long: %"PRIu64" ticks\n",
+			max_ticks);
+		return ODP_TIMER_INVALID;
+	}
+
+	if (min_ns < resolution_ns) {
+		ODP_DBG("Min timeout %"PRIu64" ns < resolution %"PRIu64" ns\n",
+			min_ns, resolution_ns);
+		return ODP_TIMER_INVALID;
+	}
 
 	odp_spinlock_lock(&odp_timer.lock);
 
 	if (odp_timer.num_timers >= NUM_TIMERS) {
 		odp_spinlock_unlock(&odp_timer.lock);
+		ODP_DBG("All timers allocated\n");
 		return ODP_TIMER_INVALID;
 	}
 
@@ -281,7 +313,7 @@  odp_timer_t odp_timer_create(const char *name, odp_buffer_pool_t pool,
 
 	timer->timer_hdl     = timer_hdl;
 	timer->pool          = pool;
-	timer->resolution_ns = RESOLUTION_NS;
+	timer->resolution_ns = resolution_ns;
 	timer->max_ticks     = MAX_TICKS;
 
 	for (i = 0; i < MAX_TICKS; i++) {
@@ -308,7 +340,7 @@  odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer_hdl, uint64_t tmo_tick,
 	odp_timeout_hdr_t *tmo_hdr;
 	timer_ring_t *timer;
 
-	id = timer_hdl - 1;
+	id = (int)timer_hdl - 1;
 	timer = &odp_timer.timer[id];
 
 	cur_tick = timer->cur_tick;
@@ -317,17 +349,17 @@  odp_timer_tmo_t odp_timer_absolute_tmo(odp_timer_t timer_hdl, uint64_t tmo_tick,
 		return ODP_TIMER_TMO_INVALID;
 	}
 
-	tick = tmo_tick - cur_tick;
-	if (tick > MAX_TICKS) {
-		ODP_DBG("timeout too far\n");
+	if ((tmo_tick - cur_tick) > MAX_TICKS) {
+		ODP_DBG("timeout too far: cur %"PRIu64" tmo %"PRIu64"\n",
+			cur_tick, tmo_tick);
 		return ODP_TIMER_TMO_INVALID;
 	}
 
-	tick = (cur_tick + tick) % MAX_TICKS;
+	tick = tmo_tick % MAX_TICKS;
 
 	tmo_buf = odp_buffer_alloc(timer->pool);
 	if (tmo_buf == ODP_BUFFER_INVALID) {
-		ODP_DBG("alloc failed\n");
+		ODP_DBG("tmo buffer alloc failed\n");
 		return ODP_TIMER_TMO_INVALID;
 	}