Super Smart Pointer - Sample Code
In continuance to my last post about memory allocations from mapped files http://blogs.microsoft.co.il/blogs/asafshelly/archive/2008/09/07/super-smart-pointer.aspx (and because Lior asked for it :) Here is the sample that I used to test the timing:
Includes:
#include "stdafx.h"
#include <WINDOWS.H>
#include <conio.h>
#define PAUSE { puts("Ready"); getch(); }
Interface:
class AllocBuff
{
public:
virtual bool New(int bytes) { return(NULL); }
virtual bool Delete() { return(false); }
virtual char* Lock() { return(false); }
virtual bool Unlock() { return(false); }
};
Memory Implementation
class MemBuff: public AllocBuff
{
char* buff;
CRITICAL_SECTION cSection;
public:
virtual bool New(int bytes)
{
InitializeCriticalSection(&cSection);
try { buff = new char[bytes]; } catch(...) { buff = NULL; }
return(buff);
}
virtual bool Delete()
{
DeleteCriticalSection(&cSection);
delete[] buff; buff = NULL;
return(true);
}
virtual char* Lock()
{
if (!buff) return(NULL);
EnterCriticalSection(&cSection);
return(buff);
}
virtual bool Unlock()
{
LeaveCriticalSection(&cSection);
return(true);
}
};
File Mapping Implementation
class FileBuff: public AllocBuff
{
static HANDLE hFile;
static HANDLE hFileMap;
static char* nextBuff;
static int tempID;
static int pageSize; int size;
char* buff;
char* mappedBuff;
CRITICAL_SECTION cSection;
public:
static bool Init()
{
SYSTEM_INFO info;
GetSystemInfo(&info);
pageSize = info.dwAllocationGranularity;
char fileName[MAX_PATH];
GetTempFileName(".", "FileBuff", tempID, fileName);
tempID++;
if (INVALID_HANDLE_VALUE != (hFile = CreateFile(fileName, GENERIC_READ|GENERIC_WRITE, FILE_SHARE_READ|FILE_SHARE_WRITE|FILE_SHARE_DELETE, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_TEMPORARY|FILE_FLAG_DELETE_ON_CLOSE, NULL)))
{
if (NULL != (hFileMap = CreateFileMapping(hFile, NULL, PAGE_READWRITE, 4, -1, NULL))) return(true);
}
return(false);
}
virtual bool New(int bytes)
{
if (NULL == hFileMap) { if (!Init()) return(NULL); }
InitializeCriticalSection(&cSection);
size = bytes;
buff = nextBuff;
nextBuff += bytes;
mappedBuff = NULL;
}
virtual bool DeInit()
{
// .... etc.
return(CloseHandle(hFile));
}
virtual bool Delete()
{
size = 0;
buff = NULL;
DeleteCriticalSection(&cSection);
return(true);
}
virtual char* Lock()
{
EnterCriticalSection(&cSection);
if (!(mappedBuff = (char*)MapViewOfFile(hFileMap, FILE_MAP_ALL_ACCESS, 0, ((DWORD)buff)/pageSize*pageSize, ((DWORD)buff) + size - ((DWORD)buff)/pageSize*pageSize)))
{
DWORD dw = GetLastError();
LeaveCriticalSection(&cSection);
return(NULL);
}
mappedBuff = mappedBuff + ((DWORD)buff)%pageSize;
return(mappedBuff);
}
bool Unlock()
{
if (mappedBuff)
{
UnmapViewOfFile(mappedBuff);
}
LeaveCriticalSection(&cSection);
return(true);
}
};
int FileBuff::tempID = 1;
int FileBuff::pageSize = 0;
char* FileBuff::nextBuff = (char*)0x10000;
HANDLE FileBuff::hFile = INVALID_HANDLE_VALUE;
HANDLE FileBuff::hFileMap = NULL;
Test Application - main
int _tmain(int argc, _TCHAR* argv[])
{
char* str = "In continuance to my last post about memory allocations from mapped files http://blogs.microsoft.co.il/blogs/asafshelly/archive/2008/09/07/super-smart-pointer.aspx (and because Lior asked for it :) Here is the sample that I used to test the timing...\n";
OutputDebugString("Starting\n");
for (int i = 0; i < 2000000; i++)
{
// AllocBuff* buff = (AllocBuff*)new MemBuff;
// AllocBuff* buff = (AllocBuff*)new FileBuff;
buff->New(255);
char* ptr = buff->Lock();
if (!ptr) throw("char* ptr = buff->Lock()");
memcpy(ptr, str, strlen(str) + 1); buff->Unlock(); ptr = NULL;
buff->Delete();
delete buff; buff = NULL;
}
OutputDebugString("Done\n");
PAUSE;
return 0;
}
Use DebugView to mesure times.
Asaf