blob: a568c3b3761fee51eb7ad422f2c80355c45739e2 [file] [log] [blame]
/****************************************************************************
| (C) Copyright 2008 Novell, Inc. All Rights Reserved.
|
| GPLv2: This program is free software; you can redistribute it
| and/or modify it under the terms of version 2 of the GNU General
| Public License as published by the Free Software Foundation.
|
| This program is distributed in the hope that it will be useful,
| but WITHOUT ANY WARRANTY; without even the implied warranty of
| MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
| GNU General Public License for more details.
+-------------------------------------------------------------------------*/
#ifndef _TIMER_H_
#define _TIMER_H_ 1
#ifdef __cplusplus
extern "C" {
#endif
#include <style.h>
typedef unsigned long long tick_t;
enum { NUM_SLOTS = 16, NUM_WHEELS = 16 };
typedef struct slot_s {
tick_t s_delta;
tick_t s_avg;
} slot_s;
typedef struct wheel_s {
unsigned wh_next;
slot_s wh_slot[NUM_SLOTS];
} wheel_s;
typedef wheel_s cascade_s[NUM_WHEELS];
void cascade (cascade_s wheel, tick_t delta);
void pr_cascade (const char *label, cascade_s wheel);
#ifdef __APPLE__
#include <sys/time.h>
static inline tick_t cputicks (void)
{
struct timeval time;
tick_t ticks;
gettimeofday( &time, NULL);
ticks = time.tv_sec * 1000000ULL + time.tv_usec;
return ticks;
}
static inline tick_t nsecs (void)
{
struct timeval time;
tick_t ticks;
gettimeofday( &time, NULL);
ticks = time.tv_sec * 1000000ULL + time.tv_usec;
return ticks * 1000;
}
#else
/*
* i386 calling convention returns 64-bit value in edx:eax, while
* x86_64 returns at rax. Also, the "A" constraint does not really
* mean rdx:rax in x86_64, so we need specialized behaviour for each
* architecture
*/
#ifdef __x86_64__
#define DECLARE_ARGS(val, low, high) unsigned low, high
#define EAX_EDX_VAL(val, low, high) ((low) | ((u64)(high) << 32))
#define EAX_EDX_ARGS(val, low, high) "a" (low), "d" (high)
#define EAX_EDX_RET(val, low, high) "=a" (low), "=d" (high)
#endif
#ifdef __i386__
#define DECLARE_ARGS(val, low, high) unsigned long long val
#define EAX_EDX_VAL(val, low, high) (val)
#define EAX_EDX_ARGS(val, low, high) "A" (val)
#define EAX_EDX_RET(val, low, high) "=A" (val)
#endif
// DON'T USE keeping here for future reference.
#if 0
static __always_inline unsigned long long cputicks (void)
{
DECLARE_ARGS(val, low, high);
// Really need barrier's but is very processor specific
//rdtsc_barrier();
asm volatile("rdtsc" : EAX_EDX_RET(val, low, high));
//rdtsc_barrier();
return EAX_EDX_VAL(val, low, high);
}
#endif
#ifndef _TIME_H
#include <time.h>
#endif
/* Link with -lrt */
static inline u64 nsecs (void)
{
struct timespec t;
clock_gettime(CLOCK_REALTIME, &t);
return (u64)t.tv_sec * 1000000000ULL + t.tv_nsec;
}
#endif
#define TIME(_c, _x) { \
u64 start; \
u64 end; \
\
start = nsecs(); \
_x; \
end = nsecs(); \
cascade(_c, end-start); \
}
#endif
#ifdef __cplusplus
}
#endif