From e88779c4ef7c265c32d73f83ca7ba3ca78821638 Mon Sep 17 00:00:00 2001
From: Xenofon Foukas <x.foukas@sms.ed.ac.uk>
Date: Wed, 6 Jan 2016 18:06:48 +0200
Subject: [PATCH] Added support for lightweight finegrained task timer

---
 openair2/ENB_APP/enb_agent.c        | 30 ++++++++++++++++++++++-------
 openair2/ENB_APP/enb_agent_common.c |  9 +++++++++
 openair2/ENB_APP/enb_agent_common.h |  4 ++++
 3 files changed, 36 insertions(+), 7 deletions(-)

diff --git a/openair2/ENB_APP/enb_agent.c b/openair2/ENB_APP/enb_agent.c
index 3c9ad7d24d..e8a4466b26 100644
--- a/openair2/ENB_APP/enb_agent.c
+++ b/openair2/ENB_APP/enb_agent.c
@@ -50,7 +50,7 @@ enb_agent_info_t  enb_agent_info;
 char in_ip[40];
 static uint16_t in_port;
 
-//void *send_thread(void *args);
+void *send_thread(void *args);
 void *receive_thread(void *args);
 pthread_t new_thread(void *(*f)(void *), void *b);
 err_code_t enb_agent_timeout(void* args);
@@ -100,20 +100,35 @@ void *enb_agent_task(void *args){
 
   return NULL;
 }
-/*
+
 void *send_thread(void *args) {
 
+#ifdef TEST_TIMER
+
   msg_context_t         *d = args;
   void                  *data;
   int                   size;
   int                   priority;
 
-  
-  while (1) {
+  struct timeval t1, t2;
+  long long t;
+  struct timespec ts;
+  unsigned int delay = 250*1000;
+  while(1) {
+    gettimeofday(&t1, NULL);
+    enb_agent_sleep_until(&ts, delay);
+    gettimeofday(&t2, NULL);
+    t = ((t2.tv_sec * 1000000) + t2.tv_usec) - ((t1.tv_sec * 1000000) + t1.tv_usec);
+    LOG_I(ENB_AGENT, "Call to sleep_until(%d) took %lld us\n", delay, t);
+    sleep(1);
+  }
+
+#endif
+  /* while (1) {
     // need logic for the timer, and 
     usleep(10);
     if (message_put(d->tx_mq, data, size, priority)) goto error;
-  }
+    }*/
 
   return NULL;
 
@@ -121,7 +136,7 @@ error:
   printf("receive_thread: there was an error\n");
   return NULL;
 }
-*/
+
 void *receive_thread(void *args) {
 
   msg_context_t         *d = args;
@@ -293,9 +308,10 @@ int enb_agent_start(mid_t mod_id, const Enb_properties_array_t* enb_properties){
   enb_agent_create_timer(1, 0, ENB_AGENT_DEFAULT, mod_id, ENB_AGENT_TIMER_TYPE_PERIODIC, enb_agent_timeout,(void*)&timer_args, &timer_id);
 #endif 
 
-  //  new_thread(send_thread, &shared_ctxt);
+  new_thread(send_thread, &shared_ctxt);
 
   //while (1) pause();
+ 
 
   LOG_I(ENB_AGENT,"client ends\n");
   return 0;
diff --git a/openair2/ENB_APP/enb_agent_common.c b/openair2/ENB_APP/enb_agent_common.c
index 0fe2c8e1ac..490658c671 100644
--- a/openair2/ENB_APP/enb_agent_common.c
+++ b/openair2/ENB_APP/enb_agent_common.c
@@ -476,6 +476,15 @@ struct enb_agent_timer_element_s * get_timer_entry(long timer_id) {
   return  RB_FIND(enb_agent_map, &timer_instance.enb_agent_head, search); 
 }
 
+void enb_agent_sleep_until(struct timespec *ts, int delay) {
+  ts->tv_nsec += delay;
+  if(ts->tv_nsec >= 1000*1000*1000){
+    ts->tv_nsec -= 1000*1000*1000;
+    ts->tv_sec++;
+  }
+  clock_nanosleep(CLOCK_MONOTONIC, TIMER_ABSTIME, ts,  NULL);
+}
+
 /*
  int i =0;
   RB_FOREACH(e, enb_agent_map, &enb_agent_head) {
diff --git a/openair2/ENB_APP/enb_agent_common.h b/openair2/ENB_APP/enb_agent_common.h
index f918914f92..d12d3849ec 100644
--- a/openair2/ENB_APP/enb_agent_common.h
+++ b/openair2/ENB_APP/enb_agent_common.h
@@ -39,6 +39,7 @@
 #ifndef ENB_AGENT_COMMON_H_
 #define ENB_AGENT_COMMON_H_
 
+#include <time.h>
 
 #include "header.pb-c.h"
 #include "progran.pb-c.h"
@@ -228,6 +229,9 @@ err_code_t enb_agent_process_timeout(long timer_id, void* timer_args);
 
 int enb_agent_compare_timer(struct enb_agent_timer_element_s *a, struct enb_agent_timer_element_s *b);
 
+/*Specify a delay in nanoseconds to timespec and sleep until then*/
+void enb_agent_sleep_until(struct timespec *ts, int delay);
+
 /* RB_PROTOTYPE is for .h files */
 RB_PROTOTYPE(enb_agent_map, enb_agent_timer_element_s, entry, enb_agent_compare_timer);
 
-- 
2.26.2