blob: 9d60840f59765b57e2d4d0823430ac1e1ea29ba5 [file] [log] [blame] [edit]
#ifndef ROS_KERN_TIME_H
#define ROS_KERN_TIME_H
#include <ros/common.h>
#include <arch/time.h>
/* (newlib) Time Value Specification Structures, P1003.1b-1993, p. 261 */
typedef long time_t; /* TODO: this is fucked. Thanks POSIX. */
struct timespec {
time_t tv_sec; /* Seconds */
long tv_nsec; /* Nanoseconds */
};
struct itimerspec {
struct timespec it_interval; /* Timer period */
struct timespec it_value; /* Timer expiration */
};
struct timeval {
time_t tv_sec; /* seconds */
time_t tv_usec; /* microseconds */
};
void train_timing();
void udelay(uint64_t usec); /* done in arch-specific files */
void udelay_sched(uint64_t usec);
uint64_t tsc2sec(uint64_t tsc_time);
uint64_t tsc2msec(uint64_t tsc_time);
uint64_t tsc2usec(uint64_t tsc_time);
uint64_t tsc2nsec(uint64_t tsc_time);
uint64_t sec2tsc(uint64_t sec);
uint64_t msec2tsc(uint64_t msec);
uint64_t usec2tsc(uint64_t usec);
uint64_t nsec2tsc(uint64_t nsec);
uint64_t epoch_tsc(void);
uint64_t epoch_sec(void);
uint64_t epoch_msec(void);
uint64_t epoch_usec(void);
uint64_t epoch_nsec(void);
void tsc2timespec(uint64_t tsc_time, struct timespec *ts);
/* Just takes a time measurement. Meant to be paired with stop_timing. Use
* this if you don't want to muck with overheads or subtraction. */
static inline __attribute__((always_inline))
uint64_t start_timing(void)
{
return read_tsc_serialized();
}
/* Takes a time measurement and subtracts the start time and timing overhead,
* to return the detected elapsed time. Use this if you don't want to muck
* with overheads or subtraction. */
static inline __attribute__((always_inline))
uint64_t stop_timing(uint64_t start_time)
{
uint64_t diff = read_tsc_serialized();
diff -= start_time;
diff -= system_timing.timing_overhead;
if ((int64_t) diff < 0) {
return 1;
}
return diff;
}
static inline __attribute__((always_inline))
uint64_t nsec(void)
{
return tsc2nsec(read_tsc());
}
/* Ancient measurement crap below. TODO: use or lose it */
#if 0
#include <pool.h>
#include <string.h>
#define TIMER_TAG_SIZE 20
#define MAX_TIMERS 20
/* timer_t
* This struct is used to keep track of counter values as they are spread
* throughput code and timing measurements are made calling TAGGED_TIMING_BEGIN
* and TAGGED_TIMING_END
*/
typedef struct Timer{
uint64_t curr_run;
uint64_t aggr_run;
char label[TIMER_TAG_SIZE];
} timer_t;
#define TAGGED_TIMING_BEGIN(tag) \
static timer_t* _timer_##tag = NULL; \
if (_timer_##tag == NULL) { \
_timer_##tag = POOL_GET(&timer_pool); \
strcpy((_timer_##tag->label), #tag); \
_timer_##tag->aggr_run = 0; \
} \
_timer_##tag->curr_run = start_timing();
#define TAGGED_TIMING_END(tag) \
({ \
_timer_##tag->curr_run = stop_timing(_timer_##tag->curr_run); \
_timer_##tag->aggr_run += _timer_##tag->curr_run; \
})
#endif
#endif /* ROS_KERN_TIME_H */