summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/kernel
diff options
context:
space:
mode:
authorjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2011-08-28 02:50:02 +0000
committerjsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68>2011-08-28 02:50:02 +0000
commit29edc4e6fb2c8fb3a93aac36d9666efd21b92bd0 (patch)
tree2b1998d904a16cdce69f69041c89cc56d474e69e /sca-cpp/trunk/kernel
parentd93ec216d63aed8ff2f08b4cba7de965dc14639c (diff)
Implement a portable alternative to __thread and get the HTTP and SQLDB components and the Auth modules working with the HTTPD multithreaded event MPM.
git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1162472 13f79535-47bb-0310-9956-ffa450edef68
Diffstat (limited to 'sca-cpp/trunk/kernel')
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp35
-rw-r--r--sca-cpp/trunk/kernel/parallel-test.cpp24
-rw-r--r--sca-cpp/trunk/kernel/parallel.hpp137
-rw-r--r--sca-cpp/trunk/kernel/string-test.cpp2
4 files changed, 189 insertions, 9 deletions
diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp
index 2a8303f638..30cc637388 100644
--- a/sca-cpp/trunk/kernel/gc.hpp
+++ b/sca-cpp/trunk/kernel/gc.hpp
@@ -33,6 +33,9 @@
#include <assert.h>
#include <new>
#include "config.hpp"
+#ifdef WANT_THREADS
+#include <pthread.h>
+#endif
namespace tuscany
{
@@ -81,10 +84,18 @@ public:
return ptr == r.ptr;
}
+ const bool operator==(T* p) const throw() {
+ return ptr == p;
+ }
+
const bool operator!=(const gc_ptr& r) const throw() {
return !this->operator==(r);
}
+ const bool operator!=(T* p) const throw() {
+ return !this->operator==(p);
+ }
+
T& operator*() const throw() {
return *ptr;
}
@@ -168,9 +179,29 @@ public:
* Maintain a stack of memory pools.
*/
#ifdef WANT_THREADS
-__thread
-#endif
+
+class gc_pool_stack_t {
+public:
+ gc_pool_stack_t() {
+ pthread_key_create(&key, NULL);
+ }
+
+ operator apr_pool_t*() const {
+ return static_cast<apr_pool_t*>(pthread_getspecific(key));
+ }
+
+ const gc_pool_stack_t& operator=(apr_pool_t* p) {
+ pthread_setspecific(key, p);
+ return *this;
+ }
+
+private:
+ pthread_key_t key;
+} gc_pool_stack;
+
+#else
apr_pool_t* gc_pool_stack = NULL;
+#endif
/**
* Return the current memory pool.
diff --git a/sca-cpp/trunk/kernel/parallel-test.cpp b/sca-cpp/trunk/kernel/parallel-test.cpp
index ab832f1472..f883d19f69 100644
--- a/sca-cpp/trunk/kernel/parallel-test.cpp
+++ b/sca-cpp/trunk/kernel/parallel-test.cpp
@@ -71,13 +71,18 @@ struct mutexPerf {
}
};
-__thread int tlsi = 0;
+const gc_ptr<int> tlsic() {
+ gc_ptr<int> i = new (gc_new<int>()) int();
+ *i = 0;
+ return i;
+}
+const perthread_ptr<int> tlsi(tlsic);
struct tlsPerf {
tlsPerf() {
}
const bool operator()() const {
- tlsi = tlsi + 1;
+ *tlsi = *tlsi + 1;
return true;
}
};
@@ -105,7 +110,7 @@ bool testAtomicPerf() {
{
const lambda<bool()> l = tlsPerf();
cout << "Thread local inc test " << time(l, 1000, count) << " ms" << endl;
- assert(tlsi == count + 1000);
+ assert(*tlsi == count + 1000);
}
return true;
}
@@ -131,18 +136,23 @@ bool checkSquareResults(const list<future<int> > r, int i) {
return true;
}
-__thread long int tlsv = 0;
+const gc_ptr<long int> tlsvc() {
+ gc_ptr<long int> i = new (gc_new<long int>()) long int();
+ *i = 0l;
+ return i;
+}
+const perthread_ptr<long int> tlsv(tlsvc);
const long int tlsset(gc_ptr<wqueue<bool>> wq, gc_ptr<wqueue<bool>> xq) {
- const long int v = tlsv;
- tlsv = threadId();
+ const long int v = *tlsv;
+ *tlsv = threadId();
enqueue(*xq, true);
dequeue(*wq);
return v;
}
const bool tlscheck(gc_ptr<wqueue<bool>> wq, gc_ptr<wqueue<bool>> xq) {
- const bool r = tlsv == threadId();
+ const bool r = *tlsv == threadId();
enqueue(*xq, true);
dequeue(*wq);
return r;
diff --git a/sca-cpp/trunk/kernel/parallel.hpp b/sca-cpp/trunk/kernel/parallel.hpp
index 9c75b8fb91..648cd60cfc 100644
--- a/sca-cpp/trunk/kernel/parallel.hpp
+++ b/sca-cpp/trunk/kernel/parallel.hpp
@@ -43,7 +43,11 @@ namespace tuscany {
* Returns the current thread id.
*/
long int threadId() {
+#ifdef IS_DARWIN
+ return syscall(SYS_thread_selfid);
+#else
return syscall(SYS_gettid);
+#endif
}
/**
@@ -315,5 +319,138 @@ const bool cancel(worker& w) {
#endif
+/**
+ * Represents a per-thread value.
+ */
+template<typename T> class perthread_ptr {
+public:
+ perthread_ptr() : key(createkey()), owner(true), cl(lambda<gc_ptr<T>()>()), managed(false) {
+ }
+
+ perthread_ptr(const lambda<gc_ptr<T>()>& cl) : key(createkey()), owner(true), cl(cl), managed(true) {
+ }
+
+ ~perthread_ptr() {
+ if (owner)
+ deletekey(key);
+ }
+
+ perthread_ptr(const perthread_ptr& c) : key(c.key), owner(false), cl(c.cl), managed(c.managed) {
+ }
+
+ perthread_ptr& operator=(const perthread_ptr& r) throw() {
+ if(this == &r)
+ return *this;
+ key = r.key;
+ owner = false;
+ cl = r.cl;
+ managed = r.managed;
+ return *this;
+ }
+
+ const perthread_ptr& operator=(const gc_ptr<T>& v) {
+ set(v);
+ return *this;
+ }
+
+ const perthread_ptr& operator=(T* v) {
+ set(v);
+ return *this;
+ }
+
+ const bool operator==(const gc_ptr<T>& r) const throw() {
+ return get() == r;
+ }
+
+ const bool operator==(T* p) const throw() {
+ return get() == p;
+ }
+
+ const bool operator!=(const gc_ptr<T>& r) const throw() {
+ return !this->operator==(r);
+ }
+
+ const bool operator!=(T* p) const throw() {
+ return !this->operator==(p);
+ }
+
+ T& operator*() const throw() {
+ return *get();
+ }
+
+ T* operator->() const throw() {
+ return get();
+ }
+
+ operator gc_ptr<T>() const {
+ return get();
+ }
+
+ operator T*() const {
+ return get();
+ }
+
+private:
+#ifdef WANT_THREADS
+ pthread_key_t createkey() {
+ pthread_key_t k;
+ pthread_key_create(&k, NULL);
+ return k;
+ }
+
+ bool deletekey(pthread_key_t k) {
+ pthread_key_delete(k);
+ return true;
+ }
+
+ bool set(const gc_ptr<T>& v) {
+ pthread_setspecific(key, (T*)v);
+ return true;
+ }
+
+ gc_ptr<T> get() const {
+ const gc_ptr<T> v = static_cast<T*>(pthread_getspecific(key));
+ if (v != NULL || !managed)
+ return v;
+ const gc_ptr<T> nv = cl();
+ pthread_setspecific(key, nv);
+ return nv;
+ }
+
+#else
+ int createkey() {
+ return 0;
+ }
+
+ bool deletekey(unused int k) {
+ return true;
+ }
+
+ bool set(const gc_ptr<T>& v) {
+ val = v;
+ return true;
+ }
+
+ gc_ptr<T> get() const {
+ if (val != NULL || !managed)
+ return val;
+ val = cl();
+ return val;
+ }
+
+#endif
+
+#ifdef WANT_THREADS
+ pthread_key_t key;
+#else
+ int key;
+ gc_ptr<T> val;
+#endif
+
+ bool owner;
+ lambda<const gc_ptr<T>()> cl;
+ bool managed;
+};
+
}
#endif /* tuscany_parallel_hpp */
diff --git a/sca-cpp/trunk/kernel/string-test.cpp b/sca-cpp/trunk/kernel/string-test.cpp
index 5919eed3de..f2f21f6ea6 100644
--- a/sca-cpp/trunk/kernel/string-test.cpp
+++ b/sca-cpp/trunk/kernel/string-test.cpp
@@ -80,6 +80,8 @@ bool testString() {
assert(find("abcd", "cd") == 2);
assert(find("abcd", "xy") == length("abcd"));
+ assert(find_first_of("abcd", "cd") == 2);
+ assert(find_first_of("abcd", "xy") == length("abcd"));
assert(substr("abcdef", 4) == "ef");
assert(substr("abcdef", 4, 2) == "ef");
assert(substr("abcdef", 4, 3) == "ef");