📄 sharedpool.cpp
字号:
/***********************************************************************
Copyright 2002 Ben Rudiak-Gould.
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA,
or visit <http://www.gnu.org/copyleft/gpl.html>.
***********************************************************************/
#define WIN32_LEAN_AND_MEAN
#define STRICT
#include <windows.h>
#include "SharedPool.h"
#include "miniport.h"
/*******************************************************************\
\*******************************************************************/
inline void* PageReserve(unsigned npages) {
return VirtualAlloc(NULL, npages*4096, MEM_RESERVE, PAGE_READWRITE);
}
inline bool PageCommit(void* p, unsigned npages) {
return !!VirtualAlloc(p, npages*4096, MEM_COMMIT, PAGE_READWRITE);
}
inline unsigned PageFree(void* p) {
return VirtualFree(p, 0, MEM_RELEASE);
}
/*******************************************************************\
\*******************************************************************/
class SharedPool {
char* latest_block_next_free_byte;
char* latest_block_end;
unsigned latest_block_index;
int locked;
char* blocks[18];
public:
static void* Create(int _locked);
void* Allocate(unsigned len);
void Clear();
void Delete();
};
inline void* SharedPool::Create(int _locked) {
char* block = (char*)PageReserve(1);
if (!block) {
return 0;
}
if (!PageCommit(block, 1)) {
PageFree(block);
return 0;
}
SharedPool* self = (SharedPool*)block;
self->latest_block_next_free_byte = block + sizeof(SharedPool);
self->latest_block_end = block + 4096;
self->locked = _locked;
self->blocks[0] = block;
return self;
}
inline void* SharedPool::Allocate(unsigned len) {
len = (len+3) & -4;
char* alloc_end = latest_block_next_free_byte + len;
if (alloc_end > latest_block_end) {
// Current block isn't big enough; allocate a new one. The size of
// block N is at least 4K * 2^N, to ensure that we'll run out of
// virtual address space before we run out of array slots.
unsigned pages_to_alloc = max((len + 4095U) >> 12, 2U << latest_block_index);
char* new_block = (char*)PageReserve(pages_to_alloc);
if (new_block == 0) {
return 0;
}
latest_block_next_free_byte = new_block;
latest_block_end = new_block + pages_to_alloc*4096;
++latest_block_index;
blocks[latest_block_index] = new_block;
alloc_end = new_block + len;
}
char* first_uncommitted_byte = (char*)(((unsigned)latest_block_next_free_byte + 4095) & -4096);
if (alloc_end > first_uncommitted_byte) {
unsigned pages_to_commit = (alloc_end - first_uncommitted_byte + 4095) >> 12;
if (!PageCommit(first_uncommitted_byte, pages_to_commit)) {
return 0;
}
}
void* rtn = latest_block_next_free_byte;
latest_block_next_free_byte = alloc_end;
return rtn;
}
inline void SharedPool::Clear() {
for (unsigned i=1; i<=latest_block_index; ++i) {
PageFree(blocks[i]);
}
latest_block_next_free_byte = blocks[0] + sizeof(SharedPool);
latest_block_end = blocks[0] + 4096;
latest_block_index = 0;
}
inline void SharedPool::Delete() {
for (unsigned i=1; i<=latest_block_index; ++i) {
PageFree(blocks[i]);
}
PageFree(blocks[0]);
}
void* SharedPool_Create(int locked) {
return SharedPool::Create(locked);
}
void* SharedPool_Alloc(void* self, unsigned len) {
return ((SharedPool*)self)->Allocate(len);
}
void SharedPool_Clear(void* self) {
((SharedPool*)self)->Clear();
}
void SharedPool_Delete(void* self) {
((SharedPool*)self)->Delete();
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -