From a5b45e8e2e99686ea73fa2793d7fec84f0d1a3ed Mon Sep 17 00:00:00 2001 From: Thomas Grill Date: Tue, 17 Dec 2002 04:36:31 +0000 Subject: "" svn path=/trunk/; revision=303 --- externals/grill/flext/source/flthr.cpp | 180 ++++++++++++--------------------- 1 file changed, 62 insertions(+), 118 deletions(-) (limited to 'externals/grill/flext/source/flthr.cpp') diff --git a/externals/grill/flext/source/flthr.cpp b/externals/grill/flext/source/flthr.cpp index 97da5584..36184025 100644 --- a/externals/grill/flext/source/flthr.cpp +++ b/externals/grill/flext/source/flthr.cpp @@ -24,10 +24,10 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include //! Thread id of system thread -pthread_t flext_base::thrid; +flext::thrid_t flext::thrid; //! Thread id of helper thread -pthread_t flext_base::thrhelpid; +flext::thrid_t flext_base::thrhelpid; flext_base::thr_entry *flext_base::thrhead = NULL,*flext_base::thrtail = NULL; flext::ThrMutex flext_base::tlmutex; @@ -35,8 +35,17 @@ flext::ThrMutex flext_base::tlmutex; //! Helper thread should terminate bool thrhelpexit = false; +//! Helper thread conditional flext::ThrCond *thrhelpcond = NULL; + +flext_base::thr_entry::thr_entry(flext_base *t,void *(*m)(thr_params *),thr_params *p,pthread_t id): + th(t),meth(m),params(p),thrid(id), + active(false),shouldexit(false), + nxt(NULL) +{} + + //! Start helper thread bool flext_base::StartHelper() { @@ -75,15 +84,7 @@ void flext_base::ThrHelper(void *) // set thread priority one point below normal // so thread construction won't disturb real-time audio - sched_param parm; - int policy; - pthread_getschedparam(thrhelpid,&policy,&parm); - int prio = parm.sched_priority; - int schmin = sched_get_priority_min(policy); - if(prio > schmin) { - parm.sched_priority = prio-1; - pthread_setschedparam(thrhelpid,policy,&parm); - } + RelPriority(-1); thrhelpcond = new ThrCond; @@ -151,105 +152,19 @@ bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *me return true; } -/* -bool flext_base::StartThread(void *(*meth)(thr_params *p),thr_params *p,char *methname) +bool flext_base::ShouldExit() const { -#ifdef FLEXT_DEBUG - if(!p) { - ERRINTERNAL(); - return false; - } -#endif - - static bool init = false; - static pthread_attr_t attr; - if(!init) { - pthread_attr_init(&attr); - pthread_attr_setdetachstate(&attr,PTHREAD_CREATE_DETACHED); - init = true; - } + for(thr_entry *ti = thrhead; ti; ti = ti->nxt) + if(ti->Is()) return ti->shouldexit; - // set thread priority one point below normal - // so thread construction won't disturb real-time audio - pthread_t id = pthread_self(); - sched_param parm; - int policy; - pthread_getschedparam(id,&policy,&parm); - int prio = parm.sched_priority; - int schmin = sched_get_priority_min(policy); - if(prio > schmin) { - parm.sched_priority = prio-1; - pthread_setschedparam(id,policy,&parm); - } - - pthread_t thrid; - int ret = pthread_create (&thrid,&attr,(void *(*)(void *))meth,p); - - // set thread priority back to normal - parm.sched_priority = prio; - pthread_setschedparam(id,policy,&parm); - - if(ret) { -#ifdef FLEXT_DEBUG - error((char *)(ret == EAGAIN?"%s - Unsufficient resources to launch thread!":"%s - Could not launch method!"),methname); -#else - error((char *)("%s - Could not launch method!"),methname); -#endif - - delete p; - return false; - } - else - return true; + // thread was not found -> EXIT!!! + return true; } -*/ bool flext_base::PushThread() { - tlmutex.Lock(); - -// post("Push thread"); - -/* - // make an entry into thread list - thr_entry *nt = new thr_entry; - if(thrtail) thrtail->nxt = nt; - else thrhead = nt; - thrtail = nt; -*/ - { -#if FLEXT_OS == FLEXT_OS_WIN - // set detached thread to lower priority class - DWORD err; - HANDLE thr = GetCurrentThread(); - DWORD cl = GetThreadPriority(thr); - if(!cl && (err = GetLastError())) - post("flext - error getting thread priority"); - else { - BOOL ret = SetThreadPriority(thr,cl-2); - if(!ret) { - err = GetLastError(); - if(!err) post("flext - error setting thread priority"); - } - } -#else - // set initial detached thread priority two points below normal - sched_param parm; - int policy; - if(pthread_getschedparam(nt->thrid,&policy,&parm)) - post("flext - can't get thread parameters"); - int prio = parm.sched_priority; - int schmin = sched_get_priority_min(policy); - if(prio > schmin) { - parm.sched_priority = prio-2; - if(pthread_setschedparam(nt->thrid,policy,&parm)) - post("flext - can't set thread parameters"); - } -#endif - } - - tlmutex.Unlock(); - + // set priority of newly created thread one point below the system thread's + RelPriority(-1); return true; } @@ -284,17 +199,33 @@ void flext_base::PopThread() tlmutex.Unlock(); } +//! Terminate all object threads void flext_base::TermThreads() { + thr_entry *t; + + // signal termination + for(t = thrhead; t; t = t->nxt) + if(t->th == this) t->shouldexit = true; + + // TODO: maybe there should be a thread conditional for every thread so that it can be signaled + // wait for thread termination - shouldexit = true; - for(int wi = 0; thrhead && wi < 100; ++wi) Sleep(0.01f); + for(int wi = 0; wi < 100; ++wi) { + int cnt = 0; + for(t = thrhead; t; t = t->nxt) + if(t->th == this) ++cnt; + if(!cnt) break; + Sleep(0.01f); + } + + // --- all object threads have terminated by now ------- qmutex.Lock(); // Lock message queue tlmutex.Lock(); // timeout -> hard termination - for(thr_entry *t = thrhead; t; ) + for(t = thrhead; t; ) if(t->th == this) { if(pthread_cancel(t->thrid)) post("%s - Thread could not be terminated!",thisName()); thr_entry *tn = t->nxt; @@ -307,26 +238,39 @@ void flext_base::TermThreads() qmutex.Unlock(); } -flext_base::thrid_t flext_base::GetThreadId() -{ - return pthread_self(); -} - -bool flext_base::ChangePriority(int dp,thrid_t id) +bool flext::RelPriority(int dp,thrid_t ref,thrid_t id) { sched_param parm; int policy; - if(pthread_getschedparam(id,&policy,&parm) < 0) { + if(pthread_getschedparam(ref,&policy,&parm) < 0) { #ifdef FLEXT_DEBUG - post("flext - failed to get parms"); + post("flext - failed to get thread priority"); #endif return false; } else { parm.sched_priority += dp; + + // MSVC++ 6 produces wrong code with the following lines!!! +// int schmin = sched_get_priority_min(policy); +// int schmax = sched_get_priority_max(policy); + + if(parm.sched_priority < sched_get_priority_min(policy)) { +#ifdef FLEXT_DEBUG + post("flext - minimum thread priority reached"); +#endif + parm.sched_priority = sched_get_priority_min(policy); + } + else if(parm.sched_priority > sched_get_priority_max(policy)) { +#ifdef FLEXT_DEBUG + post("flext - maximum thread priority reached"); +#endif + parm.sched_priority = sched_get_priority_max(policy); + } + if(pthread_setschedparam(id,policy,&parm) < 0) { #ifdef FLEXT_DEBUG - post("flext - failed to change priority"); + post("flext - failed to change thread priority"); #endif return false; } @@ -335,7 +279,7 @@ bool flext_base::ChangePriority(int dp,thrid_t id) } -int flext_base::GetPriority(thrid_t id) +int flext::GetPriority(thrid_t id) { sched_param parm; int policy; @@ -349,7 +293,7 @@ int flext_base::GetPriority(thrid_t id) } -bool flext_base::SetPriority(int p,thrid_t id) +bool flext::SetPriority(int p,thrid_t id) { sched_param parm; int policy; -- cgit v1.2.1