From b1c3f0d7ccce8feafa9f043aa5a4ee32bc78624e Mon Sep 17 00:00:00 2001 From: "Tim E. Real" Date: Sun, 13 Feb 2011 22:19:33 +0000 Subject: Fixed MusE failing with non-RT kernel. Fixed dummy audio thread not running FIFO with RT kernel. --- muse2/ChangeLog | 2 ++ muse2/muse/app.cpp | 5 +++++ muse2/muse/driver/dummyaudio.cpp | 40 ++++++++++++++++++++++++++++------------ muse2/muse/main.cpp | 8 ++++++++ muse2/muse/thread.cpp | 27 ++++++++++++++++++++------- 5 files changed, 63 insertions(+), 19 deletions(-) (limited to 'muse2') diff --git a/muse2/ChangeLog b/muse2/ChangeLog index 3bde8768..4709de2d 100644 --- a/muse2/ChangeLog +++ b/muse2/ChangeLog @@ -4,6 +4,8 @@ - removed window geometry from default template, TODO add a menu option for creating templates, which might not contain certain types of data, including geometry (rj) - fixed bug if jack zombifies during project load which led to a crash (rj) + - Fixed MusE failing with non-RT kernel. Now falls back to normal 'OTHER' scheduling. (Tim p4.0.16) + - Fixed dummy audio thread not running FIFO with RT kernel - set PTHREAD_EXPLICIT_SCHED. (Tim p4.0.16) 10.02.2011: - added cut/copy/paste and keyboard shortcuts to wave editor (rj) 09.02.2011: diff --git a/muse2/muse/app.cpp b/muse2/muse/app.cpp index 55f840b6..c1e86a2c 100644 --- a/muse2/muse/app.cpp +++ b/muse2/muse/app.cpp @@ -1246,6 +1246,11 @@ MusE::MusE(int argc, char** argv) : QMainWindow() panicToolbar->setObjectName("Panic"); panicToolbar->addAction(panicAction); + + //rlimit lim; + //getrlimit(RLIMIT_RTPRIO, &lim); + //printf("RLIMIT_RTPRIO soft:%d hard:%d\n", lim.rlim_cur, lim.rlim_max); // Reported 80, 80 even with non-RT kernel. + if (realTimePriority < sched_get_priority_min(SCHED_FIFO)) realTimePriority = sched_get_priority_min(SCHED_FIFO); else if (realTimePriority > sched_get_priority_max(SCHED_FIFO)) diff --git a/muse2/muse/driver/dummyaudio.cpp b/muse2/muse/driver/dummyaudio.cpp index f4a00b4e..d251c79f 100644 --- a/muse2/muse/driver/dummyaudio.cpp +++ b/muse2/muse/driver/dummyaudio.cpp @@ -411,38 +411,54 @@ static void* dummyLoop(void* ptr) //void DummyAudioDevice::start() void DummyAudioDevice::start(int priority) - { - //realTimePriority = priority; +{ _realTimePriority = priority; pthread_attr_t* attributes = 0; - //if (priority) { - if (realTimeScheduling && priority > 0) { + if (realTimeScheduling && _realTimePriority > 0) { attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t)); pthread_attr_init(attributes); if (pthread_attr_setschedpolicy(attributes, SCHED_FIFO)) { - printf("cannot set FIFO scheduling class for RT thread\n"); + printf("cannot set FIFO scheduling class for dummy RT thread\n"); } if (pthread_attr_setscope (attributes, PTHREAD_SCOPE_SYSTEM)) { - printf("Cannot set scheduling scope for RT thread\n"); + printf("Cannot set scheduling scope for dummy RT thread\n"); + } + // p4.0.16 Dummy was not running FIFO because this is needed. + if (pthread_attr_setinheritsched(attributes, PTHREAD_EXPLICIT_SCHED)) { + printf("Cannot set setinheritsched for dummy RT thread\n"); } + struct sched_param rt_param; memset(&rt_param, 0, sizeof(rt_param)); rt_param.sched_priority = priority; if (pthread_attr_setschedparam (attributes, &rt_param)) { - printf("Cannot set scheduling priority %d for RT thread (%s)\n", + printf("Cannot set scheduling priority %d for dummy RT thread (%s)\n", priority, strerror(errno)); } } - //pthread_attr_t* attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t)); - //pthread_attr_init(attributes); - if (pthread_create(&dummyThread, attributes, ::dummyLoop, this)) - perror("creating thread failed:"); - if (priority) + int rv = pthread_create(&dummyThread, attributes, ::dummyLoop, this); + if(!dummyThread) + { + // p4.0.16: realTimeScheduling is unreliable. It is true even in some clearly non-RT cases. + // I cannot seem to find a reliable answer to the question of "are we RT or not". + // MusE was failing with a stock kernel because of PTHREAD_EXPLICIT_SCHED. + // So we'll just have to try again without attributes. + if (realTimeScheduling && _realTimePriority > 0) + rv = pthread_create(&dummyThread, NULL, ::dummyLoop, this); + } + + if(rv || !dummyThread) + fprintf(stderr, "creating dummy audio thread failed: %s\n", strerror(rv)); + + if (attributes) // p4.0.16 + { pthread_attr_destroy(attributes); + free(attributes); } +} void DummyAudioDevice::stop () { diff --git a/muse2/muse/main.cpp b/muse2/muse/main.cpp index fccf801d..cf271ace 100644 --- a/muse2/muse/main.cpp +++ b/muse2/muse/main.cpp @@ -381,7 +381,15 @@ int main(int argc, char* argv[]) else realTimeScheduling = audioDevice->isRealtime(); + + // What unreliable nonsense. With Jack2 this reports true even if it is not running realtime. + // Jack says: "Cannot use real-time scheduling (RR/10)(1: Operation not permitted)". The kernel is non-RT. + // I cannot seem to find a reliable answer to the question, even with dummy audio and system calls. + //if (debugMsg) + // printf("realTimeScheduling:%d\n", realTimeScheduling); + useJackTransport.setValue(true); + // setup the prefetch fifo length now that the segmentSize is known // Changed by Tim. p3.3.17 // Changed to 4 *, JUST FOR TEST!!! diff --git a/muse2/muse/thread.cpp b/muse2/muse/thread.cpp index 444d5219..8e89a862 100644 --- a/muse2/muse/thread.cpp +++ b/muse2/muse/thread.cpp @@ -63,7 +63,8 @@ void Thread::start(int prio, void* ptr) // pthread_mutex_lock(&lock); - if (_realTimePriority) { + //if (_realTimePriority) { + if (realTimeScheduling && _realTimePriority > 0) { // p4.0.16 attributes = (pthread_attr_t*) malloc(sizeof(pthread_attr_t)); pthread_attr_init(attributes); @@ -98,14 +99,26 @@ void Thread::start(int prio, void* ptr) */ - int rv; - if ((rv = pthread_create(&thread, attributes, ::loop, this))) + int rv = pthread_create(&thread, attributes, ::loop, this); + if(!thread) { - fprintf(stderr, "creating thread <%s> failed: %s\n", - _name, strerror(rv)); - thread = 0; + // p4.0.16: realTimeScheduling is unreliable. It is true even in some clearly non-RT cases. + // I cannot seem to find a reliable answer to the question of "are we RT or not". + // MusE was failing with a stock kernel because of PTHREAD_EXPLICIT_SCHED. + // So we'll just have to try again without attributes. + if (realTimeScheduling && _realTimePriority > 0) + rv = pthread_create(&thread, NULL, ::loop, this); } + if(rv || !thread) + fprintf(stderr, "creating thread <%s> failed: %s\n", _name, strerror(rv)); + + if (attributes) // p4.0.16 + { + pthread_attr_destroy(attributes); + free(attributes); + } + //undoSetuid(); } @@ -316,7 +329,7 @@ void Thread::loop() if (debugMsg) printf("Thread <%s, id %p> has %s priority %d\n", _name, (void *)pthread_self(), policy == SCHED_FIFO ? "SCHED_FIFO" : "SCHED_OTHER", - _realTimePriority); + policy == SCHED_FIFO ? _realTimePriority : 0); // pthread_mutex_lock(&lock); -- cgit v1.2.3