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 } else {
00071 return 0;
00072 }
00073 } else {
00074 nextElement = 0;
00075 data = PyLong_FromVoidPtr(ptr);
00076
00077 return 1;
00078 }
00079 } else {
00080 nextElement = 0;
00081 data = PyLong_FromVoidPtr(CpdGetCurrentObject());
00082 return 1;
00083 }
00084 }
00085
00086 int CpdPythonGroup::nextIteratorUpdate(PyObject *&data, PyObject *result, void *iter) {
00087
00088 if (result != Py_None) {
00089 PyObject *str = PyObject_Str(result);
00090 CkPrintf("Freezing the application: %s\n",PyString_AsString(str));
00091 Py_DECREF(str);
00092 resultNotNone = true;
00093 return 0;
00094 }
00095 if (nextElement > 0) {
00096 if (nextElement == arriter.elems.size()) {
00097 nextElement = 0;
00098 arriter.elems.removeAll();
00099 return 0;
00100 } else {
00101 data = PyLong_FromVoidPtr(arriter.elems[nextElement++]);
00102 return 1;
00103 }
00104 }
00105
00106
00107
00108 return 0;
00109 }
00110
00111 PyObject *CpdPythonGroup::getResultFromType(char restype, void* ptr) {
00112 PyObject *result = NULL;
00113 switch (restype) {
00114 case 'c':
00115 result = PyLong_FromVoidPtr(ptr);
00116 break;
00117 case 'p':
00118 result = PyLong_FromVoidPtr(*(void**)ptr);
00119 break;
00120 case 'b':
00121 result = Py_BuildValue("b", *(char*)ptr);
00122 break;
00123 case 'h':
00124 result = Py_BuildValue("h", *(short*)ptr);
00125 break;
00126 case 'i':
00127 result = Py_BuildValue("i", *(int*)ptr);
00128 break;
00129 case 'l':
00130 result = Py_BuildValue("l", *(long*)ptr);
00131 break;
00132 case 'f':
00133 result = Py_BuildValue("f", *(float*)ptr);
00134 break;
00135 case 'd':
00136 result = Py_BuildValue("d", *(double*)ptr);
00137 break;
00138 case 's':
00139 result = Py_BuildValue("s", *(char**)ptr);
00140 break;
00141 }
00142 return result;
00143 }
00144
00145 void CpdPythonGroup::getArray(int handle) {
00146 PyObject *arg = pythonGetArg(handle);
00147 PyObject *obj;
00148 int num, size;
00149 char restype;
00150 if (PyArg_ParseTuple(arg, "Oici", &obj, &size, &restype, &num) == 0) return;
00151 char *ptr = (char*)PyLong_AsVoidPtr(obj);
00152 ptr += num * size;
00153 PyObject *result = getResultFromType(restype, ptr);
00154 pythonReturn(handle, result);
00155 }
00156
00157 void CpdPythonGroup::getValue(int handle) {
00158 PyObject *arg = pythonGetArg(handle);
00159 PyObject *obj;
00160 int offset;
00161 char restype;
00162 if (PyArg_ParseTuple(arg, "Oic", &obj, &offset, &restype) == 0) return;
00163 char *ptr = (char*)PyLong_AsVoidPtr(obj);
00164 ptr += offset;
00165 PyObject *result = getResultFromType(restype, ptr);
00166 pythonReturn(handle, result);
00167 }
00168
00169 void CpdPythonGroup::getCast(int handle) {
00170 PyObject *arg = pythonGetArg(handle);
00171 PyObject *obj;
00172 int offset;
00173 if (PyArg_ParseTuple(arg, "Oi", &obj, &offset) == 0) return;
00174 char *ptr = (char*)PyLong_AsVoidPtr(obj);
00175 ptr += offset;
00176 pythonReturn(handle, PyLong_FromVoidPtr(ptr));
00177 }
00178
00179 void CpdPythonGroup::getStatic(int handle) {
00180 PyObject *arg = pythonGetArg(handle);
00181 PyObject *location;
00182 char restype;
00183 if (PyArg_ParseTuple(arg, "Oc", &location, &restype) == 0) return;
00184 char *ptr = (char*)PyLong_AsVoidPtr(location);
00185 PyObject *result = getResultFromType(restype, ptr);
00186 pythonReturn(handle, result);
00187 }
00188
00189 void CpdPythonGroup::getMessage(int handle) {
00190 void *msg = CpdGetCurrentMsg();
00191 if (msg != NULL) pythonReturn(handle, PyLong_FromVoidPtr(msg));
00192 }
00193
00194 void CpdPythonGroup::cpdCheck(void *m) {
00195 CkCcsRequestMsg *msg = (CkCcsRequestMsg *)m;
00196
00197 PythonExecute *pyMsg = (PythonExecute *)msg->data;
00198 CmiUInt4 pyReference = prepareInterpreter(pyMsg);
00199 if (pyReference == 0) {
00200 CkPrintf("[%d] CpdPythonGroup::cpdCheck error while preparing interpreter\n",CkMyPe());
00201 }
00202 pyWorkers[pyReference].inUse = true;
00203 CmiReference(UsrToEnv(msg));
00204 CthResume(CthCreate((CthVoidFn)_callthr_executeThread, new CkThrCallArg(msg,(PythonObject*)this), 0));
00205 if (resultNotNone) CpdFreeze();
00206 }
00207
00208 void CpdPythonGroup::registerPersistent(CkCcsRequestMsg *msg) {
00209 PythonAbstract *pyAbstract = (PythonAbstract *)msg->data;
00210 pyAbstract->unpack();
00211 if (! pyAbstract->isExecute()) return;
00212 PythonExecute *pyMsg = (PythonExecute *)pyAbstract;
00213 pyMsg->unpack();
00214 CmiUInt4 pyReference = prepareInterpreter(pyMsg);
00215 PyEval_ReleaseLock();
00216 replyIntFn(this, &msg->reply, &pyReference);
00217 if (pyReference == 0) return;
00218 pyMsg->setInterpreter(pyReference);
00219 PythonIterator *iter = pyMsg->info.info;
00220 int n = ntohl(((int*)iter)[1]);
00221 DebugPersistentCheck dpc(this, msg);
00222 for (int i=0; i<n; ++i) {
00223 int ep = ntohl(((int*)iter)[i+2]);
00224 CkPrintf("registering method for EP %d\n",ep);
00225 if (ep > 0) CkpvAccess(_debugEntryTable)[ep].postProcess.push_back(dpc);
00226 else CkpvAccess(_debugEntryTable)[-ep].preProcess.push_back(dpc);
00227 }
00228 CkPrintf("[%d] Registering Persistent method (reference=%d)\n",CkMyPe(),pyReference);
00229 }
00230
00231 #include "charmdebug_python.def.h"