summaryrefslogtreecommitdiff
path: root/config/os
diff options
context:
space:
mode:
authorpbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224>2006-05-16 16:15:03 +0000
committerpbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224>2006-05-16 16:15:03 +0000
commit2ed25ba2da99578db6560cc61d39d350f2f09df9 (patch)
treeae0cb1931849517b1777d00fe7e31d206c74580e /config/os
parentb58cca6ae92482e9b54ee40fadb2e5217655451c (diff)
downloadjack1-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.c181
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;
+ }
+}
+