git-svn-id: svn+ssh://jackaudio.org/trunk/jack@757 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
@@ -15,12 +15,12 @@ implementation contained here. Andy Wingo and Kai Vehmanen provided | |||||
many small patches and documentation. Fernando Pablo Lopez-Lezcano | many small patches and documentation. Fernando Pablo Lopez-Lezcano | ||||
contributed the capabilities-based code. Jeremy Hall, Steve Harris, | contributed the capabilities-based code. Jeremy Hall, Steve Harris, | ||||
and Martin Boer contributed sample clients and utilities. Jack O'Quin | 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. | Many others have contributed patches and/or test results. |
@@ -15,7 +15,7 @@ dnl changes are made | |||||
dnl --- | dnl --- | ||||
JACK_MAJOR_VERSION=0 | JACK_MAJOR_VERSION=0 | ||||
JACK_MINOR_VERSION=98 | JACK_MINOR_VERSION=98 | ||||
JACK_MICRO_VERSION=15 | |||||
JACK_MICRO_VERSION=16 | |||||
dnl --- | dnl --- | ||||
dnl HOWTO: updating the jack protocol version | dnl HOWTO: updating the jack protocol version | ||||
@@ -275,8 +275,9 @@ dnl | |||||
CFLAGS=$JACK_CFLAGS | CFLAGS=$JACK_CFLAGS | ||||
# allow buffer resizing unless --disable-resize specified | # allow buffer resizing unless --disable-resize specified | ||||
enable_resize=yes | |||||
AC_ARG_ENABLE(resize, | 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 | if test x$enable_resize != xno ; then | ||||
AC_DEFINE(DO_BUFFER_RESIZE,,[Enable buffer resizing]) | AC_DEFINE(DO_BUFFER_RESIZE,,[Enable buffer resizing]) | ||||
@@ -6,7 +6,7 @@ CLEANFILES=doxygen-build.stamp | |||||
DOX=reference.doxygen | DOX=reference.doxygen | ||||
DOXSOURCES=mainpage.dox transport.dox porting.dox fsm.png fsm.eps \ | DOXSOURCES=mainpage.dox transport.dox porting.dox fsm.png fsm.eps \ | ||||
../jack/jack.h ../jack/types.h ../jack/transport.h \ | ../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 | ../example-clients/simple_client.c ../example-clients/inprocess.c | ||||
EXTRA_DIST=mainpage.dox transport.dox fsm.png fsm.eps porting.dox | EXTRA_DIST=mainpage.dox transport.dox fsm.png fsm.eps porting.dox | ||||
@@ -91,6 +91,8 @@ The JACK programming interfaces are described in several header files: | |||||
control mechanism for starting, stopping and repositioning clients. | control mechanism for starting, stopping and repositioning clients. | ||||
This is described in the @ref transport-design document. | This is described in the @ref transport-design document. | ||||
- @ref types.h "<jack/types.h>" defines most of the JACK data types. | - @ref types.h "<jack/types.h>" defines most of the JACK data types. | ||||
- @ref thread.h "<jack/thread.h>" functions standardize thread | |||||
creation for JACK and its clients. | |||||
In addition, the example-clients directory provides numerous examples | In addition, the example-clients directory provides numerous examples | ||||
of simple JACK clients that nevertheless use the API to do something | of simple JACK clients that nevertheless use the API to do something | ||||
@@ -369,6 +369,7 @@ INPUT = @top_srcdir@/doc/mainpage.dox \ | |||||
@top_srcdir@/jack/types.h \ | @top_srcdir@/jack/types.h \ | ||||
@top_srcdir@/jack/transport.h \ | @top_srcdir@/jack/transport.h \ | ||||
@top_srcdir@/jack/ringbuffer.h \ | @top_srcdir@/jack/ringbuffer.h \ | ||||
@top_srcdir@/jack/thread.h \ | |||||
@top_srcdir@/example-clients/simple_client.c \ | @top_srcdir@/example-clients/simple_client.c \ | ||||
@top_srcdir@/example-clients/inprocess.c | @top_srcdir@/example-clients/inprocess.c | ||||
@@ -1,12 +1,26 @@ | |||||
/* | /* | ||||
* AudioRender.cpp | * 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. | * 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 <unistd.h> | #include <unistd.h> | ||||
@@ -1,12 +1,26 @@ | |||||
/* | /* | ||||
* AudioRender.h | * 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. | * 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 <Carbon/Carbon.h> | #include <Carbon/Carbon.h> | ||||
@@ -1,11 +1,27 @@ | |||||
/* | /* | ||||
* AudioRenderBridge.c | * AudioRenderBridge.c | ||||
* jack_coreaudio | * jack_coreaudio | ||||
* Under Artistic License. | |||||
* | * | ||||
* Created by Johnny Petrantoni on Fri Jan 30 2004. | |||||
* Copyright (c) 2004 Johnny Petrantoni. All rights reserved. | * 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" | #include "AudioRenderBridge.h" | ||||
@@ -1,11 +1,27 @@ | |||||
/* | /* | ||||
* AudioRenderBridge.h | * AudioRenderBridge.h | ||||
* jack_coreaudio | * jack_coreaudio | ||||
* Under Artistic License. | |||||
* | * | ||||
* Created by Johnny Petrantoni on Fri Jan 30 2004. | |||||
* Copyright (c) 2004 Johnny Petrantoni. All rights reserved. | * 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); | typedef int (*JackRunCyclePtr) (void *driver, long bufferSize); | ||||
@@ -4,12 +4,13 @@ libjackincludedir = $(includedir)/jack | |||||
libjackinclude_HEADERS = \ | libjackinclude_HEADERS = \ | ||||
jack.h \ | jack.h \ | ||||
ringbuffer.h \ | |||||
timestamps.h \ | |||||
ringbuffer.h \ | |||||
thread.h \ | |||||
timestamps.h \ | |||||
transport.h \ | transport.h \ | ||||
types.h | types.h | ||||
noinst_HEADERS = \ | |||||
noinst_HEADERS = \ | |||||
atomicity.h \ | atomicity.h \ | ||||
driver.h \ | driver.h \ | ||||
driver_interface.h \ | driver_interface.h \ | ||||
@@ -24,6 +25,5 @@ noinst_HEADERS = \ | |||||
ringbuffer.h \ | ringbuffer.h \ | ||||
shm.h \ | shm.h \ | ||||
start.h \ | start.h \ | ||||
thread.h \ | |||||
unlock.h \ | unlock.h \ | ||||
version.h | version.h |
@@ -29,28 +29,53 @@ extern "C" { | |||||
/** @file thread.h | /** @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 | #ifdef __cplusplus | ||||
} | } | ||||
@@ -37,19 +37,15 @@ | |||||
#include <sysdeps/pThreadUtilities.h> | #include <sysdeps/pThreadUtilities.h> | ||||
#endif | #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 | int | ||||
jack_create_thread (pthread_t* thread, | jack_create_thread (pthread_t* thread, | ||||
@@ -64,19 +60,22 @@ jack_create_thread (pthread_t* thread, | |||||
struct sched_param param; | struct sched_param param; | ||||
int actual_policy; | int actual_policy; | ||||
struct sched_param actual_param; | struct sched_param actual_param; | ||||
#endif /* JACK_USE_MACH_THREADS */ | |||||
#endif /* !JACK_USE_MACH_THREADS */ | |||||
int result = 0; | int result = 0; | ||||
if (!realtime) { | if (!realtime) { | ||||
result = pthread_create (thread, 0, start_routine, arg); | 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 | #ifndef JACK_USE_MACH_THREADS | ||||
@@ -85,15 +84,30 @@ jack_create_thread (pthread_t* thread, | |||||
policy = SCHED_FIFO; | policy = SCHED_FIFO; | ||||
param.sched_priority = priority; | param.sched_priority = priority; | ||||
result = pthread_attr_setinheritsched(&attr, PTHREAD_EXPLICIT_SCHED); | 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); | 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); | 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); | 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); | 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 | /* with respect to getting scheduling class+priority set up | ||||
correctly, there are three possibilities here: | correctly, there are three possibilities here: | ||||
@@ -145,18 +159,33 @@ jack_create_thread (pthread_t* thread, | |||||
sched_getparam (0, ¤t_param); | sched_getparam (0, ¤t_param); | ||||
result = sched_setscheduler (0, policy, ¶m); | 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); | pthread_attr_init (&inherit_attr); | ||||
result = pthread_attr_setscope (&inherit_attr, | result = pthread_attr_setscope (&inherit_attr, | ||||
PTHREAD_SCOPE_SYSTEM); | 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, | result = pthread_attr_setinheritsched (&inherit_attr, | ||||
PTHREAD_INHERIT_SCHED); | 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, | result = pthread_create (thread, &inherit_attr, start_routine, | ||||
arg); | 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); | 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... */ | /* Still here? Good. Let's see if this worked... */ | ||||
result = pthread_getschedparam (*thread, &actual_policy, &actual_param); | 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 && | if (actual_policy == policy && | ||||
actual_param.sched_priority == param.sched_priority) { | 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, | /* 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); | 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 */ | #else /* JACK_USE_MACH_THREADS */ | ||||
result = pthread_create (thread, 0, start_routine, arg); | 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 */ | /* time constraint thread */ | ||||
setThreadToPriority (*thread, 96, TRUE, 10000000); | setThreadToPriority (*thread, 96, TRUE, 10000000); | ||||