summaryrefslogtreecommitdiffstats
path: root/sca-cpp/trunk/kernel/gc.hpp
diff options
context:
space:
mode:
Diffstat (limited to 'sca-cpp/trunk/kernel/gc.hpp')
-rw-r--r--sca-cpp/trunk/kernel/gc.hpp370
1 files changed, 255 insertions, 115 deletions
diff --git a/sca-cpp/trunk/kernel/gc.hpp b/sca-cpp/trunk/kernel/gc.hpp
index 32ad8160cc..7853c551dc 100644
--- a/sca-cpp/trunk/kernel/gc.hpp
+++ b/sca-cpp/trunk/kernel/gc.hpp
@@ -49,7 +49,7 @@ namespace tuscany
/**
* Force a core dump on assertion violation.
*/
-bool assertOrFail(const bool expr) {
+inline const bool assertOrFail(const bool expr) {
if (!expr)
abort();
return true;
@@ -64,63 +64,135 @@ bool assertOrFail(const bool expr) {
/**
* Pointer to a value.
*/
+#ifdef WANT_RAW_PTR
+
+template<typename T> using gc_ptr = T*;
+
+#else
+
template<typename T> class gc_ptr {
public:
- gc_ptr(T* ptr = NULL) throw() : ptr(ptr) {
+ inline gc_ptr(T* const ptr = NULL) noexcept : ptr(ptr) {
+ }
+
+ inline ~gc_ptr() noexcept {
+ }
+
+ inline gc_ptr(const gc_ptr& r) noexcept : ptr(r.ptr) {
+ }
+
+ gc_ptr& operator=(const gc_ptr& r) = delete;
+
+ inline const bool operator==(const gc_ptr& r) const noexcept {
+ if (this == &r)
+ return true;
+ return ptr == r.ptr;
+ }
+
+ inline const bool operator==(const T* const p) const noexcept {
+ return ptr == p;
+ }
+
+ inline const bool operator!=(const gc_ptr& r) const noexcept {
+ return !this->operator==(r);
+ }
+
+ inline const bool operator!=(const T* const p) const noexcept {
+ return !this->operator==(p);
+ }
+
+ inline T& operator*() const noexcept {
+ return *ptr;
+ }
+
+ inline T* const operator->() const noexcept {
+ return ptr;
+ }
+
+ inline operator T* const () const noexcept {
+ return ptr;
+ }
+
+private:
+ T* const ptr;
+};
+
+#endif
+
+/**
+ * Mutable pointer to an immutable value.
+ */
+#ifdef WANT_RAW_PTR
+
+template<typename T> using gc_mutable_ptr = T*;
+
+#else
+
+template<typename T> class gc_mutable_ptr {
+public:
+ inline gc_mutable_ptr(T* const ptr = NULL) noexcept : ptr(ptr) {
}
- ~gc_ptr() throw() {
+ inline ~gc_mutable_ptr() noexcept {
}
- gc_ptr(const gc_ptr& r) throw() : ptr(r.ptr) {
+ inline gc_mutable_ptr(const gc_mutable_ptr& r) noexcept : ptr(r.ptr) {
}
- gc_ptr& operator=(const gc_ptr& r) throw() {
- if(this == &r)
+ inline gc_mutable_ptr& operator=(T* const p) noexcept {
+ ptr = p;
+ return *this;
+ }
+
+ inline gc_mutable_ptr& operator=(const gc_mutable_ptr& r) noexcept {
+ if (this == &r)
return *this;
ptr = r.ptr;
return *this;
}
- const bool operator==(const gc_ptr& r) const throw() {
+ inline const bool operator==(const gc_mutable_ptr& r) const noexcept {
if (this == &r)
return true;
return ptr == r.ptr;
}
- const bool operator==(T* p) const throw() {
+ inline const bool operator==(T* const p) const noexcept {
return ptr == p;
}
- const bool operator!=(const gc_ptr& r) const throw() {
+ inline const bool operator!=(const gc_mutable_ptr& r) const noexcept {
return !this->operator==(r);
}
- const bool operator!=(T* p) const throw() {
+ inline const bool operator!=(T* const p) const noexcept {
return !this->operator==(p);
}
- T& operator*() const throw() {
+ inline T& operator*() const noexcept {
return *ptr;
}
- T* operator->() const throw() {
+ inline T* const operator->() const noexcept {
return ptr;
}
- operator T*() const throw() {
+ inline operator T* const () const noexcept {
return ptr;
}
+private:
T* ptr;
};
+#endif
+
/**
* Initialize APR.
*/
class gc_apr_context_t {
public:
- gc_apr_context_t() {
+ inline gc_apr_context_t() {
apr_initialize();
}
} gc_apr_context;
@@ -130,36 +202,31 @@ public:
*/
class gc_pool {
public:
- gc_pool() : apr_pool(NULL) {
+ inline gc_pool() noexcept : apr_pool(NULL) {
}
- gc_pool(apr_pool_t* p) : apr_pool(p) {
+ inline gc_pool(apr_pool_t* const p) noexcept : apr_pool(p) {
}
- gc_pool(const gc_pool& pool) : apr_pool(pool.apr_pool) {
+ inline gc_pool(const gc_pool& pool) noexcept : apr_pool(pool.apr_pool) {
}
- gc_pool& operator=(const gc_pool& pool) {
- if (this == &pool)
- return *this;
- apr_pool = pool.apr_pool;
- return *this;
- }
+ gc_pool& operator=(const gc_pool& pool) = delete;
private:
- friend apr_pool_t* pool(const gc_pool& pool);
+ friend apr_pool_t* pool(const gc_pool& pool) noexcept;
friend class gc_global_pool_t;
friend class gc_child_pool;
friend class gc_local_pool;
friend class gc_scoped_pool;
- apr_pool_t* apr_pool;
+ apr_pool_t* const apr_pool;
};
/**
* Return the APR pool used by a gc_pool.
*/
-apr_pool_t* pool(const gc_pool& pool) {
+inline apr_pool_t* pool(const gc_pool& pool) noexcept {
return pool.apr_pool;
}
@@ -168,35 +235,51 @@ apr_pool_t* pool(const gc_pool& pool) {
*/
#ifdef WANT_THREADS
+#ifdef __clang__
+
class gc_pool_stack_t {
public:
- gc_pool_stack_t() {
- int rc = pthread_key_create(&key, NULL);
- assertOrFail(rc == 0);
+ inline gc_pool_stack_t() noexcept : key(mkkey()) {
}
- operator apr_pool_t*() const {
- return static_cast<apr_pool_t*>(pthread_getspecific(key));
+ inline operator apr_pool_t*() const noexcept {
+ return (apr_pool_t*)pthread_getspecific(key);
}
- const gc_pool_stack_t& operator=(apr_pool_t* p) {
+ inline const gc_pool_stack_t& operator=(apr_pool_t* p) noexcept {
pthread_setspecific(key, p);
return *this;
}
private:
pthread_key_t key;
+
+ pthread_key_t mkkey() {
+ pthread_key_t k;
+ int rc = pthread_key_create(&k, NULL);
+ assertOrFail(rc == 0);
+ return k;
+ }
+
} gc_pool_stack;
#else
+
+__thread apr_pool_t* gc_pool_stack = NULL;
+
+#endif
+
+#else
+
apr_pool_t* gc_pool_stack = NULL;
+
#endif
/**
* Push a pool onto the stack.
*/
-apr_pool_t* gc_push_pool(apr_pool_t* pool) {
- apr_pool_t* p = gc_pool_stack;
+inline apr_pool_t* const gc_push_pool(apr_pool_t* pool) noexcept {
+ apr_pool_t* const p = gc_pool_stack;
gc_pool_stack = pool;
return p;
}
@@ -204,8 +287,8 @@ apr_pool_t* gc_push_pool(apr_pool_t* pool) {
/**
* Pop a pool from the stack.
*/
-apr_pool_t* gc_pop_pool(apr_pool_t* pool) {
- apr_pool_t* p = gc_pool_stack;
+inline apr_pool_t* const gc_pop_pool(apr_pool_t* pool) noexcept {
+ apr_pool_t* const p = gc_pool_stack;
gc_pool_stack = pool;
return p;
}
@@ -213,16 +296,17 @@ apr_pool_t* gc_pop_pool(apr_pool_t* pool) {
/**
* Return the current memory pool.
*/
-apr_pool_t* gc_current_pool() {
- apr_pool_t* p = gc_pool_stack;
+inline apr_pool_t* const gc_current_pool() noexcept {
+ apr_pool_t* const p = gc_pool_stack;
if (p != NULL)
return p;
// Create a parent pool for the current thread
- apr_pool_create(&p, NULL);
- assertOrFail(p != NULL);
- gc_push_pool(p);
- return p;
+ apr_pool_t* pp;
+ apr_pool_create(&pp, NULL);
+ assertOrFail(pp != NULL);
+ gc_push_pool(pp);
+ return pp;
}
/**
@@ -231,25 +315,23 @@ apr_pool_t* gc_current_pool() {
class gc_child_pool : public gc_pool {
public:
- gc_child_pool() : gc_pool(NULL), owner(true) {
- apr_pool_create(&apr_pool, gc_current_pool());
- assertOrFail(apr_pool != NULL);
+ inline gc_child_pool() noexcept : gc_pool(mkpool()), owner(true) {
}
- gc_child_pool(const gc_child_pool& p) : gc_pool(p.apr_pool), owner(false) {
- }
-
- const gc_child_pool& operator=(const gc_child_pool& p) {
- if(this == &p)
- return *this;
- apr_pool = p.apr_pool;
- owner = false;
- return *this;
+ inline gc_child_pool(const gc_child_pool& p) noexcept : gc_pool(p.apr_pool), owner(false) {
}
+ gc_child_pool& operator=(const gc_child_pool& p) = delete;
private:
- bool owner;
+ const bool owner;
+
+ apr_pool_t* const mkpool() {
+ apr_pool_t* p;
+ apr_pool_create(&p, gc_current_pool());
+ assertOrFail(p != NULL);
+ return p;
+ }
};
/**
@@ -258,29 +340,28 @@ private:
class gc_local_pool : public gc_pool {
public:
- gc_local_pool() : gc_pool(NULL), owner(true) {
- apr_pool_create(&apr_pool, gc_current_pool());
- assertOrFail(apr_pool != NULL);
+ inline gc_local_pool() noexcept : gc_pool(mkpool()), owner(true) {
}
- ~gc_local_pool() {
+ inline ~gc_local_pool() noexcept {
if (owner)
apr_pool_destroy(apr_pool);
}
- gc_local_pool(const gc_local_pool& p) : gc_pool(p.apr_pool), owner(false) {
+ inline gc_local_pool(const gc_local_pool& p) noexcept : gc_pool(p.apr_pool), owner(false) {
}
- const gc_local_pool& operator=(const gc_local_pool& p) {
- if(this == &p)
- return *this;
- apr_pool = p.apr_pool;
- owner = false;
- return *this;
- }
+ gc_local_pool& operator=(const gc_local_pool& p) = delete;
private:
- bool owner;
+ const bool owner;
+
+ apr_pool_t* const mkpool() {
+ apr_pool_t* p;
+ apr_pool_create(&p, gc_current_pool());
+ assertOrFail(p != NULL);
+ return p;
+ }
};
/**
@@ -290,66 +371,64 @@ private:
class gc_scoped_pool : public gc_pool {
public:
- gc_scoped_pool() : gc_pool(NULL), prev(gc_current_pool()), owner(true) {
- apr_pool_create(&apr_pool, prev);
- assertOrFail(apr_pool != NULL);
+ inline gc_scoped_pool() noexcept : gc_pool(mkpool()), prev(gc_current_pool()), owner(true) {
gc_push_pool(apr_pool);
}
- gc_scoped_pool(apr_pool_t* p) : gc_pool(p), prev(gc_current_pool()), owner(false) {
+ inline gc_scoped_pool(apr_pool_t* p) noexcept : gc_pool(p), prev(gc_current_pool()), owner(false) {
gc_push_pool(apr_pool);
}
- ~gc_scoped_pool() {
+ inline ~gc_scoped_pool() noexcept {
if (owner)
apr_pool_destroy(apr_pool);
gc_pop_pool(prev);
}
- gc_scoped_pool(const gc_scoped_pool& p) : gc_pool(p.apr_pool), prev(p.prev), owner(false) {
+ inline gc_scoped_pool(const gc_scoped_pool& p) noexcept : gc_pool(p.apr_pool), prev(p.prev), owner(false) {
}
- const gc_scoped_pool& operator=(const gc_scoped_pool& p) {
- if(this == &p)
- return *this;
- apr_pool = p.apr_pool;
- prev = p.prev;
- owner = false;
- return *this;
- }
+ gc_scoped_pool& operator=(const gc_scoped_pool& p) = delete;
private:
- apr_pool_t* prev;
- bool owner;
+ apr_pool_t* const prev;
+ const bool owner;
+
+ apr_pool_t* const mkpool() {
+ apr_pool_t* p;
+ apr_pool_create(&p, gc_current_pool());
+ assertOrFail(p != NULL);
+ return p;
+ }
};
/**
* Allocates a pointer to an object allocated from a memory pool and
* register a cleanup callback for it.
*/
-template<typename T> apr_status_t gc_pool_cleanup(void* v) {
+template<typename T> inline apr_status_t gc_pool_cleanup(void* v) {
T* t = (T*)v;
t->~T();
return APR_SUCCESS;
}
-template<typename T> T* gc_new(apr_pool_t* p) {
+template<typename T> inline T* const gc_new(apr_pool_t* const p) noexcept {
void* gc_new_ptr = apr_palloc(p, sizeof(T));
assertOrFail(gc_new_ptr != NULL);
apr_pool_cleanup_register(p, gc_new_ptr, gc_pool_cleanup<T>, apr_pool_cleanup_null) ;
return (T*)(gc_new_ptr);
}
-template<typename T> T* gc_new(const gc_pool& p) {
+template<typename T> inline T* const gc_new(const gc_pool& p) noexcept {
return gc_new<T>(pool(p));
}
-template<typename T> T* gc_new() {
+template<typename T> inline T* const gc_new() noexcept {
return gc_new<T>(gc_current_pool());
}
-template<typename T> apr_status_t gc_pool_acleanup(void* v) {
- size_t* m = static_cast<size_t*>(v);
+template<typename T> inline apr_status_t gc_pool_acleanup(void* v) {
+ size_t* m = (size_t*)v;
size_t n = *m;
T* t = (T*)(m + 1);
for (size_t i = 0; i < n; i++, t++)
@@ -357,40 +436,101 @@ template<typename T> apr_status_t gc_pool_acleanup(void* v) {
return APR_SUCCESS;
}
-template<typename T> T* gc_anew(apr_pool_t* p, size_t n) {
- size_t* gc_anew_ptr = static_cast<size_t*>(apr_palloc(p, sizeof(size_t) + sizeof(T) * n));
+template<typename T> inline T* const gc_anew(apr_pool_t* const p, const size_t n) noexcept {
+ size_t* const gc_anew_ptr = (size_t*)apr_palloc(p, sizeof(size_t) + sizeof(T) * n);
assertOrFail(gc_anew_ptr != NULL);
*gc_anew_ptr = n;
apr_pool_cleanup_register(p, gc_anew_ptr, gc_pool_acleanup<T>, apr_pool_cleanup_null) ;
return (T*)(gc_anew_ptr + 1);
}
-template<typename T> T* gc_anew(const gc_pool& p, size_t n) {
+template<typename T> inline T* const gc_anew(const gc_pool& p, const size_t n) noexcept {
return gc_anew<T>(pool(p), n);
}
-template<typename T> T* gc_anew(size_t n) {
+template<typename T> inline T* const gc_anew(const size_t n) noexcept {
return gc_anew<T>(gc_current_pool(), n);
}
/**
* Allocate an array of chars.
*/
-char* gc_cnew(apr_pool_t* p, size_t n) {
- char* gc_cnew_ptr = static_cast<char*>(apr_palloc(p, n));
+inline char* const gc_cnew(apr_pool_t* const p, const size_t n) noexcept {
+ char* const gc_cnew_ptr = (char*)apr_palloc(p, n);
assertOrFail(gc_cnew_ptr != NULL);
return gc_cnew_ptr;
}
-char* gc_cnew(size_t n) {
+inline char* const gc_cnew(const size_t n) noexcept {
return gc_cnew(gc_current_pool(), n);
}
/**
+ * Mutable reference to an immutable value.
+ */
+template<typename T> class gc_mutable_ref {
+public:
+ inline gc_mutable_ref() noexcept : ptr(new (gc_new<T>()) T()) {
+ }
+
+ inline ~gc_mutable_ref() noexcept {
+ }
+
+ inline gc_mutable_ref(const gc_mutable_ref& r) noexcept : ptr(r.ptr) {
+ }
+
+ inline gc_mutable_ref(const T& v) noexcept : ptr(new (gc_new<T>()) T(v)) {
+ }
+
+ inline gc_mutable_ref& operator=(const gc_mutable_ref& r) noexcept {
+ if (this == &r)
+ return *this;
+ ptr = r.ptr;
+ return *this;
+ }
+
+ inline gc_mutable_ref& operator=(const T& v) noexcept {
+ ptr = new (gc_new<T>()) T(v);
+ return *this;
+ }
+
+ inline const bool operator==(const gc_mutable_ref& r) const noexcept {
+ if (this == &r)
+ return true;
+ if (ptr == r.ptr)
+ return true;
+ return *ptr == *r.ptr;
+ }
+
+ inline const bool operator==(const T& v) const noexcept {
+ return *ptr == v;
+ }
+
+ inline const bool operator!=(const gc_mutable_ref& r) const noexcept {
+ return !this->operator==(r);
+ }
+
+ inline const bool operator!=(const T& v) const noexcept {
+ return !this->operator==(v);
+ }
+
+ inline operator T&() const noexcept {
+ return *ptr;
+ }
+
+ inline operator T* const () const noexcept {
+ return ptr;
+ }
+
+private:
+ T* ptr;
+};
+
+/**
* Pool based equivalent of the standard malloc function.
*/
-void* gc_pool_malloc(size_t n) {
- size_t* ptr = static_cast<size_t*>(apr_palloc(gc_current_pool(), sizeof(size_t) + n));
+inline void* gc_pool_malloc(size_t n) {
+ size_t* ptr = (size_t*)apr_palloc(gc_current_pool(), sizeof(size_t) + n);
assertOrFail(ptr != NULL);
*ptr = n;
return ptr + 1;
@@ -399,9 +539,9 @@ void* gc_pool_malloc(size_t n) {
/**
* Pool based equivalent of the standard realloc function.
*/
-void* gc_pool_realloc(void* ptr, size_t n) {
- size_t size = *(static_cast<size_t*>(ptr) - 1);
- size_t* rptr = static_cast<size_t*>(apr_palloc(gc_current_pool(), sizeof(size_t) + n));
+inline void* gc_pool_realloc(void* ptr, size_t n) {
+ size_t size = *(((size_t*)ptr) - 1);
+ size_t* rptr = (size_t*)apr_palloc(gc_current_pool(), sizeof(size_t) + n);
assertOrFail(rptr != NULL);
*rptr = n;
memcpy(rptr + 1, ptr, size < n? size : n);
@@ -411,15 +551,15 @@ void* gc_pool_realloc(void* ptr, size_t n) {
/**
* Pool based equivalent of the standard free function.
*/
-void gc_pool_free(unused void* ptr) {
+inline void gc_pool_free(unused void* ptr) {
// Memory allocated from a pool is freed when the pool is freed
}
/**
* Pool based equivalent of the standard strdup function.
*/
-char* gc_pool_strdup(const char* str) {
- char* dptr = static_cast<char*>(gc_pool_malloc(strlen(str) + 1));
+inline char* gc_pool_strdup(const char* str) {
+ char* dptr = (char*)gc_pool_malloc(strlen(str) + 1);
assertOrFail(dptr != NULL);
strcpy(dptr, str);
return dptr;
@@ -434,9 +574,9 @@ char* gc_pool_strdup(const char* str) {
/**
* Mmap based equivalent of the standard malloc function.
*/
-void* gc_mmap_malloc(size_t n, unused const void* caller) {
+inline void* gc_mmap_malloc(size_t n, unused const void* caller) {
//printf("gc_mmap_malloc %d", n);
- size_t* ptr = static_cast<size_t*>(mmap(NULL, sizeof(size_t) + n, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0));
+ size_t* ptr = (size_t*)mmap(NULL, sizeof(size_t) + n, PROT_READ | PROT_WRITE, MAP_ANONYMOUS | MAP_PRIVATE, -1, 0);
assertOrFail(ptr != NULL);
*ptr = n;
//printf(" %p\n", ptr + 1);
@@ -446,12 +586,12 @@ void* gc_mmap_malloc(size_t n, unused const void* caller) {
/**
* Mmap based equivalent of the standard realloc function.
*/
-void* gc_mmap_realloc(void* ptr, size_t n, const void* caller) {
+inline void* gc_mmap_realloc(void* ptr, size_t n, const void* caller) {
if (ptr == NULL)
return gc_mmap_malloc(n, caller);;
//printf("gc_mmap_realloc %p %d", ptr, n);
- size_t size = *(static_cast<size_t*>(ptr) - 1);
- size_t* rptr = static_cast<size_t*>(mremap(static_cast<size_t*>(ptr) - 1, sizeof(size_t) + size, sizeof(size_t) + n, MREMAP_MAYMOVE, NULL));
+ size_t size = *(((size_t*)ptr) - 1);
+ size_t* rptr = (size_t*)mremap(((size_t*)ptr) - 1, sizeof(size_t) + size, sizeof(size_t) + n, MREMAP_MAYMOVE, NULL);
assertOrFail(rptr != NULL);
*rptr = n;
//printf(" %p\n", rptr + 1);
@@ -461,18 +601,18 @@ void* gc_mmap_realloc(void* ptr, size_t n, const void* caller) {
/**
* Mmap based equivalent of the standard free function.
*/
-void gc_mmap_free(void* ptr, unused const void* caller) {
+inline void gc_mmap_free(void* ptr, unused const void* caller) {
//printf("gc_mmap_free %p\n", ptr);
if (ptr == NULL)
return;
- size_t size = *(static_cast<size_t*>(ptr) - 1);
- munmap(static_cast<size_t*>(ptr) - 1, sizeof(size_t) + size);
+ size_t size = *(((size_t*)ptr) - 1);
+ munmap(((size_t*)ptr) - 1, sizeof(size_t) + size);
}
/**
* Mmap based equivalent of the standard memalign function.
*/
-void* gc_mmap_memalign(unused size_t alignment, size_t n, unused const void* caller) {
+inline void* gc_mmap_memalign(unused size_t alignment, size_t n, unused const void* caller) {
//printf("gc_mmap_memalign %d %d\n", alignment, n);
return gc_mmap_malloc(n, caller);
}
@@ -480,7 +620,7 @@ void* gc_mmap_memalign(unused size_t alignment, size_t n, unused const void* cal
/**
* Install the mmap based memory allocation functions.
*/
-void gc_mmap_init_hook(void) {
+inline void gc_mmap_init_hook(void) {
__malloc_hook = gc_mmap_malloc;
__realloc_hook = gc_mmap_realloc;
__free_hook = gc_mmap_free;