summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorpbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224>2006-05-15 17:12:44 +0000
committerpbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224>2006-05-15 17:12:44 +0000
commit7e8cf3c23c729342d42d9270dd2cd11834a9db19 (patch)
tree8909f3b6e91a16523a9cfe54ae3c03765f928c73
parent2e06b7b6c3affbb642de54f4648e80a268f23849 (diff)
downloadjack1-7e8cf3c23c729342d42d9270dd2cd11834a9db19.tar.gz
reworked config headers etc; rework clockfix patch; exit if -R requested but unobtainable
git-svn-id: svn+ssh://jackaudio.org/trunk/jack@948 0c269be4-1314-0410-8aa9-9f06e86f4224
-rw-r--r--Makefile.am2
-rw-r--r--config/Makefile.am4
-rw-r--r--config/configure.host32
-rw-r--r--config/cpu/generic/cycles.h8
-rw-r--r--config/cpu/i386/atomicity.h38
-rw-r--r--config/cpu/i386/cycles.h14
-rw-r--r--config/cpu/i486/atomicity.h54
-rw-r--r--config/cpu/i486/cycles.h55
-rw-r--r--config/os/generic/time.h42
-rw-r--r--config/os/gnu-linux/time.h70
-rw-r--r--config/os/macosx/fakepoll.h161
-rw-r--r--config/os/macosx/poll.h179
-rw-r--r--config/os/macosx/portaudio.h28
-rw-r--r--config/os/macosx/time.h21
-rw-r--r--config/sysdeps/Makefile.am23
-rw-r--r--config/sysdeps/atomicity.h24
-rw-r--r--config/sysdeps/cycles.h28
-rw-r--r--config/sysdeps/getopt.h8
-rw-r--r--config/sysdeps/ipc.h10
-rw-r--r--config/sysdeps/mach_port.h8
-rw-r--r--config/sysdeps/pThreadUtilities.h8
-rw-r--r--config/sysdeps/poll.h14
-rw-r--r--config/sysdeps/portaudio.h8
-rw-r--r--config/sysdeps/time.c12
-rw-r--r--config/sysdeps/time.h12
-rw-r--r--configure.ac60
-rw-r--r--example-clients/Makefile.am4
-rw-r--r--example-clients/metro.c3
-rw-r--r--jack/engine.h2
-rw-r--r--jack/internal.h12
-rw-r--r--jack/thread.h4
-rw-r--r--jackd/engine.c42
-rw-r--r--jackd/jackd.1.in3
-rw-r--r--jackd/jackd.c18
-rw-r--r--libjack/Makefile.am3
-rw-r--r--libjack/client.c6
-rw-r--r--libjack/local.h4
-rw-r--r--libjack/thread.c6
38 files changed, 477 insertions, 553 deletions
diff --git a/Makefile.am b/Makefile.am
index e08a69b..b96b0bf 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -13,7 +13,7 @@ dist-check-doxygen:
@false
endif
-SUBDIRS = config jack libjack jackd drivers example-clients $(DOC_DIR)
+SUBDIRS = jack libjack jackd drivers example-clients $(DOC_DIR)
DIST_SUBDIRS = config jack libjack jackd drivers example-clients doc
pkgconfigdir = $(libdir)/pkgconfig
diff --git a/config/Makefile.am b/config/Makefile.am
index aa4b8a9..58e578d 100644
--- a/config/Makefile.am
+++ b/config/Makefile.am
@@ -3,9 +3,7 @@
# this is sufficient. Unfortunately, their CVS subdirectories also
# get distributed as a side-effect.
-EXTRA_DIST = configure.host depcomp cpu os
+EXTRA_DIST = configure.host depcomp cpu os sysdeps
MAINTAINERCLEANFILES = Makefile.in config.guess config.sub \
install-sh ltmain.sh missing mkinstalldirs
-SUBDIRS = sysdeps
-DIST_SUBDIRS = sysdeps
diff --git a/config/configure.host b/config/configure.host
index 8e369b8..02d5ed3 100644
--- a/config/configure.host
+++ b/config/configure.host
@@ -109,12 +109,8 @@ case "${host_cpu}" in
;;
esac
-# Now look for the file(s) usually tied to a CPU model, and make
-# default choices for those if they haven't been explicitly set
-# already.
-cpu_include_dir="cpu/${try_cpu}"
-atomicity_include_dir=$cpu_include_dir
-
+# set the CPU that will be used to select atomicity functionality
+ATOMICITY_TARGET=${try_cpu}
# Set any OS-dependent bits.
# Set the os_include_dir.
@@ -126,33 +122,33 @@ case "${host_os}" in
# We set os_include_dir to os/aix only on AIX 4.3 and newer, but
# os/aix/atomicity.h works on earlier versions of AIX 4.*, so we
# explicitly duplicate the directory for 4.[<3].
- os_include_dir="os/aix"
- atomicity_include_dir="os/aix"
+ OSPLATFORM="AIX"
+ ATOMICITY_TARGET="AIX"
OS_LDFLAGS="-Wl,-G"
;;
aix4.*)
- os_include_dir="os/generic"
- atomicity_include_dir="os/aix"
+ OSPLATFORM="GENERIC"
+ ATOMICITY_TARGET="AIX"
;;
aix*)
- os_include_dir="os/generic"
- atomicity_include_dir="cpu/generic"
+ OSPLATFORM="GENERIC"
+ ATOMICITY_TARGET="GENERIC"
;;
gnu* | linux* | kfreebsd*-gnu | knetbsd*-gnu)
- os_include_dir="os/gnu-linux"
+ OSPLATFORM="GNULINUX"
;;
freebsd*)
# current FreeBSD header files conflict with the OSS driver's
# barrier code, this may be fixed in 5.3, stay tuned.
- os_include_dir="os/generic"
+ OSPLATFORM="GENERIC"
USE_BARRIER="no"
;;
irix*)
- os_include_dir="os/irix"
- atomicity_include_dir=$os_include_dir
+ OSPLATFORM="IRIX"
+ ATOMICITY_TARGET="IRIX"
;;
darwin*)
- os_include_dir="os/macosx"
+ OSPLATFORM="MACOSX"
JACK_THREAD_STACK_TOUCH=10000 # need small realtime stack
JACK_CPP_VARARGS_BROKEN=1
JACK_DO_NOT_MLOCK=1
@@ -161,7 +157,7 @@ case "${host_os}" in
TRY_POSIX_SHM=yes # POSIX shm works better
;;
*)
- os_include_dir="os/generic"
+ OSPLATFORM="GENERIC"
;;
esac
diff --git a/config/cpu/generic/cycles.h b/config/cpu/generic/cycles.h
index 13eb204..79ccc3c 100644
--- a/config/cpu/generic/cycles.h
+++ b/config/cpu/generic/cycles.h
@@ -1,6 +1,5 @@
/*
Copyright (C) 2001 Paul Davis
- Code derived from various headers from the Linux kernel
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
@@ -22,20 +21,19 @@
#ifndef __jack_cycles_h__
#define __jack_cycles_h__
-/* generic solution */
+/* generic solution that is not really a solution at all */
-#warning You are compiling JACK on a platform for which jack/cycles.h needs work
+#warning You are compiling JACK on a platform for which jack/config/sysdep/cycles.h needs work
#include <sys/time.h>
typedef long cycles_t;
-extern cycles_t cacheflush_time;
static inline cycles_t get_cycles(void)
{
struct timeval tv;
gettimeofday (&tv, NULL);
- return tv.tv_usec;
+ return ((cycles_t) tv.tv_sec * 1000000) + tv.tv_usec;
}
#endif /* __jack_cycles_h__ */
diff --git a/config/cpu/i386/atomicity.h b/config/cpu/i386/atomicity.h
index 7a949c3..73be009 100644
--- a/config/cpu/i386/atomicity.h
+++ b/config/cpu/i386/atomicity.h
@@ -1,6 +1,4 @@
-// Low-level functions for atomic operations: x86, x >= 3 version -*- C++ -*-
-
-// Copyright (C) 2003 Free Software Foundation, Inc.
+// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
//
// This file is part of the GNU ISO C++ Library. This library is free
// software; you can redistribute it and/or modify it under the
@@ -32,37 +30,14 @@
typedef int _Atomic_word;
-template<int __inst>
- struct __Atomicity_lock
- {
- static volatile _Atomic_word _S_atomicity_lock;
- };
-
-template<int __inst>
-volatile _Atomic_word __Atomicity_lock<__inst>::_S_atomicity_lock = 0;
-
-template volatile _Atomic_word __Atomicity_lock<0>::_S_atomicity_lock;
-
static inline _Atomic_word
__attribute__ ((__unused__))
__exchange_and_add(volatile _Atomic_word* __mem, int __val)
{
- register _Atomic_word __result, __tmp = 1;
-
- /* obtain the atomic exchange/add spin lock */
- do {
- __asm__ __volatile__ ("xchg{l} {%0,%1|%1,%0}"
- : "=m" (__Atomicity_lock<0>::_S_atomicity_lock),
- "+r" (__tmp)
- : "m" (__Atomicity_lock<0>::_S_atomicity_lock));
- } while (__tmp);
-
- __result = *__mem;
- *__mem += __val;
-
- /* release spin lock */
- __Atomicity_lock<0>::_S_atomicity_lock = 0;
-
+ register _Atomic_word __result;
+ __asm__ __volatile__ ("lock; xaddl %0,%1"
+ : "=r" (__result), "=m" (*__mem)
+ : "0" (__val), "m" (*__mem));
return __result;
}
@@ -70,7 +45,8 @@ static inline void
__attribute__ ((__unused__))
__atomic_add(volatile _Atomic_word* __mem, int __val)
{
- __exchange_and_add(__mem, __val);
+ __asm__ __volatile__ ("lock; addl %1,%0"
+ : "=m" (*__mem) : "ir" (__val), "m" (*__mem));
}
#endif /* atomicity.h */
diff --git a/config/cpu/i386/cycles.h b/config/cpu/i386/cycles.h
index b75a456..a3094d9 100644
--- a/config/cpu/i386/cycles.h
+++ b/config/cpu/i386/cycles.h
@@ -19,6 +19,16 @@
$Id$
*/
-/* the i486 version of this header is compatible */
+#ifndef __jack_cycles_h__
+#define __jack_cycles_h__
-#include <config/cpu/i486/cycles.h>
+typedef unsigned long long cycles_t;
+
+static inline cycles_t get_cycles (void)
+{
+ unsigned long long ret;
+ __asm__ __volatile__("rdtsc" : "=A" (ret));
+ return ret;
+}
+
+#endif /* __jack_cycles_h__ */
diff --git a/config/cpu/i486/atomicity.h b/config/cpu/i486/atomicity.h
deleted file mode 100644
index 014cf62..0000000
--- a/config/cpu/i486/atomicity.h
+++ /dev/null
@@ -1,54 +0,0 @@
-// Low-level functions for atomic operations: x86, x >= 4 version -*- C++ -*-
-
-// Copyright (C) 1999, 2000, 2001 Free Software Foundation, Inc.
-//
-// This file is part of the GNU ISO C++ Library. This library is free
-// software; you can redistribute it and/or modify it under the
-// terms of the GNU General Public License as published by the
-// Free Software Foundation; either version 2, or (at your option)
-// any later version.
-
-// This library 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.
-
-// You should have received a copy of the GNU General Public License along
-// with this library; see the file COPYING. If not, write to the Free
-// Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307,
-// USA.
-
-// As a special exception, you may use this file as part of a free software
-// library without restriction. Specifically, if other files instantiate
-// templates or use macros or inline functions from this file, or you compile
-// this file and link it with other files to produce an executable, this
-// file does not by itself cause the resulting executable to be covered by
-// the GNU General Public License. This exception does not however
-// invalidate any other reasons why the executable file might be covered by
-// the GNU General Public License.
-
-#ifndef _GLIBCXX_ATOMICITY_H
-#define _GLIBCXX_ATOMICITY_H 1
-
-typedef int _Atomic_word;
-
-static inline _Atomic_word
-__attribute__ ((__unused__))
-__exchange_and_add(volatile _Atomic_word* __mem, int __val)
-{
- register _Atomic_word __result;
- __asm__ __volatile__ ("lock; xaddl %0,%1"
- : "=r" (__result), "=m" (*__mem)
- : "0" (__val), "m" (*__mem));
- return __result;
-}
-
-static inline void
-__attribute__ ((__unused__))
-__atomic_add(volatile _Atomic_word* __mem, int __val)
-{
- __asm__ __volatile__ ("lock; addl %1,%0"
- : "=m" (*__mem) : "ir" (__val), "m" (*__mem));
-}
-
-#endif /* atomicity.h */
diff --git a/config/cpu/i486/cycles.h b/config/cpu/i486/cycles.h
index 855dfb4..33579d7 100644
--- a/config/cpu/i486/cycles.h
+++ b/config/cpu/i486/cycles.h
@@ -1,54 +1,3 @@
-/*
- Copyright (C) 2001 Paul Davis
- Code derived from various headers from the Linux kernel
-
- This program is free software; you can redistribute it and/or modify
- it under the terms of the GNU General Public License as published by
- the Free Software Foundation; either version 2 of the License, or
- (at your option) any later version.
+/* the i386 version of this header is compatible */
- 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.
-
- You should have received a copy of the GNU General Public License
- along with this program; if not, write to the Free Software
- Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
-
- $Id$
-*/
-
-#ifndef __jack_cycles_h__
-#define __jack_cycles_h__
-
-/*
- * Standard way to access the cycle counter on i586+ CPUs.
- * Currently only used on SMP.
- *
- * If you really have a SMP machine with i486 chips or older,
- * compile for that, and this will just always return zero.
- * That's ok, it just means that the nicer scheduling heuristics
- * won't work for you.
- *
- * We only use the low 32 bits, and we'd simply better make sure
- * that we reschedule before that wraps. Scheduling at least every
- * four billion cycles just basically sounds like a good idea,
- * regardless of how fast the machine is.
- */
-typedef unsigned long long cycles_t;
-
-extern cycles_t cacheflush_time;
-
-#define rdtscll(val) \
- __asm__ __volatile__("rdtsc" : "=A" (val))
-
-static inline cycles_t get_cycles (void)
-{
- unsigned long long ret;
-
- rdtscll(ret);
- return ret;
-}
-
-#endif /* __jack_cycles_h__ */
+#include <config/cpu/i386/cycles.h>
diff --git a/config/os/generic/time.h b/config/os/generic/time.h
index 6082a98..7118ed8 100644
--- a/config/os/generic/time.h
+++ b/config/os/generic/time.h
@@ -22,49 +22,11 @@
#ifndef __jack_time_h__
#define __jack_time_h__
-#include <stdio.h>
#include <jack/internal.h>
-#include <sysdeps/cycles.h>
-/* This is a kludge. We need one global instantiation of this
- * variable in each address space. So, libjack/client.c declares the
- * actual storage. Other source files will see it as an extern. */
-#define JACK_TIME_GLOBAL_DECL jack_time_t __jack_cpu_mhz
-extern JACK_TIME_GLOBAL_DECL;
-
-static inline jack_time_t
+inline jack_time_t
jack_get_microseconds (void) {
- return get_cycles() / __jack_cpu_mhz;
-}
-
-/* This function is inspired by similar code in MPLayer.
- * It should be quite portable
- */
-static inline jack_time_t
-jack_get_mhz (void)
-{
- jack_time_t tsc_start, tsc_end;
- struct timeval tv_start, tv_end;
- long usec_delay;
- jack_time_t mhz;
-
- tsc_start = get_cycles();
- gettimeofday(&tv_start, NULL);
- usleep(100000);
- tsc_end = get_cycles();
- gettimeofday(&tv_end, NULL);
-
- usec_delay = 1000000 * (tv_end.tv_sec - tv_start.tv_sec)
- + (tv_end.tv_usec - tv_start.tv_usec);
- mhz = (tsc_end - tsc_start) / usec_delay;
- return mhz;
-}
-
-/* This should only be called ONCE per process. */
-static inline void
-jack_init_time ()
-{
- __jack_cpu_mhz = jack_get_mhz ();
+ return jack_get_microseconds_from_system ();
}
#endif /* __jack_time_h__ */
diff --git a/config/os/gnu-linux/time.h b/config/os/gnu-linux/time.h
index 033d4a6..e97601c 100644
--- a/config/os/gnu-linux/time.h
+++ b/config/os/gnu-linux/time.h
@@ -1,5 +1,6 @@
/*
Copyright (C) 2001-2003 Paul Davis
+ Copyright (C) 2005 Jussi Laako
This is the GNU/Linux version.
@@ -19,79 +20,18 @@
$Id$
*/
+
#ifndef __jack_time_h__
#define __jack_time_h__
-#include <stdio.h>
#include <jack/internal.h>
-#include <sysdeps/cycles.h>
-
-/* This is a kludge. We need one global instantiation of this
- * variable in each address space. So, libjack/client.c declares the
- * actual storage. Other source files will see it as an extern. */
-#define JACK_TIME_GLOBAL_DECL jack_time_t __jack_cpu_mhz
-extern JACK_TIME_GLOBAL_DECL;
-static inline jack_time_t
-jack_get_microseconds (void) {
- return get_cycles() / __jack_cpu_mhz;
-}
+extern jack_time_t (*_jack_get_microseconds)(void);
-/*
- * This is another kludge. It looks CPU-dependent, but actually it
- * reflects the lack of standards for the Linux kernel formatting of
- * /proc/cpuinfo.
- */
static inline 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;
- }
- }
-}
-
-/* This should only be called ONCE per process. */
-static inline void
-jack_init_time ()
+jack_get_microseconds (void)
{
- __jack_cpu_mhz = jack_get_mhz ();
+ return _jack_get_microseconds ();
}
#endif /* __jack_time_h__ */
diff --git a/config/os/macosx/fakepoll.h b/config/os/macosx/fakepoll.h
deleted file mode 100644
index e3f4345..0000000
--- a/config/os/macosx/fakepoll.h
+++ /dev/null
@@ -1,161 +0,0 @@
-
-// fakepoll.h
-// poll using select
-// Warning: a call to this poll() takes about 4K of stack space.
-
-// Greg Parker gparker-web@sealiesoftware.com December 2000
-// This code is in the public domain and may be copied or modified without
-// permission.
-
-// Updated May 2002:
-// * fix crash when an fd is less than 0
-// * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE
-// * don't set POLLIN or POLLOUT in revents if it wasn't requested
-// in events (only happens when an fd is in the poll set twice)
-
-#ifndef _FAKE_POLL_H
-#define _FAKE_POLL_H
-
-#include <limits.h>
-#include <sys/types.h>
-#include <sys/time.h>
-#include <unistd.h>
-#include <stdlib.h>
-#include <errno.h>
-
-typedef struct pollfd {
- int fd; /* file desc to poll */
- short events; /* events of interest on fd */
- short revents; /* events that occurred on fd */
-} pollfd_t;
-
-
-// poll flags
-#define POLLIN 0x0001
-#define POLLOUT 0x0004
-#define POLLERR 0x0008
-
-// synonyms
-#define POLLNORM POLLIN
-#define POLLPRI POLLIN
-#define POLLRDNORM POLLIN
-#define POLLRDBAND POLLIN
-#define POLLWRNORM POLLOUT
-#define POLLWRBAND POLLOUT
-
-// ignored
-#define POLLHUP 0x0010
-#define POLLNVAL 0x0020
-
-inline int poll(struct pollfd *pollSet, int pollCount, int pollTimeout)
-{
- struct timeval tv;
- struct timeval *tvp;
- fd_set readFDs, writeFDs, exceptFDs;
- fd_set *readp, *writep, *exceptp;
- struct pollfd *pollEnd, *p;
- int selected;
- int result;
- int maxFD;
-
- if (!pollSet) {
- pollEnd = NULL;
- readp = NULL;
- writep = NULL;
- exceptp = NULL;
- maxFD = 0;
- }
- else {
- pollEnd = pollSet + pollCount;
- readp = &readFDs;
- writep = &writeFDs;
- exceptp = &exceptFDs;
-
- FD_ZERO(readp);
- FD_ZERO(writep);
- FD_ZERO(exceptp);
-
- // Find the biggest fd in the poll set
- maxFD = 0;
- for (p = pollSet; p < pollEnd; p++) {
- if (p->fd > maxFD) maxFD = p->fd;
- }
-
- if (maxFD >= FD_SETSIZE) {
- // At least one fd is too big
- errno = EINVAL;
- return -1;
- }
-
- // Transcribe flags from the poll set to the fd sets
- for (p = pollSet; p < pollEnd; p++) {
- if (p->fd < 0) {
- // Negative fd checks nothing and always reports zero
- } else {
- if (p->events & POLLIN) FD_SET(p->fd, readp);
- if (p->events & POLLOUT) FD_SET(p->fd, writep);
- if (p->events != 0) {
- FD_SET(p->fd, exceptp);
- }
- // POLLERR is never set coming in; poll() always reports errors
- // But don't report if we're not listening to anything at all.
- }
- }
- }
-
- // poll timeout is in milliseconds. Convert to struct timeval.
- // poll timeout == -1 : wait forever : select timeout of NULL
- // poll timeout == 0 : return immediately : select timeout of zero
- if (pollTimeout >= 0) {
- tv.tv_sec = pollTimeout / 1000;
- tv.tv_usec = (pollTimeout % 1000) * 1000;
- tvp = &tv;
- } else {
- tvp = NULL;
- }
-
- selected = select(maxFD+1, readp, writep, exceptp, tvp);
-
- if (selected < 0) {
- // Error during select
- result = -1;
- }
- else if (selected > 0) {
- // Select found something
- // Transcribe result from fd sets to poll set.
- // Also count the number of selected fds. poll returns the
- // number of ready fds; select returns the number of bits set.
- int polled = 0;
- for (p = pollSet; p < pollEnd; p++) {
- p->revents = 0;
- if (p->fd < 0) {
- // Negative fd always reports zero
- } else {
- if ((p->events & POLLIN) && FD_ISSET(p->fd, readp)) {
- p->revents |= POLLIN;
- }
- if ((p->events & POLLOUT) && FD_ISSET(p->fd, writep)) {
- p->revents |= POLLOUT;
- }
- if ((p->events != 0) && FD_ISSET(p->fd, exceptp)) {
- p->revents |= POLLERR;
- }
-
- if (p->revents) polled++;
- }
- }
- result = polled;
- }
- else {
- // selected == 0, select timed out before anything happened
- // Clear all result bits and return zero.
- for (p = pollSet; p < pollEnd; p++) {
- p->revents = 0;
- }
- result = 0;
- }
-
- return result;
-}
-
-#endif
diff --git a/config/os/macosx/poll.h b/config/os/macosx/poll.h
index 32ef6d2..6a49e0d 100644
--- a/config/os/macosx/poll.h
+++ b/config/os/macosx/poll.h
@@ -1,29 +1,162 @@
-/*
- Copyright (C) 2004 Jack O'Quin
- Mac OS/X replacement for <sys/poll.h>. Overrides system version,
- using <sysdeps/fakepoll.h> to emulate the needed features.
+// fakepoll.h
+// poll using select
+// Warning: a call to this poll() takes about 4K of stack space.
+
+// Greg Parker gparker-web@sealiesoftware.com December 2000
+// This code is in the public domain and may be copied or modified without
+// permission.
+
+// Updated May 2002:
+// * fix crash when an fd is less than 0
+// * set errno=EINVAL if an fd is greater or equal to FD_SETSIZE
+// * don't set POLLIN or POLLOUT in revents if it wasn't requested
+// in events (only happens when an fd is in the poll set twice)
+
+#ifndef _FAKE_POLL_H
+#define _FAKE_POLL_H
+
+#include <limits.h>
+#include <sys/types.h>
+#include <sys/time.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <errno.h>
+
+typedef struct pollfd {
+ int fd; /* file desc to poll */
+ short events; /* events of interest on fd */
+ short revents; /* events that occurred on fd */
+} pollfd_t;
- 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$
-*/
+// poll flags
+#define POLLIN 0x0001
+#define POLLOUT 0x0004
+#define POLLERR 0x0008
+
+// synonyms
+#define POLLNORM POLLIN
+#define POLLPRI POLLIN
+#define POLLRDNORM POLLIN
+#define POLLRDBAND POLLIN
+#define POLLWRNORM POLLOUT
+#define POLLWRBAND POLLOUT
+
+// ignored
+#define POLLHUP 0x0010
+#define POLLNVAL 0x0020
+
+static inline int
+poll(struct pollfd *pollSet, int pollCount, int pollTimeout)
+{
+ struct timeval tv;
+ struct timeval *tvp;
+ fd_set readFDs, writeFDs, exceptFDs;
+ fd_set *readp, *writep, *exceptp;
+ struct pollfd *pollEnd, *p;
+ int selected;
+ int result;
+ int maxFD;
+
+ if (!pollSet) {
+ pollEnd = NULL;
+ readp = NULL;
+ writep = NULL;
+ exceptp = NULL;
+ maxFD = 0;
+ }
+ else {
+ pollEnd = pollSet + pollCount;
+ readp = &readFDs;
+ writep = &writeFDs;
+ exceptp = &exceptFDs;
+
+ FD_ZERO(readp);
+ FD_ZERO(writep);
+ FD_ZERO(exceptp);
+
+ // Find the biggest fd in the poll set
+ maxFD = 0;
+ for (p = pollSet; p < pollEnd; p++) {
+ if (p->fd > maxFD) maxFD = p->fd;
+ }
+
+ if (maxFD >= FD_SETSIZE) {
+ // At least one fd is too big
+ errno = EINVAL;
+ return -1;
+ }
+
+ // Transcribe flags from the poll set to the fd sets
+ for (p = pollSet; p < pollEnd; p++) {
+ if (p->fd < 0) {
+ // Negative fd checks nothing and always reports zero
+ } else {
+ if (p->events & POLLIN) FD_SET(p->fd, readp);
+ if (p->events & POLLOUT) FD_SET(p->fd, writep);
+ if (p->events != 0) {
+ FD_SET(p->fd, exceptp);
+ }
+ // POLLERR is never set coming in; poll() always reports errors
+ // But don't report if we're not listening to anything at all.
+ }
+ }
+ }
+
+ // poll timeout is in milliseconds. Convert to struct timeval.
+ // poll timeout == -1 : wait forever : select timeout of NULL
+ // poll timeout == 0 : return immediately : select timeout of zero
+ if (pollTimeout >= 0) {
+ tv.tv_sec = pollTimeout / 1000;
+ tv.tv_usec = (pollTimeout % 1000) * 1000;
+ tvp = &tv;
+ } else {
+ tvp = NULL;
+ }
+
+ selected = select(maxFD+1, readp, writep, exceptp, tvp);
+
+ if (selected < 0) {
+ // Error during select
+ result = -1;
+ }
+ else if (selected > 0) {
+ // Select found something
+ // Transcribe result from fd sets to poll set.
+ // Also count the number of selected fds. poll returns the
+ // number of ready fds; select returns the number of bits set.
+ int polled = 0;
+ for (p = pollSet; p < pollEnd; p++) {
+ p->revents = 0;
+ if (p->fd < 0) {
+ // Negative fd always reports zero
+ } else {
+ if ((p->events & POLLIN) && FD_ISSET(p->fd, readp)) {
+ p->revents |= POLLIN;
+ }
+ if ((p->events & POLLOUT) && FD_ISSET(p->fd, writep)) {
+ p->revents |= POLLOUT;
+ }
+ if ((p->events != 0) && FD_ISSET(p->fd, exceptp)) {
+ p->revents |= POLLERR;
+ }
-#ifndef __poll_h__
-#define __poll_h__
+ if (p->revents) polled++;
+ }
+ }
+ result = polled;
+ }
+ else {
+ // selected == 0, select timed out before anything happened
+ // Clear all result bits and return zero.
+ for (p = pollSet; p < pollEnd; p++) {
+ p->revents = 0;
+ }
+ result = 0;
+ }
-#include <poll.h>
+ return result;
+}
-#endif /* __poll_h__ */
+#endif
diff --git a/config/os/macosx/portaudio.h b/config/os/macosx/portaudio.h
deleted file mode 100644
index 4c43b0c..0000000
--- a/config/os/macosx/portaudio.h
+++ /dev/null
@@ -1,28 +0,0 @@
-/*
- Copyright (C) 2004 Jack O'Quin
-
- Mac OS/X specific defines.
-
- 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$
-*/
-
-#ifndef _macosx_portaudio
-#define _macosx_portaudio 1
-
-#include <PortAudio.h>
-
-#endif /* _macosx_portaudio */
diff --git a/config/os/macosx/time.h b/config/os/macosx/time.h
index 73fd898..8f39540 100644
--- a/config/os/macosx/time.h
+++ b/config/os/macosx/time.h
@@ -21,32 +21,15 @@
#ifndef __jack_time_h__
#define __jack_time_h__
-/*
- * This is the MacOSX version of <jack/time.h>. It overrides the
- * generic version via the configure.hosts mechanism.
- */
#include <jack/types.h>
#include <mach/mach_time.h>
-/* This is a kludge. We need one global instantiation of this
- * variable in each address space. So, libjack/client.c declares the
- * actual storage. Other source files will see it as an extern. */
-#define JACK_TIME_GLOBAL_DECL double __jack_time_ratio
-extern JACK_TIME_GLOBAL_DECL;
+extern double __jack_time_ratio;
static inline jack_time_t
jack_get_microseconds(void)
{
- return mach_absolute_time () * __jack_time_ratio;
-}
-
-/* This should only be called ONCE per process. */
-static inline void
-jack_init_time ()
-{
- mach_timebase_info_data_t info;
- mach_timebase_info(&info);
- __jack_time_ratio = ((float)info.numer/info.denom) / 1000;
+ return (jack_time_t) mach_absolute_time () * __jack_time_ratio;
}
#endif /* __jack_time_h__ */
diff --git a/config/sysdeps/Makefile.am b/config/sysdeps/Makefile.am
deleted file mode 100644
index efd1145..0000000
--- a/config/sysdeps/Makefile.am
+++ /dev/null
@@ -1,23 +0,0 @@
-# This directory contains links to platform-dependent headers in the
-# source tree. None are installed or distributed from here. Remember
-# that the build tree and the source tree are not always the same.
-
-MAINTAINERCLEANFILES = Makefile.in
-CLEANFILES = *.h
-
-# Link all relevant headers into the `sysdeps' directory. The order
-# of these loops determines header file precedence.
-
-all-local:
- for h in ${top_srcdir}/config/cpu/generic/*.h; do \
- $(LN_S) -f $$h .; \
- done
- for h in ${top_srcdir}/config/@cpu_include_dir@/*.h; do \
- $(LN_S) -f $$h .; \
- done
- for h in ${top_srcdir}/config/os/generic/*.h; do \
- $(LN_S) -f $$h .; \
- done
- for h in ${top_srcdir}/config/@os_include_dir@/*.h; do \
- $(LN_S) -f $$h .; \
- done
diff --git a/config/sysdeps/atomicity.h b/config/sysdeps/atomicity.h
new file mode 100644
index 0000000..94b5e08
--- /dev/null
+++ b/config/sysdeps/atomicity.h
@@ -0,0 +1,24 @@
+#ifndef _jack_sysdep_atomicity_h_
+#define _jack_sysdep_atomicity_h_
+
+#if defined(__i386__)
+
+#include <config/cpu/i386/atomicity.h>
+
+#elif defined(__x86_64)
+
+/* x86_64 can use rdtsc just like i[456]86 */
+
+#include <config/cpu/i386/atomicity.h>
+
+#elif defined(__powerpc__) || defined(__ppc__) /* linux and OSX use different tokens */
+
+#include <config/cpu/powerpc/atomicity.h>
+
+#else
+
+#include <config/cpu/generic/atomicity.h>
+
+#endif /* processor selection */
+
+#endif /* _jack_sysdep_atomicity_h_ */
diff --git a/config/sysdeps/cycles.h b/config/sysdeps/cycles.h
new file mode 100644
index 0000000..eac039e
--- /dev/null
+++ b/config/sysdeps/cycles.h
@@ -0,0 +1,28 @@
+#ifndef _jack_sysdep_cycles_h_
+#define _jack_sysdep_cycles_h_
+
+#if defined(__i386__)
+
+/* technically, i386 doesn't have a cycle counter, but
+ running JACK on a real i386 seems like a ridiculuous
+ target and gcc defines this for the entire x86 family
+ including the [456]86 that do have the counter.
+*/
+
+#include <config/cpu/i386/cycles.h>
+
+#elif defined(__x86_64)
+
+#include <config/cpu/i486/cycles.h>
+
+#elif defined(__powerpc__) || defined(__ppc__) /* linux and OSX gcc use different tokens */
+
+#include <config/cpu/powerpc/cycles.h>
+
+#else
+
+#include <config/cpu/generic/cycles.h>
+
+#endif /* processor selection */
+
+#endif /* _jack_sysdep_cycles_h_ */
diff --git a/config/sysdeps/getopt.h b/config/sysdeps/getopt.h
new file mode 100644
index 0000000..d790320
--- /dev/null
+++ b/config/sysdeps/getopt.h
@@ -0,0 +1,8 @@
+#ifndef _jack_sysdep_getopt_h_
+#define _jack_sysdep_getopt_h_
+
+#if defined(__MACH__) && defined(__APPLE__)
+#include <config/os/macosx/getopt.h>
+#endif
+
+#endif /* _jack_sysdep_getopt_h_ */
diff --git a/config/sysdeps/ipc.h b/config/sysdeps/ipc.h
new file mode 100644
index 0000000..7c200ac
--- /dev/null
+++ b/config/sysdeps/ipc.h
@@ -0,0 +1,10 @@
+#ifndef _jack_sysdep_ipc_h_
+#define _jack_sysdep_ipc_h_
+
+#if defined(__MACH__) && defined(__APPLE__)
+#include <config/os/macosx/ipc.h>
+#else
+#include <config/os/generic/ipc.h>
+#endif
+
+#endif /* _jack_sysdep_ipc_h_ */
diff --git a/config/sysdeps/mach_port.h b/config/sysdeps/mach_port.h
new file mode 100644
index 0000000..af2e0ca
--- /dev/null
+++ b/config/sysdeps/mach_port.h
@@ -0,0 +1,8 @@
+#ifndef _jack_sysdep_mach_port_h_
+#define _jack_sysdep_mach_port_h_
+
+#if defined(__MACH__) && defined(__APPLE__)
+#include <config/os/macosx/mach_port.h>
+#endif
+
+#endif /* _jack_sysdep_mach_port_h_ */
diff --git a/config/sysdeps/pThreadUtilities.h b/config/sysdeps/pThreadUtilities.h
new file mode 100644
index 0000000..b0e4e60
--- /dev/null
+++ b/config/sysdeps/pThreadUtilities.h
@@ -0,0 +1,8 @@
+#ifndef _jack_sysdep_pThreadUtilities_h_
+#define _jack_sysdep_pThreadUtilities_h_
+
+#if defined(__MACH__) && defined(__APPLE__)
+#include <config/os/macosx/pThreadUtilities.h>
+#endif
+
+#endif /* _jack_sysdep_pThreadUtilities_h_ */
diff --git a/config/sysdeps/poll.h b/config/sysdeps/poll.h
new file mode 100644
index 0000000..663ac4d
--- /dev/null
+++ b/config/sysdeps/poll.h
@@ -0,0 +1,14 @@
+#ifndef _jack_sysdep_poll_h_
+#define _jack_sysdep_poll_h_
+
+#if defined(__MACH__) && defined(__APPLE__)
+
+#include <config/os/macosx/poll.h>
+
+#else
+
+#include <poll.h>
+
+#endif
+
+#endif /* _jack_sysdep_poll_h_ */
diff --git a/config/sysdeps/portaudio.h b/config/sysdeps/portaudio.h
new file mode 100644
index 0000000..2b3adfe
--- /dev/null
+++ b/config/sysdeps/portaudio.h
@@ -0,0 +1,8 @@
+#ifndef _jack_sysdep_portaudio_h_
+#define _jack_sysdep_portaudio_h_
+
+#if defined(__MACH__) && defined(__APPLE__)
+#include <PortAudio.h>
+#endif
+
+#endif /* _jack_sysdep_portaudio_h_ */
diff --git a/config/sysdeps/time.c b/config/sysdeps/time.c
new file mode 100644
index 0000000..aef49de
--- /dev/null
+++ b/config/sysdeps/time.c
@@ -0,0 +1,12 @@
+#ifndef _jack_sysdep_time_c_
+#define _jack_sysdep_time_c_
+
+#if defined(__gnu_linux__)
+#include <config/os/gnu-linux/time.c>
+#elif defined(__MACH__) && defined(__APPLE__)
+#include <config/os/macosx/time.c>
+#else
+#include <config/os/generic/time.c>
+#endif
+
+#endif /* _jack_sysdep_time_c_ */
diff --git a/config/sysdeps/time.h b/config/sysdeps/time.h
new file mode 100644
index 0000000..ff87b53
--- /dev/null
+++ b/config/sysdeps/time.h
@@ -0,0 +1,12 @@
+#ifndef _jack_sysdep_time_h_
+#define _jack_sysdep_time_h_
+
+#if defined(__gnu_linux__)
+#include <config/os/gnu-linux/time.h>
+#elif defined(__MACH__) && defined(__APPLE__)
+#include <config/os/macosx/time.h>
+#else
+#include <config/os/generic/time.h>
+#endif
+
+#endif /* _jack_sysdep_time_h_ */
diff --git a/configure.ac b/configure.ac
index 8741ed4..793ba34 100644
--- a/configure.ac
+++ b/configure.ac
@@ -78,13 +78,46 @@ AM_PROG_LIBTOOL
AC_PROG_LN_S
AC_C_BIGENDIAN
-# configure CPU and OS dependencies for host platform
AC_MSG_CHECKING([platform dependencies])
-source $srcdir/config/configure.host
-AC_MSG_RESULT([${os_include_dir}, ${cpu_include_dir}])
+
+case "${host_os}" in
+ freebsd*)
+ # current FreeBSD header files conflict with the OSS driver's
+ # barrier code, this may be fixed in 5.3, stay tuned.
+ USE_BARRIER="no"
+ ;;
+ darwin*)
+ JACK_THREAD_STACK_TOUCH=10000 # need small realtime stack
+ JACK_CPP_VARARGS_BROKEN=1
+ JACK_DO_NOT_MLOCK=1
+ JACK_USE_MACH_THREADS=1
+ OS_LDFLAGS="-framework CoreAudio -framework CoreServices -framework AudioUnit"
+ TRY_POSIX_SHM=yes # POSIX shm works better
+ ;;
+esac
+
AC_SUBST(OS_LDFLAGS)
-AC_SUBST(os_include_dir)
-AC_SUBST(cpu_include_dir)
+
+#
+# We need to establish suitable defaults for a 64-bit OS
+libnn=lib
+case "${host_os}" in
+ linux*)
+ case "${host_cpu}" in
+ x86_64|mips64|ppc64|sparc64|s390x)
+ libnn=lib64
+ ;;
+ esac
+ ;;
+ solaris*)
+ ## libnn=lib/sparcv9 ## on 64-bit only, but that's compiler-specific
+ ;;
+esac
+
+## take care not to override the command-line setting
+if test "${libdir}" = '${exec_prefix}/lib'; then
+ libdir='${exec_prefix}/'${libnn}
+fi
# system-dependent config.h values
test "x$JACK_THREAD_STACK_TOUCH" = "x" && JACK_THREAD_STACK_TOUCH=1000000
@@ -130,6 +163,16 @@ AC_CHECK_FUNCS(on_exit atexit)
AC_CHECK_FUNCS(posix_memalign)
AC_CHECK_LIB(m, sin)
+AC_CHECK_FUNC(clock_gettime,
+ [
+ AC_DEFINE(HAVE_CLOCK_GETTIME,1,"Whether or not clock_gettime can be found in system libraries")
+ ],
+ AC_CHECK_LIB(rt, clock_getttime,
+ [
+ AC_DEFINE(HAVE_CLOCK_GETTIME,1,"Whether or not clock_gettime can be found in system libraries")
+ ])
+)
+
# should we use mlockall() on this platform?
if test "x$JACK_DO_NOT_MLOCK" = "x"; then
AC_CHECK_HEADER(sys/mman.h,
@@ -448,9 +491,10 @@ AC_ARG_ENABLE(stripped-jackd,
# plugins go in the addon dir.
-AS_AC_EXPAND(ADDON_DIR,${libdir}/jack)
+ADDON_DIR='${libdir}/jack'
AC_SUBST(ADDON_DIR)
-AC_DEFINE_UNQUOTED(ADDON_DIR,"$ADDON_DIR",[Directory for plugins])
+AS_AC_EXPAND(ADDON_DIR_EXPANDED,${libdir}/jack)
+AC_DEFINE_UNQUOTED(ADDON_DIR,"$ADDON_DIR_EXPANDED",[Directory for plugins])
AC_ARG_WITH(html-dir,
[ --with-html-dir=PATH where to install the html documentation])
@@ -622,7 +666,6 @@ AM_CONDITIONAL(STRIPPED_JACKD, $STRIPPED_JACKD)
AC_OUTPUT(
Makefile
config/Makefile
-config/sysdeps/Makefile
doc/Makefile
doc/reference.doxygen
drivers/Makefile
@@ -656,6 +699,7 @@ echo \| Build with CoreAudio support.......................... : $HAVE_COREAUDIO
echo \| Build with PortAudio support.......................... : $HAVE_PA
echo \| Compiler optimization flags........................... : $JACK_OPT_CFLAGS
echo \| Compiler full flags................................... : $CFLAGS
+echo \| Install dir for libjack + backends.................... : $libdir/jack
echo \|
echo \| Default driver backend................................ : $JACK_DEFAULT_DRIVER
echo \| Shared memory interface............................... : $JACK_SHM_TYPE
diff --git a/example-clients/Makefile.am b/example-clients/Makefile.am
index 0bb0bb0..da61f74 100644
--- a/example-clients/Makefile.am
+++ b/example-clients/Makefile.am
@@ -114,11 +114,11 @@ jack_unload_LDFLAGS = @OS_LDFLAGS@
jack_unload_LDADD = ../libjack/libjack.la
jack_midiseq_SOURCES = midiseq.c
-jack_midiseq_LDFLAGS = -lrt -ldl -lpthread
+jack_midiseq_LDFLAGS = @OS_LDFLAGS@
jack_midiseq_LDADD = ../libjack/libjack.la
jack_midisine_SOURCES = midisine.c
-jack_midisine_LDFLAGS = -lrt -ldl -lpthread -lm
+jack_midisine_LDFLAGS = @OS_LDFLAGS@
jack_midisine_LDADD = ../libjack/libjack.la
#
diff --git a/example-clients/metro.c b/example-clients/metro.c
index e94d748..56578b6 100644
--- a/example-clients/metro.c
+++ b/example-clients/metro.c
@@ -123,6 +123,7 @@ main (int argc, char *argv[])
char *client_name = 0;
char *bpm_string = "bpm";
int verbose = 0;
+ jack_status_t status;
const char *options = "f:A:D:a:d:b:n:thv";
struct option long_options[] =
@@ -208,7 +209,7 @@ main (int argc, char *argv[])
client_name = (char *) malloc (9 * sizeof (char));
strcpy (client_name, "metro");
}
- if ((client = jack_client_new (client_name)) == 0) {
+ if ((client = jack_client_open (client_name, JackNoStartServer, &status)) == 0) {
fprintf (stderr, "jack server not running?\n");
return 1;
}
diff --git a/jack/engine.h b/jack/engine.h
index bcda3bf..9f1c6db 100644
--- a/jack/engine.h
+++ b/jack/engine.h
@@ -169,6 +169,8 @@ int internal_client_request (void* ptr, jack_request_t *request);
int jack_get_fifo_fd (jack_engine_t *engine,
unsigned int which_fifo);
+extern jack_timer_type_t clock_source;
+
extern jack_client_internal_t *
jack_client_internal_by_id (jack_engine_t *engine, jack_client_id_t id);
diff --git a/jack/internal.h b/jack/internal.h
index 0b9f6e7..ddbce73 100644
--- a/jack/internal.h
+++ b/jack/internal.h
@@ -42,6 +42,17 @@ extern void jack_error (const char *fmt, ...);
#include <jack/types.h>
#include <jack/port.h>
#include <jack/transport.h>
+
+typedef enum {
+ JACK_TIMER_SYSTEM_CLOCK,
+ JACK_TIMER_CYCLE_COUNTER,
+ JACK_TIMER_HPET,
+} jack_timer_type_t;
+
+void jack_init_time ();
+void jack_set_clock_source (jack_timer_type_t);
+const char* jack_clock_source_name (jack_timer_type_t);
+
#include <sysdeps/time.h>
#include <sysdeps/atomicity.h>
@@ -130,6 +141,7 @@ typedef struct {
jack_time_t sync_time_left;
jack_frame_timer_t frame_timer;
int32_t internal;
+ jack_timer_type_t clock_source;
pid_t engine_pid;
jack_nframes_t buffer_size;
int8_t real_time;
diff --git a/jack/thread.h b/jack/thread.h
index b7d936f..40c2b6b 100644
--- a/jack/thread.h
+++ b/jack/thread.h
@@ -27,6 +27,10 @@ extern "C" {
#include <pthread.h>
+/* use 512KB stack per thread - the default is way too high to be feasible
+ * with mlockall() on many systems */
+#define THREAD_STACK 524288
+
/** @file thread.h
*
* Library functions to standardize thread creation for JACK and its
diff --git a/jackd/engine.c b/jackd/engine.c
index 624b972..a4afb61 100644
--- a/jackd/engine.c
+++ b/jackd/engine.c
@@ -78,6 +78,8 @@ typedef struct _jack_driver_info {
dlhandle handle;
} jack_driver_info_t;
+jack_timer_type_t clock_source = JACK_TIMER_SYSTEM_CLOCK;
+
static int jack_port_assign_buffer (jack_engine_t *,
jack_port_internal_t *);
static jack_port_internal_t *jack_get_port_by_name (jack_engine_t *,
@@ -1540,6 +1542,30 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int do_unlock,
uid_t euid = geteuid ();
#endif /* USE_CAPABILITIES */
+ /* before we start allocating resources, make sure that if realtime was requested that we can
+ actually do it.
+ */
+
+ if (realtime) {
+ if (jack_acquire_real_time_scheduling (pthread_self(), 10) != 0) {
+ /* can't run realtime - time to bomb */
+ return NULL;
+ }
+
+ jack_drop_real_time_scheduling (pthread_self());
+
+#ifdef USE_MLOCK
+
+ if (do_mlock && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) {
+ jack_error ("cannot lock down memory for jackd (%s)",
+ strerror (errno));
+#ifdef ENSURE_MLOCK
+ return NULL;
+#endif /* ENSURE_MLOCK */
+ }
+#endif /* USE_MLOCK */
+ }
+
/* start a thread to display messages from realtime threads */
jack_messagebuffer_init();
@@ -1675,6 +1701,11 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int do_unlock,
engine->control->xrun_delayed_usecs = 0;
engine->control->max_delayed_usecs = 0;
+ jack_set_clock_source (clock_source);
+ engine->control->clock_source = clock_source;
+
+ VERBOSE (engine, "clock source = %s\n", jack_clock_source_name (clock_source));
+
engine->control->frame_timer.frames = frame_time_offset;
engine->control->frame_timer.reset_pending = 0;
engine->control->frame_timer.current_wakeup = 0;
@@ -1726,17 +1757,6 @@ jack_engine_new (int realtime, int rtpriority, int do_mlock, int do_unlock,
}
#endif /* USE_CAPABILITIES */
-#ifdef USE_MLOCK
-
- if (realtime && do_mlock && (mlockall (MCL_CURRENT | MCL_FUTURE) != 0)) {
- jack_error ("cannot lock down memory for jackd (%s)",
- strerror (errno));
-#ifdef ENSURE_MLOCK
- return NULL;
-#endif /* ENSURE_MLOCK */
- }
-#endif /* USE_MLOCK */
-
engine->control->engine_ok = 1;
snprintf (engine->fifo_prefix, sizeof (engine->fifo_prefix),
diff --git a/jackd/jackd.1.in b/jackd/jackd.1.in
index 620a5d1..3bd98af 100644
--- a/jackd/jackd.1.in
+++ b/jackd/jackd.1.in
@@ -96,6 +96,9 @@ Unlock libraries GTK+, QT, FLTK, Wine.
\fB\-v, \-\-verbose\fR
Give verbose output.
.TP
+\fB\-c, \-\-clocksource\fR (\fI c(ycle)\fR | \fI h(pet) \fR | \fI s(ystem) \fR)
+Select a specific wall clock (Cycle Counter, HPET timer, System timer).
+.TP
\fB\-V, \-\-version\fR
Print the current JACK version number and exit.
.SS ALSA BACKEND OPTIONS
diff --git a/jackd/jackd.c b/jackd/jackd.c
index 600f1fd..fcb190b 100644
--- a/jackd/jackd.c
+++ b/jackd/jackd.c
@@ -22,6 +22,7 @@
#include <config.h>
#include <stdio.h>
+#include <ctype.h>
#include <signal.h>
#include <getopt.h>
#include <sys/types.h>
@@ -368,6 +369,7 @@ static void usage (FILE *file)
" [ --port-max OR -p maximum-number-of-ports]\n"
" [ --debug-timer OR -D ]\n"
" [ --verbose OR -v ]\n"
+" [ --clocksource OR -c [ c(ycle) | h(pet) | s(ystem) ]\n"
" [ --silent OR -s ]\n"
" [ --version OR -V ]\n"
" -d backend [ ... backend args ... ]\n"
@@ -505,7 +507,7 @@ main (int argc, char *argv[])
{
jack_driver_desc_t * desc;
- const char *options = "-ad:P:uvshVRTFl:t:mn:p:";
+ const char *options = "-ad:P:uvshVRTFl:t:mn:p:c:";
struct option long_options[] =
{
{ "driver", 1, 0, 'd' },
@@ -521,6 +523,7 @@ main (int argc, char *argv[])
{ "temporary", 0, 0, 'T' },
{ "version", 0, 0, 'V' },
{ "silent", 0, 0, 's' },
+ { "clock-source", 1, 0, 'c' },
{ 0, 0, 0, 0 }
};
int opt = 0;
@@ -544,6 +547,19 @@ main (int argc, char *argv[])
long_options, &option_index)) != EOF) {
switch (opt) {
+ case 'c':
+ if (tolower (optarg[0]) == 'h') {
+ clock_source = JACK_TIMER_HPET;
+ } else if (tolower (optarg[0]) == 'c') {
+ clock_source = JACK_TIMER_CYCLE_COUNTER;
+ } else if (tolower (optarg[0]) == 's') {
+ clock_source = JACK_TIMER_SYSTEM_CLOCK;
+ } else {
+ usage (stderr);
+ return -1;
+ }
+ break;
+
case 'd':
seen_driver = 1;
driver_name = optarg;
diff --git a/libjack/Makefile.am b/libjack/Makefile.am
index 9ba7169..0181a59 100644
--- a/libjack/Makefile.am
+++ b/libjack/Makefile.am
@@ -16,10 +16,11 @@ SOURCE_FILES = \
messagebuffer.c \
pool.c \
port.c \
- midiport.c \
+ midiport.c \
ringbuffer.c \
shm.c \
thread.c \
+ time.c \
timestamps.c \
transclient.c \
unlock.c
diff --git a/libjack/client.c b/libjack/client.c
index 28e1d7c..8b9c947 100644
--- a/libjack/client.c
+++ b/libjack/client.c
@@ -50,12 +50,12 @@
#include <jack/intsimd.h>
#include <sysdeps/time.h>
-JACK_TIME_GLOBAL_DECL; /* One instance per process. */
#include "local.h"
#include <sysdeps/poll.h>
#include <sysdeps/ipc.h>
+#include <sysdeps/cycles.h>
#ifdef JACK_USE_MACH_THREADS
#include <sysdeps/pThreadUtilities.h>
@@ -77,7 +77,6 @@ int cpu_type = 0;
#define event_fd pollfd[EVENT_POLL_INDEX].fd
#define graph_wait_fd pollfd[WAIT_POLL_INDEX].fd
-
typedef struct {
int status;
struct _jack_client *client;
@@ -992,6 +991,9 @@ jack_client_open (const char *client_name,
client->engine = (jack_control_t *) jack_shm_addr (&client->engine_shm);
+ /* initialize clock source as early as possible */
+ jack_set_clock_source (client->engine->clock_source);
+
/* now attach the client control block */
client->control_shm = res.client_shm;
if (jack_attach_shm (&client->control_shm)) {
diff --git a/libjack/local.h b/libjack/local.h
index b48543d..bcd8fb5 100644
--- a/libjack/local.h
+++ b/libjack/local.h
@@ -1,7 +1,7 @@
#ifndef __jack_libjack_local_h__
#define __jack_libjack_local_h__
-/* Client data structure, in the client's address space. */
+/* Client data structure, in the client address space. */
struct _jack_client {
jack_control_t *engine;
@@ -52,4 +52,6 @@ extern jack_port_t *jack_port_new (const jack_client_t *client,
extern void *jack_zero_filled_buffer;
+extern void jack_set_clock_source (jack_timer_type_t);
+
#endif /* __jack_libjack_local_h__ */
diff --git a/libjack/thread.c b/libjack/thread.c
index 2674bae..520ac7e 100644
--- a/libjack/thread.c
+++ b/libjack/thread.c
@@ -159,6 +159,12 @@ jack_client_create_thread (jack_client_t* client,
return result;
}
+ result = pthread_attr_setstacksize(&attr, THREAD_STACK);
+ if (result) {
+ log_result("setting thread stack size", result);
+ return result;
+ }
+
thread_args = (jack_thread_arg_t *) malloc (sizeof (jack_thread_arg_t));
thread_args->client = client;