00001 #include "charmdebug_python.decl.h"
00002
00003
00004 class CpdPython : public CBase_CpdPython {
00005 public:
00006 CpdPython (CkArgMsg *msg) {
00007 delete msg;
00008
00009
00010
00011 CProxy_CpdPythonGroup group = CProxy_CpdPythonGroup::ckNew();
00012 group.registerPython("CpdPythonGroup");
00013
00014
00015
00016
00017 CcsRegisterHandler("CpdPythonPersistent", CkCallback(CkIndex_CpdPythonGroup::registerPersistent(0), group));
00018 }
00019
00020
00021
00022 };
00023
00024 class CpdPythonArrayIterator : public CkLocIterator {
00025 public:
00026 CkVec<CkMigratable*> elems;
00027 CkArray *arr;
00028 virtual void addLocation(CkLocation &loc) {
00029 elems.insertAtEnd(arr->lookup(loc.getIndex()));
00030 }
00031 };
00032
00033 class CpdPythonGroup : public CBase_CpdPythonGroup, public CpdPersistentChecker {
00034 CpdPythonArrayIterator arriter;
00035 int nextElement;
00036 bool resultNotNone;
00037 public:
00038 CpdPythonGroup() {
00039
00040 }
00041
00042 int buildIterator(PyObject*&, void*);
00043 int nextIteratorUpdate(PyObject*&, PyObject*, void*);
00044
00045 PyObject *getResultFromType(char, void*);
00046 void getArray(int handle);
00047 void getValue(int handle);
00048 void getCast(int handle);
00049 void getStatic(int handle);
00050
00051 void getMessage(int handle);
00052
00053 void cpdCheck(void*);
00054 void registerPersistent(CkCcsRequestMsg*);
00055 };
00056
00057 int CpdPythonGroup::buildIterator(PyObject *&data, void *iter) {
00058 resultNotNone = false;
00059 int group = ntohl(*(int*)iter);
00060 if (group > 0) {
00061 CkGroupID id;
00062 id.idx = group;
00063 IrrGroup *ptr = _localBranch(id);
00064 if (ptr->isArrMgr()) {
00065 arriter.arr = (CkArray*)ptr;
00066 arriter.arr->getLocMgr()->iterate(arriter);
00067 if (arriter.elems.size() > 0) {
00068 data = PyLong_FromVoidPtr(arriter.elems[0]);
00069 nextElement = 1;
00070 return 1;
00071 } else {
00072 return 0;
00073 }
00074 } else {
00075 nextElement = 0;
00076 data = PyLong_FromVoidPtr(ptr);
00077
00078 return 1;
00079 }
00080 } else {
00081 nextElement = 0;
00082 data = PyLong_FromVoidPtr(CpdGetCurrentObject());
00083 return 1;
00084 }
00085 }
00086
00087 int CpdPythonGroup::nextIteratorUpdate(PyObject *&data, PyObject *result, void *iter) {
00088
00089 if (result != Py_None) {
00090 PyObject *str = PyObject_Str(result);
00091 CkPrintf("Freezing the application: %s\n",PyString_AsString(str));
00092 Py_DECREF(str);
00093 resultNotNone = true;
00094 return 0;
00095 }
00096 if (nextElement > 0) {
00097 if ((size_t)nextElement == arriter.elems.size()) {
00098 nextElement = 0;
00099 arriter.elems.removeAll();
00100 return 0;
00101 } else {
00102 data = PyLong_FromVoidPtr(arriter.elems[nextElement++]);
00103 return 1;
00104 }
00105 }
00106
00107
00108
00109 return 0;
00110 }
00111
00112 PyObject *CpdPythonGroup::getResultFromType(char restype, void* ptr) {
00113 PyObject *result = NULL;
00114 switch (restype) {
00115 case 'c':
00116 result = PyLong_FromVoidPtr(ptr);
00117 break;
00118 case 'p':
00119 result = PyLong_FromVoidPtr(*(void**)ptr);
00120 break;
00121 case 'b':
00122 result = Py_BuildValue("b", *(char*)ptr);
00123 break;
00124 case 'h':
00125 result = Py_BuildValue("h", *(short*)ptr);
00126 break;
00127 case 'i':
00128 result = Py_BuildValue("i", *(int*)ptr);
00129 break;
00130 case 'l':
00131 result = Py_BuildValue("l", *(long*)ptr);
00132 break;
00133 case 'f':
00134 result = Py_BuildValue("f", *(float*)ptr);
00135 break;
00136 case 'd':
00137 result = Py_BuildValue("d", *(double*)ptr);
00138 break;
00139 case 's':
00140 result = Py_BuildValue("s", *(char**)ptr);
00141 break;
00142 }
00143 return result;
00144 }
00145
00146 void CpdPythonGroup::getArray(int handle) {
00147 PyObject *arg = pythonGetArg(handle);
00148 PyObject *obj;
00149 int num, size;
00150 char restype;
00151 if (PyArg_ParseTuple(arg, "Oici", &obj, &size, &restype, &num) == 0) return;
00152 char *ptr = (char*)PyLong_AsVoidPtr(obj);
00153 ptr += num * size;
00154 PyObject *result = getResultFromType(restype, ptr);
00155 pythonReturn(handle, result);
00156 }
00157
00158 void CpdPythonGroup::getValue(int handle) {
00159 PyObject *arg = pythonGetArg(handle);
00160 PyObject *obj;
00161 int offset;
00162 char restype;
00163 if (PyArg_ParseTuple(arg, "Oic", &obj, &offset, &restype) == 0) return;
00164 char *ptr = (char*)PyLong_AsVoidPtr(obj);
00165 ptr += offset;
00166 PyObject *result = getResultFromType(restype, ptr);
00167 pythonReturn(handle, result);
00168 }
00169
00170 void CpdPythonGroup::getCast(int handle) {
00171 PyObject *arg = pythonGetArg(handle);
00172 PyObject *obj;
00173 int offset;
00174 if (PyArg_ParseTuple(arg, "Oi", &obj, &offset) == 0) return;
00175 char *ptr = (char*)PyLong_AsVoidPtr(obj);
00176 ptr += offset;
00177 pythonReturn(handle, PyLong_FromVoidPtr(ptr));
00178 }
00179
00180 void CpdPythonGroup::getStatic(int handle) {
00181 PyObject *arg = pythonGetArg(handle);
00182 PyObject *location;
00183 char restype;
00184 if (PyArg_ParseTuple(arg, "Oc", &location, &restype) == 0) return;
00185 char *ptr = (char*)PyLong_AsVoidPtr(location);
00186 PyObject *result = getResultFromType(restype, ptr);
00187 pythonReturn(handle, result);
00188 }
00189
00190 void CpdPythonGroup::getMessage(int handle) {
00191 void *msg = CpdGetCurrentMsg();
00192 if (msg != NULL) pythonReturn(handle, PyLong_FromVoidPtr(msg));
00193 }
00194
00195 void CpdPythonGroup::cpdCheck(void *m) {
00196 CkCcsRequestMsg *msg = (CkCcsRequestMsg *)m;
00197
00198 PythonExecute *pyMsg = (PythonExecute *)msg->data;
00199 CmiUInt4 pyReference = prepareInterpreter(pyMsg);
00200 if (pyReference == 0) {
00201 CkPrintf("[%d] CpdPythonGroup::cpdCheck error while preparing interpreter\n",CkMyPe());
00202 }
00203 pyWorkers[pyReference].inUse = true;
00204 CmiReference(UsrToEnv(msg));
00205 CthResume(CthCreate((CthVoidFn)_callthr_executeThread, new CkThrCallArg(msg,(PythonObject*)this), 0));
00206 if (resultNotNone) CpdFreeze();
00207 }
00208
00209 void CpdPythonGroup::registerPersistent(CkCcsRequestMsg *msg) {
00210 PythonAbstract *pyAbstract = (PythonAbstract *)msg->data;
00211 pyAbstract->unpack();
00212 if (! pyAbstract->isExecute()) return;
00213 PythonExecute *pyMsg = (PythonExecute *)pyAbstract;
00214 pyMsg->unpack();
00215 CmiUInt4 pyReference = prepareInterpreter(pyMsg);
00216 PyEval_ReleaseLock();
00217 replyIntFn(this, &msg->reply, &pyReference);
00218 if (pyReference == 0) return;
00219 pyMsg->setInterpreter(pyReference);
00220 PythonIterator *iter = pyMsg->info.info;
00221 int n = ntohl(((int*)iter)[1]);
00222 DebugPersistentCheck dpc(this, msg);
00223 for (int i=0; i<n; ++i) {
00224 int ep = ntohl(((int*)iter)[i+2]);
00225 CkPrintf("registering method for EP %d\n",ep);
00226 if (ep > 0) CkpvAccess(_debugEntryTable)[ep].postProcess.push_back(dpc);
00227 else CkpvAccess(_debugEntryTable)[-ep].preProcess.push_back(dpc);
00228 }
00229 CkPrintf("[%d] Registering Persistent method (reference=%d)\n",CkMyPe(),pyReference);
00230 }
00231
00232 #include "charmdebug_python.def.h"