Browse Source

add new file

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

+ 181
- 0
config/os/gnu-linux/time.c View File

@@ -0,0 +1,181 @@
/* -*- mode: c; c-file-style: "bsd"; -*- */
/*
Copyright (C) 2001-2003 Paul Davis
Copyright (C) 2005 Jussi Laako
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation; either version 2.1 of the License, or
(at your option) any later version.
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 Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.

$Id$
*/

#include <config.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
static int hpet_fd;
static unsigned char *hpet_ptr;
static unsigned int hpet_period; /* period length in femto secs */
#endif /* defined(__gnu_linux__) && (__i386__ || __x86_64__) */

#ifdef HPET_SUPPORT
int
jack_hpet_init ()
{
hpet_fd = open("/dev/hpet", O_RDONLY);
if (hpet_fd < 0) {
jack_error ("This system has no accessible HPET device (%s)", strerror (errno));
return -1;
}

hpet_ptr = (unsigned char *) mmap(NULL, HPET_MMAP_SIZE,
PROT_READ, MAP_SHARED, hpet_fd, 0);
if (hpet_ptr == NULL) {
jack_error ("This system has no mappable HPET device (%s)", strerror (errno));
close (hpet_fd);
return -1;
}

/* this assumes period to be constant. if needed,
it can be moved to the clock access function
*/

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

static jack_time_t
jack_get_microseconds_from_hpet (void)
{
unsigned long long hpet_counter;
long double hpet_time;

hpet_counter = *((unsigned long long *) (hpet_ptr + HPET_COUNTER));
hpet_time = (long double) hpet_counter * (long double) hpet_period *
(long double) 1e-9;
return ((jack_time_t) (hpet_time + 0.5));
}

#else

static int
jack_hpet_init ()
{
jack_error ("This version of JACK or this computer does not have HPET support.\n"
"Please choose a different clock source.");
return -1;
}

static jack_time_t
jack_get_microseconds_from_hpet (void)
{
/* never called */
return 0;
}

#endif /* HPET_SUPPORT */


jack_time_t
jack_get_microseconds_from_cycles (void) {
return get_cycles() / __jack_cpu_mhz;
}

/*
* This is another kludge. It looks CPU-dependent, but actually it
* reflects the lack of standards for the Linux kernel formatting of
* /proc/cpuinfo.
*/

jack_time_t
jack_get_mhz (void)
{
FILE *f = fopen("/proc/cpuinfo", "r");
if (f == 0)
{
perror("can't open /proc/cpuinfo\n");
exit(1);
}

for ( ; ; )
{
jack_time_t mhz;
int ret;
char buf[1000];

if (fgets(buf, sizeof(buf), f) == NULL) {
jack_error ("FATAL: cannot locate cpu MHz in "
"/proc/cpuinfo\n");
exit(1);
}

#if defined(__powerpc__)
ret = sscanf(buf, "clock\t: %" SCNu64 "MHz", &mhz);
#elif defined( __i386__ ) || defined (__hppa__) || defined (__ia64__) || \
defined(__x86_64__)
ret = sscanf(buf, "cpu MHz : %" SCNu64, &mhz);
#elif defined( __sparc__ )
ret = sscanf(buf, "Cpu0Bogo : %" SCNu64, &mhz);
#elif defined( __mc68000__ )
ret = sscanf(buf, "Clocking: %" SCNu64, &mhz);
#elif defined( __s390__ )
ret = sscanf(buf, "bogomips per cpu: %" SCNu64, &mhz);
#else /* MIPS, ARM, alpha */
ret = sscanf(buf, "BogoMIPS : %" SCNu64, &mhz);
#endif

if (ret == 1)
{
fclose(f);
return (jack_time_t)mhz;
}
}
}

void
jack_init_time ()
{
__jack_cpu_mhz = jack_get_mhz ();
}

void
jack_set_clock_source (jack_timer_type_t clocksrc)
{
switch (clocksrc)
{
case JACK_TIMER_CYCLE_COUNTER:
_jack_get_microseconds = jack_get_microseconds_from_cycles;
break;

case JACK_TIMER_HPET:
if (jack_hpet_init () == 0) {
_jack_get_microseconds = jack_get_microseconds_from_hpet;
} else {
_jack_get_microseconds = jack_get_microseconds_from_system;
}
break;

case JACK_TIMER_SYSTEM_CLOCK:
default:
_jack_get_microseconds = jack_get_microseconds_from_system;
break;
}
}


Loading…
Cancel
Save