summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/kernel
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--sca-cpp/trunk/kernel/cache.hpp46
-rw-r--r--sca-cpp/trunk/kernel/debug.hpp68
-rw-r--r--sca-cpp/trunk/kernel/dynlib-test.cpp3
-rw-r--r--sca-cpp/trunk/kernel/function.hpp43
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp30
-rw-r--r--sca-cpp/trunk/kernel/kernel-test.cpp14
-rw-r--r--sca-cpp/trunk/kernel/list.hpp51
-rw-r--r--sca-cpp/trunk/kernel/monad.hpp3
-rw-r--r--sca-cpp/trunk/kernel/parallel.hpp5
-rw-r--r--sca-cpp/trunk/kernel/value.hpp141
10 files changed, 311 insertions, 93 deletions
diff --git a/sca-cpp/trunk/kernel/cache.hpp b/sca-cpp/trunk/kernel/cache.hpp
index 28ab38c76f..4cab4e4e9b 100644
--- a/sca-cpp/trunk/kernel/cache.hpp
+++ b/sca-cpp/trunk/kernel/cache.hpp
@@ -26,6 +26,9 @@
* Simple local cache monad implementation.
*/
+#ifdef _REENTRANT
+#include <pthread.h>
+#endif
#include <sys/stat.h>
#include <string>
@@ -40,25 +43,37 @@ namespace tuscany {
*/
template<typename V> class cached {
public:
- cached() : mtime(0) {
+ cached() : mutex(mutex_init()), mtime(0) {
}
- cached(const lambda<V()>& lvalue, const lambda<unsigned long()> ltime) : lvalue(lvalue), ltime(ltime), mtime(0) {
+ cached(const lambda<V()>& lvalue, const lambda<unsigned long()> ltime) : mutex(mutex_init()), lvalue(lvalue), ltime(ltime), mtime(0) {
}
- cached(const lambda<V()>& lvalue, const lambda<unsigned long()> ltime, const unsigned long mtime, const V& v) : lvalue(lvalue), ltime(ltime), mtime(mtime), v(v) {
+ cached(const lambda<V()>& lvalue, const lambda<unsigned long()> ltime, const unsigned long mtime, const V& v) : mutex(mutex_init()), lvalue(lvalue), ltime(ltime), mtime(mtime), v(v) {
}
- cached(const cached<V>& c) : lvalue(c.lvalue), ltime(c.ltime), mtime(c.mtime), v(c.v) {
+ cached(const cached<V>& c) : mutex(mutex_init()), lvalue(c.lvalue), ltime(c.ltime), mtime(c.mtime), v(c.v) {
+ }
+
+ ~cached() {
+#ifdef _REENTRANT
+ pthread_mutex_destroy(mutex);
+#endif
}
const cached<V>& operator=(const cached<V>& c) {
if(this == &c)
return *this;
+#ifdef _REENTRANT
+ pthread_mutex_lock(mutex);
+#endif
this->lvalue = c.lvalue;
this->ltime = c.ltime;
this->mtime = c.mtime;
this->v = c.v;
+#ifdef _REENTRANT
+ pthread_mutex_unlock(mutex);
+#endif
return *this;
}
@@ -69,10 +84,31 @@ public:
const bool operator==(const cached<V>& m) const {
if (this == &m)
return true;
- return mtime == m.mtime && v == m.v;
+#ifdef _REENTRANT
+ pthread_mutex_lock(mutex);
+#endif
+ const bool r = mtime == m.mtime && v == m.v;
+#ifdef _REENTRANT
+ pthread_mutex_unlock(mutex);
+#endif
+ return r;
}
private:
+#ifdef _REENTRANT
+ pthread_mutex_t* mutex;
+ pthread_mutex_t* mutex_init() {
+ pthread_mutex_t* mx = new pthread_mutex_t();
+ pthread_mutex_init(mx, NULL);
+ return mx;
+ }
+#else
+ void* mutex;
+ void* mutex_init() {
+ return NULL;
+ }
+#endif
+
lambda<V()> lvalue;
lambda<time_t()> ltime;
unsigned long mtime;
diff --git a/sca-cpp/trunk/kernel/debug.hpp b/sca-cpp/trunk/kernel/debug.hpp
new file mode 100644
index 0000000000..8dad5fdd3c
--- /dev/null
+++ b/sca-cpp/trunk/kernel/debug.hpp
@@ -0,0 +1,68 @@
+/*
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements. See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership. The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
+ * KIND, either express or implied. See the License for the
+ * specific language governing permissions and limitations
+ * under the License.
+ */
+
+/* $Rev$ $Date$ */
+
+#ifndef tuscany_debug_hpp
+#define tuscany_debug_hpp
+
+/**
+ * Functions to help log and debug.
+ */
+
+namespace tuscany
+{
+
+#ifdef _DEBUG
+
+/**
+ * Debug log.
+ */
+template<typename V> const bool debug(const V& v, const std::string& msg) {
+ std::cerr<< msg << ": " << v << std::endl;
+ return true;
+}
+
+/**
+ * Increment / decrement a debug counter.
+ */
+bool debug_inc(long int& c) {
+ c++;
+ return true;
+}
+
+bool debug_dec(long int& c) {
+ c--;
+ return true;
+}
+
+#define unused __attribute__ ((unused))
+
+#else
+
+#define debug(v, msg)
+
+#define debug_inc(c)
+#define debug_dec(c)
+#define unused
+
+#endif
+
+}
+#endif /* tuscany_debug_hpp */
diff --git a/sca-cpp/trunk/kernel/dynlib-test.cpp b/sca-cpp/trunk/kernel/dynlib-test.cpp
index 0123b5ec79..3cc666df1a 100644
--- a/sca-cpp/trunk/kernel/dynlib-test.cpp
+++ b/sca-cpp/trunk/kernel/dynlib-test.cpp
@@ -24,6 +24,7 @@
*/
#include "function.hpp"
+#include "debug.hpp"
namespace tuscany {
namespace test {
@@ -41,7 +42,7 @@ extern "C" {
return tuscany::test::cppsquare(x);
}
- const tuscany::lambda<int(int)> csquarel(const int x) {
+ const tuscany::lambda<int(int)> csquarel() {
return tuscany::lambda<int(int)>(tuscany::test::cppsquare);
}
diff --git a/sca-cpp/trunk/kernel/function.hpp b/sca-cpp/trunk/kernel/function.hpp
index c99ee5dbad..fb2ad296d7 100644
--- a/sca-cpp/trunk/kernel/function.hpp
+++ b/sca-cpp/trunk/kernel/function.hpp
@@ -28,9 +28,12 @@
#include <iostream>
#include "gc.hpp"
+#include "debug.hpp"
namespace tuscany {
+#ifdef _DEBUG
+
/**
* Debug counters.
*/
@@ -47,6 +50,10 @@ bool resetLambdaCounters() {
return true;
}
+bool checkLambdaCounters() {
+ return countLambdas == 0;
+}
+
bool printLambdaCounters() {
std::cout << "countLambdas " << countLambdas << std::endl;
std::cout << "countELambdas " << countELambdas << std::endl;
@@ -58,6 +65,14 @@ bool printLambdaCounters() {
return true;
}
+#else
+
+#define resetLambdaCounters()
+#define checkLambdaCounters() true
+#define printLambdaCounters()
+
+#endif
+
/**
* Lambda function type.
*/
@@ -77,17 +92,17 @@ public:
template<typename F> class Proxy: public Callable {
public:
Proxy(const F& f) : function(f) {
- countProxies++;
- countFProxies ++;
+ debug_inc(countProxies);
+ debug_inc(countFProxies);
}
Proxy(const Proxy& p) : function(p.function) {
- countProxies++;
- countCProxies ++;
+ debug_inc(countProxies);
+ debug_inc(countCProxies);
}
~Proxy() {
- countProxies--;
+ debug_dec(countProxies);
}
virtual const R operator() (P... p) const {
@@ -108,11 +123,11 @@ private:
unsigned int refCount;
unsigned int acquire() {
- return __sync_add_and_fetch(&refCount, 1);
+ return gc_add_and_fetch(refCount, (unsigned int)1);
}
unsigned int release() {
- return __sync_sub_and_fetch(&refCount, 1);
+ return gc_sub_and_fetch(refCount, (unsigned int)1);
}
};
@@ -121,21 +136,21 @@ template<typename S> class lambda;
template<typename R, typename... P> class lambda<R(P...)> {
public:
lambda() : callable(0) {
- countLambdas++;
- countELambdas++;
+ debug_inc(countLambdas);
+ debug_inc(countELambdas);
}
template<typename F> lambda(const F f) : callable(0) {
typedef typename CallableType::template Proxy<F> ProxyType;
- countLambdas++;
- countFLambdas++;
+ debug_inc(countLambdas);
+ debug_inc(countFLambdas);
callable = gc_counting_ptr<CallableType>(new ProxyType(f));
}
lambda(const lambda& l) {
- countLambdas++;
- countCLambdas++;
+ debug_inc(countLambdas);
+ debug_inc(countCLambdas);
callable = l.callable;
}
@@ -147,7 +162,7 @@ public:
}
~lambda() {
- countLambdas--;
+ debug_dec(countLambdas);
}
const bool operator==(const lambda& l) const {
diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp
index 7739e714c2..bb5bbccb24 100644
--- a/sca-cpp/trunk/kernel/gc.hpp
+++ b/sca-cpp/trunk/kernel/gc.hpp
@@ -33,6 +33,24 @@
namespace tuscany
{
+/**
+ * Macros used to add or subtract values to reference counters.
+ * In a multithreaded environment, define MTHREAD_GC to use
+ * the GCC __sync_add_and_fetch and __sync_sub_and_fetch built
+ * in functions.
+ */
+#ifdef MTHREAD_GC
+
+#define gc_add_and_fetch(t, v) __sync_add_and_fetch(&(t), v)
+#define gc_sub_and_fetch(t, v) __sync_sub_and_fetch(&(t), v)
+
+#else
+
+#define gc_add_and_fetch(t, v) ((t) = (t) + (v))
+#define gc_sub_and_fetch(t, v) ((t) = (t) - (v))
+
+#endif
+
template<typename T> class gc_ptr {
public:
gc_ptr(T* p = 0) throw() : countingRef(p == 0? 0 : new CountingRef(p)) {
@@ -95,12 +113,12 @@ private:
void acquire(CountingRef* ref) throw() {
if(ref)
- __sync_add_and_fetch(&ref->count, 1);
+ gc_add_and_fetch(ref->count, (unsigned int)1);
}
void release() throw() {
if(countingRef) {
- unsigned rc = __sync_sub_and_fetch(&countingRef->count, 1);
+ unsigned rc = gc_sub_and_fetch(countingRef->count, (unsigned int)1);
if(rc == 0) {
delete countingRef->ptr;
delete countingRef;
@@ -178,12 +196,12 @@ private:
void acquire(CountingRef* ref) throw() {
if(ref)
- __sync_add_and_fetch(&ref->count, 1);
+ gc_add_and_fetch(ref->count, (unsigned int)1);
}
void release() throw() {
if(countingRef) {
- unsigned rc = __sync_sub_and_fetch(&countingRef->count, 1);
+ unsigned rc = gc_sub_and_fetch(countingRef->count, (unsigned int)1);
if(rc == 0) {
delete[] countingRef->ptr;
delete countingRef;
@@ -311,11 +329,11 @@ private:
}
unsigned int acquire() {
- return __sync_add_and_fetch(&refCount, 1);
+ return gc_add_and_fetch(refCount, (unsigned int)1);
}
unsigned int release() {
- return __sync_sub_and_fetch(&refCount, 1);
+ return gc_sub_and_fetch(refCount, (unsigned int)1);
}
};
diff --git a/sca-cpp/trunk/kernel/kernel-test.cpp b/sca-cpp/trunk/kernel/kernel-test.cpp
index 24d67e1a9a..388fbf7436 100644
--- a/sca-cpp/trunk/kernel/kernel-test.cpp
+++ b/sca-cpp/trunk/kernel/kernel-test.cpp
@@ -81,7 +81,7 @@ bool testLambda() {
bool testLambdaGC() {
resetLambdaCounters();
testLambda();
- assert(countLambdas == 0);
+ assert(checkLambdaCounters());
return true;
}
@@ -140,8 +140,8 @@ bool testListGC() {
countElements = 0;
testCons();
testSet();
- assert(countLambdas == 0);
- assert(countlists == 0);
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
assert(countElements == 0);
return true;
}
@@ -296,7 +296,7 @@ double testSeqMap(double x) {
return x;
}
-double testSeqReduce(double v, double accum) {
+double testSeqReduce(unused double v, double accum) {
return accum + 1.0;
}
@@ -351,9 +351,9 @@ bool testValueGC() {
resetListCounters();
resetValueCounters();
testValue();
- assert(countValues == 0);
- assert(countLambdas == 0);
- assert(countlists == 0);
+ assert(checkValueCounters());
+ assert(checkLambdaCounters());
+ assert(checkListCounters());
return true;
}
diff --git a/sca-cpp/trunk/kernel/list.hpp b/sca-cpp/trunk/kernel/list.hpp
index c21efe173b..da00a5a40d 100644
--- a/sca-cpp/trunk/kernel/list.hpp
+++ b/sca-cpp/trunk/kernel/list.hpp
@@ -28,27 +28,46 @@
#include <iostream>
#include "function.hpp"
+#include "debug.hpp"
namespace tuscany {
-long countlists = 0;
-long countIlists = 0;
-long countClists = 0;
-long countElists = 0;
+#ifdef _DEBUG
+
+/**
+ * Debug counters.
+ */
+long countLists = 0;
+long countILists = 0;
+long countCLists = 0;
+long countELists = 0;
bool resetListCounters() {
- countlists = countIlists = countClists = countElists = 0;
+ countLists = countILists = countCLists = countELists = 0;
return true;
}
+bool checkListCounters() {
+ return countLists == 0;
+}
+
bool printListCounters() {
- std::cout << "countlists " << countlists << std::endl;
- std::cout << "countElists " << countElists << std::endl;
- std::cout << "countIlists " << countIlists << std::endl;
- std::cout << "countClists " << countClists << std::endl;
+ std::cout << "countLists " << countLists << std::endl;
+ std::cout << "countELists " << countELists << std::endl;
+ std::cout << "countILists " << countILists << std::endl;
+ std::cout << "countCLists " << countCLists << std::endl;
return true;
}
+#else
+
+#define resetListCounters()
+#define checkListCounters() true
+#define printListCounters()
+
+#endif
+
+
/**
* A car/cdr lisp-like pair, base structure to construct lists.
*/
@@ -57,20 +76,20 @@ template<typename T> class list {
public:
list() {
- countlists++;
- countElists++;
+ debug_inc(countLists);
+ debug_inc(countELists);
}
list(const T car, const lambda<list<T> ()>& cdr) :
car(car), cdr(cdr) {
- countlists++;
- countIlists++;
+ debug_inc(countLists);
+ debug_inc(countILists);
}
list(const list& p) :
car(p.car), cdr(p.cdr) {
- countlists++;
- countClists++;
+ debug_inc(countLists);
+ debug_inc(countCLists);
}
const list& operator=(const list<T>& p) {
@@ -82,7 +101,7 @@ public:
}
~list() {
- countlists--;
+ debug_dec(countLists);
}
const bool operator==(const list<T>& p) const {
diff --git a/sca-cpp/trunk/kernel/monad.hpp b/sca-cpp/trunk/kernel/monad.hpp
index 1a45640c32..31eb390f1c 100644
--- a/sca-cpp/trunk/kernel/monad.hpp
+++ b/sca-cpp/trunk/kernel/monad.hpp
@@ -28,7 +28,9 @@
#include <string>
#include <iostream>
+
#include "function.hpp"
+#include "debug.hpp"
namespace tuscany
{
@@ -280,6 +282,7 @@ template<typename V, typename F> const lambda<failable<V, F>(V)> success() {
* Returns a failable monad with a failure in it.
*/
template<typename V, typename F> const failable<V, F> mkfailure(const F& f) {
+ debug(f, "failable::mkfailure");
return failable<V, F>(false, f);
}
diff --git a/sca-cpp/trunk/kernel/parallel.hpp b/sca-cpp/trunk/kernel/parallel.hpp
index c2a948bbeb..987d662e23 100644
--- a/sca-cpp/trunk/kernel/parallel.hpp
+++ b/sca-cpp/trunk/kernel/parallel.hpp
@@ -28,6 +28,7 @@
#include <pthread.h>
#include <sys/syscall.h>
+
#include "function.hpp"
namespace tuscany {
@@ -59,11 +60,11 @@ private:
}
unsigned int acquire() {
- return __sync_add_and_fetch(&refCount, 1);
+ return __sync_add_and_fetch(&refCount, (unsigned int)1);
}
unsigned int release() {
- return __sync_sub_and_fetch(&refCount, 1);
+ return __sync_sub_and_fetch(&refCount, (unsigned int)1);
}
bool set(const T& v) {
diff --git a/sca-cpp/trunk/kernel/value.hpp b/sca-cpp/trunk/kernel/value.hpp
index d602b30623..a99309869f 100644
--- a/sca-cpp/trunk/kernel/value.hpp
+++ b/sca-cpp/trunk/kernel/value.hpp
@@ -32,10 +32,16 @@
#include "gc.hpp"
#include "function.hpp"
#include "list.hpp"
+#include "debug.hpp"
namespace tuscany
{
+#ifdef _DEBUG
+
+/**
+ * Debug counters.
+ */
long int countValues = 0;
long int countEValues = 0;
long int countCValues = 0;
@@ -46,6 +52,10 @@ bool resetValueCounters() {
return true;
}
+bool checkValueCounters() {
+ return countValues == 0;
+}
+
bool printValueCounters() {
std::cout << "countValues " << countValues << std::endl;
std::cout << "countEValues " << countEValues << std::endl;
@@ -54,6 +64,14 @@ bool printValueCounters() {
return true;
}
+#else
+
+#define resetValueCounters()
+#define checkValueCounters() true
+#define printValueCounters()
+
+#endif
+
class value;
class value {
@@ -65,13 +83,13 @@ public:
value() :
type(value::Undefined) {
- countValues++;
- countEValues++;
+ debug_inc(countValues);
+ debug_inc(countEValues);
}
value(const value& v) {
- countValues++;
- countCValues++;
+ debug_inc(countValues);
+ debug_inc(countCValues);
type = v.type;
switch(type) {
case value::List:
@@ -127,73 +145,73 @@ public:
}
virtual ~value() {
- countValues--;
+ debug_dec(countValues);
}
value(const lambda<value(list<value>&)>& func) :
type(value::Lambda), data(vdata(func)) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const std::string& str) :
type(value::String), data(vdata(result(str))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const char* str) :
type(value::Symbol), data(vdata(result(std::string(str)))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const list<value>& lst) :
type(value::List), data(vdata(result(lst))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const list<list<value> >& l) :
type(value::List), data(vdata(result(listOfValues(l)))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const double num) :
type(value::Number), data(vdata(result(num))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const int num) :
type(value::Number), data(vdata(result((double)num))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const bool boo) :
type(value::Bool), data(vdata(result(boo))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const char chr) :
type(value::Char), data(vdata(result(chr))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const gc_ptr<value> ptr) :
type(value::Ptr), data(vdata(result(ptr))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
value(const gc_pool_ptr<value> ptr) :
type(value::PoolPtr), data(vdata(result(ptr))) {
- countValues++;
- countVValues++;
+ debug_inc(countValues);
+ debug_inc(countVValues);
}
const bool operator!=(const value& v) const {
@@ -237,11 +255,6 @@ public:
operator const std::string() const {
switch(type) {
- case value::List:
- case value::Lambda:
- case value::Ptr:
- case value::PoolPtr:
- return "";
case value::Symbol:
case value::String:
return str()();
@@ -250,12 +263,8 @@ public:
sos << num()();
return sos.str();
}
- case value::Bool: {
- if(boo()())
- return "true";
- else
- return "false";
- }
+ case value::Bool:
+ return boo()()? "true" : "false";
case value::Char: {
std::ostringstream sos;
sos << chr()();
@@ -267,19 +276,67 @@ public:
}
operator const double() const {
- return num()();
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return atof(str()().c_str());
+ case value::Number:
+ return (double)num()();
+ case value::Bool:
+ return boo()()? 1.0 : 0.0;
+ case value::Char:
+ return (double)chr()();
+ default:
+ return 0.0;
+ }
}
operator const int() const {
- return num()();
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return atoi(str()().c_str());
+ case value::Number:
+ return (int)num()();
+ case value::Bool:
+ return boo()()? 1 : 0;
+ case value::Char:
+ return (int)chr()();
+ default:
+ return 0;
+ }
}
operator const bool() const {
- return boo()();
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return str()() == "true";
+ case value::Number:
+ return (int)num()() != 0;
+ case value::Bool:
+ return boo()();
+ case value::Char:
+ return (int)chr()() != 0;
+ default:
+ return 0;
+ }
}
operator const char() const {
- return chr()();
+ switch(type) {
+ case value::Symbol:
+ case value::String:
+ return 0;
+ case value::Number:
+ return (char)num()();
+ case value::Bool:
+ return (char)boo()();
+ case value::Char:
+ return chr()();
+ default:
+ return 0;
+ }
}
operator const gc_ptr<value>() const {