Alien-libpanda

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

1.2.3    22.07.2019
           - move fake std::string_view to panda::string_view + related changes
           - fix endian.h for C++17 clang (fuck macros)
           - fix intrusive_chain compilation for clang17
           - fix compilation warnings for clang17
           - return #include <ostream> to log.h (unfortunately, but there is no workaround)
           - remove panda::lib/traits/etc namespace, accumulate all utils in panda::
1.2.2    15.07.2019
           - fix compiler warnings
1.2.1    12.07.2019
           - add get_global_[tls_]ptr
           - add PANDA_GLOBAL/TLS_MEMBER[_PTR] macros helpers for creating static members
             (global or tls) which has the same address across any shared library.
           - change log level names to camel case (fuck the fucking macros)
           - fix intrusive_chain size(): now O(1)
           - CallbackDispatcher: extended callback is now accepted only in add_event_listener
             to resolve ambiguity with template lambdas when dispatcher.add([](auto...) { });
1.2.0    25.06.2019
           - add panda::excepted (expected with strict error checking and exception propagation)
           - add panda::expected (P0323R7)
           - add string_view compare operators with const C*
           - removed panda::shared_ptr, panda::Refcounted (use panda::Refcnt instead)
           - iptr now uses refcnt_inc/dec/get proxies

src/panda/memory.cc  view on Meta::CPAN

#include "memory.h"
#include "string.h"
#include <map>
#include <mutex>
#include <string.h>

namespace panda {

static std::map<string, void*> global_ptrs;
static std::mutex              global_ptrs_mutex;

static thread_local std::map<string, void*> global_tls_ptrs;

static const int START_SIZE = 16;

DynamicMemoryPool* DynamicMemoryPool::_global_instance = new DynamicMemoryPool();

void* detail::__get_global_ptr (const std::type_info& ti, const char* name, void* val) {
    string key(ti.name());
    if (name) key += name;

    std::lock_guard<std::mutex> guard(global_ptrs_mutex);
    auto it = global_ptrs.find(key);
    if (it != global_ptrs.end()) return it->second;

    global_ptrs.emplace(key, val);
    return val;
}

void* detail::__get_global_tls_ptr (const std::type_info& ti, const char* name, void* val) {
    string key(ti.name());
    if (name) key += name;

    auto it = global_tls_ptrs.find(key);
    if (it != global_tls_ptrs.end()) return it->second;

    global_tls_ptrs.emplace(key, val);
    return val;
}

void MemoryPool::grow () {
    size_t pools_cnt = pools.size();
    if (pools_cnt) {
        pools.resize(pools_cnt+1);
        pools[pools_cnt].size = pools[pools_cnt-1].size*2;
    } else {
        pools.resize(1);

src/panda/memory.h  view on Meta::CPAN

#pragma once
#include <vector>
#include <memory>
#include <assert.h>
#include <stdexcept>

namespace panda {

namespace detail {
    void* __get_global_ptr     (const std::type_info& ti, const char* name, void* val);
    void* __get_global_tls_ptr (const std::type_info& ti, const char* name, void* val);
}

template <class CLASS, class T>
inline T* get_global_ptr (T* val, const char* name = NULL) {
    return reinterpret_cast<T*>(detail::__get_global_ptr(typeid(CLASS), name, reinterpret_cast<void*>(val)));
}

template <class CLASS, class T>
inline T* get_global_tls_ptr (T* val, const char* name = NULL) {
    return reinterpret_cast<T*>(detail::__get_global_tls_ptr(typeid(CLASS), name, reinterpret_cast<void*>(val)));
}

#define PANDA_GLOBAL_MEMBER_PTR(CLASS, TYPE, accessor, defval)              \
    static TYPE accessor () {                                               \
        static TYPE ptr;                                                    \
        if (!ptr) ptr = panda::get_global_ptr<CLASS>(defval, #accessor);    \
        return ptr;                                                         \
    }

#define PANDA_GLOBAL_MEMBER(CLASS, TYPE, accessor, defval)          \
    static TYPE& accessor () {                                      \
        static TYPE* ptr;                                           \
        if (!ptr) {                                                 \
            static TYPE val = defval;                               \
            ptr = panda::get_global_ptr<CLASS>(&val, #accessor);    \
        }                                                           \
        return *ptr;                                                \
    }

#define PANDA_GLOBAL_MEMBER_AS_PTR(CLASS, TYPE, accessor, defval)   \
    static TYPE* accessor () {                                      \
        static TYPE* ptr;                                           \
        if (!ptr) {                                                 \
            static TYPE val = defval;                               \
            ptr = panda::get_global_ptr<CLASS>(&val, #accessor);    \
        }                                                           \
        return ptr;                                                 \
    }

#define PANDA_TLS_MEMBER_PTR(CLASS, TYPE, accessor, defval)                         \
    static TYPE accessor () {                                                       \
        static thread_local TYPE _ptr;                                              \
        TYPE ptr = _ptr;                                                            \
        if (!ptr) ptr = _ptr = panda::get_global_tls_ptr<CLASS>(defval, #accessor); \
        return ptr;                                                                 \
    }

#define PANDA_TLS_MEMBER(CLASS, TYPE, accessor, defval)                     \
    static TYPE& accessor () {                                              \
        static thread_local TYPE* _ptr;                                     \
        TYPE* ptr = _ptr;                                                   \
        if (!ptr) {                                                         \
            static thread_local TYPE val = defval;                          \
            ptr = _ptr = panda::get_global_tls_ptr<CLASS>(&val, #accessor); \
        }                                                                   \
        return *ptr;                                                        \
    }

#define PANDA_TLS_MEMBER_AS_PTR(CLASS, TYPE, accessor, defval)              \
    static TYPE* accessor () {                                              \
        static thread_local TYPE* _ptr;                                     \
        TYPE* ptr = _ptr;                                                   \
        if (!ptr) {                                                         \
            static thread_local TYPE val = defval;                          \
            ptr = _ptr = panda::get_global_tls_ptr<CLASS>(&val, #accessor); \
        }                                                                   \
        return ptr;                                                         \
    }

struct MemoryPool {
    MemoryPool (size_t blocksize) : first_free(NULL) {
        this->blocksize = round_up(blocksize);
    }

    void* allocate () {

src/panda/memory.h  view on Meta::CPAN

        const size_t factor = sizeof(void*);
        if ((size & (factor-1)) == 0) return size;
        size += factor;
        size &= ~((size_t)(factor-1));
        return size;
    }
};

template <int BLOCKSIZE>
struct StaticMemoryPool {
    PANDA_GLOBAL_MEMBER_PTR(StaticMemoryPool, MemoryPool*, global_instance, new MemoryPool(BLOCKSIZE));
    PANDA_TLS_MEMBER_PTR   (StaticMemoryPool, MemoryPool*, instance,        new MemoryPool(BLOCKSIZE));

    static void* allocate   ()        { return instance()->allocate(); }
    static void  deallocate (void* p) { instance()->deallocate(p); }
};

template <> struct StaticMemoryPool<7> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<6> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<5> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<4> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<3> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<2> : StaticMemoryPool<8> {};
template <> struct StaticMemoryPool<1> : StaticMemoryPool<8> {};


struct DynamicMemoryPool {
    static DynamicMemoryPool* global_instance () { return _global_instance; }

    PANDA_TLS_MEMBER_PTR(DynamicMemoryPool, DynamicMemoryPool*, instance, new DynamicMemoryPool());

    DynamicMemoryPool ();

    void* allocate (size_t size) {
        if (size == 0) return NULL;
        MemoryPool* pool;
        if (size <= 1024) {
            pool = small_pools[(size-1)>>2];

src/panda/memory.h  view on Meta::CPAN

        else if (size <= 16384)  pool = medium_pools[(size-1)>>6];
        else if (size <= 262144) pool = big_pools[(size-1)>>10];
        else throw std::invalid_argument("ObjectAllocator: object size cannot exceed 256k");
        pool->deallocate(ptr);
    }

    ~DynamicMemoryPool ();

private:
    static constexpr const int POOLS_CNT = 256;
    static DynamicMemoryPool* _global_instance;
    MemoryPool* small_pools[POOLS_CNT];
    MemoryPool* medium_pools[POOLS_CNT];
    MemoryPool* big_pools[POOLS_CNT];

};

template <class TARGET, bool THREAD_SAFE = true>
struct AllocatedObject {
    static void* operator new (size_t, void* p) { return p; }

src/panda/memory.h  view on Meta::CPAN

        if (size == sizeof(TARGET)) StaticMemoryPool<sizeof(TARGET)>::deallocate(p);
        else                        DynamicMemoryPool::instance()->deallocate(p, size);
    }
};

template <class TARGET>
struct AllocatedObject<TARGET, false> {
    static void* operator new (size_t, void* p) { return p; }

    static void* operator new (size_t size) {
        if (size == sizeof(TARGET)) return StaticMemoryPool<sizeof(TARGET)>::global_instance()->allocate();
        else                        return DynamicMemoryPool::global_instance()->allocate(size);
    }

    static void operator delete (void* p, size_t size) {
        if (size == sizeof(TARGET)) StaticMemoryPool<sizeof(TARGET)>::global_instance()->deallocate(p);
        else                        DynamicMemoryPool::global_instance()->deallocate(p, size);
    }
};

}

t/string_test.h  view on Meta::CPAN

            auto e = s.end();
            REQUIRE(b >= b);
            REQUIRE(!(b > b));
            REQUIRE(e > b);
            REQUIRE(b < e);
            REQUIRE(b <= e);
            REQUIRE(e <= e);
            REQUIRE(!(e < e ));
        }

        SECTION("global -+ operators") {
            auto b = s.begin();
            auto e = s.end();

            REQUIRE(*(b + 1) == (T)'1');
            REQUIRE(*(2 + b) == (T)'2');
            REQUIRE(*(e - 1) == (T)'9');
            REQUIRE(*(2 - e) == (T)'8');
        }

        SECTION("as const iterator") {



( run in 0.603 second using v1.01-cache-2.11-cpan-49f99fa48dc )