aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThomas Grill <xovo@users.sourceforge.net>2005-03-08 04:57:17 +0000
committerThomas Grill <xovo@users.sourceforge.net>2005-03-08 04:57:17 +0000
commitdfcbb9904402efc8f0deec2a16bd905b911da0aa (patch)
tree70e23992a3ad440ccab7c54946e3b00de3b82433
parent8a3c1f78e0b705aa3fa02ff4b842cbc53906824c (diff)
updated flext lock-free containers
install flcontainers.h Lifos and Fifos with reservoir forgot about void... svn path=/trunk/; revision=2601
-rw-r--r--externals/grill/flext/package.txt2
-rw-r--r--externals/grill/flext/source/flcontainers.h10
-rwxr-xr-xexternals/grill/flext/source/flqueue.cpp68
3 files changed, 33 insertions, 47 deletions
diff --git a/externals/grill/flext/package.txt b/externals/grill/flext/package.txt
index e3fcdb60..dd74d18c 100644
--- a/externals/grill/flext/package.txt
+++ b/externals/grill/flext/package.txt
@@ -35,7 +35,7 @@ SRCS= \
flatom_app.cpp flatom_part.cpp flitem.cpp flmeth.cpp flmsg.cpp \
flproxy.cpp flqueue.cpp flbind.cpp
HDRS= \
- flprefix.h flstdc.h flbase.h flclass.h flext.h flsupport.h flmap.h fldsp.h flinternal.h \
+ flprefix.h flstdc.h flbase.h flclass.h flext.h flsupport.h flmap.h fldsp.h flinternal.h flcontainers.h \
fldefs.h fldefs_hdr.h fldefs_setup.h \
fldefs_methcb.h fldefs_meththr.h fldefs_methadd.h fldefs_methbind.h fldefs_methcall.h \
fldefs_attrcb.h fldefs_attrvar.h fldefs_attradd.h
diff --git a/externals/grill/flext/source/flcontainers.h b/externals/grill/flext/source/flcontainers.h
index ad32055a..a97df172 100644
--- a/externals/grill/flext/source/flcontainers.h
+++ b/externals/grill/flext/source/flcontainers.h
@@ -270,13 +270,14 @@ public:
inline T *Pop() { return static_cast<T *>(Lifo::Pop()); }
};
-template <typename T>
+template <typename T,int M = 2,int O = 1>
class PooledLifo
: public TypedLifo<T>
{
public:
inline T *New() { T *n = reuse.Pop(); return n?n:new T; }
- inline Free(T *p) { if(reuse.Size() < Size()) reuse.Push(p); else delete p; }
+ inline size_t Size() const { return TypedLifo<T>::Size(); }
+ inline void Free(T *p) { if(reuse.Size() < Size()*M+O) reuse.Push(p); else delete p; }
private:
TypedLifo<T> reuse;
};
@@ -347,13 +348,14 @@ public:
inline T *Clear() { return static_cast<T *>(Fifo::Clear()); }
};
-template <typename T>
+template <typename T,int M = 2,int O = 1>
class PooledFifo
: public TypedFifo<T>
{
public:
inline T *New() { T *n = reuse.Pop(); return n?n:new T; }
- inline Free(T *p) { if(reuse.Size() < Size()) reuse.Push(p); else delete p; }
+ inline size_t Size() const { return TypedFifo<T>::Size(); }
+ inline void Free(T *p) { if(reuse.Size() < Size()*M+O) reuse.Push(p); else delete p; }
private:
TypedLifo<T> reuse;
};
diff --git a/externals/grill/flext/source/flqueue.cpp b/externals/grill/flext/source/flqueue.cpp
index 75f7842e..a580bb53 100755
--- a/externals/grill/flext/source/flqueue.cpp
+++ b/externals/grill/flext/source/flqueue.cpp
@@ -27,25 +27,23 @@ flext::thrid_t flext::thrmsgid = 0;
#endif
+static void Trigger();
+
class qmsg:
public flext,
public Fifo::Cell
{
public:
- qmsg(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av)
- : msg(s,ac,av)
- , th(t),out(o)
- {}
-
- void Set(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av)
+ inline qmsg &Set(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av)
{
th = t;
out = o;
msg(s,ac,av);
+ return *this;
}
// \note PD sys lock must already be held by caller
- void Send() const
+ inline void Send() const
{
if(out < 0)
// message to self
@@ -61,28 +59,36 @@ private:
AtomAnything msg;
};
-/* \TODO This is only thread-safe if called from one thread which need NOT be the case.
- Reimplement in a thread-safe manner!!!
-*/
+
+
+typedef PooledFifo<qmsg> QueueFifo;
+
class Queue:
public flext,
- public TypedFifo<qmsg>
+ public QueueFifo
{
public:
inline bool Empty() const { return Size() == 0; }
- void New(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av);
+ inline void Push(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av)
+ {
+ qmsg *m = QueueFifo::New();
+ FLEXT_ASSERT(m);
+ m->Set(t,o,s,ac,av);
+ Put(m);
+ Trigger();
+ }
inline void Push(flext_base *th,int o) // bang
{
- New(th,o,sym_bang,0,NULL);
+ Push(th,o,sym_bang,0,NULL);
}
inline void Push(flext_base *th,int o,float dt)
{
t_atom at;
SetFloat(at,dt);
- New(th,o,sym_float,1,&at);
+ Push(th,o,sym_float,1,&at);
}
inline void Push(flext_base *th,int o,int dt)
@@ -97,14 +103,14 @@ public:
#else
#error Not implemented!
#endif
- New(th,o,sym,1,&at);
+ Push(th,o,sym,1,&at);
}
inline void Push(flext_base *th,int o,const t_symbol *dt)
{
t_atom at;
SetSymbol(at,dt);
- New(th,o,sym_symbol,1,&at);
+ Push(th,o,sym_symbol,1,&at);
}
void Push(flext_base *th,int o,const t_atom &a)
@@ -126,31 +132,16 @@ public:
error("atom type not supported");
return;
}
- New(th,o,sym,1,&a);
+ Push(th,o,sym,1,&a);
}
inline void Push(flext_base *th,int o,int argc,const t_atom *argv)
{
- New(th,o,sym_list,argc,argv);
- }
-
- inline void Push(flext_base *th,int o,const t_symbol *sym,int argc,const t_atom *argv)
- {
- New(th,o,sym,argc,argv);
+ Push(th,o,sym_list,argc,argv);
}
};
-static Queue queue,requeue;
-
-void Queue::New(flext_base *t,int o,const t_symbol *s,int ac,const t_atom *av)
-{
- qmsg *m = requeue.Get();
- if(m)
- m->Set(t,o,s,ac,av);
- else
- m = new qmsg(t,o,s,ac,av);
- Put(m);
-}
+static Queue queue;
#if FLEXT_QMODE == 2
@@ -180,7 +171,7 @@ static void QWork(bool syslock)
qmsg *q;
while((q = queue.Get()) != NULL) {
q->Send();
- requeue.Put(q);
+ queue.Free(q);
}
#if FLEXT_QMODE == 2
@@ -305,41 +296,34 @@ void flext_base::StartQueue()
void flext_base::ToQueueBang(int o) const
{
queue.Push(const_cast<flext_base *>(this),o);
- Trigger();
}
void flext_base::ToQueueFloat(int o,float f) const
{
queue.Push(const_cast<flext_base *>(this),o,f);
- Trigger();
}
void flext_base::ToQueueInt(int o,int f) const
{
queue.Push(const_cast<flext_base *>(this),o,f);
- Trigger();
}
void flext_base::ToQueueSymbol(int o,const t_symbol *s) const
{
queue.Push(const_cast<flext_base *>(this),o,s);
- Trigger();
}
void flext_base::ToQueueAtom(int o,const t_atom &at) const
{
queue.Push(const_cast<flext_base *>(this),o,at);
- Trigger();
}
void flext_base::ToQueueList(int o,int argc,const t_atom *argv) const
{
queue.Push(const_cast<flext_base *>(this),o,argc,argv);
- Trigger();
}
void flext_base::ToQueueAnything(int o,const t_symbol *s,int argc,const t_atom *argv) const
{
queue.Push(const_cast<flext_base *>(this),o,s,argc,argv);
- Trigger();
}