diff options
author | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-08-28 02:50:02 +0000 |
---|---|---|
committer | jsdelfino <jsdelfino@13f79535-47bb-0310-9956-ffa450edef68> | 2011-08-28 02:50:02 +0000 |
commit | 29edc4e6fb2c8fb3a93aac36d9666efd21b92bd0 (patch) | |
tree | 2b1998d904a16cdce69f69041c89cc56d474e69e /sca-cpp/trunk/kernel | |
parent | d93ec216d63aed8ff2f08b4cba7de965dc14639c (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.hpp | 35 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/parallel-test.cpp | 24 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/parallel.hpp | 137 | ||||
-rw-r--r-- | sca-cpp/trunk/kernel/string-test.cpp | 2 |
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"); |