BXE: min->MIN, plus an spatch
[akaros.git] / kern / include / time.h
1 #ifndef ROS_KERN_TIME_H
2 #define ROS_KERN_TIME_H
3
4 #include <ros/common.h>
5 #include <arch/time.h>
6
7 /* (newlib) Time Value Specification Structures, P1003.1b-1993, p. 261 */
8 typedef long time_t; /* TODO: this is fucked.  Thanks POSIX. */
9
10 struct timespec {
11   time_t  tv_sec;   /* Seconds */
12   long    tv_nsec;  /* Nanoseconds */
13 };
14
15 struct itimerspec {
16   struct timespec  it_interval;  /* Timer period */
17   struct timespec  it_value;     /* Timer expiration */
18 };
19
20 struct timeval {
21         time_t tv_sec;  /* seconds */
22         time_t tv_usec; /* microseconds */
23 };
24
25 void train_timing();
26 void udelay(uint64_t usec);     /* done in arch-specific files */
27 void udelay_sched(uint64_t usec);
28 uint64_t tsc2sec(uint64_t tsc_time);
29 uint64_t tsc2msec(uint64_t tsc_time);
30 uint64_t tsc2usec(uint64_t tsc_time);
31 uint64_t tsc2nsec(uint64_t tsc_time);
32 uint64_t sec2tsc(uint64_t sec);
33 uint64_t msec2tsc(uint64_t msec);
34 uint64_t usec2tsc(uint64_t usec);
35 uint64_t nsec2tsc(uint64_t nsec);
36 uint64_t epoch_seconds(void);
37 void tsc2timespec(uint64_t tsc_time, struct timespec *ts);
38
39 /* Just takes a time measurement.  Meant to be paired with stop_timing.  Use
40  * this if you don't want to muck with overheads or subtraction. */
41 static inline __attribute__((always_inline))
42 uint64_t start_timing(void)
43 {
44     return read_tsc_serialized();
45 }
46
47 /* Takes a time measurement and subtracts the start time and timing overhead,
48  * to return the detected elapsed time.  Use this if you don't want to muck
49  * with overheads or subtraction. */
50 static inline __attribute__((always_inline))
51 uint64_t stop_timing(uint64_t start_time)
52 {
53     uint64_t diff = read_tsc_serialized();
54     diff -= start_time;
55     diff -= system_timing.timing_overhead;
56         if ((int64_t) diff < 0) {
57                 return 1;
58         }
59         return diff;
60 }
61
62 static inline __attribute__((always_inline))
63 uint64_t nsec(void)
64 {
65         return tsc2nsec(read_tsc());
66 }
67
68
69 /* Ancient measurement crap below.  TODO: use or lose it */
70
71 #if 0
72 #include <pool.h>
73 #include <string.h>
74
75 #define TIMER_TAG_SIZE 20
76 #define MAX_TIMERS 20
77 /* timer_t
78  * This struct is used to keep track of counter values as they are spread
79  * throughput code and timing measurements are made calling TAGGED_TIMING_BEGIN
80  * and TAGGED_TIMING_END
81  */
82 typedef struct Timer{
83         uint64_t curr_run;
84         uint64_t aggr_run;
85         char label[TIMER_TAG_SIZE];
86 } timer_t;
87
88 #define TAGGED_TIMING_BEGIN(tag)                    \
89         static timer_t* _timer_##tag = NULL;            \
90         if (_timer_##tag == NULL) {                     \
91                 _timer_##tag = POOL_GET(&timer_pool);       \
92                 strcpy((_timer_##tag->label), #tag);        \
93                 _timer_##tag->aggr_run = 0;                 \
94         }                                               \
95         _timer_##tag->curr_run = start_timing();
96 #define TAGGED_TIMING_END(tag)                                              \
97 ({                                                                          \
98         _timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run);           \
99         _timer_##tag->aggr_run += _timer_##tag->curr_run;                       \
100 })
101
102 #endif
103 #endif /* ROS_KERN_TIME_H */