Update of /cvsroot/pure-data/externals/grill/flext/source In directory sc8-pr-cvs1.sourceforge.net:/tmp/cvs-serv25804/source
Modified Files: flbase.cpp flbase.h flclass.h flcontainers.h fldefs_hdr.h flfeatures.h fllib.cpp flsupport.h fltimer.cpp Log Message: enabled templates for flext classes, inlined timer functions, some more ToOut/Sys methods fixed help name definition added flfeatures.h for compile-time version-specific feature detection changed eol-style adapted for pd-devel 0.39 minimal fix for timers cosmetic changes to calm the compiler changes for Mac/Intel
Index: flbase.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/flbase.cpp,v retrieving revision 1.27 retrieving revision 1.28 diff -C2 -d -r1.27 -r1.28 *** flbase.cpp 24 May 2006 12:20:57 -0000 1.27 --- flbase.cpp 20 Sep 2006 14:24:10 -0000 1.28 *************** *** 99,106 **** #if FLEXT_SYS == FLEXT_SYS_PD char tmp[256]; ! if(dir) { ! strcpy(tmp,dir); ! strcat(tmp,"/"); ! strcat(tmp,ref); } else --- 99,107 ---- #if FLEXT_SYS == FLEXT_SYS_PD char tmp[256]; ! if(dir && *dir) { ! strcpy(tmp,dir); ! char *last = tmp+strlen(tmp)-1; ! if(*last != '/') strcat(last,"/"); ! strcat(last,ref); } else
Index: flclass.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/flclass.h,v retrieving revision 1.69 retrieving revision 1.70 diff -C2 -d -r1.69 -r1.70 *** flclass.h 24 May 2006 12:20:57 -0000 1.69 --- flclass.h 20 Sep 2006 14:24:10 -0000 1.70 *************** *** 227,230 **** --- 227,232 ---- //! Output anything (index n starts with 0) void ToOutAnything(int n,const AtomAnything &any) const { ToOutAnything(n,any.Header(),any.Count(),any.Atoms()); } + //! Output anything (index n starts with 0) + void ToOutAnything(int n,const t_symbol *s,const AtomList &list) const { ToOutAnything(n,s,list.Count(),list.Atoms()); } //! @} FLEXT_C_IO_OUT *************** *** 829,834 **** --- 831,840 ---- void ToSysInt(int n,int f) const { outlet *o = GetOut(n); if(o) { CRITON(); outlet_flint((t_outlet *)o,f); CRITOFF(); } } void 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 ToSysString(int n,const char *s) const { ToSysSymbol(n,MakeSymbol(s)); } void 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 ToSysList(int n,const AtomList &list) const { ToSysList(n,list.Count(),list.Atoms()); } void 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(); } } + void ToSysAnything(int n,const AtomAnything &any) const { ToSysAnything(n,any.Header(),any.Count(),any.Atoms()); } + void ToSysAnything(int n,const t_symbol *s,const AtomList &list) const { ToSysAnything(n,s,list.Count(),list.Atoms()); }
void ToSysBool(int n,bool f) const { ToSysInt(n,f?1:0); }
Index: flsupport.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/flsupport.h,v retrieving revision 1.105 retrieving revision 1.106 diff -C2 -d -r1.105 -r1.106 *** flsupport.h 24 May 2006 12:20:57 -0000 1.105 --- flsupport.h 20 Sep 2006 14:24:10 -0000 1.106 *************** *** 1125,1138 **** \remark it may differ from the clock of the operating system */ /*! \brief Get time since real-time system startup. \note This is not the time of the operating system but of the real-time system. ! \note It depends on the time source the system is synchronized to. */ ! static double GetTime(); /*! \brief Get time granularity of the GetTime function. \note This can be zero if not determined. */ ! static double GetTimeGrain();
/*! \brief Get operating system time since flext startup. --- 1125,1159 ---- \remark it may differ from the clock of the operating system */ + /*! \brief Get time since real-time system startup. \note This is not the time of the operating system but of the real-time system. ! \note It may depend on the time source the system is synchronized to (e.g. audio sample rate). */ ! static double GetTime() ! { ! #if FLEXT_SYS == FLEXT_SYS_PD ! return clock_gettimesince(0)*0.001; ! #elif FLEXT_SYS == FLEXT_SYS_MAX ! double tm; ! clock_getftime(&tm); ! return tm*0.001; ! #else ! #error Not implemented ! #endif ! } /*! \brief Get time granularity of the GetTime function. \note This can be zero if not determined. */ ! static double GetTimeGrain() ! { ! #if FLEXT_SYS == FLEXT_SYS_PD ! return 0; ! #elif FLEXT_SYS == FLEXT_SYS_MAX ! return 0.001; ! #else ! #error Not implemented ! #endif ! }
/*! \brief Get operating system time since flext startup.
Index: flcontainers.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/flcontainers.h,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** flcontainers.h 27 Jun 2006 22:46:00 -0000 1.9 --- flcontainers.h 20 Sep 2006 14:24:10 -0000 1.10 *************** *** 1,473 **** ! /* ! ! flext - C++ layer for Max/MSP and pd (pure data) externals ! ! Copyright (c) 2001-2006 Thomas Grill (gr@grrrr.org) ! For information on usage and redistribution, and for a DISCLAIMER OF ALL ! WARRANTIES, see the file, "license.txt," in this distribution. ! ! */ ! ! /*! \file flcontainers.h ! \brief Lock-free container classes ! ! This code has been adapted from the MidiShare project (c)Grame ! http://midishare.sourceforge.net ! */ ! ! #ifndef __FLCONTAINERS_H ! #define __FLCONTAINERS_H ! ! ! #include "flprefix.h" ! ! ! // define that precautiously... ! // it's faster without that but we can't really know... ! #define __SMP__ ! ! ! class FLEXT_SHARE Lifo ! { ! public: ! class Cell ! { ! friend class Lifo; ! friend class Fifo; ! private: ! Cell *link; ! }; ! ! inline Lifo() { Init(); } ! ! inline void Init() { ic = oc = 0; top = NULL; } ! ! inline Cell *Avail() { return (Cell *)top; } ! ! #if defined(_MSC_VER) && FLEXT_CPU == FLEXT_CPU_IA32 ! #ifdef __SMP__ ! #define LOCK lock ! #else ! #define LOCK ! #endif ! ! inline void Push(Cell *cell) ! { ! __asm ! { ! push eax ! push ebx ! push ecx ! push edx ! push esi ! mov esi, this ! mov eax, dword ptr [esi] ! mov ecx, cell ! mov edx, dword ptr [esi+4] ! _loop: ! mov ebx, eax ! inc ebx ! mov [ecx], edx ! LOCK cmpxchg8b qword ptr [esi] ! jnz _loop ! pop esi ! pop edx ! pop ecx ! pop ebx ! pop eax ! } ! } ! ! inline Cell *Pop() ! { ! __asm ! { ! push ebx ! push ecx ! push edx ! push esi ! mov esi, this ! add esi, 4 /* point to top */ ! mov edx, dword ptr [esi+4] ! mov eax, dword ptr [esi] ! test eax, eax ! jz _end ! _loop: ! mov ebx, dword ptr [eax] ! mov ecx, edx ! inc ecx ! LOCK cmpxchg8b qword ptr [esi] ! jz _end ! test eax, eax ! jnz _loop ! _end: ! pop esi ! pop edx ! pop ecx ! pop ebx ! } ! } ! ! inline size_t Size() const { return ic-oc; } ! #elif defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_IA32 ! #ifndef SMPLOCK ! # ifdef __SMP__ ! # define SMPLOCK "lock ; " ! # else ! # define SMPLOCK "" ! # endif ! #endif ! ! inline void Push(Cell *cl) ! { ! __asm__ __volatile__ ( ! "# LFPUSH \n\t" ! "pushl %%ebx \n\t" ! "pushl %%ecx \n\t" ! "movl 0(%%esi), %%eax \n\t" ! "movl 4(%%esi), %%edx \n" ! "1: \t" ! "movl %%eax, %%ebx \n\t" ! "incl %%ebx \n\t" ! "movl %%edx, (%%ecx) \n\t" ! SMPLOCK "cmpxchg8b (%%esi) \n\t" ! "jnz 1b \n\t" ! "popl %%ecx \n\t" ! "popl %%ebx \n\t" ! :/* no output */ ! :"S" (this), "c" (cl) ! :"memory", "eax", "edx"); ! } ! ! inline Cell *Pop() ! { ! Cell *v=0; ! __asm__ __volatile__ ( ! "# LFPOP \n\t" ! "pushl %%ebx \n\t" ! "pushl %%ecx \n\t" ! "movl 4(%%esi), %%edx \n\t" ! "movl (%%esi), %%eax \n\t" ! "testl %%eax, %%eax \n\t" ! "jz 2f \n" ! "1: \t" ! "movl (%%eax), %%ebx \n\t" ! "movl %%edx, %%ecx \n\t" ! "incl %%ecx \n\t" ! SMPLOCK "cmpxchg8b (%%esi) \n\t" ! "jz 2f \n\t" ! "testl %%eax, %%eax \n\t" ! "jnz 1b \n" ! "2: \t" ! "popl %%ecx \n\t" ! "popl %%ebx \n\t" ! :"=a" (v) ! :"S" (&this->top) ! :"memory", "edx"); ! return v; ! } ! ! inline size_t Size() const ! { ! size_t n; ! __asm__ __volatile__ ( ! "# LFSIZE \n\t" ! "movl 8(%%esi), %%edx \n\t" ! "movl (%%esi), %%eax \n\t" ! "subl %%edx, %%eax \n\t" ! :"=a" (n) ! :"S" (this) ! :"memory", "edx"); ! return n; ! } ! #elif 0 //defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_X86_64 ! /* attention - this only works for EMT64 or newer revisions of AMD 64-bit cpus */ ! #ifndef SMPLOCK ! # ifdef __SMP__ ! # define SMPLOCK "lock ; " ! # else ! # define SMPLOCK "" ! # endif ! #endif ! ! inline void Push(Cell *cl) ! { ! __asm__ __volatile__ ( ! "# LFPUSH \n\t" ! "push %%rbx \n\t" ! "push %%rcx \n\t" ! "mov 0(%%rsi), %%rax \n\t" ! "mov 8(%%rsi), %%rdx \n" ! "1: \t" ! "mov %%rax, %%rbx \n\t" ! "inc %%rbx \n\t" ! "mov %%rdx, (%%rcx) \n\t" ! SMPLOCK "cmpxchg16b (%%rsi) \n\t" ! "jnz 1b \n\t" ! "pop %%rcx \n\t" ! "pop %%rbx \n\t" ! :/* no output */ ! :"S" (this), "c" (cl) ! :"memory", "rax", "rdx"); ! } ! ! inline Cell *Pop() ! { ! Cell *v=0; ! __asm__ __volatile__ ( ! "# LFPOP \n\t" ! "push %%rbx \n\t" ! "push %%rcx \n\t" ! "mov 8(%%rsi), %%rdx \n\t" ! "mov (%%rsi), %%rax \n\t" ! "test %%rax, %%rax \n\t" ! "jz 2f \n" ! "1: \t" ! "mov (%%rax), %%rbx \n\t" ! "mov %%rdx, %%rcx \n\t" ! "inc %%rcx \n\t" ! SMPLOCK "cmpxchg16b (%%rsi) \n\t" ! "jz 2f \n\t" ! "test %%rax, %%rax \n\t" ! "jnz 1b \n" ! "2: \t" ! "pop %%rcx \n\t" ! "pop %%rbx \n\t" ! :"=a" (v) ! :"S" (&this->top) ! :"memory", "rdx"); ! return v; ! } ! ! inline size_t Size() const ! { ! size_t n; ! __asm__ __volatile__ ( ! "# LFSIZE \n\t" ! "mov 16(%%rsi), %%rdx \n\t" ! "mov (%%rsi), %%rax \n\t" ! "sub %%rdx, %%rax \n\t" ! :"=a" (n) ! :"S" (this) ! :"memory", "rdx"); ! return n; ! } ! ! #elif defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_PPC ! inline void Push(register Cell *cl) ! { ! register volatile long t1; ! register long t2=0; ! asm volatile ( ! "# LFPUSH \n" ! "0: \n" ! " lwarx %0, %3, %1 \n" ! " stw %0, 0(%2) \n" ! " sync \n" ! " stwcx. %2, %3, %1 \n" ! " bne- 0b \n" ! "0: \n" ! " lwarx %0, %3, %4 \n" ! " addi %0, %0, 1 \n" ! " sync \n" ! " stwcx. %0, %3, %4 \n" ! " bne- 0b \n" ! : "=r" (t1) ! : "r" (&this->top), "r" (cl), "r" (t2), "r" (&this->oc), "0" (t1) ! : "r0" /* prevents using r0 because of the ambiguity of 'addi' coding: */ ! /* gcc version 2.95.3 20010315 (release - Linux-Mandrake 8.0 for PPC) */ ! /* compiles the instruction "addi 0, 0, n" as li 0, n */ ! ); ! } ! ! inline Cell *Pop() ! { ! register Cell *result; ! register volatile long a, b; ! register long c=0; ! asm volatile ( ! "# LFPOP \n" ! "0: \n" ! " lwarx %4, %1, %2 \n" /* creates a reservation on lf */ ! " cmpwi %4, 0 \n" /* test if the lifo is empty */ ! " beq- 1f \n" ! " lwz %5, 0(%4) \n" /* next cell in b */ ! " sync \n" /* synchronize instructions */ ! " stwcx. %5, %1, %2 \n" /* if the reservation is not altered */ ! /* modify lifo top */ ! " bne- 0b \n" /* otherwise: loop and try again */ ! "0: \n" ! " lwarx %5, %1, %3 \n" /* creates a reservation on lf->count */ ! " addi %5, %5, -1 \n" /* dec count */ ! " sync \n" /* synchronize instructions */ ! " stwcx. %5, %1, %3 \n" /* conditionnal store */ ! " bne- 0b \n" ! "1: \n" ! " mr %0, %4 \n" ! :"=r" (result), "=r" (c) ! : "r" (&this->top), "r" (&this->oc), "r" (a), "r" (b), "1" (c) ! : "r0" /* prevents using r0 because of the ambiguity of 'addi' coding: */ ! /* gcc version 2.95.3 20010315 (release - Linux-Mandrake 8.0 for PPC) */ ! /* compiles the instruction "addi 0, 0, n" as li 0, n */ ! ); ! return result; ! } ! ! inline size_t Size() const { return oc; } ! ! #else ! // no lock free code available for this compiler/platform ! ! inline void Push(Cell *c) ! { ! #ifdef FLEXT_THREADS ! mutex.Lock(); ! #endif ! c->link = (Cell *)top; ! top = c; ! ++oc; ! #ifdef FLEXT_THREADS ! mutex.Unlock(); ! #endif ! } ! ! inline Cell *Pop() ! { ! if(top) { ! Cell *r; ! #ifdef FLEXT_THREADS ! mutex.Lock(); ! #endif ! r = (Cell *)top; ! top = r->link; ! --oc; ! #ifdef FLEXT_THREADS ! mutex.Unlock(); ! #endif ! return r; ! } ! else ! return NULL; ! } ! ! inline size_t Size() const { return oc; } ! ! private: ! #ifdef FLEXT_THREADS ! flext::ThrMutex mutex; ! #endif ! ! #endif ! ! private: ! // don't change order! ! volatile size_t ic; // input (push) count ! volatile Cell *top; // top of the stack ! volatile size_t oc; // output (pop) count ! #ifdef __POWERPC__ ! size_t unused[5]; // lifo size must be at least 32 bytes ! // to avoid livelock in multiprocessor ! #endif ! }; ! ! template <typename T> ! class TypedLifo ! : public Lifo ! { ! public: ! inline T *Avail() { return static_cast<T *>(Lifo::Avail()); } ! inline void Push(T *c) { Lifo::Push(static_cast<T *>(c)); } ! inline T *Pop() { return static_cast<T *>(Lifo::Pop()); } ! }; ! ! 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 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; ! }; ! ! ! class FLEXT_SHARE Fifo ! { ! public: ! typedef Lifo::Cell Cell; ! ! void Init() { in.Init(); out.Init(); } ! ! inline size_t Size() const { return in.Size()+out.Size(); } ! ! inline void Put(Cell *cl) { in.Push(cl); } ! ! Cell *Get() ! { ! Cell *v1 = out.Pop(); ! if(!v1) { ! v1 = in.Pop(); ! if(v1) ! for(Cell *v2; (v2 = in.Pop()) != NULL; v1 = v2) ! out.Push(v1); ! } ! return v1; ! } ! ! Cell *Avail() ! { ! Cell *v1 = out.Avail(); ! if(v1) ! return v1; ! else { ! for(Cell *v2; (v2 = in.Pop()) != NULL; ) ! out.Push(v2); ! return out.Avail(); ! } ! } ! ! Cell *Clear() ! { ! Cell *first = Get(); ! if(!first) return NULL; ! ! Cell *next,*cur = first; ! while((next = Get()) != NULL) { ! cur->link = next; ! cur = next; ! } ! cur->link = NULL; ! ! Init(); ! return first; ! } ! ! Lifo in,out; ! }; ! ! template <typename T> ! class TypedFifo ! : public Fifo ! { ! public: ! inline T *Avail() { return static_cast<T *>(Fifo::Avail()); } ! inline void Put(T *c) { Fifo::Put(static_cast<T *>(c)); } ! inline T *Get() { return static_cast<T *>(Fifo::Get()); } ! inline T *Clear() { return static_cast<T *>(Fifo::Clear()); } ! }; ! ! 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 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; ! }; ! ! #endif --- 1,473 ---- ! /* ! ! flext - C++ layer for Max/MSP and pd (pure data) externals ! ! Copyright (c) 2001-2006 Thomas Grill (gr@grrrr.org) ! For information on usage and redistribution, and for a DISCLAIMER OF ALL ! WARRANTIES, see the file, "license.txt," in this distribution. ! ! */ ! ! /*! \file flcontainers.h ! \brief Lock-free container classes ! ! This code has been adapted from the MidiShare project (c)Grame ! http://midishare.sourceforge.net ! */ ! ! #ifndef __FLCONTAINERS_H ! #define __FLCONTAINERS_H ! ! ! #include "flprefix.h" ! ! ! // define that precautiously... ! // it's faster without that but we can't really know... ! #define __SMP__ ! ! ! class FLEXT_SHARE Lifo ! { ! public: ! class Cell ! { ! friend class Lifo; ! friend class Fifo; ! private: ! Cell *link; ! }; ! ! inline Lifo() { Init(); } ! ! inline void Init() { ic = oc = 0; top = NULL; } ! ! inline Cell *Avail() { return (Cell *)top; } ! ! #if defined(_MSC_VER) && FLEXT_CPU == FLEXT_CPU_IA32 ! #ifdef __SMP__ ! #define LOCK lock ! #else ! #define LOCK ! #endif ! ! inline void Push(Cell *cell) ! { ! __asm ! { ! push eax ! push ebx ! push ecx ! push edx ! push esi ! mov esi, this ! mov eax, dword ptr [esi] ! mov ecx, cell ! mov edx, dword ptr [esi+4] ! _loop: ! mov ebx, eax ! inc ebx ! mov [ecx], edx ! LOCK cmpxchg8b qword ptr [esi] ! jnz _loop ! pop esi ! pop edx ! pop ecx ! pop ebx ! pop eax ! } ! } ! ! inline Cell *Pop() ! { ! __asm ! { ! push ebx ! push ecx ! push edx ! push esi ! mov esi, this ! add esi, 4 /* point to top */ ! mov edx, dword ptr [esi+4] ! mov eax, dword ptr [esi] ! test eax, eax ! jz _end ! _loop: ! mov ebx, dword ptr [eax] ! mov ecx, edx ! inc ecx ! LOCK cmpxchg8b qword ptr [esi] ! jz _end ! test eax, eax ! jnz _loop ! _end: ! pop esi ! pop edx ! pop ecx ! pop ebx ! } ! } ! ! inline size_t Size() const { return ic-oc; } ! #elif defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_IA32 ! #ifndef SMPLOCK ! # ifdef __SMP__ ! # define SMPLOCK "lock ; " ! # else ! # define SMPLOCK "" ! # endif ! #endif ! ! inline void Push(Cell *cl) ! { ! __asm__ __volatile__ ( ! "# LFPUSH \n\t" ! "pushl %%ebx \n\t" ! "pushl %%ecx \n\t" ! "movl 0(%%esi), %%eax \n\t" ! "movl 4(%%esi), %%edx \n" ! "1: \t" ! "movl %%eax, %%ebx \n\t" ! "incl %%ebx \n\t" ! "movl %%edx, (%%ecx) \n\t" ! SMPLOCK "cmpxchg8b (%%esi) \n\t" ! "jnz 1b \n\t" ! "popl %%ecx \n\t" ! "popl %%ebx \n\t" ! :/* no output */ ! :"S" (this), "c" (cl) ! :"memory", "eax", "edx"); ! } ! ! inline Cell *Pop() ! { ! Cell *v=0; ! __asm__ __volatile__ ( ! "# LFPOP \n\t" ! "pushl %%ebx \n\t" ! "pushl %%ecx \n\t" ! "movl 4(%%esi), %%edx \n\t" ! "movl (%%esi), %%eax \n\t" ! "testl %%eax, %%eax \n\t" ! "jz 2f \n" ! "1: \t" ! "movl (%%eax), %%ebx \n\t" ! "movl %%edx, %%ecx \n\t" ! "incl %%ecx \n\t" ! SMPLOCK "cmpxchg8b (%%esi) \n\t" ! "jz 2f \n\t" ! "testl %%eax, %%eax \n\t" ! "jnz 1b \n" ! "2: \t" ! "popl %%ecx \n\t" ! "popl %%ebx \n\t" ! :"=a" (v) ! :"S" (&this->top) ! :"memory", "edx"); ! return v; ! } ! ! inline size_t Size() const ! { ! size_t n; ! __asm__ __volatile__ ( ! "# LFSIZE \n\t" ! "movl 8(%%esi), %%edx \n\t" ! "movl (%%esi), %%eax \n\t" ! "subl %%edx, %%eax \n\t" ! :"=a" (n) ! :"S" (this) ! :"memory", "edx"); ! return n; ! } ! #elif 0 //defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_X86_64 ! /* attention - this only works for EMT64 or newer revisions of AMD 64-bit cpus */ ! #ifndef SMPLOCK ! # ifdef __SMP__ ! # define SMPLOCK "lock ; " ! # else ! # define SMPLOCK "" ! # endif ! #endif ! ! inline void Push(Cell *cl) ! { ! __asm__ __volatile__ ( ! "# LFPUSH \n\t" ! "push %%rbx \n\t" ! "push %%rcx \n\t" ! "mov 0(%%rsi), %%rax \n\t" ! "mov 8(%%rsi), %%rdx \n" ! "1: \t" ! "mov %%rax, %%rbx \n\t" ! "inc %%rbx \n\t" ! "mov %%rdx, (%%rcx) \n\t" ! SMPLOCK "cmpxchg16b (%%rsi) \n\t" ! "jnz 1b \n\t" ! "pop %%rcx \n\t" ! "pop %%rbx \n\t" ! :/* no output */ ! :"S" (this), "c" (cl) ! :"memory", "rax", "rdx"); ! } ! ! inline Cell *Pop() ! { ! Cell *v=0; ! __asm__ __volatile__ ( ! "# LFPOP \n\t" ! "push %%rbx \n\t" ! "push %%rcx \n\t" ! "mov 8(%%rsi), %%rdx \n\t" ! "mov (%%rsi), %%rax \n\t" ! "test %%rax, %%rax \n\t" ! "jz 2f \n" ! "1: \t" ! "mov (%%rax), %%rbx \n\t" ! "mov %%rdx, %%rcx \n\t" ! "inc %%rcx \n\t" ! SMPLOCK "cmpxchg16b (%%rsi) \n\t" ! "jz 2f \n\t" ! "test %%rax, %%rax \n\t" ! "jnz 1b \n" ! "2: \t" ! "pop %%rcx \n\t" ! "pop %%rbx \n\t" ! :"=a" (v) ! :"S" (&this->top) ! :"memory", "rdx"); ! return v; ! } ! ! inline size_t Size() const ! { ! size_t n; ! __asm__ __volatile__ ( ! "# LFSIZE \n\t" ! "mov 16(%%rsi), %%rdx \n\t" ! "mov (%%rsi), %%rax \n\t" ! "sub %%rdx, %%rax \n\t" ! :"=a" (n) ! :"S" (this) ! :"memory", "rdx"); ! return n; ! } ! ! #elif defined(__GNUC__) && FLEXT_CPU == FLEXT_CPU_PPC ! inline void Push(register Cell *cl) ! { ! register volatile long t1; ! register long t2=0; ! asm volatile ( ! "# LFPUSH \n" ! "0: \n" ! " lwarx %0, %3, %1 \n" ! " stw %0, 0(%2) \n" ! " sync \n" ! " stwcx. %2, %3, %1 \n" ! " bne- 0b \n" ! "0: \n" ! " lwarx %0, %3, %4 \n" ! " addi %0, %0, 1 \n" ! " sync \n" ! " stwcx. %0, %3, %4 \n" ! " bne- 0b \n" ! : "=r" (t1) ! : "r" (&this->top), "r" (cl), "r" (t2), "r" (&this->oc), "0" (t1) ! : "r0" /* prevents using r0 because of the ambiguity of 'addi' coding: */ ! /* gcc version 2.95.3 20010315 (release - Linux-Mandrake 8.0 for PPC) */ ! /* compiles the instruction "addi 0, 0, n" as li 0, n */ ! ); ! } ! ! inline Cell *Pop() ! { ! register Cell *result; ! register volatile long a, b; ! register long c=0; ! asm volatile ( ! "# LFPOP \n" ! "0: \n" ! " lwarx %4, %1, %2 \n" /* creates a reservation on lf */ ! " cmpwi %4, 0 \n" /* test if the lifo is empty */ ! " beq- 1f \n" ! " lwz %5, 0(%4) \n" /* next cell in b */ ! " sync \n" /* synchronize instructions */ ! " stwcx. %5, %1, %2 \n" /* if the reservation is not altered */ ! /* modify lifo top */ ! " bne- 0b \n" /* otherwise: loop and try again */ ! "0: \n" ! " lwarx %5, %1, %3 \n" /* creates a reservation on lf->count */ ! " addi %5, %5, -1 \n" /* dec count */ ! " sync \n" /* synchronize instructions */ ! " stwcx. %5, %1, %3 \n" /* conditionnal store */ ! " bne- 0b \n" ! "1: \n" ! " mr %0, %4 \n" ! :"=r" (result), "=r" (c) ! : "r" (&this->top), "r" (&this->oc), "r" (a), "r" (b), "1" (c) ! : "r0" /* prevents using r0 because of the ambiguity of 'addi' coding: */ ! /* gcc version 2.95.3 20010315 (release - Linux-Mandrake 8.0 for PPC) */ ! /* compiles the instruction "addi 0, 0, n" as li 0, n */ ! ); ! return result; ! } ! ! inline size_t Size() const { return oc; } ! ! #else ! // no lock free code available for this compiler/platform ! ! inline void Push(Cell *c) ! { ! #ifdef FLEXT_THREADS ! mutex.Lock(); ! #endif ! c->link = (Cell *)top; ! top = c; ! ++oc; ! #ifdef FLEXT_THREADS ! mutex.Unlock(); ! #endif ! } ! ! inline Cell *Pop() ! { ! if(top) { ! Cell *r; ! #ifdef FLEXT_THREADS ! mutex.Lock(); ! #endif ! r = (Cell *)top; ! top = r->link; ! --oc; ! #ifdef FLEXT_THREADS ! mutex.Unlock(); ! #endif ! return r; ! } ! else ! return NULL; ! } ! ! inline size_t Size() const { return oc; } ! ! private: ! #ifdef FLEXT_THREADS ! flext::ThrMutex mutex; ! #endif ! ! #endif ! ! private: ! // don't change order! ! volatile size_t ic; // input (push) count ! volatile Cell *top; // top of the stack ! volatile size_t oc; // output (pop) count ! #ifdef __POWERPC__ ! size_t unused[5]; // lifo size must be at least 32 bytes ! // to avoid livelock in multiprocessor ! #endif ! }; ! ! template <typename T> ! class TypedLifo ! : public Lifo ! { ! public: ! inline T *Avail() { return static_cast<T *>(Lifo::Avail()); } ! inline void Push(T *c) { Lifo::Push(static_cast<T *>(c)); } ! inline T *Pop() { return static_cast<T *>(Lifo::Pop()); } ! }; ! ! 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 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; ! }; ! ! ! class FLEXT_SHARE Fifo ! { ! public: ! typedef Lifo::Cell Cell; ! ! void Init() { in.Init(); out.Init(); } ! ! inline size_t Size() const { return in.Size()+out.Size(); } ! ! inline void Put(Cell *cl) { in.Push(cl); } ! ! Cell *Get() ! { ! Cell *v1 = out.Pop(); ! if(!v1) { ! v1 = in.Pop(); ! if(v1) ! for(Cell *v2; (v2 = in.Pop()) != NULL; v1 = v2) ! out.Push(v1); ! } ! return v1; ! } ! ! Cell *Avail() ! { ! Cell *v1 = out.Avail(); ! if(v1) ! return v1; ! else { ! for(Cell *v2; (v2 = in.Pop()) != NULL; ) ! out.Push(v2); ! return out.Avail(); ! } ! } ! ! Cell *Clear() ! { ! Cell *first = Get(); ! if(!first) return NULL; ! ! Cell *next,*cur = first; ! while((next = Get()) != NULL) { ! cur->link = next; ! cur = next; ! } ! cur->link = NULL; ! ! Init(); ! return first; ! } ! ! Lifo in,out; ! }; ! ! template <typename T> ! class TypedFifo ! : public Fifo ! { ! public: ! inline T *Avail() { return static_cast<T *>(Fifo::Avail()); } ! inline void Put(T *c) { Fifo::Put(static_cast<T *>(c)); } ! inline T *Get() { return static_cast<T *>(Fifo::Get()); } ! inline T *Clear() { return static_cast<T *>(Fifo::Clear()); } ! }; ! ! 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 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; ! }; ! ! #endif
Index: fltimer.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/fltimer.cpp,v retrieving revision 1.9 retrieving revision 1.10 diff -C2 -d -r1.9 -r1.10 *** fltimer.cpp 23 May 2005 16:52:45 -0000 1.9 --- fltimer.cpp 20 Sep 2006 14:24:10 -0000 1.10 *************** *** 26,54 ****
- - double flext::GetTime() - { - #if FLEXT_SYS == FLEXT_SYS_PD - return clock_gettimesince(0)*0.001; - #elif FLEXT_SYS == FLEXT_SYS_MAX - double tm; - clock_getftime(&tm); - return tm*0.001; - #else - #error Not implemented - #endif - } - - double flext::GetTimeGrain() - { - #if FLEXT_SYS == FLEXT_SYS_PD - return 0; - #elif FLEXT_SYS == FLEXT_SYS_MAX - return 0.001; - #else - #error Not implemented - #endif - } - #if FLEXT_OS == FLEXT_OS_WIN static double perffrq = 0; --- 26,29 ---- *************** *** 247,253 **** { userdata = data; ! period = tm; #if FLEXT_SYS == FLEXT_SYS_PD ! clock_delay(clk,tm*1000); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_fdelay(clk,tm*1000.); --- 222,228 ---- { userdata = data; ! period = tm; #if FLEXT_SYS == FLEXT_SYS_PD ! clock_delay(clk,tm*1000.); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_fdelay(clk,tm*1000.); *************** *** 258,271 **** }
! /*! \brief Callback function for system clock. ! \todo Make periodic events scheduled as such. ! */ void flext::Timer::callback(Timer *tmr) { if(tmr->period) { ! // clearly it would be more precise if the periodic event is scheduled as such ! // and not retriggered every time #if FLEXT_SYS == FLEXT_SYS_PD ! clock_delay(tmr->clk,tmr->period*1000); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_fdelay(tmr->clk,tmr->period*1000.); --- 233,250 ---- }
! //! \brief Callback function for system clock. void flext::Timer::callback(Timer *tmr) { + #if FLEXT_SYS == FLEXT_SYS_MAX + if(tmr->queued) + qelem_set(tmr->qelem); + else + #endif + tmr->Work(); + if(tmr->period) { ! // reschedule #if FLEXT_SYS == FLEXT_SYS_PD ! clock_delay(tmr->clk,tmr->period*1000.); #elif FLEXT_SYS == FLEXT_SYS_MAX clock_fdelay(tmr->clk,tmr->period*1000.); *************** *** 274,284 **** #endif } - - #if FLEXT_SYS == FLEXT_SYS_MAX - if(tmr->queued) - qelem_set(tmr->qelem); - else - #endif - tmr->Work(); }
--- 253,256 ----
Index: fllib.cpp =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/fllib.cpp,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** fllib.cpp 20 Jun 2006 00:04:11 -0000 1.39 --- fllib.cpp 20 Sep 2006 14:24:10 -0000 1.40 *************** *** 42,46 **** static const char *extract(const char *name,int ix = 0) { ! static char tmp[1024]; const char *n = name; --- 42,46 ---- static const char *extract(const char *name,int ix = 0) { ! char tmp[1024]; const char *n = name; *************** *** 48,66 ****
if(del) { ! if(ix < 0) { ! char *t = tmp; ! while(n < del && (isspace(*n) || strchr(ALIASSLASHES,*n))) ++n; ! while(n < del && !isspace(*n)) { ! char c = *(n++); ! *(t++) = strchr(ALIASSLASHES,c)?ALIASSLASH:c; ! } ! while(*t == ALIASSLASH && t > tmp) --t; ! *t = 0; ! ! return tmp; }
! n = del+1; }
while(*n && isspace(*n)) ++n; --- 48,70 ----
if(del) { ! #if 0 ! char *t = tmp; ! while(n < del && (isspace(*n) || strchr(ALIASSLASHES,*n))) ++n; ! while(n < del && !isspace(*n)) { ! char c = *(n++); ! *(t++) = strchr(ALIASSLASHES,c)?ALIASSLASH:c; } + while(*t == ALIASSLASH && t > tmp) --t; + *t = 0; + #endif + if(ix < 0) + return del+1;
! strncpy(tmp,name,del-name); ! tmp[del-name] = 0; ! n = tmp; } + else if(ix < 0) + return NULL; // no explicit help name
while(*n && isspace(*n)) ++n; *************** *** 302,306 ****
// make help reference ! flext_obj::DefineHelp(clid,idname,extract(names,-1),dsp);
for(int ix = 0; ; ++ix) { --- 306,319 ----
// make help reference ! const char *helptxt = extract(names,-1); ! if(helptxt) { ! const char *sl = strchr(helptxt,'/'); ! if(sl && !sl[1]) ! // helptxt is only the path (path with trailing /) ! flext_obj::DefineHelp(clid,idname,helptxt,dsp); ! else ! // helptxt is path and patch name ! flext_obj::DefineHelp(clid,helptxt,NULL,dsp); ! }
for(int ix = 0; ; ++ix) {
Index: fldefs_hdr.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/fldefs_hdr.h,v retrieving revision 1.2 retrieving revision 1.3 diff -C2 -d -r1.2 -r1.3 *** fldefs_hdr.h 26 Jan 2005 05:01:45 -0000 1.2 --- fldefs_hdr.h 20 Sep 2006 14:24:10 -0000 1.3 *************** *** 33,36 **** --- 33,40 ---- FLEXT_REALHDR(NEW_CLASS, PARENT_CLASS)
+ #define FLEXT_HEADER_T(NEW_CLASS,PARENT_CLASS) \ + \ + FLEXT_REALHDR_T(NEW_CLASS, PARENT_CLASS) + /*! \brief Flext class header with setup function \param NEW_CLASS name of the current C++ class *************** *** 47,50 **** --- 51,58 ---- FLEXT_REALHDR_S(NEW_CLASS, PARENT_CLASS, SETUPFUN)
+ #define FLEXT_HEADER_TS(NEW_CLASS, PARENT_CLASS, SETUPFUN)\ + \ + FLEXT_REALHDR_TS(NEW_CLASS, PARENT_CLASS, SETUPFUN) +
//! @} FLEXT_D_HEADER
Index: flbase.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/flbase.h,v retrieving revision 1.39 retrieving revision 1.40 diff -C2 -d -r1.39 -r1.40 *** flbase.h 20 Jun 2006 00:04:11 -0000 1.39 --- flbase.h 20 Sep 2006 14:24:10 -0000 1.40 *************** *** 332,335 **** --- 332,363 ---- }
+ #define FLEXT_REALHDR_T(NEW_CLASS, PARENT_CLASS) \ + public: \ + typedef NEW_CLASS thisType; \ + typedef PARENT_CLASS thisParent; \ + typedef typename thisParent::t_classid t_classid; \ + static FLEXT_CLASSDEF(flext_obj) *__init__(int argc,t_atom *argv); \ + static void __free__(flext_hdr *hdr) { \ + FLEXT_CLASSDEF(flext_obj) *mydata = hdr->data; delete mydata; \ + hdr->flext_hdr::~flext_hdr(); \ + } \ + static void __setup__(t_classid classid) { thisParent::__setup__(classid); } + + + #define FLEXT_REALHDR_TS(NEW_CLASS, PARENT_CLASS,SETUPFUN) \ + public: \ + typedef NEW_CLASS thisType; \ + typedef PARENT_CLASS thisParent; \ + typedef typename thisParent::t_classid t_classid; \ + static FLEXT_CLASSDEF(flext_obj) *__init__(int argc,t_atom *argv); \ + static void __free__(flext_hdr *hdr) { \ + FLEXT_CLASSDEF(flext_obj) *mydata = hdr->data; delete mydata; \ + hdr->flext_hdr::~flext_hdr(); \ + } \ + static void __setup__(t_classid classid) { \ + thisParent::__setup__(classid); \ + thisType::SETUPFUN(classid); \ + } +
// generate name of dsp/non-dsp setup function
Index: flfeatures.h =================================================================== RCS file: /cvsroot/pure-data/externals/grill/flext/source/flfeatures.h,v retrieving revision 1.1 retrieving revision 1.2 diff -C2 -d -r1.1 -r1.2 *** flfeatures.h 22 Aug 2005 19:20:27 -0000 1.1 --- flfeatures.h 20 Sep 2006 14:24:10 -0000 1.2 *************** *** 1,34 **** ! /* ! ! flext - C++ layer for Max/MSP and pd (pure data) externals ! ! Copyright (c) 2001-2005 Thomas Grill (gr@grrrr.org) ! For information on usage and redistribution, and for a DISCLAIMER OF ALL ! WARRANTIES, see the file, "license.txt," in this distribution. ! ! */ ! ! /*! \file flfeatures.h ! \brief Detect version-specific features. ! */ ! ! #ifndef __FLFEATURES_H ! #define __FLFEATURES_H ! ! // check if PD API supports buffer dirty time ! #if defined(PD_DEVEL_VERSION) && defined(PD_MAJOR_VERSION) && defined(PD_MINOR_VERSION) ! #if PD_MINOR_VERSION >= 36 && PD_MINOR_VERSION <= 38 ! // array locks have been removed in devel_0_39 ! #define _FLEXT_HAVE_PD_GARRAYLOCKS ! #endif ! #if PD_MINOR_VERSION >= 36 ! #define _FLEXT_HAVE_PD_GARRAYUPDATETIME ! #endif ! #endif ! ! #if defined(MAC_VERSION) || defined(WIN_VERSION) ! // not for OS9 ! #define _FLEXT_HAVE_MAX_INUSEFLAG ! #endif ! ! #endif --- 1,34 ---- ! /* ! ! flext - C++ layer for Max/MSP and pd (pure data) externals ! ! Copyright (c) 2001-2005 Thomas Grill (gr@grrrr.org) ! For information on usage and redistribution, and for a DISCLAIMER OF ALL ! WARRANTIES, see the file, "license.txt," in this distribution. ! ! */ ! ! /*! \file flfeatures.h ! \brief Detect version-specific features. ! */ ! ! #ifndef __FLFEATURES_H ! #define __FLFEATURES_H ! ! // check if PD API supports buffer dirty time ! #if defined(PD_DEVEL_VERSION) && defined(PD_MAJOR_VERSION) && defined(PD_MINOR_VERSION) ! #if PD_MINOR_VERSION >= 36 && PD_MINOR_VERSION <= 38 ! // array locks have been removed in devel_0_39 ! #define _FLEXT_HAVE_PD_GARRAYLOCKS ! #endif ! #if PD_MINOR_VERSION >= 36 ! #define _FLEXT_HAVE_PD_GARRAYUPDATETIME ! #endif ! #endif ! ! #if defined(MAC_VERSION) || defined(WIN_VERSION) ! // not for OS9 ! #define _FLEXT_HAVE_MAX_INUSEFLAG ! #endif ! ! #endif