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;


發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章