#define __CPU_TRACER
#define __CPU_USAGE

#ifdef __CPU_TRACER
#include <rtl_fifo.h>

#define EXEC   11
#define ACTIV  22
#define LOCKM   33
#define UNLKM   44
struct events_stuct{
  int type;
  int id;
  hrtime_t in,out;
};

#ifdef __SCHEDULER__
struct events_stuct events;
hrtime_t ini_time=0;
int first_time = 0;
#else
extern struct events_stuct events;
extern hrtime_t ini_time;
extern int first_time ;
#endif

#define FIFO 0
#define MAXTASKS 100

#ifdef __CPU_USAGE
#define window_size 10
#define UNIT 100000
#endif  

#ifdef __SCHEDULER__

#ifdef __CPU_USAGE
unsigned int ntasks=0;
pthread_t threads[MAXTASKS];
hrtime_t t_usage[MAXTASKS];
hrtime_t t_u_counter[MAXTASKS];
hrtime_t last_t_u_counter[MAXTASKS];
hrtime_t PERIOD=1*1000*1000*1000LL;
//#include <print.h>
hrtime_t usage_window[window_size];
unsigned long sample;
#endif
#else

#ifdef __CPU_USAGE
extern unsigned int ntasks;
extern pthread_t threads[MAXTASKS];
extern hrtime_t t_usage[MAXTASKS];
extern hrtime_t PERIOD;
extern unsigned long sample;
extern hrtime_t usage_window[window_size];
#endif

#endif 

#endif

#ifdef __CPU_TRACER
// Code taken from I. Ripoll & P. Balbastre implementation of the rtlinux edf scheduler.
extern inline void rt_print_request(struct rtl_thread_struct *task, int is_linux_task)
{
	events.type = ACTIV;
	if (is_linux_task){
		events.id   = 0;
	} else {
		events.id   = ((int)task->user[0]);
	}
	events.in   = task->resume_time;
	events.out =  task->resume_time;
	rtf_put(0, (char *) &events,  sizeof(events));
}

extern inline void rt_print_exec(schedule_t *sched, hrtime_t now){
	if ((sched->rtl_current != NULL)) {
		events.type = EXEC;
		events.in   = ini_time;
		events.out  = now;
		if (sched->rtl_current != &sched->rtl_linux_task) {
			events.id   = (int)sched->rtl_current->user[0];
                        rtf_put(0, (void *) &events,  sizeof(events));
                        first_time=1;
                } else {
			events.id   = 0;
			if (first_time!=0)
				rtf_put(0, (void *) &events,  sizeof(events));
                }
                
	}     
}

#define rt_print_timer_request(events,timer,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)timer->owner->user[0]); \
  events.in   = timer->expires.it_value; \
  events.out  = events.in + timer->expires.it_interval; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)

#define rt_print_now_request(events,now,task,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)task->user[0]);\
  events.in   = now; \
  events.out  = events.in; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)

#define rt_print_activ_request(events,now,task,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)task->user[0])+3;\
  events.in   = now; \
  events.out  = events.in; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)

#define rt_print_suspend_request(events,now,task,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)task->user[0])+4;\
  events.in   = now; \
  events.out  = events.in; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)

#define rt_print_app_activ_request(events,now,task,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)task->user[0])+1;\
  events.in   = now; \
  events.out  = events.in; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)

#define rt_print_app_suspend_request(events,now,task,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)task->user[0])+2;\
  events.in   = now; \
  events.out  = events.in; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)

#define rt_print_resume_time_request(events,t,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)t->thread->user[0]); \
  events.in   = t->thread->resume_time; \
  events.out  = events.in; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)


#define rt_print_fixed_request(events,t,fifo) do { \
  events.type = ACTIV; \
  events.id   = ((int)t->thread->user[0]); \
  events.in   = t->resume_time; \
  events.out  = events.in + t->period; \
  rtf_put(fifo, (char *) &events,  sizeof(events)); \
} while (0)

#endif













