diff options
author | pbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224> | 2006-05-15 17:12:44 +0000 |
---|---|---|
committer | pbd <pbd@0c269be4-1314-0410-8aa9-9f06e86f4224> | 2006-05-15 17:12:44 +0000 |
commit | 7e8cf3c23c729342d42d9270dd2cd11834a9db19 (patch) | |
tree | 8909f3b6e91a16523a9cfe54ae3c03765f928c73 | |
parent | 2e06b7b6c3affbb642de54f4648e80a268f23849 (diff) | |
download | jack1-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
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; |