diff options
Diffstat (limited to 'externals/grill/flext')
-rw-r--r-- | externals/grill/flext/flext.vcproj | 2 | ||||
-rw-r--r-- | externals/grill/flext/source/flclass.h | 9 | ||||
-rw-r--r-- | externals/grill/flext/source/flout.cpp | 59 | ||||
-rwxr-xr-x | externals/grill/flext/source/flqueue.cpp | 193 |
4 files changed, 143 insertions, 120 deletions
diff --git a/externals/grill/flext/flext.vcproj b/externals/grill/flext/flext.vcproj index 33ac33d0..d5cba32f 100644 --- a/externals/grill/flext/flext.vcproj +++ b/externals/grill/flext/flext.vcproj @@ -349,7 +349,7 @@ Name="VCCLCompilerTool" Optimization="0" AdditionalIncludeDirectories="f:\prog\pd\pd-cvs\src,f:\prog\packs\pthreads,f:\prog\audio\sndobj\include,f:\prog\audio\stk\include" - PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLEXT_SYS_PD;FLEXT_THREADS;FLEXT_USE_SIMD;FLEXT_SHARED;FLEXT_EXPORTS" + PreprocessorDefinitions="WIN32;_DEBUG;_LIB;FLEXT_SYS_PD;FLEXT_THREADS;FLEXT_USE_SIMD;FLEXT_SHARED;FLEXT_EXPORTS;FLEXT_PDLOCK" BasicRuntimeChecks="3" RuntimeLibrary="3" RuntimeTypeInfo="TRUE" diff --git a/externals/grill/flext/source/flclass.h b/externals/grill/flext/source/flclass.h index 8b0e0dc7..3667e961 100644 --- a/externals/grill/flext/source/flclass.h +++ b/externals/grill/flext/source/flclass.h @@ -644,6 +644,15 @@ protected: methfun fun; }; + // these outlet functions don't check for thread but send directly to the real-time system + void ToSysBang(int n) const; + void ToSysFloat(int n,float f) const; + void ToSysInt(int n,int f) const; + void ToSysBool(int n,bool f) const { ToSysInt(n,f?1:0); } + void ToSysSymbol(int n,const t_symbol *s) const; + void ToSysList(int n,int argc,const t_atom *argv) const; + void ToSysAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const; + private: class pxbnd_object; public: diff --git a/externals/grill/flext/source/flout.cpp b/externals/grill/flext/source/flout.cpp index c32f710f..a2f69978 100644 --- a/externals/grill/flext/source/flout.cpp +++ b/externals/grill/flext/source/flout.cpp @@ -17,43 +17,44 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include <string.h> #if FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX - -#ifndef FLEXT_THREADS -void flext_base::ToOutBang(int n) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_bang((t_outlet *)o); CRITOFF(); } } -void flext_base::ToOutFloat(int n,float f) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_float((t_outlet *)o,f); CRITOFF(); } } -void flext_base::ToOutInt(int n,int f) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_flint((t_outlet *)o,f); CRITOFF(); } } -void flext_base::ToOutSymbol(int n,const t_symbol *s) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_symbol((t_outlet *)o,const_cast<t_symbol *>(s)); CRITOFF(); } } -void flext_base::ToOutList(int n,int argc,const t_atom *argv) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_list((t_outlet *)o,const_cast<t_symbol *>(sym_list),argc,(t_atom *)argv); CRITOFF(); } } -void flext_base::ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_anything((t_outlet *)o,const_cast<t_symbol *>(s),argc,(t_atom *)argv); CRITOFF(); } } -#else -void flext_base::ToOutBang(int n) const { if(IsSystemThread()) { outlet *o = GetOut(n); if(o) { CRITON(); outlet_bang((t_outlet *)o); CRITOFF(); } } else ToQueueBang(n); } -void flext_base::ToOutFloat(int n,float f) const { if(IsSystemThread()) { outlet *o = GetOut(n); if(o) { CRITON(); outlet_float((t_outlet *)o,f); CRITOFF(); } } else ToQueueFloat(n,f); } -void flext_base::ToOutInt(int n,int f) const { if(IsSystemThread()) { outlet *o = GetOut(n); if(o) { CRITON(); outlet_flint((t_outlet *)o,f); CRITOFF(); } } else ToQueueInt(n,f); } -void flext_base::ToOutSymbol(int n,const t_symbol *s) const { if(IsSystemThread()) { outlet *o = GetOut(n); if(o) { CRITON(); outlet_symbol((t_outlet *)o,const_cast<t_symbol *>(s)); CRITOFF(); } } else ToQueueSymbol(n,s); } -void flext_base::ToOutList(int n,int argc,const t_atom *argv) const { if(IsSystemThread()) { outlet *o = GetOut(n); if(o) { CRITON(); outlet_list((t_outlet *)o,const_cast<t_symbol *>(sym_list),argc,(t_atom *)argv); CRITOFF(); } } else ToQueueList(n,argc,(t_atom *)argv); } -void flext_base::ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { if(IsSystemThread()) { outlet *o = GetOut(n); if(o) { CRITON(); outlet_anything((t_outlet *)o,const_cast<t_symbol *>(s),argc,(t_atom *)argv); CRITOFF(); } } else ToQueueAnything(n,s,argc,(t_atom *)argv); } -#endif + +void flext_base::ToSysBang(int n) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_bang((t_outlet *)o); CRITOFF(); } } +void flext_base::ToSysFloat(int n,float f) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_float((t_outlet *)o,f); CRITOFF(); } } +void flext_base::ToSysInt(int n,int f) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_flint((t_outlet *)o,f); CRITOFF(); } } +void flext_base::ToSysSymbol(int n,const t_symbol *s) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_symbol((t_outlet *)o,const_cast<t_symbol *>(s)); CRITOFF(); } } +void flext_base::ToSysList(int n,int argc,const t_atom *argv) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_list((t_outlet *)o,const_cast<t_symbol *>(sym_list),argc,(t_atom *)argv); CRITOFF(); } } +void flext_base::ToSysAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_anything((t_outlet *)o,const_cast<t_symbol *>(s),argc,(t_atom *)argv); CRITOFF(); } } #elif FLEXT_SYS == FLEXT_SYS_JMAX -#ifndef FLEXT_THREADS -void flext_base::ToOutBang(int n) const { fts_outlet_bang((fts_object *)thisHdr(),n); } -void flext_base::ToOutFloat(int n,float f) const { fts_outlet_float((fts_object *)thisHdr(),n,f); } -void flext_base::ToOutInt(int n,int f) const { fts_outlet_int((fts_object *)thisHdr(),n,f); } -void flext_base::ToOutSymbol(int n,const t_symbol *s) const { fts_outlet_symbol((fts_object *)thisHdr(),n,s); } -void flext_base::ToOutList(int n,int argc,const t_atom *argv) const { fts_outlet_send((fts_object *)thisHdr(),n,sym_list,argc,(t_atom *)argv); } -void flext_base::ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { fts_outlet_send((fts_object *)thisHdr(),n,const_cast<t_symbol *>(s),argc,(t_atom *)argv); } +void flext_base::ToSysBang(int n) const { fts_outlet_bang((fts_object *)thisHdr(),n); } +void flext_base::ToSysFloat(int n,float f) const { fts_outlet_float((fts_object *)thisHdr(),n,f); } +void flext_base::ToSysInt(int n,int f) const { fts_outlet_int((fts_object *)thisHdr(),n,f); } +void flext_base::ToSysSymbol(int n,const t_symbol *s) const { fts_outlet_symbol((fts_object *)thisHdr(),n,s); } +void flext_base::ToSysList(int n,int argc,const t_atom *argv) const { fts_outlet_send((fts_object *)thisHdr(),n,sym_list,argc,(t_atom *)argv); } +void flext_base::ToSysAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { fts_outlet_send((fts_object *)thisHdr(),n,const_cast<t_symbol *>(s),argc,(t_atom *)argv); } + #else -void flext_base::ToOutBang(int n) const { if(IsSystemThread()) fts_outlet_bang((fts_object *)thisHdr(),n); else ToQueueBang(n); } -void flext_base::ToOutFloat(int n,float f) const { if(IsSystemThread()) fts_outlet_float((fts_object *)thisHdr(),n,f); else ToQueueFloat(n,f); } -void flext_base::ToOutInt(int n,int f) const { if(IsSystemThread()) fts_outlet_int((fts_object *)thisHdr(),n,f); else ToQueueInt(n,f); } -void flext_base::ToOutSymbol(int n,const t_symbol *s) const { if(IsSystemThread()) fts_outlet_symbol((fts_object *)thisHdr(),n,s); else ToQueueSymbol(n,s); } -void flext_base::ToOutList(int n,int argc,const t_atom *argv) const { if(IsSystemThread()) fts_outlet_send((fts_object *)thisHdr(),n,sym_list,argc,(t_atom *)argv); else ToQueueList(n,argc,(t_atom *)argv); } -void flext_base::ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { if(IsSystemThread()) fts_outlet_send((fts_object *)thisHdr(),n,const_cast<t_symbol *>(s),argc,(t_atom *)argv); else ToQueueAnything(n,s,argc,(t_atom *)argv); } +#error Not implemented #endif +#ifndef FLEXT_THREADS +void flext_base::ToOutBang(int n) const { ToSysBang(n); } +void flext_base::ToOutFloat(int n,float f) const { ToSysFloat(n,f); } +void flext_base::ToOutInt(int n,int f) const { ToSysInt(n,f); } +void flext_base::ToOutSymbol(int n,const t_symbol *s) const { ToSysSymbol(n,s); } +void flext_base::ToOutList(int n,int argc,const t_atom *argv) const { ToSysList(n,argc,argv); } +void flext_base::ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { ToSysAnything(n,s,argc,argv); } +#else +void flext_base::ToOutBang(int n) const { if(IsSystemThread()) ToSysBang(n); else ToQueueBang(n); } +void flext_base::ToOutFloat(int n,float f) const { if(IsSystemThread()) ToSysFloat(n,f); else ToQueueFloat(n,f); } +void flext_base::ToOutInt(int n,int f) const { if(IsSystemThread()) ToSysInt(n,f); else ToQueueInt(n,f); } +void flext_base::ToOutSymbol(int n,const t_symbol *s) const { if(IsSystemThread()) ToSysSymbol(n,s); else ToQueueSymbol(n,s); } +void flext_base::ToOutList(int n,int argc,const t_atom *argv) const { if(IsSystemThread()) ToSysList(n,argc,argv); else ToQueueList(n,argc,argv); } +void flext_base::ToOutAnything(int n,const t_symbol *s,int argc,const t_atom *argv) const { if(IsSystemThread()) ToSysAnything(n,s,argc,argv); else ToQueueAnything(n,s,argc,argv); } #endif + bool flext_base::InitInlets() { bool ok = true; diff --git a/externals/grill/flext/source/flqueue.cpp b/externals/grill/flext/source/flqueue.cpp index ea432e5b..34bf9b9f 100755 --- a/externals/grill/flext/source/flqueue.cpp +++ b/externals/grill/flext/source/flqueue.cpp @@ -61,6 +61,7 @@ void qmsg::Clear() tp = tp_none; } +static int qcnt = 0; static qmsg *qhead = NULL,*qtail = NULL; #ifdef FLEXT_QTHR @@ -73,86 +74,99 @@ static t_qelem *qclk = NULL; static flext::ThrMutex qmutex; #endif +#define CHUNK 10 + static void QWork(bool qlock,bool syslock) { -#ifdef FLEXT_THREADS - if(qlock) qmutex.Lock(); -#endif -#ifdef FLEXT_QTHR - if(syslock) pd_lock(); -#endif - for(;;) { - qmsg *m = qhead; - if(!m) break; - - if(m->out < 0) { - // message to self - - const int n = -1-m->out; - t_atom tmp; - - switch(m->tp) { - case qmsg::tp_bang: - m->th->m_methodmain(n,flext::sym_bang,0,&tmp); - break; - case qmsg::tp_float: - flext::SetFloat(tmp,m->_float); - m->th->m_methodmain(n,flext::sym_float,1,&tmp); - break; - case qmsg::tp_int: - flext::SetInt(tmp,m->_int); -#if FLEXT_SYS == FLEXT_SYS_PD - m->th->m_methodmain(n,flext::sym_float,1,&tmp); -#elif FLEXT_SYS == FLEXT_SYS_MAX - m->th->m_methodmain(n,flext::sym_int,1,&tmp); -#else -#error Not implemented! -#endif - case qmsg::tp_sym: - flext::SetSymbol(tmp,m->_sym); - m->th->m_methodmain(n,flext::sym_symbol,1,&tmp); - break; - case qmsg::tp_list: - m->th->m_methodmain(n,flext::sym_list,m->_list.argc,m->_list.argv); - break; - case qmsg::tp_any: - m->th->m_methodmain(n,m->_any.s,m->_any.argc,m->_any.argv); - break; - #ifdef FLEXT_DEBUG - default: ERRINTERNAL(); - #endif - } - } - else { - // message to outlet - - switch(m->tp) { - case qmsg::tp_bang: m->th->ToOutBang(m->out); break; - case qmsg::tp_float: m->th->ToOutFloat(m->out,m->_float); break; - case qmsg::tp_int: m->th->ToOutInt(m->out,m->_int); break; - case qmsg::tp_sym: m->th->ToOutSymbol(m->out,m->_sym); break; - case qmsg::tp_list: m->th->ToOutList(m->out,m->_list.argc,m->_list.argv); break; - case qmsg::tp_any: m->th->ToOutAnything(m->out,m->_any.s,m->_any.argc,m->_any.argv); break; - #ifdef FLEXT_DEBUG - default: ERRINTERNAL(); - #endif - } - } - - qhead = m->nxt; - if(!qhead) qtail = NULL; - m->nxt = NULL; - delete m; - } -#ifdef FLEXT_QTHR - if(syslock) pd_unlock(); -#endif -#ifdef FLEXT_THREADS - if(qlock) qmutex.Unlock(); -#endif + // since qcnt can only be increased from any other function than QWork + // qc will be a minimum guaranteed number of present queue elements + int qc = qcnt; + if(!qc) break; + + #ifdef FLEXT_QTHR + if(syslock) pd_lock(); + #endif + + for(int i = 0; i < qc && qhead; ++i) { + #ifdef FLEXT_THREADS + if(qlock) qmutex.Lock(); + #endif + qmsg *m = qhead; + qcnt--; + qhead = m->nxt; + if(!qhead) qtail = NULL; + m->nxt = NULL; + #ifdef FLEXT_THREADS + if(qlock) qmutex.Unlock(); + #endif + + if(m->out < 0) { + // message to self + + const int n = -1-m->out; + t_atom tmp; + + switch(m->tp) { + case qmsg::tp_bang: + m->th->m_methodmain(n,flext::sym_bang,0,&tmp); + break; + case qmsg::tp_float: + flext::SetFloat(tmp,m->_float); + m->th->m_methodmain(n,flext::sym_float,1,&tmp); + break; + case qmsg::tp_int: + flext::SetInt(tmp,m->_int); + #if FLEXT_SYS == FLEXT_SYS_PD + m->th->m_methodmain(n,flext::sym_float,1,&tmp); + #elif FLEXT_SYS == FLEXT_SYS_MAX + m->th->m_methodmain(n,flext::sym_int,1,&tmp); + #else + #error Not implemented! + #endif + case qmsg::tp_sym: + flext::SetSymbol(tmp,m->_sym); + m->th->m_methodmain(n,flext::sym_symbol,1,&tmp); + break; + case qmsg::tp_list: + m->th->m_methodmain(n,flext::sym_list,m->_list.argc,m->_list.argv); + break; + case qmsg::tp_any: + m->th->m_methodmain(n,m->_any.s,m->_any.argc,m->_any.argv); + break; + #ifdef FLEXT_DEBUG + default: ERRINTERNAL(); + #endif + } + } + else { + // message to outlet + + switch(m->tp) { + case qmsg::tp_bang: m->th->ToSysBang(m->out); break; + case qmsg::tp_float: m->th->ToSysFloat(m->out,m->_float); break; + case qmsg::tp_int: m->th->ToSysInt(m->out,m->_int); break; + case qmsg::tp_sym: m->th->ToSysSymbol(m->out,m->_sym); break; + case qmsg::tp_list: m->th->ToSysList(m->out,m->_list.argc,m->_list.argv); break; + case qmsg::tp_any: m->th->ToSysAnything(m->out,m->_any.s,m->_any.argc,m->_any.argv); break; + #ifdef FLEXT_DEBUG + default: ERRINTERNAL(); + #endif + } + } + + // delete processed queue element + delete m; + } // inner loop + + #ifdef FLEXT_QTHR + if(syslock) pd_unlock(); + #endif + + } // for(;;) } +#if !defined(FLEXT_QTHR) #if FLEXT_SYS == FLEXT_SYS_JMAX static void QTick(fts_object_t *c,int winlet, fts_symbol_t s, int ac, const fts_atom_t *at) { @@ -161,21 +175,12 @@ static void QTick(flext_base *c) { #endif // post("qtick"); -#if defined(FLEXT_THREADS) && defined(FLEXT_DEBUG) && !defined(FLEXT_QTHR) - if(!flext::IsSystemThread()) { - error("flext - Queue tick called by wrong thread!"); - return; - } -#endif - QWork(true,true); - -/* -#if !defined(FLEXT_QTHR) && (FLEXT_SYS == FLEXT_SYS_PD || FLEXT_SYS == FLEXT_SYS_MAX) - // Reclocking for safety - clock_delay(qclk,10); +#ifdef FLEXT_THREADS + FLEXT_ASSERT(flext::IsSystemThread()); #endif -*/ + QWork(true,false); } +#endif /* It would be sufficient to only flush messages belonging to object th @@ -189,7 +194,13 @@ void flext_base::QFlush(flext_base *th) return; } #endif - while(qhead) QWork(true,false); +#ifdef FLEXT_THREADS + qmutex.Lock(); +#endif + while(qcnt) QWork(false,false); +#ifdef FLEXT_THREADS + qmutex.Unlock(); +#endif } static void Queue(qmsg *m) @@ -202,6 +213,7 @@ static void Queue(qmsg *m) if(qtail) qtail->nxt = m; else qhead = m; qtail = m; + qcnt++; #ifdef FLEXT_THREADS qmutex.Unlock(); #endif @@ -228,7 +240,7 @@ static void Queue(qmsg *m) void QWorker(flext::thr_params *) { for(;;) { - qthrcond.TimedWait(0.01); + qthrcond.Wait(); QWork(true,true); } } @@ -238,6 +250,7 @@ void flext_base::StartQueue() { // message queue ticker qhead = qtail = NULL; + qcnt = 0; #ifdef FLEXT_QTHR LaunchThread(QWorker,NULL); |