diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2005-03-08 04:57:17 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2005-03-08 04:57:17 +0000 |
commit | dfcbb9904402efc8f0deec2a16bd905b911da0aa (patch) | |
tree | 70e23992a3ad440ccab7c54946e3b00de3b82433 | |
parent | 8a3c1f78e0b705aa3fa02ff4b842cbc53906824c (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.txt | 2 | ||||
-rw-r--r-- | externals/grill/flext/source/flcontainers.h | 10 | ||||
-rwxr-xr-x | externals/grill/flext/source/flqueue.cpp | 68 |
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(); } |