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/flclass.h | 41 +------ externals/grill/flext/source/flext.cpp | 2 +- externals/grill/flext/source/flprefix.h | 50 ++++++--- externals/grill/flext/source/flsupport.h | 37 +++++++ externals/grill/flext/source/flthr.cpp | 180 +++++++++++-------------------- 5 files changed, 139 insertions(+), 171 deletions(-) (limited to 'externals/grill/flext/source') diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h index 6f74b5fe..66da8e7a 100644 --- a/externals/grill/flext/source/flclass.h +++ b/externals/grill/flext/source/flclass.h @@ -392,37 +392,8 @@ public: @{ */ - /*! \brief Check if current thread should terminate - \todo Check for currently running thread - */ - bool ShouldExit() const { return shouldexit; } - - //! Check if current thread is the realtime system's thread - bool IsSystemThread() const { pthread_t cur = pthread_self(); return pthread_equal(cur,thrid) != 0; } - - /*! \brief Yield to other threads - \remark A call to this is only needed for systems with cooperative multitasking like MacOS<=9 - */ - static void ThrYield() { sched_yield(); } - - typedef pthread_t thrid_t; - - /*! \brief Get current thread id - */ - static thrid_t GetThreadId(); - - /*! \brief Increase/Decrease priority of a thread - */ - static bool ChangePriority(int dp,thrid_t thr = GetThreadId()); - - /*! \brief Get priority of a thread - */ - static int GetPriority(thrid_t thr = GetThreadId()); - - /*! \brief Set priority of a thread - */ - static bool SetPriority(int p,thrid_t thr = GetThreadId()); - + //! Check if current thread should terminate + bool ShouldExit() const; #endif // FLEXT_THREADS @@ -467,12 +438,12 @@ protected: class thr_entry { public: - thr_entry(flext_base *t,void *(*m)(thr_params *),thr_params *p,pthread_t id = pthread_self()): th(t),meth(m),params(p),thrid(id),active(false),nxt(NULL) {} + thr_entry(flext_base *t,void *(*m)(thr_params *),thr_params *p,pthread_t id = pthread_self()); //! \brief Check if this class represents the current thread bool Is(pthread_t id = pthread_self()) const { return pthread_equal(thrid,id) != 0; } - bool active; + bool active,shouldexit; pthread_t thrid; void *(*meth)(thr_params *); thr_params *params; @@ -660,10 +631,6 @@ private: static bool cb_SetAttrib(flext_base *c,const t_symbol *s,int argc,const t_atom *argv) { return c->SetAttrib(s,argc,argv); } #ifdef FLEXT_THREADS - bool shouldexit; - int thrcount; - - static pthread_t thrid; // the thread that created the object (the system thread) ThrMutex qmutex; static thr_entry *thrhead,*thrtail; diff --git a/externals/grill/flext/source/flext.cpp b/externals/grill/flext/source/flext.cpp index d0fdb766..764bfa98 100644 --- a/externals/grill/flext/source/flext.cpp +++ b/externals/grill/flext/source/flext.cpp @@ -130,7 +130,7 @@ flext_base::flext_base(): LOG1("%s - flext logging is on",thisName()); #ifdef FLEXT_THREADS - shouldexit = false; +// shouldexit = false; // thrhead = thrtail = NULL; #endif qhead = qtail = NULL; diff --git a/externals/grill/flext/source/flprefix.h b/externals/grill/flext/source/flprefix.h index 34debe69..d2c7f173 100755 --- a/externals/grill/flext/source/flprefix.h +++ b/externals/grill/flext/source/flprefix.h @@ -15,41 +15,61 @@ WARRANTIES, see the file, "license.txt," in this distribution. #ifndef __FLEXT_PREFIX_H #define __FLEXT_PREFIX_H -// definitions for FLEXT_SYS +// --- definitions for FLEXT_SYS --------------------- #define FLEXT_SYS_UNKNOWN 0 -#define FLEXT_SYS_MAX 1 -#define FLEXT_SYS_PD 2 -// definitions for FLEXT_OS +#ifndef FLEXT_SYS_MAX + #define FLEXT_SYS_MAX 1 +#else + // already defined + #undef FLEXT_SYS_MAX + #define FLEXT_SYS_MAX 1 + #define FLEXT_SYS FLEXT_SYS_MAX +#endif + +#ifndef FLEXT_SYS_PD + #define FLEXT_SYS_PD 2 +#else + // already defined + #undef FLEXT_SYS_PD + #define FLEXT_SYS_PD 2 + #define FLEXT_SYS FLEXT_SYS_PD +#endif + +// --- definitions for FLEXT_OS ---------------------- #define FLEXT_OS_UNKNOWN 0 #define FLEXT_OS_WIN 1 #define FLEXT_OS_MACOS 2 #define FLEXT_OS_LINUX 3 #define FLEXT_OS_IRIX 4 -// definitions for FLEXT_CPU +// --- definitions for FLEXT_CPU --------------------- #define FLEXT_CPU_UNKNOWN 0 #define FLEXT_CPU_INTEL 1 #define FLEXT_CPU_PPC 2 #define FLEXT_CPU_MIPS 3 #define FLEXT_CPU_ALPHA 4 - - -// Old definitions -#if defined(MAXMSP) - #define FLEXT_SYS FLEXT_SYS_MAX -// #undef MAXMSP -#elif defined(PD) - #define FLEXT_SYS FLEXT_SYS_PD -// #undef PD -// #undef NT +// --------------------------------------------------- +// support old definitions + +#ifndef FLEXT_SYS + #if defined(MAXMSP) + #define FLEXT_SYS FLEXT_SYS_MAX + // #undef MAXMSP + #elif defined(PD) + #define FLEXT_SYS FLEXT_SYS_PD + // #undef PD + // #undef NT + #endif #endif #if defined(_DEBUG) #define FLEXT_DEBUG #endif +// --------------------------------------------------- + // Definition of supported real-time systems #if FLEXT_SYS == FLEXT_SYS_MAX #elif FLEXT_SYS == FLEXT_SYS_PD diff --git a/externals/grill/flext/source/flsupport.h b/externals/grill/flext/source/flsupport.h index 08036ff5..9429599d 100644 --- a/externals/grill/flext/source/flsupport.h +++ b/externals/grill/flext/source/flsupport.h @@ -391,6 +391,43 @@ public: @{ */ + //! thread type + typedef pthread_t thrid_t; + +protected: + //! system's thread id + static thrid_t thrid; // the system thread + +public: + + //! Check if current thread is the realtime system's thread + static bool IsSystemThread() { pthread_t cur = pthread_self(); return pthread_equal(cur,thrid) != 0; } + + /*! \brief Yield to other threads + \remark A call to this is only needed for systems with cooperative multitasking like MacOS<=9 + */ + static void ThrYield() { sched_yield(); } + + /*! \brief Get current thread id + */ + static thrid_t GetThreadId() { return pthread_self(); } + + /*! \brief Get current thread id + */ + static thrid_t GetSysThreadId() { return thrid; } + + /*! \brief Increase/Decrease priority of a thread + */ + static bool RelPriority(int dp,thrid_t ref = GetSysThreadId(),thrid_t thr = GetThreadId()); + + /*! \brief Get priority of a thread + */ + static int GetPriority(thrid_t thr = GetThreadId()); + + /*! \brief Set priority of a thread + */ + static bool SetPriority(int p,thrid_t thr = GetThreadId()); + /*! \brief Thread mutex \sa pthreads documentation */ 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