diff --git a/AUTHORS b/AUTHORS index 9723c38..801c440 100644 --- a/AUTHORS +++ b/AUTHORS @@ -15,12 +15,12 @@ implementation contained here. Andy Wingo and Kai Vehmanen provided many small patches and documentation. Fernando Pablo Lopez-Lezcano contributed the capabilities-based code. Jeremy Hall, Steve Harris, and Martin Boer contributed sample clients and utilities. Jack O'Quin -contributed new transport interfaces, implemented the buffer size -callback, and added much documentation. Taybin Rutkin helps with -patch management and releases. Melanie Thielker contributed -significantly to JACK's interaction with aspects of both POSIX and -System V APIs. Stephane Letz ported JACK to Mac OS X. Jussi Laako -wrote the OSS driver interface. Tilman Linneweh ported JACK to -FreeBSD. +contributed new transport interfaces, buffer resizing, documentation +and many bug fixes. Taybin Rutkin helps with patch management and +releases. Melanie Thielker contributed significantly to JACK's +interaction with aspects of both POSIX and System V APIs. Stephane +Letz ported JACK to Mac OS X. Jussi Laako wrote the OSS driver +interface. Tilman Linneweh ported JACK to FreeBSD. Johnny Petrantoni +wrote the Mac OS X CoreAudio driver interface. Many others have contributed patches and/or test results. diff --git a/configure.in b/configure.in index a937585..e902c65 100644 --- a/configure.in +++ b/configure.in @@ -15,7 +15,7 @@ dnl changes are made dnl --- JACK_MAJOR_VERSION=0 JACK_MINOR_VERSION=98 -JACK_MICRO_VERSION=15 +JACK_MICRO_VERSION=16 dnl --- dnl HOWTO: updating the jack protocol version @@ -275,8 +275,9 @@ dnl CFLAGS=$JACK_CFLAGS # allow buffer resizing unless --disable-resize specified +enable_resize=yes AC_ARG_ENABLE(resize, - AC_HELP_STRING([--enable-resize], [enable buffer resizing]), + AC_HELP_STRING([--disable-resize], [disable buffer resizing]), [ if test x$enable_resize != xno ; then AC_DEFINE(DO_BUFFER_RESIZE,,[Enable buffer resizing]) diff --git a/doc/Makefile.am b/doc/Makefile.am index 6a62ecf..cba0b8c 100644 --- a/doc/Makefile.am +++ b/doc/Makefile.am @@ -6,7 +6,7 @@ CLEANFILES=doxygen-build.stamp DOX=reference.doxygen DOXSOURCES=mainpage.dox transport.dox porting.dox fsm.png fsm.eps \ ../jack/jack.h ../jack/types.h ../jack/transport.h \ - ../jack/ringbuffer.h ../jack/port.h \ + ../jack/ringbuffer.h ../jack/thread.h ../jack/port.h \ ../example-clients/simple_client.c ../example-clients/inprocess.c EXTRA_DIST=mainpage.dox transport.dox fsm.png fsm.eps porting.dox diff --git a/doc/mainpage.dox b/doc/mainpage.dox index 8fa5917..1811fe9 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -91,6 +91,8 @@ The JACK programming interfaces are described in several header files: control mechanism for starting, stopping and repositioning clients. This is described in the @ref transport-design document. - @ref types.h "" defines most of the JACK data types. + - @ref thread.h "" functions standardize thread + creation for JACK and its clients. In addition, the example-clients directory provides numerous examples of simple JACK clients that nevertheless use the API to do something diff --git a/doc/reference.doxygen.in b/doc/reference.doxygen.in index fec4555..3992ad5 100644 --- a/doc/reference.doxygen.in +++ b/doc/reference.doxygen.in @@ -369,6 +369,7 @@ INPUT = @top_srcdir@/doc/mainpage.dox \ @top_srcdir@/jack/types.h \ @top_srcdir@/jack/transport.h \ @top_srcdir@/jack/ringbuffer.h \ + @top_srcdir@/jack/thread.h \ @top_srcdir@/example-clients/simple_client.c \ @top_srcdir@/example-clients/inprocess.c diff --git a/drivers/coreaudio/AudioRender.cpp b/drivers/coreaudio/AudioRender.cpp index 739b55f..ec5e442 100644 --- a/drivers/coreaudio/AudioRender.cpp +++ b/drivers/coreaudio/AudioRender.cpp @@ -1,12 +1,26 @@ /* * AudioRender.cpp - * Under Artistic License. - * This code is part of Panda framework (moduleloader.cpp) - * http://xpanda.sourceforge.net * - * Created by Johnny Petrantoni on Fri Jan 30 2004. * Copyright (c) 2004 Johnny Petrantoni. All rights reserved. * + * 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. + * + * Created by Johnny Petrantoni on Fri Jan 30 2004. + * This code is part of Panda framework (moduleloader.cpp) + * http://xpanda.sourceforge.net */ #include diff --git a/drivers/coreaudio/AudioRender.h b/drivers/coreaudio/AudioRender.h index b56b6fb..4ad93ca 100644 --- a/drivers/coreaudio/AudioRender.h +++ b/drivers/coreaudio/AudioRender.h @@ -1,12 +1,26 @@ /* * AudioRender.h - * Under Artistic License. - * This code is part of Panda framework (moduleloader.hpp) - * http://xpanda.sourceforge.net * - * Created by Johnny Petrantoni on Fri Jan 30 2004. * Copyright (c) 2004 Johnny Petrantoni. All rights reserved. * + * 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. + * + * Created by Johnny Petrantoni on Fri Jan 30 2004. + * This code is part of Panda framework (moduleloader.cpp) + * http://xpanda.sourceforge.net */ #include diff --git a/drivers/coreaudio/AudioRenderBridge.cpp b/drivers/coreaudio/AudioRenderBridge.cpp index 06daaa3..352e00d 100644 --- a/drivers/coreaudio/AudioRenderBridge.cpp +++ b/drivers/coreaudio/AudioRenderBridge.cpp @@ -1,11 +1,27 @@ /* * AudioRenderBridge.c * jack_coreaudio - * Under Artistic License. * - * Created by Johnny Petrantoni on Fri Jan 30 2004. * Copyright (c) 2004 Johnny Petrantoni. All rights reserved. * + * 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. + * + * Created by Johnny Petrantoni on Fri Jan 30 2004. + * This code is part of Panda framework (moduleloader.cpp) + * http://xpanda.sourceforge.net */ #include "AudioRenderBridge.h" diff --git a/drivers/coreaudio/AudioRenderBridge.h b/drivers/coreaudio/AudioRenderBridge.h index f788b89..3257a1f 100644 --- a/drivers/coreaudio/AudioRenderBridge.h +++ b/drivers/coreaudio/AudioRenderBridge.h @@ -1,11 +1,27 @@ /* * AudioRenderBridge.h * jack_coreaudio - * Under Artistic License. * - * Created by Johnny Petrantoni on Fri Jan 30 2004. * Copyright (c) 2004 Johnny Petrantoni. All rights reserved. * + * 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. + * + * Created by Johnny Petrantoni on Fri Jan 30 2004. + * This code is part of Panda framework (moduleloader.cpp) + * http://xpanda.sourceforge.net */ typedef int (*JackRunCyclePtr) (void *driver, long bufferSize); diff --git a/jack/Makefile.am b/jack/Makefile.am index 2cffd6a..9a9fa4f 100644 --- a/jack/Makefile.am +++ b/jack/Makefile.am @@ -4,12 +4,13 @@ libjackincludedir = $(includedir)/jack libjackinclude_HEADERS = \ jack.h \ - ringbuffer.h \ - timestamps.h \ + ringbuffer.h \ + thread.h \ + timestamps.h \ transport.h \ types.h -noinst_HEADERS = \ +noinst_HEADERS = \ atomicity.h \ driver.h \ driver_interface.h \ @@ -24,6 +25,5 @@ noinst_HEADERS = \ ringbuffer.h \ shm.h \ start.h \ - thread.h \ unlock.h \ version.h diff --git a/jack/thread.h b/jack/thread.h index f57982f..7b6e0fa 100644 --- a/jack/thread.h +++ b/jack/thread.h @@ -29,28 +29,53 @@ extern "C" { /** @file thread.h * - * A library functions to standardize thread creation for both jackd and its - * clients. + * Library functions to standardize thread creation for JACK and its + * clients. These interfaces hide some system variations in the + * handling of realtime scheduling and associated privileges. */ /** + * Attempt to enable realtime scheduling for a thread. On some + * systems that may require special privileges. * + * @param thread POSIX thread ID. + * @param priority requested thread priority. + * + * @returns 0, if successful; EPERM, if the calling process lacks + * required realtime privileges; otherwise some other error number. */ -int jack_create_thread (pthread_t* thread, - int priority, - int realtime, /* boolean */ - void*(*start_routine)(void*), - void* arg); +int jack_acquire_real_time_scheduling (pthread_t thread, + int priority); /** + * Create a thread for JACK or one of its clients. The thread is + * created executing @a start_routine with @a arg as its sole + * argument. + * + * @param thread place to return POSIX thread ID. + * @param priority thread priority, if realtime. + * @param realtime true for the thread to use realtime scheduling. On + * some systems that may require special privileges. + * @param start_routine function the thread calls when it starts. + * @param arg parameter passed to the @a start_routine. * + * @returns 0, if successful; EPERM, if the calling process lacks + * required realtime privileges; otherwise some other error number. */ -extern int jack_acquire_real_time_scheduling (pthread_t, int priority); +int jack_create_thread (pthread_t *thread, + int priority, + int realtime, /* boolean */ + void *(*start_routine)(void*), + void *arg); /** + * Drop realtime scheduling for a thread. + * + * @param thread POSIX thread ID. * + * @returns 0, if successful; otherwise an error number. */ -extern int jack_drop_real_time_scheduling (pthread_t); +int jack_drop_real_time_scheduling (pthread_t thread); #ifdef __cplusplus } diff --git a/libjack/thread.c b/libjack/thread.c index 90c3fbe..50a70d2 100644 --- a/libjack/thread.c +++ b/libjack/thread.c @@ -37,19 +37,15 @@ #include #endif -#define log_internal(msg, res, fatal) \ - if (res) { \ - char outbuf[500]; \ - snprintf(outbuf, sizeof(outbuf), \ - "jack_create_thread: error %d %s: %s", \ - res, msg, strerror(res)); \ - jack_error(outbuf); \ - if (fatal) \ - return res; \ - } - -#define log_result(msg) log_internal(msg, result, 1); -#define log_result_nonfatal(msg) log_internal(msg, result, 0); +static inline void +log_result (char *msg, int res) +{ + char outbuf[500]; + snprintf(outbuf, sizeof(outbuf), + "jack_create_thread: error %d %s: %s", + res, msg, strerror(res)); + jack_error(outbuf); +} int jack_create_thread (pthread_t* thread, @@ -64,19 +60,22 @@ jack_create_thread (pthread_t* thread, struct sched_param param; int actual_policy; struct sched_param actual_param; -#endif /* JACK_USE_MACH_THREADS */ +#endif /* !JACK_USE_MACH_THREADS */ + int result = 0; if (!realtime) { result = pthread_create (thread, 0, start_routine, arg); - log_result("creating thread with default parameters"); - - return 0; + if (result) { + log_result("creating thread with default parameters", + result); + } + return result; } - /* realtime thread. this disgusting mess is a - * reflection of the 2nd-class nature of RT - * programming under POSIX in general and Linux in particular. + /* realtime thread. this disgusting mess is a reflection of + * the 2nd-class nature of RT programming under POSIX in + * general and Linux in particular. */ #ifndef JACK_USE_MACH_THREADS @@ -85,15 +84,30 @@ jack_create_thread (pthread_t* thread, policy = SCHED_FIFO; param.sched_priority = priority; result = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); - log_result("requesting explicit scheduling"); + if (result) { + log_result("requesting explicit scheduling", result); + return result; + } result = pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_JOINABLE); - log_result("requesting joinable thread creation"); + if (result) { + log_result("requesting joinable thread creation", result); + return result; + } result = pthread_attr_setscope(&attr, PTHREAD_SCOPE_SYSTEM); - log_result("requesting system scheduling scope"); + if (result) { + log_result("requesting system scheduling scope", result); + return result; + } result = pthread_attr_setschedpolicy(&attr, policy); - log_result("requesting non-standard scheduling policy"); + if (result) { + log_result("requesting non-standard scheduling policy", result); + return result; + } result = pthread_attr_setschedparam(&attr, ¶m); - log_result("requesting thread priority"); + if (result) { + log_result("requesting thread priority", result); + return result; + } /* with respect to getting scheduling class+priority set up correctly, there are three possibilities here: @@ -145,18 +159,33 @@ jack_create_thread (pthread_t* thread, sched_getparam (0, ¤t_param); result = sched_setscheduler (0, policy, ¶m); - log_result("switching current thread to rt for inheritance"); + if (result) { + log_result("switching current thread to rt for " + "inheritance", result); + return result; + } pthread_attr_init (&inherit_attr); result = pthread_attr_setscope (&inherit_attr, PTHREAD_SCOPE_SYSTEM); - log_result("requesting system scheduling scope for inheritance"); + if (result) { + log_result("requesting system scheduling scope " + "for inheritance", result); + return result; + } result = pthread_attr_setinheritsched (&inherit_attr, PTHREAD_INHERIT_SCHED); - log_result("requesting inheritance of scheduling parameters"); + if (result) { + log_result("requesting inheritance of scheduling " + "parameters", result); + return result; + } result = pthread_create (thread, &inherit_attr, start_routine, arg); - log_result_nonfatal("creating real-time thread by inheritance"); + if (result) { + log_result("creating real-time thread by inheritance", + result); + } sched_setscheduler (0, current_policy, ¤t_param); @@ -167,14 +196,14 @@ jack_create_thread (pthread_t* thread, /* Still here? Good. Let's see if this worked... */ result = pthread_getschedparam (*thread, &actual_policy, &actual_param); - log_result ("verifying scheduler parameters"); + if (result) { + log_result ("verifying scheduler parameters", result); + return result; + } if (actual_policy == policy && actual_param.sched_priority == param.sched_priority) { - - /* everything worked OK */ - - return 0; + return 0; /* everything worked OK */ } /* we failed to set the sched class and priority, @@ -185,12 +214,20 @@ jack_create_thread (pthread_t* thread, */ result = pthread_setschedparam (*thread, policy, ¶m); - log_result("setting scheduler parameters after thread creation"); + if (result) { + log_result("setting scheduler parameters after thread " + "creation", result); + return result; + } #else /* JACK_USE_MACH_THREADS */ result = pthread_create (thread, 0, start_routine, arg); - log_result ("creating realtime thread"); + if (result) { + log_result ("creating realtime thread", result); + return result; + } + /* time constraint thread */ setThreadToPriority (*thread, 96, TRUE, 10000000);