knight/shared/KePageAllocator.cpp
author GoD-Tony <aangione@gmail.com>
Sun Aug 04 10:03:40 2013 -0400 (2013-08-04)
changeset 3971 d2e8100b2814
parent 2226 d10b38524be3
permissions -rw-r--r--
Added ISDKHooks interface with entity listeners (bug 5602, r=psychonic).
dvander@2226
     1
#include "KePageAllocator.h"
dvander@2226
     2
dvander@2226
     3
using namespace Knight;
dvander@2226
     4
dvander@2226
     5
struct PageInfo
dvander@2226
     6
{
dvander@2226
     7
	PageInfo *next;
dvander@2226
     8
	void *base;
dvander@2226
     9
};
dvander@2226
    10
dvander@2226
    11
class Knight::KePageAllocator
dvander@2226
    12
{
dvander@2226
    13
public:
dvander@2226
    14
	size_t page_size;
dvander@2226
    15
	size_t page_granularity;
dvander@2226
    16
	PageInfo *free_pages;
dvander@2226
    17
	PageInfo *page_blocks;
dvander@2226
    18
};
dvander@2226
    19
dvander@2226
    20
static void *ke_LumpPageAlloc(KePageAllocator *alloc)
dvander@2226
    21
{
dvander@2226
    22
	void *base;
dvander@2226
    23
	char *page;
dvander@2226
    24
	PageInfo *lump;
dvander@2226
    25
	size_t pagesInBlock;
dvander@2226
    26
dvander@2226
    27
#if defined KE_PLATFORM_WINDOWS
dvander@2226
    28
	base = VirtualAlloc(
dvander@2226
    29
		NULL,
dvander@2226
    30
		alloc->page_granularity,
dvander@2226
    31
		MEM_COMMIT|MEM_RESERVE,
dvander@2226
    32
		PAGE_READWRITE);
dvander@2226
    33
#elif defined KE_PLATFORM_POSIX
dvander@2226
    34
	base = valloc(alloc->page_granularity);
dvander@2226
    35
#else 
dvander@2226
    36
#error "Unsupported platform"
dvander@2226
    37
#endif
dvander@2226
    38
dvander@2226
    39
	if (base == NULL)
dvander@2226
    40
	{
dvander@2226
    41
		return NULL;
dvander@2226
    42
	}
dvander@2226
    43
dvander@2226
    44
	lump = new PageInfo;
dvander@2226
    45
	lump->base = base;
dvander@2226
    46
	lump->next = alloc->page_blocks;
dvander@2226
    47
	alloc->page_blocks = lump->next;
dvander@2226
    48
dvander@2226
    49
	page = (char *)base + alloc->page_size;
dvander@2226
    50
	pagesInBlock = alloc->page_granularity / alloc->page_size;
dvander@2226
    51
dvander@2226
    52
	for (size_t i = 1; i < pagesInBlock; i++)
dvander@2226
    53
	{
dvander@2226
    54
		lump = new PageInfo;
dvander@2226
    55
		lump->base = page;
dvander@2226
    56
		lump->next = alloc->free_pages;
dvander@2226
    57
		alloc->free_pages = lump;
dvander@2226
    58
		page += alloc->page_size;
dvander@2226
    59
	}
dvander@2226
    60
dvander@2226
    61
	return base;
dvander@2226
    62
}
dvander@2226
    63
dvander@2226
    64
KePageAllocator *Knight::KE_CreatePageAllocator()
dvander@2226
    65
{
dvander@2226
    66
	KePageAllocator *alloc;
dvander@2226
    67
dvander@2226
    68
	alloc = new KePageAllocator;
dvander@2226
    69
	
dvander@2226
    70
#if defined KE_PLATFORM_WINDOWS
dvander@2226
    71
	SYSTEM_INFO info;
dvander@2226
    72
	
dvander@2226
    73
	GetSystemInfo(&info);
dvander@2226
    74
	alloc->page_size = info.dwPageSize;
dvander@2226
    75
	alloc->page_granularity = info.dwAllocationGranularity;
dvander@2226
    76
#elif defined KE_PLATFORM_POSIX
dvander@2226
    77
	alloc->page_size = sysconf(_SC_PAGESIZE);
dvander@2226
    78
	alloc->page_granularity = alloc->page_size * 16;
dvander@2226
    79
#else 
dvander@2226
    80
#error "Unsupported platform"
dvander@2226
    81
#endif
dvander@2226
    82
dvander@2226
    83
	alloc->free_pages = NULL;
dvander@2226
    84
	alloc->page_blocks = NULL;
dvander@2226
    85
dvander@2226
    86
	return alloc;
dvander@2226
    87
}
dvander@2226
    88
dvander@2226
    89
void Knight::KE_DestroyPageAllocator(KePageAllocator *alloc)
dvander@2226
    90
{
dvander@2226
    91
	PageInfo *info, *next;
dvander@2226
    92
dvander@2226
    93
	info = alloc->page_blocks;
dvander@2226
    94
	while (info != NULL)
dvander@2226
    95
	{
dvander@2226
    96
		next = info->next;
dvander@2226
    97
#if defined KE_PLATFORM_WINDOWS
dvander@2226
    98
		VirtualFree(info->base, 0, MEM_RELEASE);
dvander@2226
    99
#elif defined KE_PLATFORM_WINDOWS
dvander@2226
   100
		free(info->base);
dvander@2226
   101
#else 
dvander@2226
   102
#error "Unsupported platform"
dvander@2226
   103
#endif
dvander@2226
   104
		delete info;
dvander@2226
   105
		next = info;
dvander@2226
   106
	}
dvander@2226
   107
dvander@2226
   108
	info = alloc->free_pages;
dvander@2226
   109
	while (info != NULL)
dvander@2226
   110
	{
dvander@2226
   111
		next = info->next;
dvander@2226
   112
		delete info;
dvander@2226
   113
		info = next;
dvander@2226
   114
	}
dvander@2226
   115
}
dvander@2226
   116
dvander@2226
   117
void *Knight::KE_PageAlloc(KePageAllocator *alloc)
dvander@2226
   118
{
dvander@2226
   119
	if (alloc->free_pages != NULL)
dvander@2226
   120
	{
dvander@2226
   121
		void *base;
dvander@2226
   122
		PageInfo *info;
dvander@2226
   123
dvander@2226
   124
		info = alloc->free_pages;
dvander@2226
   125
		alloc->free_pages = info->next;
dvander@2226
   126
		base = info->base;
dvander@2226
   127
		delete info;
dvander@2226
   128
dvander@2226
   129
		return base;
dvander@2226
   130
	}
dvander@2226
   131
dvander@2226
   132
	return ke_LumpPageAlloc(alloc);
dvander@2226
   133
}
dvander@2226
   134
dvander@2226
   135
void Knight::KE_PageFree(KePageAllocator *alloc, void *page)
dvander@2226
   136
{
dvander@2226
   137
	PageInfo *info;
dvander@2226
   138
dvander@2226
   139
	info = new PageInfo;
dvander@2226
   140
	info->base = page;
dvander@2226
   141
	info->next = alloc->free_pages;
dvander@2226
   142
	alloc->free_pages = info->next;
dvander@2226
   143
}
dvander@2226
   144
dvander@2226
   145
size_t Knight::KE_PageSize(KePageAllocator *alloc)
dvander@2226
   146
{
dvander@2226
   147
	return alloc->page_size;
dvander@2226
   148
}