Make all block allocations use the same func [2/2]
[akaros.git] / kern / include / time.h
1 #pragma once
2
3 #include <ros/common.h>
4 #include <ros/time.h>
5 #include <arch/time.h>
6 #include <ros/procinfo.h>
7
8 void train_timing();
9 void udelay(uint64_t usec);     /* done in arch-specific files */
10 uint64_t tsc2sec(uint64_t tsc_time);
11 uint64_t tsc2msec(uint64_t tsc_time);
12 uint64_t tsc2usec(uint64_t tsc_time);
13 uint64_t tsc2nsec(uint64_t tsc_time);
14 uint64_t sec2tsc(uint64_t sec);
15 uint64_t msec2tsc(uint64_t msec);
16 uint64_t usec2tsc(uint64_t usec);
17 uint64_t nsec2tsc(uint64_t nsec);
18 uint64_t epoch_tsc(void);
19 uint64_t epoch_sec(void);
20 uint64_t epoch_msec(void);
21 uint64_t epoch_usec(void);
22 uint64_t epoch_nsec(void);
23 void tsc2timespec(uint64_t tsc_time, struct timespec *ts);
24
25 /* Just takes a time measurement.  Meant to be paired with stop_timing.  Use
26  * this if you don't want to muck with overheads or subtraction. */
27 static inline __attribute__((always_inline))
28 uint64_t start_timing(void)
29 {
30     return read_tsc_serialized();
31 }
32
33 /* Takes a time measurement and subtracts the start time and timing overhead,
34  * to return the detected elapsed time.  Use this if you don't want to muck
35  * with overheads or subtraction. */
36 static inline __attribute__((always_inline))
37 uint64_t stop_timing(uint64_t start_time)
38 {
39     uint64_t diff = read_tsc_serialized();
40     diff -= start_time;
41     diff -= __proc_global_info.tsc_overhead;
42         if ((int64_t) diff < 0) {
43                 return 1;
44         }
45         return diff;
46 }
47
48 static inline __attribute__((always_inline))
49 uint64_t nsec(void)
50 {
51         return tsc2nsec(read_tsc());
52 }
53
54
55 /* Ancient measurement crap below.  TODO: use or lose it */
56
57 #if 0
58 #include <pool.h>
59 #include <string.h>
60
61 #define TIMER_TAG_SIZE 20
62 #define MAX_TIMERS 20
63 /* timer_t
64  * This struct is used to keep track of counter values as they are spread
65  * throughput code and timing measurements are made calling TAGGED_TIMING_BEGIN
66  * and TAGGED_TIMING_END
67  */
68 typedef struct Timer{
69         uint64_t curr_run;
70         uint64_t aggr_run;
71         char label[TIMER_TAG_SIZE];
72 } timer_t;
73
74 #define TAGGED_TIMING_BEGIN(tag)                    \
75         static timer_t* _timer_##tag = NULL;            \
76         if (_timer_##tag == NULL) {                     \
77                 _timer_##tag = POOL_GET(&timer_pool);       \
78                 strcpy((_timer_##tag->label), #tag);        \
79                 _timer_##tag->aggr_run = 0;                 \
80         }                                               \
81         _timer_##tag->curr_run = start_timing();
82 #define TAGGED_TIMING_END(tag)                                              \
83 ({                                                                          \
84         _timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run);           \
85         _timer_##tag->aggr_run += _timer_##tag->curr_run;                       \
86 })
87
88 #endif