diff options
author | Thomas Grill <xovo@users.sourceforge.net> | 2005-03-14 04:58:13 +0000 |
---|---|---|
committer | Thomas Grill <xovo@users.sourceforge.net> | 2005-03-14 04:58:13 +0000 |
commit | 3e0446e7fda10c3d85a628b8c1effaa5bf7f5529 (patch) | |
tree | eac19e282f78a1d64759ca7dbeff02ee63d6a1d1 /externals/grill/py/source | |
parent | bf9523d0f232dc39ddf0b5d1985e93d431100c13 (diff) |
fixes for OSX
docs
optimizations and fixes
use optimized version
optimized function calls
adjust pd and py files for correct argument passing
more optimizations
svn path=/trunk/; revision=2627
Diffstat (limited to 'externals/grill/py/source')
-rw-r--r-- | externals/grill/py/source/main.cpp | 26 | ||||
-rw-r--r-- | externals/grill/py/source/main.h | 25 | ||||
-rw-r--r-- | externals/grill/py/source/py.cpp | 12 | ||||
-rw-r--r-- | externals/grill/py/source/pybuffer.cpp | 12 | ||||
-rw-r--r-- | externals/grill/py/source/pydsp.cpp | 72 | ||||
-rw-r--r-- | externals/grill/py/source/pyext.cpp | 18 |
6 files changed, 86 insertions, 79 deletions
diff --git a/externals/grill/py/source/main.cpp b/externals/grill/py/source/main.cpp index aa234cc4..252d3408 100644 --- a/externals/grill/py/source/main.cpp +++ b/externals/grill/py/source/main.cpp @@ -24,8 +24,8 @@ static PyObject *gcollect = NULL; typedef std::map<flext::thrid_t,PyThreadState *> PyThrMap; static PyInterpreterState *pymain = NULL; -static PyThreadState *pythrmain = NULL; static PyThrMap pythrmap; +PyThreadState *pybase::pythrsys = NULL; int pybase::lockcount = 0; @@ -62,8 +62,6 @@ void pybase::FreeThreadState() PyObject *pybase::module_obj = NULL; PyObject *pybase::module_dict = NULL; -PyObject *pybase::emptytuple = NULL; - void initsymbol(); void initsamplebuffer(); @@ -95,12 +93,12 @@ void pybase::lib_setup() PyEval_InitThreads(); // get thread state - pythrmain = PyThreadState_Get(); + pythrsys = PyThreadState_Get(); // get main interpreter state - pymain = pythrmain->interp; + pymain = pythrsys->interp; // add thread state of main thread to map - pythrmap[GetThreadId()] = pythrmain; + pythrmap[GetThreadId()] = pythrsys; #endif // sys.argv must be set to empty tuple @@ -143,8 +141,6 @@ void pybase::lib_setup() initsamplebuffer(); PyModule_AddObject(module_obj,"Buffer",(PyObject *)&pySamplebuffer_Type); - emptytuple = PyTuple_New(0); - // ------------------------------------------------------------- FLEXT_SETUP(pyobj); @@ -169,14 +165,14 @@ pybase::pybase() , shouldexit(false),thrcount(0),stoptick(0) #endif { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Py_INCREF(module_obj); PyUnlock(state); } pybase::~pybase() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Py_XDECREF(module_obj); PyUnlock(state); } @@ -527,13 +523,13 @@ bool pybase::qucall(PyObject *fun,PyObject *args) void pybase::threadworker() { FifoEl *el; - PyThreadState *state; + PyThreadState *my = FindThreadState(),*state; ++thrcount; for(;;) { while(el = qufifo.Get()) { ++thrcount; - state = PyLock(); + state = PyLock(my); callpy(el->fun,el->args); Py_XDECREF(el->fun); Py_XDECREF(el->args); @@ -547,7 +543,7 @@ void pybase::threadworker() qucond.Wait(); } - state = PyLock(); + state = PyLock(my); // unref remaining Python objects while(el = qufifo.Get()) { Py_XDECREF(el->fun); @@ -575,9 +571,7 @@ short pybase::patcher_myvol(t_patcher *x) bool pybase::collect() { if(gcollect) { - Py_INCREF(emptytuple); - PyObject *ret = PyObject_Call(gcollect,emptytuple,NULL); - Py_DECREF(emptytuple); + PyObject *ret = PyObject_CallObject(gcollect,NULL); if(ret) { #ifdef FLEXT_DEBUG int refs = PyInt_AsLong(ret); diff --git a/externals/grill/py/source/main.h b/externals/grill/py/source/main.h index c76d43fa..f9df5807 100644 --- a/externals/grill/py/source/main.h +++ b/externals/grill/py/source/main.h @@ -92,8 +92,6 @@ protected: enum retval { nothing,atom,sequ }; - static PyObject *emptytuple; - // --- module stuff ----- static PyObject *module_obj,*module_dict; @@ -154,9 +152,12 @@ protected: void threadworker(); PyFifo qufifo; ThrCond qucond; + static PyThreadState *pythrsys; static PyThreadState *FindThreadState(); static void FreeThreadState(); +#else + static PyThreadState *FindThreadState() { return NULL; } #endif public: @@ -166,27 +167,35 @@ public: inline void Lock() { mutex.Unlock(); } inline void Unlock() { mutex.Unlock(); } - // this is respecially needed when one py/pyext object calls another one + // this is especially needed when one py/pyext object calls another one // we don't want the message to be queued, but otoh we have to avoid deadlock // (recursive calls can only happen in the system thread) static int lockcount; - inline PyThreadState *PyLock() + inline PyThreadState *PyLock(PyThreadState *st = FindThreadState()) { if(!IsSystemThread() || !lockcount++) PyEval_AcquireLock(); - return PyThreadState_Swap(FindThreadState()); + return PyThreadState_Swap(st); + } + + inline PyThreadState *PyLockSys() + { + if(!lockcount++) PyEval_AcquireLock(); + return PyThreadState_Swap(pythrsys); } inline void PyUnlock(PyThreadState *st) { - PyThreadState_Swap(st); - if(!IsSystemThread() || !--lockcount) PyEval_ReleaseLock(); + PyThreadState *old = PyThreadState_Swap(st); + if(old != pythrsys || !--lockcount) PyEval_ReleaseLock(); } + #else inline void Lock() {} inline void Unlock() {} - inline PyThreadState *PyLock() { return NULL; } + inline PyThreadState *PyLock(PyThreadState *) { return NULL; } + inline PyThreadState *PyLockSys() { return NULL; } inline void PyUnlock(PyThreadState *st) {} #endif diff --git a/externals/grill/py/source/py.cpp b/externals/grill/py/source/py.cpp index bf3ff8fb..eb1d2390 100644 --- a/externals/grill/py/source/py.cpp +++ b/externals/grill/py/source/py.cpp @@ -133,7 +133,7 @@ pyobj::pyobj(int argc,const t_atom *argv): FLEXT_CALLMETHOD(threadworker); #endif - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); if(argc > 2) SetArgs(argc-2,argv+2); @@ -188,7 +188,7 @@ pyobj::pyobj(int argc,const t_atom *argv): pyobj::~pyobj() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Unregister("_py"); PyUnlock(state); } @@ -208,7 +208,7 @@ bool pyobj::CbMethodResort(int n,const t_symbol *s,int argc,const t_atom *argv) void pyobj::m_reload() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Unregister("_py"); @@ -222,7 +222,7 @@ void pyobj::m_reload() void pyobj::m_reload_(int argc,const t_atom *argv) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); SetArgs(argc,argv); PyUnlock(state); @@ -231,7 +231,7 @@ void pyobj::m_reload_(int argc,const t_atom *argv) void pyobj::m_set(int argc,const t_atom *argv) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); int ix = 0; if(argc >= 2) { @@ -328,7 +328,7 @@ void pyobj::Reload() bool pyobj::callpy(PyObject *fun,PyObject *args) { - PyObject *ret = PyObject_Call(fun,args,NULL); + PyObject *ret = PyObject_CallObject(fun,args); if(ret == NULL) { // function not found resp. arguments not matching PyErr_Print(); diff --git a/externals/grill/py/source/pybuffer.cpp b/externals/grill/py/source/pybuffer.cpp index 6e7e571b..f95c4bc6 100644 --- a/externals/grill/py/source/pybuffer.cpp +++ b/externals/grill/py/source/pybuffer.cpp @@ -11,15 +11,25 @@ WARRANTIES, see the file, "license.txt," in this distribution. #include "main.h"
#ifdef PY_NUMARRAY
+#if FLEXT_OS == FLEXT_OS_MAC
+#include <Python/numarray/numarray.h>
+#else
#include <numarray/numarray.h>
+#endif
static bool nasupport = false;
static NumarrayType numtype;
#endif
// PD defines a T_OBJECT symbol
#undef T_OBJECT
-#include "structmember.h"
+
+#if FLEXT_OS == FLEXT_OS_MAC
+#include "Python/bufferobject.h"
+#include "Python/structmember.h"
+#else
#include "bufferobject.h"
+#include "structmember.h"
+#endif
static PyObject *buffer_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
diff --git a/externals/grill/py/source/pydsp.cpp b/externals/grill/py/source/pydsp.cpp index b1f50c0d..4c9eea5c 100644 --- a/externals/grill/py/source/pydsp.cpp +++ b/externals/grill/py/source/pydsp.cpp @@ -26,7 +26,7 @@ protected: virtual PyObject *GetSig(int ix,bool in);
- void NewBuffers(bool update = false);
+ void NewBuffers();
void FreeBuffers();
PyObject *dspfun,*sigfun;
@@ -46,18 +46,11 @@ bool pydsp::DoInit() if(pyobj)
{
- NewBuffers();
-
dspfun = PyObject_GetAttrString(pyobj,"_dsp"); // get ref
if(dspfun && !PyMethod_Check(dspfun)) {
Py_DECREF(dspfun);
dspfun = NULL;
}
- sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref
- if(sigfun && !PyMethod_Check(sigfun)) {
- Py_DECREF(sigfun);
- sigfun = NULL;
- }
}
return true;
}
@@ -72,29 +65,28 @@ void pydsp::DoExit() PyObject *NAFromBuffer(PyObject *buf,int c,int n);
-void pydsp::NewBuffers(bool update)
+void pydsp::NewBuffers()
{
int i,n = Blocksize();
const int ins = CntInSig(),outs = CntOutSig();
t_sample *const *insigs = InSig();
t_sample *const *outsigs = OutSig();
+ // inlet/outlet count can't change so we don't have to deallocate
if(!buffers) {
int cnt = ins+outs;
- if(cnt) {
- buffers = new PyObject *[cnt];
- memset(buffers,0,cnt*sizeof(*buffers));
- }
+ buffers = new PyObject *[cnt];
+ memset(buffers,0,cnt*sizeof(*buffers));
}
for(i = 0; i < ins; ++i) {
- if(update) Py_XDECREF(buffers[i]);
+ Py_XDECREF(buffers[i]);
PyObject *b = PyBuffer_FromReadWriteMemory(insigs[i],n*sizeof(t_sample));
buffers[i] = NAFromBuffer(b,1,n);
Py_DECREF(b);
}
for(i = 0; i < outs; ++i) {
- if(update) Py_XDECREF(buffers[ins+i]);
+ Py_XDECREF(buffers[ins+i]);
if(i < ins && outsigs[i] == insigs[i]) {
// same vectors - share the objects!
buffers[ins+i] = buffers[i];
@@ -120,15 +112,14 @@ void pydsp::FreeBuffers() bool pydsp::CbDsp()
{
- if(CntInSig() || CntOutSig())
+ if(pyobj && (CntInSig() || CntOutSig()))
{
- NewBuffers(true);
+ PyThreadState *state = PyLockSys();
+
+ NewBuffers();
if(dspfun) {
- PyThreadState *state = PyLock();
-// Py_INCREF(emptytuple);
- PyObject *ret = PyObject_Call(dspfun,emptytuple,NULL);
-// Py_DECREF(emptytuple);
+ PyObject *ret = PyObject_CallObject(dspfun,NULL);
if(ret)
Py_DECREF(ret);
else {
@@ -138,9 +129,20 @@ bool pydsp::CbDsp() PyErr_Clear();
#endif
}
- PyUnlock(state);
}
- return true;
+
+ // do that here instead of where dspfun is initialized, so that
+ // _signal can be assigned in _dsp
+ // optimizations may be done there to assign the right _signal version
+ Py_XDECREF(sigfun);
+ sigfun = PyObject_GetAttrString(pyobj,"_signal"); // get ref
+ if(sigfun && !PyMethod_Check(sigfun)) {
+ Py_DECREF(sigfun);
+ sigfun = NULL;
+ }
+
+ PyUnlock(state);
+ return sigfun != NULL;
}
else
// switch on dsp only if there are signal inlets or outlets
@@ -149,25 +151,19 @@ bool pydsp::CbDsp() void pydsp::CbSignal()
{
- if(sigfun) {
- PyThreadState *state = PyLock();
-// Py_INCREF(emptytuple);
- PyObject *ret = PyObject_Call(sigfun,emptytuple,NULL);
-// Py_DECREF(emptytuple);
-
- if(ret)
- Py_DECREF(ret);
- else {
+ PyThreadState *state = PyLockSys();
+ PyObject *ret = PyObject_CallObject(sigfun,NULL);
+
+ if(ret)
+ Py_DECREF(ret);
+ else {
#ifdef FLEXT_DEBUG
- PyErr_Print();
+ PyErr_Print();
#else
- PyErr_Clear();
+ PyErr_Clear();
#endif
- }
- PyUnlock(state);
}
- else
- flext_dsp::CbSignal();
+ PyUnlock(state);
}
PyObject *pydsp::GetSig(int ix,bool in)
diff --git a/externals/grill/py/source/pyext.cpp b/externals/grill/py/source/pyext.cpp index 0ebeab68..2d772d15 100644 --- a/externals/grill/py/source/pyext.cpp +++ b/externals/grill/py/source/pyext.cpp @@ -131,7 +131,7 @@ pyext::pyext(int argc,const t_atom *argv,bool sig): const t_atom *clname = NULL; - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); // init script module if(argc > apre) { @@ -188,7 +188,7 @@ pyext::pyext(int argc,const t_atom *argv,bool sig): bool pyext::Init() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); if(methname) { MakeInstance(); @@ -215,7 +215,7 @@ void pyext::Exit() { pybase::Exit(); // exit threads - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); DoExit(); Unregister("_pyext"); UnimportModule(); @@ -259,15 +259,13 @@ void pyext::DoExit() // try to run del to clean up the class instance PyObject *objdel = PyObject_GetAttrString(pyobj,"_del"); if(objdel) { - Py_INCREF(emptytuple); - PyObject *ret = PyObject_Call(objdel,emptytuple,NULL); + PyObject *ret = PyObject_CallObject(objdel,NULL); if(ret) Py_DECREF(ret); #ifdef FLEXT_DEBUG else post("%s - Could not call _del method",thisName()); #endif - Py_DECREF(emptytuple); Py_DECREF(objdel); } else @@ -381,7 +379,7 @@ void pyext::Reload() void pyext::m_reload() { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); Unregister("_pyext"); // self @@ -403,7 +401,7 @@ void pyext::m_reload_(int argc,const t_atom *argv) void pyext::m_get(const t_symbol *s) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); PyObject *pvar = PyObject_GetAttrString(pyobj,const_cast<char *>(GetString(s))); /* fetch bound method */ if(!pvar) { @@ -431,7 +429,7 @@ void pyext::m_get(const t_symbol *s) void pyext::m_set(int argc,const t_atom *argv) { - PyThreadState *state = PyLock(); + PyThreadState *state = PyLockSys(); if(argc < 2 || !IsString(argv[0])) post("%s - Syntax: set varname arguments...",thisName()); @@ -506,7 +504,7 @@ void pyext::m_help() bool pyext::callpy(PyObject *fun,PyObject *args) { - PyObject *ret = PyObject_Call(fun,args,NULL); + PyObject *ret = PyObject_CallObject(fun,args); if(ret == NULL) { // function not found resp. arguments not matching PyErr_Print(); |