Browse Source

- Handle 32-bit counter wrap

- Handle both 32- and 64-bit counters
- Clean up


git-svn-id: svn+ssh://jackaudio.org/trunk/jack@992 0c269be4-1314-0410-8aa9-9f06e86f4224
tags/0.109.0
sonarnerd 19 years ago
parent
commit
6139e56628
1 changed files with 27 additions and 19 deletions
  1. +27
    -19
      config/os/gnu-linux/time.c

+ 27
- 19
config/os/gnu-linux/time.c View File

@@ -22,28 +22,37 @@

#include <config.h>

#include <stdint.h>

static jack_time_t __jack_cpu_mhz = 0;
jack_time_t (*_jack_get_microseconds)(void) = 0;

#if defined(__gnu_linux__) && (defined(__i386__) || defined(__x86_64__))
#define HPET_SUPPORT
#define HPET_MMAP_SIZE 1024
#define HPET_PERIOD 0x004
#define HPET_COUNTER 0x0f0
#define HPET_MMAP_SIZE 1024
#define HPET_CAPS 0x000
#define HPET_PERIOD 0x004
#define HPET_COUNTER 0x0f0
#define HPET_CAPS_COUNTER_64BIT (1 << 13)
#if defined(__x86_64__)
#define HPET_64BIT
typedef uint64_t hpet_counter_t;
#else
#define HPET_32BIT
typedef uint32_t hpet_counter_t;
#endif
static int hpet_fd;
static unsigned char *hpet_ptr;
static unsigned int hpet_period; /* period length in femto secs */
static uint32_t hpet_period; /* period length in femto secs */
static uint64_t hpet_offset = 0;
static uint64_t hpet_wrap;
static hpet_counter_t hpet_previous = 0;
#endif /* defined(__gnu_linux__) && (__i386__ || __x86_64__) */

#ifdef HPET_SUPPORT
int
jack_hpet_init ()
{
uint32_t hpet_caps;

hpet_fd = open("/dev/hpet", O_RDONLY);
if (hpet_fd < 0) {
jack_error ("This system has no accessible HPET device (%s)", strerror (errno));
@@ -61,28 +70,27 @@ jack_hpet_init ()
/* this assumes period to be constant. if needed,
it can be moved to the clock access function
*/
hpet_period = *((uint32_t *) (hpet_ptr + HPET_PERIOD));
hpet_caps = *((uint32_t *) (hpet_ptr + HPET_CAPS));
hpet_wrap = ((hpet_caps & HPET_CAPS_COUNTER_64BIT) &&
(sizeof(hpet_counter_t) == sizeof(uint64_t))) ?
0 : ((uint64_t) 1 << 32);

hpet_period = *((unsigned int *) (hpet_ptr + HPET_PERIOD));
return 0;
}

static jack_time_t
jack_get_microseconds_from_hpet (void)
{
#ifdef HPET_64BIT
unsigned long long hpet_counter;
#else
unsigned int hpet_counter;
#endif
hpet_counter_t hpet_counter;
long double hpet_time;

#ifdef HPET_64BIT
hpet_counter = *((unsigned long long *) (hpet_ptr + HPET_COUNTER));
#else
hpet_counter = *((unsigned int *) (hpet_ptr + HPET_COUNTER));
#endif
hpet_time = (long double) hpet_counter * (long double) hpet_period *
(long double) 1e-9;
hpet_counter = *((hpet_counter_t *) (hpet_ptr + HPET_COUNTER));
if (unlikely(hpet_counter < hpet_previous))
hpet_offset += hpet_wrap;
hpet_previous = hpet_counter;
hpet_time = (long double) (hpet_offset + hpet_counter) *
(long double) hpet_period * (long double) 1e-9;
return ((jack_time_t) (hpet_time + 0.5));
}



Loading…
Cancel
Save