Vcores always start in vcore context
[akaros.git] / kern / include / ros / time.h
1 #ifndef ROS_INC_TIME_H
2 #define ROS_INC_TIME_H
3
4 #include <pool.h>
5 #include <string.h>
6
7 #define TIMER_TAG_SIZE 20
8 #define MAX_TIMERS 20
9
10 /* start_timing()
11  * This function simply reads the tsc in a serialized fashion and returns its
12  * value.  It is pusposefully annotated with a noinline so that the overheads 
13  * assocaited with calling it are as deterministic as possible.
14  */
15 uint64_t start_timing() __attribute__((noinline));
16
17 /* stop_timing()
18  * This function reads the tsc in a serialized fashion and subtracts the value
19  * it reads from the value passed in as a paramter in order to determine the 
20  * difference between the two values.  A global timing_overhead value is also 
21  * subtracted to compensate for the overhead associated with calling both
22  * start and stop timing and returning their values.
23  * This function is purposefully annotated with a noinline so that 
24  * the overheads assocaited with calling it are as deterministic as possible.
25  */
26 uint64_t stop_timing(uint64_t val) __attribute__((noinline));
27
28 /* train_timing()
29  * This function is intended to train the timing_overhead variable for use by
30  * stop_timing().  It runs through a loop calling start/stop and averaging the 
31  * overhead of calling them without doing any useful work in between.
32  */
33 void train_timing();
34
35 /* timer_t
36  * This struct is used to keep track of counter values as they are spread
37  * throughput code and timing measurements are made calling TAGGED_TIMING_BEGIN
38  * and TAGGED_TIMING_END
39  */
40 typedef struct Timer{
41         uint64_t curr_run;
42         uint64_t aggr_run;
43         char label[TIMER_TAG_SIZE];
44 } timer_t;
45
46 //TODO: ifdef measurement? error check when pool runs low
47 #define TAGGED_TIMING_BEGIN(tag)                    \
48         static timer_t* _timer_##tag = NULL;            \
49         if (_timer_##tag == NULL) {                     \
50                 _timer_##tag = POOL_GET(&timer_pool);       \
51                 strcpy((_timer_##tag->label), #tag);        \
52                 _timer_##tag->aggr_run = 0;                 \
53         }                                               \
54         _timer_##tag->curr_run = start_timing();
55 #define TAGGED_TIMING_END(tag)                                              \
56 ({                                                                          \
57         _timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run);           \
58         _timer_##tag->aggr_run += _timer_##tag->curr_run;                       \
59 })
60
61 #endif /* ROS_INC_TIME_H */