diff options
author | pbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224> | 2006-05-16 16:15:03 +0000 |
---|---|---|
committer | pbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224> | 2006-05-16 16:15:03 +0000 |
commit | 2ed25ba2da99578db6560cc61d39d350f2f09df9 (patch) | |
tree | ae0cb1931849517b1777d00fe7e31d206c74580e /config/os | |
parent | b58cca6ae92482e9b54ee40fadb2e5217655451c (diff) | |
download | jack1-2ed25ba2da99578db6560cc61d39d350f2f09df9.tar.gz |
add new file
git-svn-id: svn+ssh://jackaudio.org/trunk/jack@956 0c269be4-1314-0410-8aa9-9f06e86f4224
Diffstat (limited to 'config/os')
-rw-r--r-- | config/os/gnu-linux/time.c | 181 |
1 files changed, 181 insertions, 0 deletions
diff --git a/config/os/gnu-linux/time.c b/config/os/gnu-linux/time.c new file mode 100644 index 0000000..ca1391b --- /dev/null +++ b/config/os/gnu-linux/time.c @@ -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; + } +} + |