内存分配子

来源:互联网 发布:蜘蛛软件刷奖软件下载 编辑:程序博客网 时间:2024/06/16 03:54
#ifndef __OOM_ALLOCATER__H__#define __OOM_ALLOCATER__H__#ifdef _MSC_VER#if _MSC_VER > 1000#pragma once#endif#endif#ifndef __STC_NAMESPACE_BEGIN #define __STC_NAMESPACE_BEGIN namespace stc{#endif#ifndef __STC_NAMESPACE_END#define __STC_NAMESPACE_END }#endif#include <cstddef>#include <cassert>#include <cstdlib>#include <new>#include <stdexcept>__STC_NAMESPACE_BEGINtemplate <int _Ty>class oom_allocater{typedef void(*new_handler)();private:static new_handler__oom_handler;static void* oom_malloc(const std::size_t);static void* oom_realloc(void*, const std::size_t);public:static void* allocate(const std::size_t __Sz){const std::size_t __tSz = __Sz ? __Sz : 1u;void* __Res = ::malloc(__tSz);if (__Res == NULL)__Res = oom_malloc(__tSz);return __Res;}static void* realloc(void* __Src, const std::size_t, const std::size_t __nSz){void* __Res = ::realloc(__Src, __nSz);if (__Res == NULL)oom_realloc(__Src, __nSz);return __Res;}static void deallocate(void* __Src, const std::size_t __Sz){::free(__Src);}static void(*set_new_handler(void(*__nHd)())) (){new_handler __oHd = __oom_handler;__oom_handler  = __nHd;return __oHd;}};template <int _Ty>void(*(oom_allocater<_Ty>::__oom_handler))() = NULL;template <int _Ty>void* oom_allocater<_Ty>::oom_malloc(const std::size_t __Sz){const std::size_t __tSz = __Sz ? __Sz : 1u;new_handler __tmp_new_handler = NULL;void* __Res = NULL;while (true){__tmp_new_handler = __oom_handler;if (__tmp_new_handler == NULL)throw std::bad_alloc();(*__tmp_new_handler)();__Res = ::malloc(__tSz);if (__Res) return __Res;}}template <int _Ty>void* oom_allocater<_Ty>::oom_realloc(void* __Src, const std::size_t __nSz){try{void* __nSrc = oom_allocater<_Ty>::malloc(__nSz);::free(__Src);__Src = __nSrc;return __nSrc;}catch (const std::bad_alloc&){throw std::bad_alloc("");return __Src;}catch (...){ throw std::bad_alloc(""); }}typedef oom_allocater<0> malloc_alloc;__STC_NAMESPACE_END#endif#ifndef __ALLOCATER__H__#define __ALLOCATER__H__#ifdef _MSC_VER#if _MSC_VER > 1000#pragma once#endif#endif#include <cassert>#include <string>#include "oom_allocater.h"__STC_NAMESPACE_BEGIN#pragma pack(push)#pragma pack(4)class list_node{public:list_node():__Src(NULL), __Next(NULL){}void* __Src;list_node*__Next;};#pragma pack(pop)inline list_node* __creat_node(const std::size_t __Sz = 1u){if (__Sz == 1u)return new list_node;return new list_node[__Sz];}inline void __destroy_node(list_node*& __p, const std::size_t __Sz = 1u){if (__Sz == 1u)delete __p;else delete[] __p;__p = NULL;}const std::size_t __ALIGN  = 4u;const std::size_t __MAX_BYTES = 128u;const std::size_t __NFREELIST = __MAX_BYTES / __ALIGN;const std::size_t __round_up(const std::size_t __Sz){return static_cast<std::size_t>(((__Sz)+__ALIGN - 1) & ~(__ALIGN - 1));}const std::size_t __index(const std::size_t __Sz){return static_cast<std::size_t>(((__Sz + __ALIGN - 1) / __ALIGN - 1));}template <typename _Ty>class allocater{public:template <typename _Ty2>struct bind{typedef allocater<_Ty2> other;};static _Ty* allocate(const std::size_t);static _Ty* realloc(void*, const std::size_t, const std::size_t);static void deallocate(void*, const std::size_t);template <typename _Ty2>static void construct(_Ty* const __Src, const _Ty2& __Val){new (__Src)_Ty(__Val);}static void construct(_Ty* const __Src){new (__Src)_Ty();}static void destroy(_Ty* const __Src){__Src->~_Ty();}static _Ty* address(const _Ty& __Val){return &__Val;}allocater& operator =(const allocater&) = default;private:static void __refill(const std::size_t);static char* __chunk_alloc(const std::size_t, std::size_t&);static const std::size_t __bit_size(const std::size_t);private:static list_node* __free_list[__NFREELIST];static char* __start_free;static char*        __end_free;static std::size_t  __heap_size;};template <typename _Ty>list_node* allocater<_Ty>::__free_list[__NFREELIST] = {NULL, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL,NULL, NULL, NULL, NULL, NULL,NULL, NULL};template <typename _Ty>char* allocater<_Ty>::__start_free = NULL;template <typename _Ty>char* allocater<_Ty>::__end_free = NULL;template <typename _Ty>std::size_t allocater<_Ty>::__heap_size = 0u;template <typename _Ty>const std::size_t allocater<_Ty>::__bit_size(const std::size_t __Sz){const std::size_t __tSz = __Sz ? __Sz : 1u;//如果不为0那么还是返回它的大小,如果是零那么大小要求为1return static_cast<size_t>(__tSz * sizeof(_Ty));}template <typename _Ty>_Ty* allocater<_Ty>::allocate(const std::size_t __Sz){const std::size_t __bSz = __bit_size(__Sz);if (__bSz > __MAX_BYTES){return static_cast<_Ty*>(malloc_alloc::allocate(__bSz));}const std::size_t __Solt = __index(__bSz);list_node* __Res = __free_list[__Solt];if (__Res == NULL){__refill(__round_up(__bSz));__Res = __free_list[__Solt];}__free_list[__Solt] = __Res->__Next;_Ty* __Src= static_cast<_Ty*>(__Res->__Src);__destroy_node(__Res);return __Src;}template <typename _Ty>_Ty* allocater<_Ty>::realloc(void* __Src, const std::size_t __oSz, const std::size_t __nSz){const std::size_t __bnSz = __bit_size(__nSz);const std::size_t __boSz = __bit_size(__oSz);_Ty* __Res = static_cast<_Ty*>(allocater<_Ty>::allocate(__bnSz));allocater<_Ty>::deallocate(__Src, __boSz);return __Res;}template <typename _Ty>void allocater<_Ty>::deallocate(void* __Src, const std::size_t __Sz){const std::size_t __bSz = __bit_size(__Sz);if (__bSz > __MAX_BYTES){malloc_alloc::deallocate(__Src, __bSz);return;}list_node* __node = __creat_node();__node->__Src  = __Src;const std::size_t __Solt = __index(__bSz);__node->__Next  = __free_list[__Solt];__free_list[__Solt] = __node;}template <typename _Ty>//重新填大小为Sz块大小的项void allocater<_Ty>::__refill(const std::size_t __Sz){assert(__Sz);std::size_t __Node_Sz = 20u;//defalut node size;char* __chunk = __chunk_alloc(__Sz, __Node_Sz);const std::size_t __Solt = __index(__Sz);list_node* __Curr = NULL;list_node* __Prev = __creat_node();__Prev->__Src = __chunk;__free_list[__Solt] = __Prev;for (std::size_t i = 1u; i < __Node_Sz; ++i){__chunk+= __Sz;__Curr= __creat_node();__Curr->__Next= __Prev;__Curr->__Src= __chunk;__Prev= __Curr;}}template <typename _Ty>char* allocater<_Ty>::__chunk_alloc(const std::size_t __Sz, std::size_t& __Node_Sz){assert(__Sz);const std::size_t __lSz = __end_free - __start_free;const std::size_t __tSz = __Sz * __Node_Sz;char* __Res = NULL;if (__lSz >= __tSz){__Res = __start_free;__start_free += __tSz;return (__Res);}if (__lSz >= __Sz){//如果能给出内存,但是不够所有的__Node_Sz = __lSz / __Sz;__Res  = __start_free;__start_free += static_cast<std::size_t>(__Node_Sz * __Sz);return (__Res);}//剩下的完全不够了const std::size_t __bit_get = __tSz * 2 + __round_up(__heap_size >> 4);const std::size_t __Solt= __index(__lSz ? __lSz : 1u);//如果left size 为0会出现BUGif (__lSz){//如果剩下还有内存,那么就放入到现在的表中list_node* __node= __creat_node();__node->__Src= __start_free;__node->__Next= __free_list[__Solt];__free_list[__Solt] = __node;}__start_free = (char*)::malloc(__bit_get);if (__start_free == NULL){//如果内存足了,就从现在的表项中找合适的for (std::size_t i = __Solt; i < __NFREELIST; ++i){if (__free_list[i]){list_node* __node = __free_list[i];__start_free= static_cast<char*>(__node->__Src);__free_list[i]  = __node->__Next;__destroy_node(__node);__end_free= __start_free + (i + 1) * __ALIGN;return __chunk_alloc(__Sz, __Node_Sz);}}__start_free = static_cast<char*>(malloc_alloc::allocate(__bit_get));//尝试使用用户自己定义的机制找}__heap_size = __bit_get;__end_free= __start_free + __bit_get;return __chunk_alloc(__Sz, __Node_Sz);}__STC_NAMESPACE_END#endif

0 0