diff --git a/example/timer/odp_timer_test.c b/example/timer/odp_timer_test.c
index dbe0e5b..bf1d7df 100644
--- a/example/timer/odp_timer_test.c
+++ b/example/timer/odp_timer_test.c
@@ -26,9 +26,19 @@
 #define MAX_WORKERS           32            /**< Max worker threads */
 #define MSG_POOL_SIZE         (4*1024*1024) /**< Message pool size */
 
+/* Nanoseconds */
+#define USEC 1000UL
+#define MSEC 1000000UL
+#define SEC  1000000000UL
+
 /** Test arguments */
 typedef struct {
-	int core_count; /**< Core count*/
+	int core_count;    /**< Core count*/
+	int resolution_us; /**< Timeout resolution in usec*/
+	int min_us;        /**< Minimum timeout in usec*/
+	int max_us;        /**< Maximum timeout in usec*/
+	int period_us;     /**< Timeout period in usec*/
+	int tmo_count;     /**< Timeout count*/
 } test_args_t;
 
 
@@ -40,26 +50,39 @@ static odp_timer_t test_timer;
 
 
 /** @private test timeout */
-static void test_timeouts(int thr)
+static void test_abs_timeouts(int thr, test_args_t *args)
 {
 	uint64_t tick;
+	uint64_t period;
+	uint64_t period_ns;
 	odp_queue_t queue;
 	odp_buffer_t buf;
-	int num = 10;
+	int num;
 
 	ODP_DBG("  [%i] test_timeouts\n", thr);
 
 	queue = odp_queue_lookup("timer_queue");
 
-	tick = odp_timer_current_tick(test_timer);
+	period_ns = args->period_us*USEC;
+	period    = odp_timer_ns_to_tick(test_timer, period_ns);
 
-	tick += 100;
+	ODP_DBG("  [%i] period %"PRIu64" ticks,  %"PRIu64" ns\n", thr,
+		period, period_ns);
 
-	odp_timer_absolute_tmo(test_timer, tick,
-			       queue, ODP_BUFFER_INVALID);
+	tick = odp_timer_current_tick(test_timer);
 
 	ODP_DBG("  [%i] current tick %"PRIu64"\n", thr, tick);
 
+	tick += period;
+
+	if (odp_timer_absolute_tmo(test_timer, tick, queue, ODP_BUFFER_INVALID)
+	    == ODP_TIMER_TMO_INVALID){
+		ODP_DBG("Timeout request failed\n");
+		return;
+	}
+
+	num = args->tmo_count;
+
 	while (1) {
 		odp_timeout_t tmo;
 
@@ -77,7 +100,7 @@ static void test_timeouts(int thr)
 		if (num == 0)
 			break;
 
-		tick += 100;
+		tick += period;
 
 		odp_timer_absolute_tmo(test_timer, tick,
 				       queue, ODP_BUFFER_INVALID);
@@ -91,28 +114,22 @@ static void test_timeouts(int thr)
 /**
  * @internal Worker thread
  *
- * @param arg  Arguments
+ * @param ptr  Pointer to test arguments
  *
- * @return NULL on failure
+ * @return Pointer to exit status
  */
-static void *run_thread(void *arg)
+static void *run_thread(void *ptr)
 {
 	int thr;
 	odp_buffer_pool_t msg_pool;
+	test_args_t *args;
 
-	thr = odp_thread_id();
+	args = ptr;
+	thr  = odp_thread_id();
 
 	printf("Thread %i starts on core %i\n", thr, odp_thread_core());
 
 	/*
-	 * Test barriers back-to-back
-	 */
-	odp_barrier_sync(&test_barrier);
-	odp_barrier_sync(&test_barrier);
-	odp_barrier_sync(&test_barrier);
-	odp_barrier_sync(&test_barrier);
-
-	/*
 	 * Find the buffer pool
 	 */
 	msg_pool = odp_buffer_pool_lookup("msg_pool");
@@ -124,12 +141,12 @@ static void *run_thread(void *arg)
 
 	odp_barrier_sync(&test_barrier);
 
-	test_timeouts(thr);
+	test_abs_timeouts(thr, args);
 
 
 	printf("Thread %i exits\n", thr);
 	fflush(NULL);
-	return arg;
+	return NULL;
 }
 
 
@@ -141,6 +158,11 @@ static void print_usage(void)
 	printf("\n\nUsage: ./odp_example [options]\n");
 	printf("Options:\n");
 	printf("  -c, --count <number>    core count, core IDs start from 1\n");
+	printf("  -r, --resolution <us>   timeout resolution in usec\n");
+	printf("  -m, --min <us>          minimum timeout in usec\n");
+	printf("  -x, --max <us>          maximum timeout in usec\n");
+	printf("  -p, --period <us>       timeout period in usec\n");
+	printf("  -t, --timeouts <count>  timeout repeat count\n");
 	printf("  -h, --help              this help\n");
 	printf("\n\n");
 }
@@ -159,13 +181,27 @@ static void parse_args(int argc, char *argv[], test_args_t *args)
 	int long_index;
 
 	static struct option longopts[] = {
-		{"count", required_argument, NULL, 'c'},
-		{"help", no_argument, NULL, 'h'},
+		{"count",      required_argument, NULL, 'c'},
+		{"resolution", required_argument, NULL, 'r'},
+		{"min",        required_argument, NULL, 'm'},
+		{"max",        required_argument, NULL, 'x'},
+		{"period",     required_argument, NULL, 'p'},
+		{"timeouts",   required_argument, NULL, 't'},
+		{"help",       no_argument,       NULL, 'h'},
 		{NULL, 0, NULL, 0}
 	};
 
+	/* defaults */
+	args->core_count    = 0; /* all cores */
+	args->resolution_us = 10000;
+	args->min_us        = args->resolution_us;
+	args->max_us        = 100000000;
+	args->period_us     = 1000000;
+	args->tmo_count     = 30;
+
 	while (1) {
-		opt = getopt_long(argc, argv, "+c:h", longopts, &long_index);
+		opt = getopt_long(argc, argv, "+c:r:m:x:p:t:h",
+				 longopts, &long_index);
 
 		if (opt == -1)
 			break;	/* No more options */
@@ -174,7 +210,21 @@ static void parse_args(int argc, char *argv[], test_args_t *args)
 		case 'c':
 			args->core_count = atoi(optarg);
 			break;
-
+		case 'r':
+			args->resolution_us = atoi(optarg);
+			break;
+		case 'm':
+			args->min_us = atoi(optarg);
+			break;
+		case 'x':
+			args->max_us = atoi(optarg);
+			break;
+		case 'p':
+			args->period_us = atoi(optarg);
+			break;
+		case 't':
+			args->tmo_count = atoi(optarg);
+			break;
 		case 'h':
 			print_usage();
 			exit(EXIT_SUCCESS);
@@ -203,7 +253,7 @@ int main(int argc, char *argv[])
 	uint64_t cycles, ns;
 	odp_queue_param_t param;
 
-	printf("\nODP example starts\n");
+	printf("\nODP timer example starts\n");
 
 	memset(&args, 0, sizeof(args));
 	parse_args(argc, argv, &args);
@@ -248,6 +298,11 @@ int main(int argc, char *argv[])
 		first_core = 0;
 
 	printf("first core:         %i\n", first_core);
+	printf("resolution:         %i usec\n", args.resolution_us);
+	printf("min timeout:        %i usec\n", args.min_us);
+	printf("max timeout:        %i usec\n", args.max_us);
+	printf("period:             %i usec\n", args.period_us);
+	printf("timeouts:           %i\n", args.tmo_count);
 
 	/*
 	 * Init this thread. It makes also ODP calls when
@@ -288,8 +343,9 @@ int main(int argc, char *argv[])
 	}
 
 	test_timer = odp_timer_create("test_timer", pool,
-				      1000000, 1000000, 1000000000000UL);
-
+				      args.resolution_us*USEC,
+				      args.min_us*USEC,
+				      args.max_us*USEC);
 
 	odp_shm_print_all();
 
@@ -302,7 +358,7 @@ int main(int argc, char *argv[])
 	printf("  %12"PRIu64" cycles  ->  %12"PRIu64" ns\n", cycles,
 	       odp_time_cycles_to_ns(cycles));
 
-	for (ns = 1; ns <= 100000000000UL; ns *= 10) {
+	for (ns = 1; ns <= 100*SEC; ns *= 10) {
 		cycles = odp_time_ns_to_cycles(ns);
 
 		printf("  %12"PRIu64" ns      ->  %12"PRIu64" cycles\n", ns,
@@ -318,7 +374,7 @@ int main(int argc, char *argv[])
 
 	/* Create and launch worker threads */
 	odp_linux_pthread_create(thread_tbl, num_workers, first_core,
-				 run_thread, NULL);
+				 run_thread, &args);
 
 	/* Wait for worker threads to exit */
 	odp_linux_pthread_join(thread_tbl, num_workers);
