Commit 8468547e authored by thomas's avatar thomas
Browse files

no message


git-svn-id: https://svn.grrrr.org/ext/trunk@656 4d9ac71a-51e6-0310-8455-cad1006bcd31
parent 0a0b5642
......@@ -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"
......
......@@ -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:
......
......@@ -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;
......
......@@ -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);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment