akaros/kern/include/time.h
<<
>>
Prefs
   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/* Conversion factors */
   9#define NSEC_PER_SEC    1000000000L
  10#define NSEC_PER_MSEC   1000000L
  11#define NSEC_PER_USEC   1000L
  12
  13void time_init(void);
  14void udelay(uint64_t usec);     /* done in arch-specific files */
  15
  16uint64_t read_persistent_clock(void);   /* arch-specific */
  17
  18uint64_t tsc2nsec(uint64_t tsc_time);
  19
  20static inline uint64_t tsc2usec(uint64_t tsc_time)
  21{
  22        return tsc2nsec(tsc_time) / NSEC_PER_USEC;
  23}
  24
  25static inline uint64_t tsc2msec(uint64_t tsc_time)
  26{
  27        return tsc2nsec(tsc_time) / NSEC_PER_MSEC;
  28}
  29
  30static inline uint64_t tsc2sec(uint64_t tsc_time)
  31{
  32        return tsc2nsec(tsc_time) / NSEC_PER_SEC;
  33}
  34
  35uint64_t nsec2tsc(uint64_t nsec);
  36
  37static inline uint64_t usec2tsc(uint64_t usec)
  38{
  39        return nsec2tsc(usec * NSEC_PER_USEC);
  40}
  41
  42static inline uint64_t msec2tsc(uint64_t msec)
  43{
  44        return nsec2tsc(msec * NSEC_PER_MSEC);
  45}
  46
  47static inline uint64_t sec2tsc(uint64_t sec)
  48{
  49        return nsec2tsc(sec * NSEC_PER_SEC);
  50}
  51
  52uint64_t epoch_nsec(void);
  53
  54static inline struct timespec nsec2timespec(uint64_t ns)
  55{
  56        return (struct timespec) {
  57                .tv_sec = ns / NSEC_PER_SEC,
  58                .tv_nsec = ns % NSEC_PER_SEC
  59        };
  60}
  61
  62static inline struct timeval nsec2timeval(uint64_t ns)
  63{
  64        return (struct timeval) {
  65                .tv_sec = ns / NSEC_PER_SEC,
  66                .tv_usec = (ns % NSEC_PER_SEC) / NSEC_PER_USEC
  67        };
  68}
  69
  70static inline struct timespec tsc2timespec(uint64_t tsc_time)
  71{
  72        return nsec2timespec(tsc2nsec(tsc_time));
  73}
  74
  75/* Just takes a time measurement.  Meant to be paired with stop_timing.  Use
  76 * this if you don't want to muck with overheads or subtraction. */
  77static inline __attribute__((always_inline))
  78uint64_t start_timing(void)
  79{
  80    return read_tsc_serialized();
  81}
  82
  83/* Takes a time measurement and subtracts the start time and timing overhead,
  84 * to return the detected elapsed time.  Use this if you don't want to muck
  85 * with overheads or subtraction. */
  86static inline __attribute__((always_inline))
  87uint64_t stop_timing(uint64_t start_time)
  88{
  89    uint64_t diff = read_tsc_serialized();
  90    diff -= start_time;
  91    diff -= __proc_global_info.tsc_overhead;
  92        if ((int64_t) diff < 0) {
  93                return 1;
  94        }
  95        return diff;
  96}
  97
  98static inline __attribute__((always_inline))
  99uint64_t nsec(void)
 100{
 101        return tsc2nsec(read_tsc());
 102}
 103
 104
 105/* Ancient measurement crap below.  TODO: use or lose it */
 106
 107#if 0
 108#include <pool.h>
 109#include <string.h>
 110
 111#define TIMER_TAG_SIZE 20
 112#define MAX_TIMERS 20
 113/* timer_t
 114 * This struct is used to keep track of counter values as they are spread
 115 * throughput code and timing measurements are made calling TAGGED_TIMING_BEGIN
 116 * and TAGGED_TIMING_END
 117 */
 118typedef struct Timer{
 119        uint64_t curr_run;
 120        uint64_t aggr_run;
 121        char label[TIMER_TAG_SIZE];
 122} timer_t;
 123
 124#define TAGGED_TIMING_BEGIN(tag)                    \
 125        static timer_t* _timer_##tag = NULL;            \
 126        if (_timer_##tag == NULL) {                     \
 127                _timer_##tag = POOL_GET(&timer_pool);       \
 128                strcpy((_timer_##tag->label), #tag);        \
 129                _timer_##tag->aggr_run = 0;                 \
 130        }                                               \
 131        _timer_##tag->curr_run = start_timing();
 132#define TAGGED_TIMING_END(tag)                                              \
 133({                                                                          \
 134        _timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run);       \
 135        _timer_##tag->aggr_run += _timer_##tag->curr_run;                   \
 136})
 137
 138#endif
 139