From ae0b7c0063db6236be2d7cf01ddbf2159f77c98c Mon Sep 17 00:00:00 2001 From: jsdelfino Date: Tue, 11 Dec 2012 03:51:03 +0000 Subject: Port kernel to C++11 and refactor some of the core modules. Convert functors to lambdas, and add C++ const, noexcept and inline annotations to get more efficient generated code. git-svn-id: http://svn.us.apache.org/repos/asf/tuscany@1419985 13f79535-47bb-0310-9956-ffa450edef68 --- sca-cpp/trunk/kernel/gc.hpp | 370 ++++++++++++++++++++++++++++++-------------- 1 file changed, 255 insertions(+), 115 deletions(-) (limited to 'sca-cpp/trunk/kernel/gc.hpp') 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 using gc_ptr = T*; + +#else + template 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 using gc_mutable_ptr = T*; + +#else + +template 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(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 apr_status_t gc_pool_cleanup(void* v) { +template inline apr_status_t gc_pool_cleanup(void* v) { T* t = (T*)v; t->~T(); return APR_SUCCESS; } -template T* gc_new(apr_pool_t* p) { +template 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, apr_pool_cleanup_null) ; return (T*)(gc_new_ptr); } -template T* gc_new(const gc_pool& p) { +template inline T* const gc_new(const gc_pool& p) noexcept { return gc_new(pool(p)); } -template T* gc_new() { +template inline T* const gc_new() noexcept { return gc_new(gc_current_pool()); } -template apr_status_t gc_pool_acleanup(void* v) { - size_t* m = static_cast(v); +template 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 apr_status_t gc_pool_acleanup(void* v) { return APR_SUCCESS; } -template T* gc_anew(apr_pool_t* p, size_t n) { - size_t* gc_anew_ptr = static_cast(apr_palloc(p, sizeof(size_t) + sizeof(T) * n)); +template 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, apr_pool_cleanup_null) ; return (T*)(gc_anew_ptr + 1); } -template T* gc_anew(const gc_pool& p, size_t n) { +template inline T* const gc_anew(const gc_pool& p, const size_t n) noexcept { return gc_anew(pool(p), n); } -template T* gc_anew(size_t n) { +template inline T* const gc_anew(const size_t n) noexcept { return gc_anew(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(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 class gc_mutable_ref { +public: + inline gc_mutable_ref() noexcept : ptr(new (gc_new()) 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(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(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(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(ptr) - 1); - size_t* rptr = static_cast(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(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(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(ptr) - 1); - size_t* rptr = static_cast(mremap(static_cast(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(ptr) - 1); - munmap(static_cast(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; -- cgit v1.2.3