From 48b51efd9dc9f5eda079191ff21106024190c1b4 Mon Sep 17 00:00:00 2001 From: sletz Date: Fri, 4 Mar 2011 12:29:20 +0000 Subject: [PATCH] Synchronize jack.h with JACK1, use jack_native_thread_t type in POSIX and OSX thread implementation. git-svn-id: http://subversion.jackaudio.org/jack/jack2/trunk/jackmp@4146 0c269be4-1314-0410-8aa9-9f06e86f4224 --- common/JackDebugClient.cpp | 12 +- common/JackError.h | 11 +- common/JackTime.h | 1 - common/JackTypes.h | 6 + common/jack/jack.h | 336 ++++++++++++++++++++++++++++++------- common/timestamps.c | 11 +- macosx/JackMachThread.cpp | 26 +-- macosx/JackMachThread.h | 28 ++-- posix/JackPosixThread.cpp | 64 +++---- posix/JackPosixThread.h | 26 +-- posix/JackTypes_os.h | 2 + 11 files changed, 373 insertions(+), 150 deletions(-) diff --git a/common/JackDebugClient.cpp b/common/JackDebugClient.cpp index 77a6df28..3c389abc 100644 --- a/common/JackDebugClient.cpp +++ b/common/JackDebugClient.cpp @@ -12,7 +12,7 @@ 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 +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -116,17 +116,17 @@ int JackDebugClient::Close() void JackDebugClient::CheckClient(const char* function_name) const { *fStream << "CheckClient : " << function_name << ", calling thread : " << pthread_self() << endl; - + if (fIsClosed > 0) { - *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl; + *fStream << "!!! ERROR !!! : Accessing a client '" << fClientName << "' already closed " << "from " << function_name << endl; *fStream << "This is likely to cause crash !'" << endl; #ifdef __APPLE__ // Debugger(); - #endif + #endif } } -pthread_t JackDebugClient::GetThreadID() +jack_native_thread_t JackDebugClient::GetThreadID() { CheckClient("GetThreadID"); return fClient->GetThreadID(); @@ -428,7 +428,7 @@ void JackDebugClient::OnInfoShutdown(JackInfoShutdownCallback callback, void *ar CheckClient("OnInfoShutdown"); fClient->OnInfoShutdown(callback, arg); } - + int JackDebugClient::TimeCallback(jack_nframes_t nframes, void *arg) { JackDebugClient* client = (JackDebugClient*)arg; diff --git a/common/JackError.h b/common/JackError.h index 425266f9..15e39f86 100644 --- a/common/JackError.h +++ b/common/JackError.h @@ -7,12 +7,12 @@ 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. @@ -25,7 +25,6 @@ #include #include #include "JackCompilerDeps.h" -#include "types.h" #ifdef __cplusplus extern "C" @@ -44,17 +43,17 @@ extern "C" EXPORT extern void (*jack_error_callback)(const char *desc); EXPORT extern void (*jack_info_callback)(const char *desc); - + EXPORT extern void default_jack_error_callback(const char *desc); EXPORT extern void default_jack_info_callback(const char *desc); - + EXPORT extern void silent_jack_error_callback(const char *desc); EXPORT extern void silent_jack_info_callback(const char *desc); typedef void (* jack_log_function_t)(int level, const char *message); void jack_log_function(int level, const char *message); - + EXPORT int set_threaded_log_function(); #ifdef __cplusplus diff --git a/common/JackTime.h b/common/JackTime.h index 10ef1e8c..505903c6 100644 --- a/common/JackTime.h +++ b/common/JackTime.h @@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #ifndef __JackTime__ #define __JackTime__ -#include "types.h" #include "JackCompilerDeps.h" #include "JackTypes.h" diff --git a/common/JackTypes.h b/common/JackTypes.h index 234be17a..b4bad8d6 100644 --- a/common/JackTypes.h +++ b/common/JackTypes.h @@ -34,6 +34,12 @@ typedef signed long SInt32; #include "JackTypes_os.h" +/** + * Type used to represent the value of free running + * monotonic clock with units of microseconds. + */ +typedef uint64_t jack_time_t; + typedef uint16_t jack_int_t; // Internal type for ports and refnum typedef enum { diff --git a/common/jack/jack.h b/common/jack/jack.h index 70ee1c3e..40f06ddd 100644 --- a/common/jack/jack.h +++ b/common/jack/jack.h @@ -522,6 +522,64 @@ int jack_set_xrun_callback (jack_client_t *, /*@}*/ +/** + * Tell the Jack server to call @a latency_callback whenever it + * is necessary to recompute the latencies for some or all + * Jack ports. + * + * @a latency_callback will be called twice each time it is + * needed, once being passed JackCaptureLatency and once + * JackPlaybackLatency. See @ref LatencyFunctions for + * the definition of each type of latency and related functions. + * + * IMPORTANT: Most JACK clients do NOT need to register a latency + * callback. + * + * Clients that meet any of the following conditions do NOT + * need to register a latency callback: + * + * - have only input ports + * - have only output ports + * - their output is totally unrelated to their input + * - their output is not delayed relative to their input + * (i.e. data that arrives in a given process() + * callback is processed and output again in the + * same callback) + * + * Clients NOT registering a latency callback MUST also + * satisfy this condition: + * + * - have no multiple distinct internal signal pathways + * + * This means that if your client has more than 1 input and + * output port, and considers them always "correlated" + * (e.g. as a stereo pair), then there is only 1 (e.g. stereo) + * signal pathway through the client. This would be true, + * for example, of a stereo FX rack client that has a + * left/right input pair and a left/right output pair. + * + * However, this is somewhat a matter of perspective. The + * same FX rack client could be connected so that its + * two input ports were connected to entirely separate + * sources. Under these conditions, the fact that the client + * does not register a latency callback MAY result + * in port latency values being incorrect. + * + * Clients that do not meet any of those conditions SHOULD + * register a latency callback. + * + * See the documentation for @ref jack_port_set_latency_range() + * on how the callback should operate. Remember that the @a mode + * argument given to the latency callback will need to be + * passed into @ref jack_port_set_latency_range() + * + * @return 0 on success, otherwise a non-zero error code + */ +int jack_set_latency_callback (jack_client_t *, + JackLatencyCallback latency_callback, + void *) JACK_WEAK_EXPORT; +/*@}*/ + /** * @defgroup ServerClientControl Controlling & querying JACK server operation * @{ @@ -784,66 +842,6 @@ int jack_port_tie (jack_port_t *src, jack_port_t *dst) JACK_OPTIONAL_WEAK_DEPREC */ int jack_port_untie (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; - /** - * @return the time (in frames) between data being available or - * delivered at/to a port, and the time at which it arrived at or is - * delivered to the "other side" of the port. E.g. for a physical - * audio output port, this is the time between writing to the port and - * when the signal will leave the connector. For a physical audio - * input port, this is the time between the sound arriving at the - * connector and the corresponding frames being readable from the - * port. - */ -jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * The maximum of the sum of the latencies in every - * connection path that can be drawn between the port and other - * ports with the @ref JackPortIsTerminal flag set. - */ -jack_nframes_t jack_port_get_total_latency (jack_client_t *, - jack_port_t *port) JACK_OPTIONAL_WEAK_EXPORT; - -/** - * The port latency is zero by default. Clients that control - * physical hardware with non-zero latency should call this - * to set the latency to its correct value. Note that the value - * should include any systemic latency present "outside" the - * physical hardware controlled by the client. For example, - * for a client controlling a digital audio interface connected - * to an external digital converter, the latency setting should - * include both buffering by the audio interface *and* the converter. - */ -void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_EXPORT; - -/** -* Request a complete recomputation of a port's total latency. This -* can be called by a client that has just changed the internal -* latency of its port using @function jack_port_set_latency -* and wants to ensure that all signal pathways in the graph -* are updated with respect to the values that will be returned -* by @function jack_port_get_total_latency. -* -* @return zero for successful execution of the request. non-zero -* otherwise. -*/ -int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_EXPORT; - -/** -* Request a complete recomputation of all port latencies. This -* can be called by a client that has just changed the internal -* latency of its port using @function jack_port_set_latency -* and wants to ensure that all signal pathways in the graph -* are updated with respect to the values that will be returned -* by @function jack_port_get_total_latency. It allows a client -* to change multiple port latencies without triggering a -* recompute for each change. -* -* @return zero for successful execution of the request. non-zero -* otherwise. -*/ - int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; - /** * Modify a port's short name. May be called at any time. If the * resulting full name (including the @a "client_name:" prefix) is @@ -981,6 +979,224 @@ int jack_port_name_size(void) JACK_OPTIONAL_WEAK_EXPORT; */ int jack_port_type_size(void) JACK_OPTIONAL_WEAK_EXPORT; +/** + * @return the buffersize of a port of type @arg port_type. + * + * this function may only be called in a buffer_size callback. + */ +size_t jack_port_type_get_buffer_size (jack_client_t *client, const char *port_type) JACK_WEAK_EXPORT; + +/*@}*/ + +/** + * @defgroup LatencyFunctions Managing and determining latency + * + * The purpose of JACK's latency API is to allow clients to + * easily answer two questions: + * + * - How long has it been since the data read from a port arrived + * at the edge of the JACK graph (either via a physical port + * or being synthesized from scratch)? + * + * - How long will it be before the data written to a port arrives + * at the edge of a JACK graph? + + * To help answering these two questions, all JACK ports have two + * latency values associated with them, both measured in frames: + * + * capture latency: how long since the data read from + * the buffer of a port arrived at at + * a port marked with JackPortIsTerminal. + * The data will have come from the "outside + * world" if the terminal port is also + * marked with JackPortIsPhysical, or + * will have been synthesized by the client + * that owns the terminal port. + * + * playback latency: how long until the data + * written to the buffer of port will reach a port + * marked with JackPortIsTerminal. + * + * Both latencies might potentially have more than one value + * because there may be multiple pathways to/from a given port + * and a terminal port. Latency is therefore generally + * expressed a min/max pair. + * + * In most common setups, the minimum and maximum latency + * are the same, but this design accomodates more complex + * routing, and allows applications (and thus users) to + * detect cases where routing is creating an anomalous + * situation that may either need fixing or more + * sophisticated handling by clients that care about + * latency. + * + * See also @ref jack_set_latency_callback for details on how + * clients that add latency to the signal path should interact + * with JACK to ensure that the correct latency figures are + * used. + * @{ + */ + +/** + * The port latency is zero by default. Clients that control + * physical hardware with non-zero latency should call this + * to set the latency to its correct value. Note that the value + * should include any systemic latency present "outside" the + * physical hardware controlled by the client. For example, + * for a client controlling a digital audio interface connected + * to an external digital converter, the latency setting should + * include both buffering by the audio interface *and* the converter. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by a latency callback that calls @ref + * jack_port_set_latency_range(). + */ +void jack_port_set_latency (jack_port_t *, jack_nframes_t) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * return the latency range defined by @a mode for + * @a port, in frames. + * + * See @ref LatencyFunctions for the definition of each latency value. + * + * This is normally used in the LatencyCallback. + * and therefor safe to execute from callbacks. + */ +void jack_port_get_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; + +/** + * set the minimum and maximum latencies defined by + * @a mode for @a port, in frames. + * + * See @ref LatencyFunctions for the definition of each latency value. + * + * This function should ONLY be used inside a latency + * callback. The client should determine the current + * value of the latency using @ref jack_port_get_latency_range() + * (called using the same mode as @a mode) + * and then add some number of frames to that reflects + * latency added by the client. + * + * How much latency a client adds will vary + * dramatically. For most clients, the answer is zero + * and there is no reason for them to register a latency + * callback and thus they should never call this + * function. + * + * More complex clients that take an input signal, + * transform it in some way and output the result but + * not during the same process() callback will + * generally know a single constant value to add + * to the value returned by @ref jack_port_get_latency_range(). + * + * Such clients would register a latency callback (see + * @ref jack_set_latency_callback) and must know what input + * ports feed which output ports as part of their + * internal state. Their latency callback will update + * the ports' latency values appropriately. + * + * A pseudo-code example will help. The @a mode argument to the latency + * callback will determine whether playback or capture + * latency is being set. The callback will use + * @ref jack_port_set_latency_range() as follows: + * + * \code + * jack_latency_range_t range; + * if (mode == JackPlaybackLatency) { + * foreach input_port in (all self-registered port) { + * jack_port_get_latency_range (port_feeding_input_port, JackPlaybackLatency, &range); + * range.min += min_delay_added_as_signal_flows_from port_feeding to input_port; + * range.max += max_delay_added_as_signal_flows_from port_feeding to input_port; + * jack_port_set_latency_range (input_port, JackPlaybackLatency, &range); + * } + * } else if (mode == JackCaptureLatency) { + * foreach output_port in (all self-registered port) { + * jack_port_get_latency_range (port_fed_by_output_port, JackCaptureLatency, &range); + * range.min += min_delay_added_as_signal_flows_from_output_port_to_fed_by_port; + * range.max += max_delay_added_as_signal_flows_from_output_port_to_fed_by_port; + * jack_port_set_latency_range (output_port, JackCaptureLatency, &range); + * } + * } + * \endcode + * + * In this relatively simple pseudo-code example, it is assumed that + * each input port or output is connected to only 1 output or input + * port respectively. + * + * If a port is connected to more than 1 other port, then the + * range.min and range.max values passed to @ref + * jack_port_set_latency_range() should reflect the minimum and + * maximum values across all connected ports. + * + * See the description of @ref jack_set_latency_callback for more + * information. + */ +void jack_port_set_latency_range (jack_port_t *port, jack_latency_callback_mode_t mode, jack_latency_range_t *range) JACK_WEAK_EXPORT; + +/** + * Request a complete recomputation of all port latencies. This + * can be called by a client that has just changed the internal + * latency of its port using jack_port_set_latency + * and wants to ensure that all signal pathways in the graph + * are updated with respect to the values that will be returned + * by jack_port_get_total_latency. It allows a client + * to change multiple port latencies without triggering a + * recompute for each change. + * + * @return zero for successful execution of the request. non-zero + * otherwise. + */ +int jack_recompute_total_latencies (jack_client_t*) JACK_OPTIONAL_WEAK_EXPORT; + +/** + * @return the time (in frames) between data being available or + * delivered at/to a port, and the time at which it arrived at or is + * delivered to the "other side" of the port. E.g. for a physical + * audio output port, this is the time between writing to the port and + * when the signal will leave the connector. For a physical audio + * input port, this is the time between the sound arriving at the + * connector and the corresponding frames being readable from the + * port. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_port_get_latency_range() in any existing + * use cases. + */ +jack_nframes_t jack_port_get_latency (jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * The maximum of the sum of the latencies in every + * connection path that can be drawn between the port and other + * ports with the @ref JackPortIsTerminal flag set. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_port_get_latency_range() in any existing + * use cases. + */ +jack_nframes_t jack_port_get_total_latency (jack_client_t *, + jack_port_t *port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + +/** + * Request a complete recomputation of a port's total latency. This + * can be called by a client that has just changed the internal + * latency of its port using jack_port_set_latency + * and wants to ensure that all signal pathways in the graph + * are updated with respect to the values that will be returned + * by jack_port_get_total_latency. + * + * @return zero for successful execution of the request. non-zero + * otherwise. + * + * @deprecated This method will be removed in the next major + * release of JACK. It should not be used in new code, and should + * be replaced by jack_recompute_total_latencies() in any existing + * use cases. + */ +int jack_recompute_total_latency (jack_client_t*, jack_port_t* port) JACK_OPTIONAL_WEAK_DEPRECATED_EXPORT; + /*@}*/ /** diff --git a/common/timestamps.c b/common/timestamps.c index 7a48e8a9..d8a2cda9 100644 --- a/common/timestamps.c +++ b/common/timestamps.c @@ -1,24 +1,25 @@ /* Copyright (C) 2002-2003 Paul Davis - + 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 + along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include #include +#include #include "timestamps.h" #include "JackTime.h" @@ -60,7 +61,7 @@ jack_dump_timestamps (FILE *out) unsigned long i; for (i = 0; i < timestamp_index; ++i) { - fprintf (out, "%-.32s %" PRIu64 " %" PRIu64, + fprintf (out, "%-.32s %" PRIu64 " %" PRIu64, timestamps[i].what, timestamps[i].when, timestamps[i].when - timestamps[0].when); if (i > 0) { diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 9a7ed47d..dc102a4e 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -13,7 +13,7 @@ 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 +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. namespace Jack { -int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint) +int JackMachThread::SetThreadToPriority(jack_native_thread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint) { if (inPriority == 96) { // REAL-TIME / TIME-CONSTRAINT THREAD @@ -64,18 +64,18 @@ int JackMachThread::SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boo } // returns the thread's priority as it was last set by the API -UInt32 JackMachThread::GetThreadSetPriority(pthread_t thread) +UInt32 JackMachThread::GetThreadSetPriority(jack_native_thread_t thread) { return GetThreadPriority(thread, THREAD_SET_PRIORITY); } // returns the thread's priority as it was last scheduled by the Kernel -UInt32 JackMachThread::GetThreadScheduledPriority(pthread_t thread) +UInt32 JackMachThread::GetThreadScheduledPriority(jack_native_thread_t thread) { return GetThreadPriority(thread, THREAD_SCHEDULED_PRIORITY); } -UInt32 JackMachThread::GetThreadPriority(pthread_t thread, int inWhichPriority) +UInt32 JackMachThread::GetThreadPriority(jack_native_thread_t thread, int inWhichPriority) { thread_basic_info_data_t threadInfo; policy_info_data_t thePolicyInfo; @@ -118,7 +118,7 @@ UInt32 JackMachThread::GetThreadPriority(pthread_t thread, int inWhichPriority) return 0; } -int JackMachThread::GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint) +int JackMachThread::GetParams(jack_native_thread_t thread, UInt64* period, UInt64* computation, UInt64* constraint) { thread_time_constraint_policy_data_t theTCPolicy; mach_msg_type_number_t count = THREAD_TIME_CONSTRAINT_POLICY_COUNT; @@ -144,11 +144,11 @@ int JackMachThread::Kill() { // pthread_cancel still not yet implemented in Darwin (TO CHECK ON TIGER) jack_log("JackMachThread::Kill"); - - if (fThread != (pthread_t)NULL) { // If thread has been started + + if (fThread != (jack_native_thread_t)NULL) { // If thread has been started mach_port_t machThread = pthread_mach_thread_np(fThread); int res = (thread_terminate(machThread) == KERN_SUCCESS) ? 0 : -1; - fThread = (pthread_t)NULL; + fThread = (jack_native_thread_t)NULL; return res; } else { return -1; @@ -159,7 +159,7 @@ int JackMachThread::AcquireRealTime() { jack_log("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); - return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; + return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; } int JackMachThread::AcquireSelfRealTime() @@ -181,7 +181,7 @@ int JackMachThread::AcquireSelfRealTime(int priority) return AcquireSelfRealTime(); } -int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) +int JackMachThread::AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) { SetThreadToPriority(thread, 96, true, period, computation, constraint); return 0; @@ -189,7 +189,7 @@ int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 c int JackMachThread::DropRealTime() { - return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; + return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1; } int JackMachThread::DropSelfRealTime() @@ -197,7 +197,7 @@ int JackMachThread::DropSelfRealTime() return DropRealTimeImp(pthread_self()); } -int JackMachThread::DropRealTimeImp(pthread_t thread) +int JackMachThread::DropRealTimeImp(jack_native_thread_t thread) { SetThreadToPriority(thread, 63, false, 0, 0, 0); return 0; diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index c7a44f79..c22ce20a 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -13,7 +13,7 @@ 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 +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -87,9 +87,9 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread UInt64 fComputation; UInt64 fConstraint; - static UInt32 GetThreadSetPriority(pthread_t thread); - static UInt32 GetThreadScheduledPriority(pthread_t thread); - static UInt32 GetThreadPriority(pthread_t thread, int inWhichPriority); + static UInt32 GetThreadSetPriority(jack_native_thread_t thread); + static UInt32 GetThreadScheduledPriority(jack_native_thread_t thread); + static UInt32 GetThreadPriority(jack_native_thread_t thread, int inWhichPriority); public: @@ -105,23 +105,23 @@ class SERVER_EXPORT JackMachThread : public JackPosixThread int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself - + int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself - + int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself - + void SetParams(UInt64 period, UInt64 computation, UInt64 constraint); - static int GetParams(pthread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); - static int SetThreadToPriority(pthread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); + static int GetParams(jack_native_thread_t thread, UInt64* period, UInt64* computation, UInt64* constraint); + static int SetThreadToPriority(jack_native_thread_t thread, UInt32 inPriority, Boolean inIsFixed, UInt64 period, UInt64 computation, UInt64 constraint); - static int AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint); - static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) - { - return JackMachThread::AcquireRealTimeImp(thread, period, computation, constraint); + static int AcquireRealTimeImp(jack_native_thread_t thread, UInt64 period, UInt64 computation, UInt64 constraint); + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) + { + return JackMachThread::AcquireRealTimeImp(thread, period, computation, constraint); } - static int DropRealTimeImp(pthread_t thread); + static int DropRealTimeImp(jack_native_thread_t thread); }; } // end of namespace diff --git a/posix/JackPosixThread.cpp b/posix/JackPosixThread.cpp index 4b4315db..aed3796b 100644 --- a/posix/JackPosixThread.cpp +++ b/posix/JackPosixThread.cpp @@ -13,7 +13,7 @@ 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 +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -40,19 +40,19 @@ void* JackPosixThread::ThreadHandler(void* arg) if ((err = pthread_setcanceltype(obj->fCancellation, NULL)) != 0) { jack_error("pthread_setcanceltype err = %s", strerror(err)); } - + // Signal creation thread when started with StartSync jack_log("ThreadHandler: start"); obj->fStatus = kIniting; - + // Call Init method if (!runnable->Init()) { jack_error("Thread init fails: thread quits"); return 0; } - + obj->fStatus = kRunning; - + // If Init succeed, start the thread loop bool res = true; while (obj->fStatus == kRunning && res) { @@ -76,11 +76,11 @@ int JackPosixThread::Start() return 0; } } - + int JackPosixThread::StartSync() { fStatus = kStarting; - + if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { fStatus = kIdle; return -1; @@ -90,10 +90,10 @@ int JackPosixThread::StartSync() JackSleep(1000); } return (count == 1000) ? -1 : 0; - } + } } - -int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) + +int JackPosixThread::StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) { pthread_attr_t attributes; struct sched_param rt_param; @@ -111,19 +111,19 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi } if (realtime) { - + jack_log("Create RT thread"); if ((res = pthread_attr_setinheritsched(&attributes, PTHREAD_EXPLICIT_SCHED))) { jack_error("Cannot request explicit scheduling for RT thread res = %d", res); return -1; } - + if ((res = pthread_attr_setschedpolicy(&attributes, JACK_SCHED_POLICY))) { jack_error("Cannot set RR scheduling class for RT thread res = %d", res); return -1; } - + memset(&rt_param, 0, sizeof(rt_param)); rt_param.sched_priority = priority; @@ -152,13 +152,13 @@ int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, voi int JackPosixThread::Kill() { - if (fThread != (pthread_t)NULL) { // If thread has been started + if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Kill"); void* status; pthread_cancel(fThread); pthread_join(fThread, &status); fStatus = kIdle; - fThread = (pthread_t)NULL; + fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; @@ -167,21 +167,21 @@ int JackPosixThread::Kill() int JackPosixThread::Stop() { - if (fThread != (pthread_t)NULL) { // If thread has been started + if (fThread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Stop"); void* status; fStatus = kIdle; // Request for the thread to stop pthread_join(fThread, &status); - fThread = (pthread_t)NULL; + fThread = (jack_native_thread_t)NULL; return 0; } else { return -1; } } -int JackPosixThread::KillImp(pthread_t thread) +int JackPosixThread::KillImp(jack_native_thread_t thread) { - if (thread != (pthread_t)NULL) { // If thread has been started + if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Kill"); void* status; pthread_cancel(thread); @@ -192,9 +192,9 @@ int JackPosixThread::KillImp(pthread_t thread) } } -int JackPosixThread::StopImp(pthread_t thread) +int JackPosixThread::StopImp(jack_native_thread_t thread) { - if (thread != (pthread_t)NULL) { // If thread has been started + if (thread != (jack_native_thread_t)NULL) { // If thread has been started jack_log("JackPosixThread::Stop"); void* status; pthread_join(thread, &status); @@ -206,7 +206,7 @@ int JackPosixThread::StopImp(pthread_t thread) int JackPosixThread::AcquireRealTime() { - return (fThread != (pthread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; + return (fThread != (jack_native_thread_t)NULL) ? AcquireRealTimeImp(fThread, fPriority) : -1; } int JackPosixThread::AcquireSelfRealTime() @@ -225,7 +225,7 @@ int JackPosixThread::AcquireSelfRealTime(int priority) fPriority = priority; return AcquireSelfRealTime(); } -int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority) +int JackPosixThread::AcquireRealTimeImp(jack_native_thread_t thread, int priority) { struct sched_param rtparam; int res; @@ -243,7 +243,7 @@ int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority) int JackPosixThread::DropRealTime() { - return (fThread != (pthread_t)NULL) ? DropRealTimeImp(fThread) : -1; + return (fThread != (jack_native_thread_t)NULL) ? DropRealTimeImp(fThread) : -1; } int JackPosixThread::DropSelfRealTime() @@ -251,7 +251,7 @@ int JackPosixThread::DropSelfRealTime() return DropRealTimeImp(pthread_self()); } -int JackPosixThread::DropRealTimeImp(pthread_t thread) +int JackPosixThread::DropRealTimeImp(jack_native_thread_t thread) { struct sched_param rtparam; int res; @@ -265,7 +265,7 @@ int JackPosixThread::DropRealTimeImp(pthread_t thread) return 0; } -pthread_t JackPosixThread::GetThreadID() +jack_native_thread_t JackPosixThread::GetThreadID() { return fThread; } @@ -320,42 +320,42 @@ bool jack_get_thread_realtime_priority_range(int * min_ptr, int * max_ptr) bool jack_tls_allocate_key(jack_tls_key *key_ptr) { int ret; - + ret = pthread_key_create(key_ptr, NULL); if (ret != 0) { jack_error("pthread_key_create() failed with error %d", ret); return false; } - + return true; } bool jack_tls_free_key(jack_tls_key key) { int ret; - + ret = pthread_key_delete(key); if (ret != 0) { jack_error("pthread_key_delete() failed with error %d", ret); return false; } - + return true; } bool jack_tls_set(jack_tls_key key, void *data_ptr) { int ret; - + ret = pthread_setspecific(key, (const void *)data_ptr); if (ret != 0) { jack_error("pthread_setspecific() failed with error %d", ret); return false; } - + return true; } diff --git a/posix/JackPosixThread.h b/posix/JackPosixThread.h index d38c573c..764a48df 100644 --- a/posix/JackPosixThread.h +++ b/posix/JackPosixThread.h @@ -13,7 +13,7 @@ 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 +along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ @@ -40,16 +40,16 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface protected: - pthread_t fThread; + jack_native_thread_t fThread; static void* ThreadHandler(void* arg); public: JackPosixThread(JackRunnableInterface* runnable, bool real_time, int priority, int cancellation) - : JackThreadInterface(runnable, priority, real_time, cancellation), fThread((pthread_t)NULL) + : JackThreadInterface(runnable, priority, real_time, cancellation), fThread((jack_native_thread_t)NULL) {} JackPosixThread(JackRunnableInterface* runnable, int cancellation = PTHREAD_CANCEL_ASYNCHRONOUS) - : JackThreadInterface(runnable, 0, false, cancellation), fThread((pthread_t)NULL) + : JackThreadInterface(runnable, 0, false, cancellation), fThread((jack_native_thread_t)NULL) {} int Start(); @@ -60,23 +60,23 @@ class SERVER_EXPORT JackPosixThread : public detail::JackThreadInterface int AcquireRealTime(); // Used when called from another thread int AcquireSelfRealTime(); // Used when called from thread itself - + int AcquireRealTime(int priority); // Used when called from another thread int AcquireSelfRealTime(int priority); // Used when called from thread itself - + int DropRealTime(); // Used when called from another thread int DropSelfRealTime(); // Used when called from thread itself - pthread_t GetThreadID(); + jack_native_thread_t GetThreadID(); bool IsThread(); - static int AcquireRealTimeImp(pthread_t thread, int priority); - static int AcquireRealTimeImp(pthread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority); + static int AcquireRealTimeImp(jack_native_thread_t thread, int priority, UInt64 period, UInt64 computation, UInt64 constraint) { return JackPosixThread::AcquireRealTimeImp(thread, priority); } - static int DropRealTimeImp(pthread_t thread); - static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); - static int StopImp(pthread_t thread); - static int KillImp(pthread_t thread); + static int DropRealTimeImp(jack_native_thread_t thread); + static int StartImp(jack_native_thread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); + static int StopImp(jack_native_thread_t thread); + static int KillImp(jack_native_thread_t thread); }; SERVER_EXPORT void ThreadExit(); diff --git a/posix/JackTypes_os.h b/posix/JackTypes_os.h index 01e6c9b9..896d91ea 100644 --- a/posix/JackTypes_os.h +++ b/posix/JackTypes_os.h @@ -26,6 +26,8 @@ typedef unsigned long long UInt64; typedef pthread_key_t jack_tls_key; +typedef pthread_t jack_native_thread_t; + typedef int (*jack_thread_creator_t)(pthread_t*, const pthread_attr_t*, void* (*function)(void*), void* arg); #endif