nginx内存池代码

#include <iostream>
#include <algorithm>
#include <vector>
#include "myallocator.h"
using namespace std;
int main() {
	vector<int, myallocator<int>> vec;
	for (int i = 0; i < 100; ++i) {
		vec.push_back(rand() % 100);
	}
	int i = 0;
	for (int val : vec) {
		if ((++i) % 10 == 0)cout << endl;
		cout << val << "  ";
	}
	cout << endl;
	sort(vec.begin(), vec.end());
	i = 0;
	for (int val : vec) {
		if ((++i) % 10 == 0)cout << endl;
		cout << val << "  ";
	}
	cout << endl;
	return 0;
}
#pragma once
#include <mutex>
#include <iostream>
using namespace std;

//封装了malloc和free操作,可以设置OOM释放内存的回调函数
template <int __inst>
class __malloc_alloc_template {
private:
	static void* _S_oom_malloc(size_t);
	static void* _S_oom_realloc(void*, size_t);
	static void (*__malloc_alloc_oom_handler)();

public:

	static void* allocate(size_t __n)
	{
		void* __result = malloc(__n);
		if (0 == __result) __result = _S_oom_malloc(__n);
		return __result;
	}

	static void deallocate(void* __p, size_t  __n)
	{
		free(__p);
	}

	static void* reallocate(void* __p, size_t  old_sz, size_t __new_sz)
	{
		void* __result = realloc(__p, __new_sz);
		if (0 == __result) __result = _S_oom_realloc(__p, __new_sz);
		return __result;
	}

	static void (*__set_malloc_handler(void (*__f)()))()
	{
		void (*__old)() = __malloc_alloc_oom_handler;
		__malloc_alloc_oom_handler = __f;
		return(__old);
	}

};
template <int __inst>
void (*__malloc_alloc_template<__inst>::__malloc_alloc_oom_handler)() = nullptr;


template <int __inst>
void* __malloc_alloc_template<__inst>::_S_oom_malloc(size_t __n)
{
	void (*__my_malloc_handler)();
	void* __result;

	for (;;) {
		__my_malloc_handler = __malloc_alloc_oom_handler;
		if (0 == __my_malloc_handler) { throw std::bad_alloc(); }
		(*__my_malloc_handler)();
		__result = malloc(__n);
		if (__result) return(__result);
	}
}

template <int __inst>
void* __malloc_alloc_template<__inst>::_S_oom_realloc(void* __p, size_t __n)
{
	void (*__my_malloc_handler)();
	void* __result;
	for (;;) {
		__my_malloc_handler = __malloc_alloc_oom_handler;
		if (0 == __my_malloc_handler) { throw std::bad_alloc(); }
		(*__my_malloc_handler)();
		__result = realloc(__p, __n);
		if (__result) return(__result);
	}
}

typedef __malloc_alloc_template<0> malloc_alloc;



//实现移植SGI STL二级空间配置器内存池代码
template <typename T>
class myallocator {
public:
	using value_type = T;
	constexpr myallocator()noexcept {}
	constexpr myallocator(const myallocator&)noexcept = default;
	template<class _Other>
	constexpr myallocator(const myallocator<_Other>&)noexcept {}

	//内存开辟
	T* allocate(size_t __n) {
		__n = __n * sizeof(T);
		void* __ret = nullptr;
		if (__n > (size_t)_MAX_BYTES) {
			__ret = malloc_alloc::allocate(__n);
		}
		else {
			_Obj* volatile* __my_free_list = _S_free_list + _S_freelist_index(__n);
			std::lock_guard<std::mutex> guard(mtx);
			_Obj* __result = *__my_free_list;
			if (__result == nullptr) {
				__ret = _S_refill(_S_round_up(__n));
			}
			else {
				*__my_free_list = __result->_M_free_list_link;
				__ret = __result;
			}
		}
		return (T*)__ret;
	}

	//内存释放
	void deallocate(void* __p, size_t __n) {
		if (__n > (size_t)_MAX_BYTES) {
			malloc_alloc::deallocate(__p, __n);
		}
		else {
			_Obj* volatile* __my_free_list = _S_free_list + _S_freelist_index(__n);
			_Obj* __q = (_Obj*)__p;
			std::lock_guard<std::mutex> guard(mtx);
			__q->_M_free_list_link = *__my_free_list;
			*__my_free_list = __q;
		}
	}

	//内存扩容或内存缩容
	void* reallocate(void* __p, size_t __old_sz, size_t __new_sz) {
		cout << "void* reallocate(void* __p, size_t __old_sz, size_t __new_sz)" << endl;
		void* __result;
		size_t __copy_sz;
		if (__old_sz > (size_t)_MAX_BYTES && __new_sz > (size_t)_MAX_BYTES) {
			return realloc(__p, __new_sz);
		}
		if (_S_round_up(__old_sz) == _S_round_up(__new_sz)) {
			return __p;
		}
		__result = allocate(__new_sz);
		__copy_sz = __new_sz > __old_sz ? __old_sz : __new_sz;
		memcpy(__result, __p, __copy_sz);
		deallocate(__p, __old_sz);
		return __result;
	}

	//对象构造
	void construct(T* __p, const T& val) {
		new (__p)T(val);
	}

	//对象析构
	void destroy(T* __p) {
		__p->~T();
	}

private:

	//负责分配自由链表,chunk块  __nobjs个__size大小的chunk块
	static char* _S_chunk_alloc(size_t __size, int& __nobjs) {
		char* __result;
		size_t __total_bytes = __size * __nobjs;
		size_t __bytes_left = _S_end_free - _S_start_free;
		if (__bytes_left >= __total_bytes) {
			__result = _S_start_free;
			_S_start_free += __total_bytes;
			return __result;
		}
		else if (__bytes_left >= __size) {
			__nobjs = (int)(__bytes_left / __size);
			__total_bytes = __nobjs * __size;
			__result = _S_start_free;
			_S_start_free += __total_bytes;
			return __result;
		}
		else {
			size_t __bytes_to_get = 2 * __total_bytes + _S_round_up(_S_heap_size >> 4);
			if (__bytes_left > 0) {
				_Obj* volatile* __my_free_list = _S_free_list + _S_freelist_index(__bytes_left);
				((_Obj*)_S_start_free)->_M_free_list_link = *__my_free_list;
				*__my_free_list = (_Obj*)_S_start_free;
			}
			_S_start_free = (char*)malloc(__bytes_to_get);
			if (_S_start_free == nullptr) {

				size_t __i;
				_Obj* volatile* __my_free_list;
				_Obj* __p;
				for (__i = __size; __i <= (size_t)_MAX_BYTES; __i += ((size_t)_ALIGN)) {
					__my_free_list = _S_free_list + _S_freelist_index(__i);
					__p = *__my_free_list;
					if (__p != nullptr) {
						*__my_free_list = __p->_M_free_list_link;
						_S_start_free = (char*)__p;
						_S_end_free = _S_start_free + __i;
						return _S_chunk_alloc(__size, __nobjs);
					}
				}
				_S_end_free = nullptr;
				_S_start_free = (char*)malloc_alloc::allocate(__bytes_to_get);
			}
			_S_heap_size += __bytes_to_get;
			_S_end_free = _S_start_free + __bytes_to_get;
			return _S_chunk_alloc(__size, __nobjs);
		}
	}

	//将分配好的chunk块进行连接
	static void* _S_refill(size_t __n) {
		int __nobjs = 20;
		/*char* __chunk = new char[20];*/
		char* __chunk = _S_chunk_alloc(__n, __nobjs);
		_Obj* volatile* __my_free_list;
		_Obj* __result=nullptr;
		_Obj* __current_obj;
		_Obj* __next_obj;
		int __i;
		if (1 == __nobjs) return __chunk;
		__my_free_list = _S_free_list + _S_freelist_index(__n);
		__result = (_Obj*)__chunk;
		*__my_free_list = __next_obj = (_Obj*)(__chunk + __n);
		
			for (__i = 1; ; __i++) {
				__current_obj = __next_obj;
				__next_obj = (_Obj*)((char*)__next_obj + __n);
				if (__i == __nobjs - 1) {
					__current_obj->_M_free_list_link = nullptr;
					break;
				}
				else {
					__current_obj->_M_free_list_link = __next_obj;
				}
			}
		
		
		return __result;
	}

	enum { _ALIGN = 8 };//自由链表是从8字节开始,以8字节为对齐方式,一直扩充到128
	enum { _MAX_BYTES = 128 };//内存池最大的chunk块
	enum { _NFREELISTS = 16 };//自由链表的个数

	//将__bytes上调至最邻近的8的倍数
	static size_t _S_round_up(size_t __bytes) {
		return (((__bytes)+(size_t)_ALIGN - 1) & ~((size_t)_ALIGN - 1));
	}

	//返回__bytes大小的小额区块位于_s_free_list中的编号
	static size_t _S_freelist_index(size_t __bytes) {
		return (((__bytes)+(size_t)_ALIGN - 1) / (size_t)_ALIGN - 1);
	}

	//每个chunk块的头信息 _M_free_list_link 是下一个chunk块的地址
	union _Obj {
		union _Obj* _M_free_list_link;
		char _M_client_data[1];
	};

	//chunk块链表数组
	static _Obj* volatile _S_free_list[_NFREELISTS];

	//已分配的chunk块的使用情况
	static char* _S_start_free;
	static char* _S_end_free;
	static size_t _S_heap_size;

	//内存池基于free list实现 考虑线程安全
	static std::mutex mtx;
};
template <typename T>
char* myallocator<T>::_S_start_free = nullptr;

template <typename T>
char* myallocator<T>::_S_end_free = nullptr;

template <typename T>
size_t myallocator<T>::_S_heap_size = 0;

template <typename T>
typename myallocator<T>::_Obj* volatile myallocator<T>::_S_free_list[_NFREELISTS] =
{ nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr,nullptr };

template <typename T>
std::mutex myallocator<T>::mtx;

  • 3
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

yyycqupt

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值