SGI一级空间配置器的简单介绍与实现

SGI一级空间配置器原理的简单介绍

       SGI一级空间配置器里边提供给用户使用的接口就只有三个,allocate 、deallocate 和 reallocate。allocate函数用于申请空间,用户将需要的字节数传给该函数,然后在函数里边调用 malloc()函数来申请空间,如果申请成功,那么直接将这块空间的地址返回给用户。如果申请失败了,说明系统里边空间已经不足了,那么接下来的处理就稍微麻烦一点,需要使用一个oom_malloc函数来帮忙申请空间。

       这个oom_malloc函数里边的实现跟C++中的new的实现比较相似。因为系统里边已经没有空间供我们申请了,所以只能将当前程序中的一些不需要的空间释放掉(还给系统),然后再调用malloc函数重新进行申请。系统是不知道哪部分空间是我们已经不需要了的,只有用户自己知道,所以,系统是不会主动帮我们释放空间的,释放空间的函数只有由我们用户自己来提供。如果用户没有提供这样一个函数,那么系统也就没法了,只能抛异常了。

       有可能我们申请的空间比较大,调用一次释放空间的函数,释放的空间有可能还不足以提供给我们,所以,以上这个释放空间然后申请空间的过程应该是一个循环的过程,知道空间申请成功,循环就退出了。

      reallocate 和 allocate 的实现很相似,基本就是多了一个参数,我就不重复讲了。deallocate 是用于释放空间的,它的实现非常简单,就是调用一下free()函数。

具体实现

#pragma once
#include <new>
#include <iostream>
using namespace std;

#define THROW_BAD_ALLOC cerr<<"out of memory"<<endl;exit(1)

template <int inst>
class Alloc_malloc_template
{
public:
	//Allocate用于申请空间
	static void* Allocate(size_t n)
	{
		void* result = malloc(n);
		//申请失败,使用oom_malloc()重新尝试申请
		if (result == NULL)
			Oom_malloc(n);
		return result;
	}

	//Deallocate用于释放空间
	static void* Deallocate(void* p, size_t /* size*/)
	{
		free(p);
	}

	//Reallocate用于根据需要调整已经存在的空间的大小
	static void* Reallocate(void* p, size_t size)
	{
		void* result = realloc(p, size);
		//申请失败,使用oom_realloc()尝试申请
		if (result == NULL)
			Oom_realloc(p, size);
		return result;
	}

	//Set_malloc_handler函数是用于设置用户提供的释放空间的函数指针
	static void(*Set_malloc_handler(void(*f)())) ()
	{
		void(*old)() = _Malloc_alloc_oom_handler;
		_Malloc_alloc_oom_handler = f;
		return (old);
	}

private:
	//通过用户提供的释放空间(释放自己已经不用了的空间)的函数不断的释放空间并检测
	//直到释放出的空间足够分配给申请的空间
	//如果用户没有提供释放空间的函数,则抛异常
	static void* Oom_malloc(size_t size)
	{
		void* result;
		void(*My_malloc_handler)();
		for (;;)
		{
			My_malloc_handler = _Malloc_alloc_oom_handler;
			if (0 == My_malloc_handler)//用户没有提供释放空间的函数
				THROW_BAD_ALLOC;
			result = malloc(size);
			if (result)
				return result;
		}
	}

	static void* Oom_realloc(void* p, size_t size)
	{
		void* result;
		void(*my_malloc_handler) ();
		for (;;)
		{
			my_malloc_handler = _Malloc_alloc_oom_handler;
			if (0 == my_malloc_handler)
				THROW_BAD_ALLOC;
			result = realloc(p, size);
			if (result)
				return result;
		}
	}

private:
	static void(*_Malloc_alloc_oom_handler)();
};

//类外初始化静态成员变量 _malloc_alloc_oom_handler
template <int inst>
void(* Alloc_malloc_template<inst>::_Malloc_alloc_oom_handler)() = 0;


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值