Commit 0d720114 authored by Thomas Grill's avatar Thomas Grill
Browse files

Fixed deadlocks in threaded inline builds because of wrong function lookup (Lock()/Unlock())

parent cb714e88
......@@ -1897,6 +1897,7 @@
FLEXT_USE_SIMD,
);
GCC_VERSION = "";
MACOSX_DEPLOYMENT_TARGET = 10.6;
PRODUCT_NAME = "$(PROJECT_NAME)";
WARNING_CFLAGS = (
"-Wmost",
......@@ -1918,6 +1919,7 @@
FLEXT_USE_SIMD,
);
GCC_VERSION = "";
MACOSX_DEPLOYMENT_TARGET = 10.6;
PRODUCT_NAME = "$(PROJECT_NAME)";
WARNING_CFLAGS = (
"-Wmost",
......
......@@ -60,8 +60,6 @@ class Queue:
public FLEXT_TEMPINST(QueueFifo)
{
public:
Queue(void *dummy=NULL) {} // strange... constructor is needed to auto-instantiate static data of this kind
inline bool Empty() const { return !Avail(); }
void Push(MsgBundle *m); // defined after MsgBundle (gcc 3.3. won't take it otherwise...)
......@@ -70,19 +68,19 @@ public:
FLEXT_TEMPLATE
struct QVars {
#if FLEXT_QMODE == 2
static flext::ThrCond qthrcond;
static flext::ThrCond *qthrcond;
#elif FLEXT_QMODE == 0
static t_clock *qclk;
#endif
static FLEXT_TEMPINST(Queue) queue;
static FLEXT_TEMPINST(Queue) *queue;
};
#if FLEXT_QMODE == 2
FLEXT_TEMPIMPL(flext::ThrCond QVars)::qthrcond;
FLEXT_TEMPIMPL(flext::ThrCond *QVars)::qthrcond = NULL;
#elif FLEXT_QMODE == 0
FLEXT_TEMPIMPL(t_clock *QVars)::qclk = NULL;
#endif
FLEXT_TEMPIMPL(FLEXT_TEMPINST(Queue) QVars)::queue(NULL);
FLEXT_TEMPIMPL(FLEXT_TEMPINST(Queue) *QVars)::queue = NULL;
......@@ -95,7 +93,7 @@ FLEXT_TEMPIMPL(class FLEXT_CLASSDEF(flext))::MsgBundle:
public:
static MsgBundle *New()
{
MsgBundle *m = FLEXT_TEMPINST(QVars)::queue.New();
MsgBundle *m = FLEXT_TEMPINST(QVars)::queue->New();
m->msg.Init();
return m;
}
......@@ -109,7 +107,7 @@ public:
mi = mn;
}
m->msg.Free();
FLEXT_TEMPINST(QVars)::queue.Free(m);
FLEXT_TEMPINST(QVars)::queue->Free(m);
}
bool BelongsTo(flext_base *t) const
......@@ -400,13 +398,13 @@ FLEXT_TEMPLATE bool QWork(bool syslock,flext_base *flushobj = NULL)
// qc will be a minimum guaranteed number of present queue elements.
// On the other hand, if new queue elements are added by the methods called
// in the loop, these will be sent in the next tick to avoid recursion overflow.
if(!FLEXT_TEMPINST(QVars)::queue.Avail()) break;
if(!FLEXT_TEMPINST(QVars)::queue->Avail()) break;
#if FLEXT_QMODE == 2
if(syslock) flext::Lock();
#endif
while((q = FLEXT_TEMPINST(QVars)::queue.Get()) != NULL) {
while((q = FLEXT_TEMPINST(QVars)::queue->Get()) != NULL) {
if(q->Send())
newmsgs.Push(q); // remember messages to be processed again
else
......@@ -422,11 +420,11 @@ FLEXT_TEMPLATE bool QWork(bool syslock,flext_base *flushobj = NULL)
// enqueue messages that have to be processed again
while((q = newmsgs.Get()) != NULL)
if(!flushobj || !q->BelongsTo(flushobj))
FLEXT_TEMPINST(QVars)::queue.Push(q);
FLEXT_TEMPINST(QVars)::queue->Push(q);
else
flext::MsgBundle::Free(q);
return FLEXT_TEMPINST(QVars)::queue.Avail();
return FLEXT_TEMPINST(QVars)::queue->Avail();
}
#endif
......@@ -474,16 +472,15 @@ But then the order of sent messages is not as intended
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::QFlush(flext_base *th)
{
FLEXT_ASSERT(!IsThreadRegistered());
while(!FLEXT_TEMPINST(QVars)::queue.Empty()) FLEXT_TEMPINST(QWork)(false,th);
while(!FLEXT_TEMPINST(QVars)::queue->Empty()) FLEXT_TEMPINST(QWork)(false,th);
}
template<typename>
void Trigger()
FLEXT_TEMPLATE void Trigger()
{
#if FLEXT_SYS == FLEXT_SYS_PD
# if FLEXT_QMODE == 2
// wake up worker thread
FLEXT_TEMPINST(QVars)::qthrcond.Signal();
FLEXT_TEMPINST(QVars)::qthrcond->Signal();
# elif FLEXT_QMODE == 1 && !defined(PERMANENTIDLE)
if(!qtickactive) {
sys_callback(FLEXT_TEMPINST(QTick),NULL,0);
......@@ -516,7 +513,7 @@ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::QWorker(thr_params *)
qustarted = true;
for(;;) {
// we need a timed wait so that idle processing can take place
FLEXT_TEMPINST(QVars)::qthrcond.TimedWait(0.001);
FLEXT_TEMPINST(QVars)::qthrcond->TimedWait(0.001);
FLEXT_TEMPINST(QWork)(true);
}
}
......@@ -524,6 +521,11 @@ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::QWorker(thr_params *)
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::StartQueue()
{
#if FLEXT_QMODE == 2
FLEXT_TEMPINST(QVars)::qthrcond = new FLEXT_CLASSDEF(flext)::ThrCond;
#endif
FLEXT_TEMPINST(QVars)::queue = new FLEXT_TEMPINST(Queue);
if(qustarted) return;
#if FLEXT_QMODE == 1
# ifdef PERMANENTIDLE
......@@ -556,12 +558,12 @@ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::MsgFree(MsgBundle *m)
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ToSysMsg(MsgBundle *m)
{
m->Send();
FLEXT_TEMPINST(QVars)::queue.Free(m);
FLEXT_TEMPINST(QVars)::queue->Free(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext))::ToQueueMsg(MsgBundle *m)
{
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
......@@ -570,49 +572,49 @@ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueBang(int o) const
{
MsgBundle *m = MsgBundle::New();
m->Add(const_cast<flext_base *>(this),o);
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueFloat(int o,float f) const
{
MsgBundle *m = MsgBundle::New();
m->Add(const_cast<flext_base *>(this),o,f);
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueInt(int o,int f) const
{
MsgBundle *m = MsgBundle::New();
m->Add(const_cast<flext_base *>(this),o,f);
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueSymbol(int o,const t_symbol *s) const
{
MsgBundle *m = MsgBundle::New();
m->Add(const_cast<flext_base *>(this),o,s);
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueAtom(int o,const t_atom &at) const
{
MsgBundle *m = MsgBundle::New();
m->Add(const_cast<flext_base *>(this),o,at);
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueList(int o,int argc,const t_atom *argv) const
{
MsgBundle *m = MsgBundle::New();
m->Add(const_cast<flext_base *>(this),o,argc,argv);
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::ToQueueAnything(int o,const t_symbol *s,int argc,const t_atom *argv) const
{
MsgBundle *m = MsgBundle::New();
m->Add(const_cast<flext_base *>(this),o,s,argc,argv);
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
......@@ -674,7 +676,7 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::QueueForward(const t_symbol *recv,co
MsgBundle *m = MsgBundle::New();
m->Add(recv,s,argc,argv);
// send over queue
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
return true;
}
......@@ -689,7 +691,7 @@ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddIdle()
MsgBundle *m = MsgBundle::New();
m->Idle(const_cast<flext_base *>(this));
// send over queue
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddIdle(bool (*idlefun)(int argc,const t_atom *argv),int argc,const t_atom *argv)
......@@ -697,7 +699,7 @@ FLEXT_TEMPIMPL(void FLEXT_CLASSDEF(flext_base))::AddIdle(bool (*idlefun)(int arg
MsgBundle *m = MsgBundle::New();
m->Idle(idlefun,argc,argv);
// send over queue
FLEXT_TEMPINST(QVars)::queue.Push(m);
FLEXT_TEMPINST(QVars)::queue->Push(m);
}
#include "flpopns.h"
......
......@@ -431,15 +431,15 @@ public:
static void CopyMem(void *dst,const void *src,int bytes);
//! Copy a sample array
static void CopySamples(t_sample *dst,const t_sample *src,int cnt);
static void CopySamples(typename buffer::Element *dst,const typename buffer::Element *src,int cnt) { CopyMem(dst,src,sizeof(*src)*cnt); }
template<typename T> static void CopySamples(T *dst,const T *src,int cnt) { CopyMem(dst,src,sizeof(*src)*cnt); }
//! Set a memory region
static void ZeroMem(void *dst,int bytes);
//! Set a sample array to a fixed value
static void SetSamples(t_sample *dst,int cnt,t_sample s);
static void SetSamples(typename buffer::Element *dst,int cnt,t_sample s) { for(int i = 0; i < cnt; ++i) dst[i] = s; }
template<typename T> static void SetSamples(T *dst,int cnt,t_sample s) { for(int i = 0; i < cnt; ++i) dst[i] = s; }
//! Set a sample array to 0
static void ZeroSamples(t_sample *dst,int cnt) { SetSamples(dst,cnt,0); }
static void ZeroSamples(typename buffer::Element *dst,int cnt) { ZeroMem(dst,sizeof(*dst)*cnt); }
template<typename T> static void ZeroSamples(T *dst,int cnt) { ZeroMem(dst,sizeof(*dst)*cnt); }
//! Get a 32 bit hash value from an atom
......
......@@ -501,7 +501,7 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext_base))::StopThreads()
HANDLE hnd = OpenThread(THREAD_ALL_ACCESS,TRUE,ti->thrid);
TerminateThread(hnd,0);
#else
#error Not implemented
# error Not implemented
#endif
FLEXT_TEMPINST(ThrRegistry)::pending.Free(ti);
}
......@@ -517,9 +517,9 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::RelPriority(int dp,thrid_t ref,thrid
sched_param parm;
int policy;
if(pthread_getschedparam(ref,&policy,&parm) < 0) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to get thread priority");
#endif
# endif
return false;
}
else {
......@@ -530,22 +530,22 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::RelPriority(int dp,thrid_t ref,thrid
// int schmax = sched_get_priority_max(policy);
if(parm.sched_priority < sched_get_priority_min(policy)) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - minimum thread priority reached");
#endif
# endif
parm.sched_priority = sched_get_priority_min(policy);
}
else if(parm.sched_priority > sched_get_priority_max(policy)) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - maximum thread priority reached");
#endif
# endif
parm.sched_priority = sched_get_priority_max(policy);
}
if(pthread_setschedparam(id,policy,&parm) < 0) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to change thread priority");
#endif
# endif
return false;
}
}
......@@ -557,30 +557,30 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::RelPriority(int dp,thrid_t ref,thrid
int pr = GetThreadPriority(href);
if(pr == THREAD_PRIORITY_ERROR_RETURN) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to get thread priority");
#endif
# endif
return false;
}
pr += dp;
if(pr < THREAD_PRIORITY_IDLE) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - minimum thread priority reached");
#endif
# endif
pr = THREAD_PRIORITY_IDLE;
}
else if(pr > THREAD_PRIORITY_TIME_CRITICAL) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - maximum thread priority reached");
#endif
# endif
pr = THREAD_PRIORITY_TIME_CRITICAL;
}
if(SetThreadPriority(hid,pr) == 0) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to change thread priority");
#endif
# endif
return false;
}
return true;
......@@ -594,15 +594,15 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::RelPriority(int dp,thrid_t ref,thrid
if(dp < 0) w /= 1<<(-dp);
else w *= 1<<dp;
if(w < 1) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - minimum thread priority reached");
#endif
# endif
w = 1;
}
else if(w > 10000) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - maximum thread priority reached");
#endif
# endif
w = 10000;
}
ti->weight = w;
......@@ -610,7 +610,7 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::RelPriority(int dp,thrid_t ref,thrid
}
else return false;
#else
#error
# error
#endif
}
......@@ -621,9 +621,9 @@ FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::GetPriority(thrid_t id)
sched_param parm;
int policy;
if(pthread_getschedparam(id,&policy,&parm) < 0) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to get parms");
#endif
# endif
return -1;
}
return parm.sched_priority;
......@@ -633,9 +633,9 @@ FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::GetPriority(thrid_t id)
int pr = GetThreadPriority(hid);
if(pr == THREAD_PRIORITY_ERROR_RETURN) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to get thread priority");
#endif
# endif
return -1;
}
return pr;
......@@ -645,7 +645,7 @@ FLEXT_TEMPIMPL(int FLEXT_CLASSDEF(flext))::GetPriority(thrid_t id)
if(!ti) ti = FLEXT_TEMPINST(ThrRegistry)::active.Find(id);
return ti?ti->weight:-1;
#else
#error
# error
#endif
}
......@@ -656,17 +656,17 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::SetPriority(int p,thrid_t id)
sched_param parm;
int policy;
if(pthread_getschedparam(id,&policy,&parm) < 0) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to get parms");
#endif
# endif
return false;
}
else {
parm.sched_priority = p;
if(pthread_setschedparam(id,policy,&parm) < 0) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to change priority");
#endif
# endif
return false;
}
}
......@@ -675,9 +675,9 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::SetPriority(int p,thrid_t id)
#elif FLEXT_THREADS == FLEXT_THR_WIN32
HANDLE hid = OpenThread(THREAD_ALL_ACCESS,TRUE,id);
if(SetThreadPriority(hid,p) == 0) {
#ifdef FLEXT_DEBUG
# ifdef FLEXT_DEBUG
post("flext - failed to change thread priority");
#endif
# endif
return false;
}
return true;
......@@ -687,16 +687,16 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::SetPriority(int p,thrid_t id)
if(!ti) ti = FLEXT_TEMPINST(ThrRegistry)::active.Find(id);
return ti && MPSetTaskWeight(id,ti->weight = p) == noErr;
#else
#error
# error
#endif
}
#if FLEXT_THREADS == FLEXT_THR_POSIX
FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::ThrCond::Wait() {
Lock();
this->Lock(); // use this-> to avoid wrong function invocation (global Unlock)
bool ret = pthread_cond_wait(&cond,&this->mutex) == 0;
Unlock();
this->Unlock(); // use this-> to avoid wrong function invocation (global Unlock)
return ret;
}
......@@ -704,24 +704,24 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::ThrCond::TimedWait(double ftm)
{
timespec tm;
#if FLEXT_OS == FLEXT_OS_WIN && FLEXT_OSAPI == FLEXT_OSAPI_WIN_NATIVE
#ifdef _MSC_VER
# ifdef _MSC_VER
_timeb tmb;
_ftime(&tmb);
#else
# else
timeb tmb;
ftime(&tmb);
#endif
# endif
tm.tv_nsec = tmb.millitm*1000000;
tm.tv_sec = (long)tmb.time;
#else // POSIX
#if 0 // find out when the following is defined
clock_gettime(CLOCK_REALTIME,tm);
#else
# if defined(_POSIX_TIMERS) && (_POSIX_TIMERS > 0)
clock_gettime(CLOCK_REALTIME,&tm);
# else
struct timeval tp;
gettimeofday(&tp, NULL);
tm.tv_nsec = tp.tv_usec*1000;
tm.tv_sec = tp.tv_sec;
#endif
# endif
#endif
tm.tv_nsec += (long)((ftm-(long)ftm)*1.e9);
......@@ -729,9 +729,9 @@ FLEXT_TEMPIMPL(bool FLEXT_CLASSDEF(flext))::ThrCond::TimedWait(double ftm)
tm.tv_sec += (long)ftm+(tm.tv_nsec-nns)/1000000000;
tm.tv_nsec = nns;
Lock();
this->Lock(); // use this-> to avoid wrong function invocation (global Unlock)
bool ret = pthread_cond_timedwait(&cond,&this->mutex,&tm) == 0;
Unlock();
this->Unlock(); // use this-> to avoid wrong function invocation (global Unlock)
return ret;
}
#endif
......
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