diff --git a/common/JackAPI.cpp b/common/JackAPI.cpp index 3fa79422..11c21609 100644 --- a/common/JackAPI.cpp +++ b/common/JackAPI.cpp @@ -26,6 +26,13 @@ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. #include "JackGlobals.h" #include "JackTime.h" #include "JackExports.h" +#ifdef __APPLE__ + #include "JackMachThread.h" +#elif WIN32 + #include "JackWinThread.h" +#else + #include "JackPosixThread.h" +#endif #include using namespace Jack; @@ -1073,8 +1080,13 @@ EXPORT void jack_reset_max_delayed_usecs(jack_client_t* ext_client) EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority) { - JackLog("jack_acquire_real_time_scheduling: not yet implemented\n"); - return -1; + #ifdef __APPLE__ + return JackMachThread::AcquireRealTimeImp(thread, 0, 500 * 1000, 500 * 1000); + #elif WIN32 + return JackWinThread::AcquireRealTimeImp(thread, priority); + #else + return JackPosixThread::AcquireRealTimeImp(thread, priority); + #endif } EXPORT int jack_client_create_thread(jack_client_t* client, @@ -1084,14 +1096,24 @@ EXPORT int jack_client_create_thread(jack_client_t* client, void *(*start_routine)(void*), void *arg) { - JackLog("jack_client_create_thread: not yet implemented\n"); - return -1; + #ifdef __APPLE__ + return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg); + #elif WIN32 + return JackWinThread::StartImp(thread, priority, realtime, start_routine, arg); + #else + return JackPosixThread::StartImp(thread, priority, realtime, start_routine, arg); + #endif } EXPORT int jack_drop_real_time_scheduling(pthread_t thread) { - JackLog("jack_drop_real_time_scheduling: not yet implemented\n"); - return -1; + #ifdef __APPLE__ + return JackMachThread::DropRealTimeImp(thread); + #elif WIN32 + return JackWinThread::DropRealTimeImp(thread); + #else + return JackPosixThread::DropRealTimeImp(thread); + #endif } // intclient.h diff --git a/common/JackPosixThread.cpp b/common/JackPosixThread.cpp index 44153865..479db4f5 100644 --- a/common/JackPosixThread.cpp +++ b/common/JackPosixThread.cpp @@ -56,10 +56,22 @@ void* JackPosixThread::ThreadHandler(void* arg) int JackPosixThread::Start() { - int res; - fRunning = true; + fRunning = true; + + // Check if the thread was correctly started + if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { + fRunning = false; + return -1; + } else { + return 0; + } +} - if (fRealTime) { +int JackPosixThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg) +{ + int res; + + if (realtime) { JackLog("Create RT thread\n"); @@ -98,14 +110,14 @@ int JackPosixThread::Start() } memset(&rt_param, 0, sizeof(rt_param)); - rt_param.sched_priority = fPriority; + rt_param.sched_priority = priority; if ((res = pthread_attr_setschedparam(&attributes, &rt_param))) { jack_error("Cannot set scheduling priority for RT thread %d %s", res, strerror(errno)); return -1; } - if ((res = pthread_create(&fThread, &attributes, ThreadHandler, this))) { + if ((res = pthread_create(thread, &attributes, start_routine, arg))) { jack_error("Cannot set create thread %d %s", res, strerror(errno)); return -1; } @@ -114,7 +126,7 @@ int JackPosixThread::Start() } else { JackLog("Create non RT thread\n"); - if ((res = pthread_create(&fThread, 0, ThreadHandler, this))) { + if ((res = pthread_create(thread, 0, start_routine, arg))) { jack_error("Cannot set create thread %d %s", res, strerror(errno)); return -1; } @@ -159,18 +171,25 @@ int JackPosixThread::Stop() int JackPosixThread::AcquireRealTime() { - struct sched_param rtparam; - int res; + return (fThread) ? AcquireRealTimeImp(fThread, fPriority) : -1; +} - if (!fThread) - return -1; +int JackPosixThread::AcquireRealTime(int priority) +{ + fPriority = priority; + return AcquireRealTime(); +} +int JackPosixThread::AcquireRealTimeImp(pthread_t thread, int priority) +{ + struct sched_param rtparam; + int res; memset(&rtparam, 0, sizeof(rtparam)); - rtparam.sched_priority = fPriority; + rtparam.sched_priority = priority; //if ((res = pthread_setschedparam(fThread, SCHED_FIFO, &rtparam)) != 0) { - if ((res = pthread_setschedparam(fThread, SCHED_RR, &rtparam)) != 0) { + if ((res = pthread_setschedparam(thread, SCHED_RR, &rtparam)) != 0) { jack_error("Cannot use real-time scheduling (FIFO/%d) " "(%d: %s)", rtparam.sched_priority, res, strerror(res)); @@ -179,24 +198,19 @@ int JackPosixThread::AcquireRealTime() return 0; } -int JackPosixThread::AcquireRealTime(int priority) +int JackPosixThread::DropRealTime() { - fPriority = priority; - return AcquireRealTime(); + return (fThread) ? DropRealTimeImp(fThread) : -1; } -int JackPosixThread::DropRealTime() +int JackPosixThread::DropRealTimeImp(pthread_t thread) { - struct sched_param rtparam; + struct sched_param rtparam; int res; - - if (!fThread) - return -1; - memset(&rtparam, 0, sizeof(rtparam)); rtparam.sched_priority = 0; - if ((res = pthread_setschedparam(fThread, SCHED_OTHER, &rtparam)) != 0) { + if ((res = pthread_setschedparam(thread, SCHED_OTHER, &rtparam)) != 0) { jack_error("Cannot switch to normal scheduling priority(%s)\n", strerror(errno)); return -1; } diff --git a/common/JackPosixThread.h b/common/JackPosixThread.h index 34927984..38f43107 100644 --- a/common/JackPosixThread.h +++ b/common/JackPosixThread.h @@ -37,7 +37,6 @@ class JackPosixThread : public JackThread protected: pthread_t fThread; - static void* ThreadHandler(void* arg); public: @@ -65,6 +64,11 @@ class JackPosixThread : public JackThread virtual int DropRealTime(); pthread_t GetThreadID(); + + static int AcquireRealTimeImp(pthread_t thread, int priority); + static int DropRealTimeImp(pthread_t thread); + static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); + }; } // end of namespace diff --git a/linux/alsa/JackAlsaDriver.cpp b/linux/alsa/JackAlsaDriver.cpp index 677626c6..9f71e859 100644 --- a/linux/alsa/JackAlsaDriver.cpp +++ b/linux/alsa/JackAlsaDriver.cpp @@ -2567,7 +2567,7 @@ extern "C" capture = TRUE; if (strcmp (param->value.str, "none") != 0) { capture_pcm_name = strdup (param->value.str); - printf("capture device %s\n", capture_pcm_name); + printf("capture device %s\n", capture_pcm_name); } break; @@ -2575,7 +2575,7 @@ extern "C" playback = TRUE; if (strcmp (param->value.str, "none") != 0) { playback_pcm_name = strdup (param->value.str); - printf("playback device %s\n", playback_pcm_name); + printf("playback device %s\n", playback_pcm_name); } break; @@ -2587,8 +2587,8 @@ extern "C" case 'd': playback_pcm_name = strdup (param->value.str); capture_pcm_name = strdup (param->value.str); - printf("playback device %s\n", playback_pcm_name); - printf("capture device %s\n", capture_pcm_name); + printf("playback device %s\n", playback_pcm_name); + printf("capture device %s\n", capture_pcm_name); break; case 'H': diff --git a/macosx/JackMachThread.cpp b/macosx/JackMachThread.cpp index 00733c1f..69dd78d1 100644 --- a/macosx/JackMachThread.cpp +++ b/macosx/JackMachThread.cpp @@ -152,34 +152,33 @@ int JackMachThread::Kill() } } -/* int JackMachThread::AcquireRealTime() { JackLog("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld\n", long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); - return (fThread) ? SetThreadToPriority(fThread, 96, true, fPeriod, fComputation, fConstraint) : -1; + + return (fThread) ? AcquireRealTimeImp(fThread, fPeriod, fComputation, fConstraint) : -1; } -*/ -int JackMachThread::AcquireRealTime() +int JackMachThread::AcquireRealTimeImp(pthread_t thread, UInt64 period, UInt64 computation, UInt64 constraint) { - JackLog("JackMachThread::AcquireRealTime fPeriod = %ld fComputation = %ld fConstraint = %ld\n", - long(fPeriod / 1000), long(fComputation / 1000), long(fConstraint / 1000)); - if (fThread) { - SetThreadToPriority(fThread, 96, true, fPeriod, fComputation, fConstraint); - UInt64 fPeriod; - UInt64 fComputation; - UInt64 fConstraint; - GetParams(&fPeriod, &fComputation, &fConstraint); - return 0; - } else - return -1; + SetThreadToPriority(thread, 96, true, period, computation, constraint); + UInt64 int_period; + UInt64 int_computation; + UInt64 int_constraint; + GetParams(&int_period, &int_computation, &int_constraint); + return 0; } int JackMachThread::DropRealTime() { - //return (fThread) ? SetThreadToPriority(fThread, 31, false, 0, 0, 0) : -1; - return (fThread) ? SetThreadToPriority(fThread, 63, false, 0, 0, 0) : -1; + return (fThread) ? DropRealTimeImp(fThread) : -1; +} + +int JackMachThread::DropRealTimeImp(pthread_t thread) +{ + SetThreadToPriority(thread, 63, false, 0, 0, 0); + return 0; } void JackMachThread::SetParams(UInt64 period, UInt64 computation, UInt64 constraint) diff --git a/macosx/JackMachThread.h b/macosx/JackMachThread.h index 77d76142..46f7adf3 100644 --- a/macosx/JackMachThread.h +++ b/macosx/JackMachThread.h @@ -114,6 +114,9 @@ class JackMachThread : public JackPosixThread void SetParams(UInt64 period, UInt64 computation, UInt64 constraint); static int GetParams(UInt64* period, UInt64* computation, UInt64* constraint); static int SetThreadToPriority(pthread_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 DropRealTimeImp(pthread_t thread); }; } // end of namespace diff --git a/windows/JackWinThread.cpp b/windows/JackWinThread.cpp index c1349bfb..9f82e003 100644 --- a/windows/JackWinThread.cpp +++ b/windows/JackWinThread.cpp @@ -68,98 +68,109 @@ JackWinThread::~JackWinThread() CloseHandle(fEvent); } -int JackWinThread::Start() -{ - DWORD id; - - fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (fEvent == NULL) { - jack_error("Cannot create event error = %d", GetLastError()); - return -1; - } - - fRunning = true; - - if (fRealTime) { - - JackLog("Create RT thread\n"); - fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); - - if (fThread == NULL) { - jack_error("Cannot create thread error = %d", GetLastError()); - return -1; - } - - if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) { - jack_error("Cannot set priority class = %d", GetLastError()); - return -1; - } - - return 0; - - } else { - - JackLog("Create non RT thread\n"); - fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); - - if (fThread == NULL) { - jack_error("Cannot create thread error = %d", GetLastError()); - return -1; - } - - return 0; - } -} - -int JackWinThread::StartSync() -{ - DWORD id; - - fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); - if (fEvent == NULL) { - jack_error("Cannot create event error = %d", GetLastError()); - return -1; - } - - if (fRealTime) { - - JackLog("Create RT thread\n"); - fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); - - if (fThread == NULL) { - jack_error("Cannot create thread error = %d", GetLastError()); - return -1; - } - - if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec - jack_error("Thread has not started"); - return -1; - } - - if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) { - jack_error("Cannot set priority class = %d", GetLastError()); - return -1; - } - - return 0; - - } else { - - JackLog("Create non RT thread\n"); - fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); - - if (fThread == NULL) { - jack_error("Cannot create thread error = %d", GetLastError()); - return -1; - } - - if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec - jack_error("Thread has not started"); - return -1; - } - - return 0; - } +int JackWinThread::Start() +{ + fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (fEvent == NULL) { + jack_error("Cannot create event error = %d", GetLastError()); + return -1; + } + + fRunning = true; + + // Check if the thread was correctly started + if (StartImp(&fThread, fPriority, fRealTime, ThreadHandler, this) < 0) { + fRunning = false; + return -1; + } else { + return 0; + } +} + +int JackWinThread::StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); +{ + DWORD id; + + if (realtime) { + + JackLog("Create RT thread\n"); + *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id); + + if (*thread == NULL) { + jack_error("Cannot create thread error = %d", GetLastError()); + return -1; + } + + if (!SetThreadPriority(*thread, THREAD_PRIORITY_TIME_CRITICAL)) { + jack_error("Cannot set priority class = %d", GetLastError()); + return -1; + } + + return 0; + + } else { + + JackLog("Create non RT thread\n"); + *thread = CreateThread(NULL, 0, start_routine, arg, 0, &id); + + if (fThread == NULL) { + jack_error("Cannot create thread error = %d", GetLastError()); + return -1; + } + + return 0; + } +} + +int JackWinThread::StartSync() +{ + DWORD id; + + fEvent = CreateEvent(NULL, FALSE, FALSE, NULL); + if (fEvent == NULL) { + jack_error("Cannot create event error = %d", GetLastError()); + return -1; + } + + if (fRealTime) { + + JackLog("Create RT thread\n"); + fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); + + if (fThread == NULL) { + jack_error("Cannot create thread error = %d", GetLastError()); + return -1; + } + + if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec + jack_error("Thread has not started"); + return -1; + } + + if (!SetThreadPriority(fThread, THREAD_PRIORITY_TIME_CRITICAL)) { + jack_error("Cannot set priority class = %d", GetLastError()); + return -1; + } + + return 0; + + } else { + + JackLog("Create non RT thread\n"); + fThread = CreateThread(NULL, 0, ThreadHandler, (void*)this, 0, &id); + + if (fThread == NULL) { + jack_error("Cannot create thread error = %d", GetLastError()); + return -1; + } + + if (WaitForSingleObject(fEvent, 3000) != WAIT_OBJECT_0) { // wait 3 sec + jack_error("Thread has not started"); + return -1; + } + + return 0; + } } // voir http://www.microsoft.com/belux/msdn/nl/community/columns/ldoc/multithread1.mspx @@ -167,9 +178,9 @@ int JackWinThread::StartSync() int JackWinThread::Kill() { if (fThread) { // If thread has been started - TerminateThread(fThread, 0); + TerminateThread(fThread, 0); WaitForSingleObject(fThread, INFINITE); - CloseHandle(fThread); + CloseHandle(fThread); JackLog("JackWinThread::Kill 2\n"); fThread = NULL; fRunning = false; @@ -195,6 +206,7 @@ int JackWinThread::Stop() int JackWinThread::AcquireRealTime() { + /* JackLog("JackWinThread::AcquireRealTime\n"); if (fThread) { @@ -207,14 +219,33 @@ int JackWinThread::AcquireRealTime() } else { return -1; } + */ + return (fThread) ? AcquireRealTimeImp(fThread, fPriority) : -1; } int JackWinThread::AcquireRealTime(int priority) { - JackLog("JackWinThread::AcquireRealTime priority = %ld\n", priority); - return AcquireRealTime(); + //JackLog("JackWinThread::AcquireRealTime priority = %ld\n", priority); + //return AcquireRealTime(); + + fPriority = priority; + return AcquireRealTime(); +} + +int JackWinThread::AcquireRealTimeImp(pthread_t thread, int priority) +{ + JackLog("JackWinThread::AcquireRealTime\n"); + + if (SetThreadPriority(thread, THREAD_PRIORITY_TIME_CRITICAL)) { + JackLog("JackWinThread::AcquireRealTime OK\n"); + return 0; + } else { + jack_error("Cannot set thread priority = %d", GetLastError()); + return -1; + } } +/* int JackWinThread::DropRealTime() { if (fThread) { @@ -227,6 +258,21 @@ int JackWinThread::DropRealTime() return -1; } } +*/ +int JackWinThread::DropRealTime() +{ + return DropRealTime(fThread); +} + +int JackWinThread::DropRealTime(pthread_t thread) +{ + if (SetThreadPriority(thread, THREAD_PRIORITY_NORMAL)) { + return 0; + } else { + jack_error("Cannot set thread priority = %d", GetLastError()); + return -1; + } +} pthread_t JackWinThread::GetThreadID() { diff --git a/windows/JackWinThread.h b/windows/JackWinThread.h index 4ec38621..b8ff419c 100644 --- a/windows/JackWinThread.h +++ b/windows/JackWinThread.h @@ -57,6 +57,11 @@ class JackWinThread : public JackThread int DropRealTime(); pthread_t GetThreadID(); + + static int AcquireRealTimeImp(pthread_t thread, int priority); + static int DropRealTimeImp(pthread_t thread); + static int StartImp(pthread_t* thread, int priority, int realtime, void*(*start_routine)(void*), void* arg); + }; } // end of namespace