summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/modules
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-07-16 06:48:11 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2012-07-16 06:48:11 +0000
commit574ccee478b9da9457cdf0e476b8df6eb584b580 (patch)
tree5a8166f47057ed322294db7816e2732d1d18f7bc /sca-cpp/trunk/modules
parent419f903ff44a22debba43976baae1e86c1e5d871 (diff)
Minor memory management, performance, and tracing improvements.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1361917 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp/trunk/modules')
-rw-r--r--sca-cpp/trunk/modules/atom/atom-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/js/eval.hpp15
-rw-r--r--sca-cpp/trunk/modules/js/js-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/json/json-test.cpp38
-rw-r--r--sca-cpp/trunk/modules/python/eval.hpp75
-rw-r--r--sca-cpp/trunk/modules/python/python-test.cpp37
-rw-r--r--sca-cpp/trunk/modules/rss/rss-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/scdl/scdl-test.cpp1
-rw-r--r--sca-cpp/trunk/modules/scheme/scheme-test.cpp1
9 files changed, 138 insertions, 32 deletions
diff --git a/sca-cpp/trunk/modules/atom/atom-test.cpp b/sca-cpp/trunk/modules/atom/atom-test.cpp
index e00c75a62f..479ed64f29 100644
--- a/sca-cpp/trunk/modules/atom/atom-test.cpp
+++ b/sca-cpp/trunk/modules/atom/atom-test.cpp
@@ -273,6 +273,7 @@ bool testFeed() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::atom::testEntry();
diff --git a/sca-cpp/trunk/modules/js/eval.hpp b/sca-cpp/trunk/modules/js/eval.hpp
index 21fa274d2c..f8f4cbe598 100644
--- a/sca-cpp/trunk/modules/js/eval.hpp
+++ b/sca-cpp/trunk/modules/js/eval.hpp
@@ -65,7 +65,7 @@ public:
JSRuntime() {
// Create JS runtime
debug("js::jsruntime");
- rt = JS_NewRuntime(32L * 1024L * 1024L);
+ rt = JS_NewRuntime(1L * 512L * 1024L);
if(rt == NULL)
cleanup();
}
@@ -114,14 +114,19 @@ public:
debug("js::jscontext");
if (jsContext != NULL) {
cx = jsContext;
+ JS_BeginRequest(cx);
return;
}
+ debug("js::jsnewcontext");
cx = JS_NewContext(jsRuntime, 8192);
if(cx == NULL)
return;
+ JS_BeginRequest(cx);
+
JS_SetOptions(cx, JSOPTION_VAROBJFIX | JSOPTION_JIT | JSOPTION_METHODJIT);
JS_SetVersion(cx, JSVERSION_LATEST);
JS_SetErrorReporter(cx, reportError);
+ //JS_SetGCZeal(cx, 2);
// Create global JS object
global = JS_NewCompartmentAndGlobalObject(cx, &jsGlobalClass, NULL);
@@ -140,8 +145,6 @@ public:
~JSContext() {
debug("js::~jscontext");
- if (cx != NULL)
- JS_MaybeGC(cx);
cleanup();
}
@@ -156,8 +159,12 @@ public:
private:
bool cleanup() {
if(cx != NULL) {
- if (cx != jsContext)
+ JS_MaybeGC(cx);
+ JS_EndRequest(cx);
+ if (cx != jsContext) {
+ debug("js::jsdestroycontext");
JS_DestroyContext(cx);
+ }
cx = NULL;
}
return true;
diff --git a/sca-cpp/trunk/modules/js/js-test.cpp b/sca-cpp/trunk/modules/js/js-test.cpp
index 9cbf000ac3..a7e5597610 100644
--- a/sca-cpp/trunk/modules/js/js-test.cpp
+++ b/sca-cpp/trunk/modules/js/js-test.cpp
@@ -42,6 +42,7 @@ bool testJSEval() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::js::testJSEval();
diff --git a/sca-cpp/trunk/modules/json/json-test.cpp b/sca-cpp/trunk/modules/json/json-test.cpp
index 61aac4ee02..945b6c072c 100644
--- a/sca-cpp/trunk/modules/json/json-test.cpp
+++ b/sca-cpp/trunk/modules/json/json-test.cpp
@@ -27,6 +27,7 @@
#include "stream.hpp"
#include "string.hpp"
#include "json.hpp"
+#include "perf.hpp"
namespace tuscany {
namespace json {
@@ -74,6 +75,7 @@ const string jsarray("{\n"
"}");
bool testJSON() {
+ gc_scoped_pool pool;
const js::JSContext cx;
{
@@ -217,6 +219,7 @@ const string jsechores("{\n"
"}");
bool testJSONRPC() {
+ gc_scoped_pool pool;
js::JSContext cx;
{
const string lm("{\"id\": 1, \"method\": \"test\", \"params\": []}");
@@ -283,14 +286,49 @@ bool testJSONRPC() {
return true;
}
+struct testReadWrite {
+ testReadWrite() {
+ }
+ const bool operator()() const {
+ gc_scoped_pool pool;
+ js::JSContext cx;
+
+ const list<value> ad = mklist<value>(mklist<value>(attribute, "city", string("san francisco")), mklist<value>(attribute, "state", string("ca")));
+ const list<value> ac = mklist<value>(mklist<value>(element, "id", string("1234")), mklist<value>(attribute, "balance", 1000));
+ const list<value> cr = mklist<value>(mklist<value> (attribute, "name", string("jdoe")), cons<value>(element, cons<value>("address", ad)), cons<value>(element, cons<value>("account", ac)));
+ const list<value> c = mklist<value>(cons<value>(element, cons<value>("customer", cr)));
+
+ ostringstream os;
+ writeJSON<ostream*>(jsonWriter, &os, c, cx);
+ assert(str(os) == jscustomer);
+
+ istringstream is(jscustomer);
+ const list<string> il = streamList(is);
+ const list<value> r = content(readJSON(il, cx));
+ assert(r == c);
+ return true;
+ }
+};
+
+bool testJSONPerf() {
+ gc_scoped_pool pool;
+
+ const lambda<bool()> rwl = lambda<bool()>(testReadWrite());
+ cout << "JSON read + write test " << time(rwl, 5, 200) << " ms" << endl;
+
+ return true;
+}
+
}
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::json::testJSON();
tuscany::json::testJSONRPC();
+ tuscany::json::testJSONPerf();
tuscany::cout << "OK" << tuscany::endl;
diff --git a/sca-cpp/trunk/modules/python/eval.hpp b/sca-cpp/trunk/modules/python/eval.hpp
index da5d226789..5c0be7d261 100644
--- a/sca-cpp/trunk/modules/python/eval.hpp
+++ b/sca-cpp/trunk/modules/python/eval.hpp
@@ -26,6 +26,8 @@
* Python script evaluation logic.
*/
#if PYTHON_VERSION == 27
+#undef _POSIX_C_SOURCE
+#undef _XOPEN_SOURCE
#include <python2.7/Python.h>
#include <python2.7/frameobject.h>
#include <python2.7/traceback.h>
@@ -71,15 +73,12 @@ public:
PythonRuntime() {
debug("python::pythonruntime");
+ // Save current process id
#ifdef WANT_THREADS
pthread_mutex_init(&mutex, NULL);
-
-#ifdef IS_DARWIN
- // Save current process id
pthread_mutex_init(&pidmutex, NULL);
- pid = processId();
-#endif
#endif
+ pid = processId();
// Initialize the Python interpreter
#ifdef IS_DARWIN
@@ -134,11 +133,9 @@ public:
private:
#ifdef WANT_THREADS
pthread_mutex_t mutex;
-#ifdef IS_DARWIN
pthread_mutex_t pidmutex;
- unsigned long pid;
-#endif
#endif
+ unsigned long pid;
friend class PythonThreadIn;
friend class PythonThreadOut;
@@ -177,8 +174,8 @@ const string lastError(PythonRuntime* py) {
PyObject* trace = NULL;
PyErr_Fetch(&type, &val, &trace);
if (type != NULL && val != NULL) {
- PyObject* stype = PyObject_Str(type);
- PyObject* sval = PyObject_Str(val);
+ PyObject* stype = PyObject_Repr(type);
+ PyObject* sval = PyObject_Repr(val);
string msg = string() + PyString_AsString(stype) + " : " + PyString_AsString(sval) + lastErrorTrace(trace);
pyDecRef(stype, py);
pyDecRef(sval, py);
@@ -220,11 +217,10 @@ private:
class PythonThreadIn {
public:
PythonThreadIn(PythonRuntime* py) : py(py) {
-#ifdef WANT_THREADS
-#ifdef IS_DARWIN
// Reinitialize Python thread support after a fork
const unsigned long pid = processId();
+#ifdef WANT_THREADS
if (pid != py->pid) {
pthread_mutex_lock(&py->pidmutex);
if (pid != py->pid) {
@@ -236,16 +232,26 @@ public:
}
pthread_mutex_unlock(&py->pidmutex);
}
-#endif
// Acquire the Python GIL
//debug("python::gil::ensure");
gstate = PyGILState_Ensure();
//debug("python::gil::ensured");
+#else
+ if (pid != py->pid) {
+ debug("python::afterfork");
+ PyOS_AfterFork();
+ debug("python::afterforked");
+ py->pid = pid;
+ }
#endif
}
~PythonThreadIn() {
+ // Run Python cyclic reference garbage collector
+ //const size_t c = PyGC_Collect();
+ //debug(c, "python::gc::collect::c");
+
#ifdef WANT_THREADS
// Release the Python GIL
//debug("python::gil::release");
@@ -520,7 +526,6 @@ PyObject* valueToPyObject(const value& v, PythonRuntime* py) {
/**
* Convert a python tuple to a list of values.
*/
-
const list<value> pyTupleToValuesHelper(PyObject* o, const size_t i, const size_t size, PythonRuntime* py) {
if (i == size)
return list<value>();
@@ -546,6 +551,15 @@ struct pyCallable {
pyCallable(const pyCallable& c) : func(c.func), py(c.py), owner(false) {
}
+ const pyCallable& operator=(const pyCallable& c) {
+ if(this == &c)
+ return *this;
+ func = c.func;
+ py = c.py;
+ owner = false;
+ return *this;
+ }
+
~pyCallable() {
if (!owner)
return;
@@ -554,8 +568,7 @@ struct pyCallable {
const value operator()(const list<value>& args) const {
PythonThreadIn pyin(py);
- {
- // Temp
+ if (debug_islogging()) {
PyObject* rfunc = PyObject_Repr(func);
char* s = NULL;
Py_ssize_t l = 0;
@@ -564,8 +577,7 @@ struct pyCallable {
pyDecRef(rfunc, py);
}
PyObject* pyargs = valuesToPyTuple(args, py);
- {
- // Temp
+ if (debug_islogging()) {
PyObject* rargs = PyObject_Repr(pyargs);
char* s = NULL;
Py_ssize_t l = 0;
@@ -573,9 +585,11 @@ struct pyCallable {
debug(string(s, l), "python::operator()::args");
pyDecRef(rargs, py);
}
+
PyObject* result = PyObject_CallObject(func, pyargs);
- const value v = pyObjectToValue(result, py);
pyDecRef(pyargs, py);
+
+ const value v = pyObjectToValue(result, py);
pyDecRef(result, py);
return v;
}
@@ -605,6 +619,8 @@ const value pyObjectToValue(PyObject *o, PythonRuntime* py) {
return value((double)PyFloat_AsDouble(o));
if (PyTuple_Check(o))
return pyTupleToValues(o, py);
+ if (PyObject_TypeCheck(o, &pyLambda_type))
+ return *(((pyLambda*)o)->func);
if (PyCallable_Check(o))
return lambda<value(const list<value>&)>(pyCallable(o, py));
return value();
@@ -646,10 +662,14 @@ const failable<value> evalScript(const value& expr, PyObject* script, PythonRunt
// Call the function
PyObject* result = PyObject_CallObject(func, args);
+ if (result == NULL) {
+ const string msg = lastError(&py);
+ pyDecRef(func, &py);
+ pyDecRef(args, &py);
+ return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + msg);
+ }
pyDecRef(func, &py);
pyDecRef(args, &py);
- if (result == NULL)
- return mkfailure<value>(string("Function call failed: ") + car<value>(expr) + " : " + lastError(&py));
// Convert python result to a value
const value v = pyObjectToValue(result, &py);
@@ -680,10 +700,19 @@ const failable<PyObject*> readScript(const string& name, const string& path, ist
return mkfailure<PyObject*>(string("Couldn't compile script: ") + path + " : " + lastError(&py));
PyObject* mod = PyImport_ExecCodeModuleEx(const_cast<char*>(c_str(name)), code, const_cast<char*>(c_str(path)));
if (mod == NULL) {
+ const string msg = lastError(&py);
pyDecRef(code, &py);
- return mkfailure<PyObject*>(string("Couldn't import module: ") + path + " : " + lastError(&py));
+ return mkfailure<PyObject*>(string("Couldn't import module: ") + path + " : " + msg);
}
- return mod;
+ pyDecRef(code, &py);
+ pyDecRef(mod, &py);
+
+ // Lookup the loaded module
+ PyObject *lmod = PyDict_GetItemString(mods, const_cast<char*>(c_str(name)));
+ if (lmod != NULL)
+ return lmod;
+
+ return mkfailure<PyObject*>(string("Couldn't lookup module: ") + path);
}
/**
diff --git a/sca-cpp/trunk/modules/python/python-test.cpp b/sca-cpp/trunk/modules/python/python-test.cpp
index bc275f27c7..29a66cc2e7 100644
--- a/sca-cpp/trunk/modules/python/python-test.cpp
+++ b/sca-cpp/trunk/modules/python/python-test.cpp
@@ -42,7 +42,7 @@ bool testEvalExpr() {
PythonRuntime py;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script1", "script1.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -54,6 +54,29 @@ bool testEvalExpr() {
return true;
}
+const string testPythonMap =
+ "def addmap(x, y):\n"
+ " return tuple(map(lambda i: i + y, x))\n";
+
+bool testEvalList() {
+ gc_scoped_pool pool;
+ PythonRuntime py;
+
+ istringstream is(testPythonMap);
+ failable<PyObject*> script = readScript("script2", "script2.py", is, py);
+ assert(hasContent(script));
+
+ const value exp = mklist<value>("addmap", mklist<value>(1, 2, 3), 1);
+ const failable<value> r = evalScript(exp, content(script), py);
+ assert(hasContent(r));
+ assert(car<value>(content(r)) == value(2));
+ assert(cadr<value>(content(r)) == value(3));
+ assert(caddr<value>(content(r)) == value(4));
+
+ releaseScript(content(script), py);
+ return true;
+}
+
const value mult(const list<value>& args) {
const double x = car(args);
const double y = cadr(args);
@@ -104,7 +127,7 @@ struct testEvalReadAdd {
}
const bool operator()() const {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script3", "script3.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -139,7 +162,7 @@ bool testEvalPerf() {
cout << "Python read + eval test " << time(erl, 5, 10000) << " ms" << endl;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script4", "script4.py", is, py);
assert(hasContent(script));
const lambda<bool()> el = lambda<bool()>(testEvalAdd(content(script), py));
@@ -158,7 +181,7 @@ struct testReadEvalAddLoop {
const bool operator()() const {
for (int i = 0; i < 100; i++) {
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script6", "script6.py", is, py);
assert(hasContent(script));
const value exp = mklist<value>("add", 2, 3);
@@ -247,7 +270,7 @@ bool testThreads() {
cout << "Python eval + read thread test " << time(elr, 1, 1) / 10000.0 << " ms" << endl;
istringstream is(testPythonAdd);
- failable<PyObject*> script = readScript("script", "script.py", is, py);
+ failable<PyObject*> script = readScript("script7", "script7.py", is, py);
assert(hasContent(script));
const lambda<bool()> el = lambda<bool()>(testEvalThreads(w, max, content(script), py));
@@ -263,9 +286,13 @@ bool testThreads() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::python::testEvalExpr();
+ tuscany::python::testEvalList();
+ tuscany::python::testEvalLambda();
+ tuscany::python::testEvalLambda();
tuscany::python::testEvalLambda();
tuscany::python::testEvalPerf();
#ifdef WANT_THREADS
diff --git a/sca-cpp/trunk/modules/rss/rss-test.cpp b/sca-cpp/trunk/modules/rss/rss-test.cpp
index b30792bfe1..be1dcac574 100644
--- a/sca-cpp/trunk/modules/rss/rss-test.cpp
+++ b/sca-cpp/trunk/modules/rss/rss-test.cpp
@@ -240,6 +240,7 @@ bool testFeed() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::rss::testEntry();
diff --git a/sca-cpp/trunk/modules/scdl/scdl-test.cpp b/sca-cpp/trunk/modules/scdl/scdl-test.cpp
index 94baf930a9..4c10f515df 100644
--- a/sca-cpp/trunk/modules/scdl/scdl-test.cpp
+++ b/sca-cpp/trunk/modules/scdl/scdl-test.cpp
@@ -110,6 +110,7 @@ bool testProperties() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::scdl::testComposite();
diff --git a/sca-cpp/trunk/modules/scheme/scheme-test.cpp b/sca-cpp/trunk/modules/scheme/scheme-test.cpp
index dd97bc358d..5b69b8e588 100644
--- a/sca-cpp/trunk/modules/scheme/scheme-test.cpp
+++ b/sca-cpp/trunk/modules/scheme/scheme-test.cpp
@@ -225,6 +225,7 @@ bool testEvalGC() {
}
int main() {
+ tuscany::gc_scoped_pool p;
tuscany::cout << "Testing..." << tuscany::endl;
tuscany::scheme::testEnv();