MEM_LARGE_PAGES
Posted: Wed Sep 18, 2013 8:33 pm
Hi,
I've been trying to make the hash table to be allocated using MEM_LARGE_PAGES, but I haven't been able to do it successfully.
I have already set the right account privileges manually and run my engine just right after reboot, but it just doesn't work, it allways gives the error:
"GC large_page: No required number of large pages found. Please reboot.....".
I use Windows 7 x64, and a core i7 i950, and 24Gb RAM.
The function to use in the code below is:
void* alloc_large_pages(size_t size, const char* hint) ;
the second parameter 'hint' has no use.
Does anyone have managed to do this successfully?
best regards,
Alvaro
I've been trying to make the hash table to be allocated using MEM_LARGE_PAGES, but I haven't been able to do it successfully.
I have already set the right account privileges manually and run my engine just right after reboot, but it just doesn't work, it allways gives the error:
"GC large_page: No required number of large pages found. Please reboot.....".
I use Windows 7 x64, and a core i7 i950, and 24Gb RAM.
The function to use in the code below is:
void* alloc_large_pages(size_t size, const char* hint) ;
the second parameter 'hint' has no use.
Does anyone have managed to do this successfully?
best regards,
Alvaro
Code: Select all
// make baseNumber multiple of number, without decreasing baseNumber
size_t myMakeMultiple(size_t baseNumber, size_t number) {
size_t multiple;
multiple = baseNumber + number - 1;
multiple -= (multiple % number);
return multiple;
}
bool set_privilege(HANDLE process, LPCTSTR priv_name, bool is_enable)
{
HANDLE token;
TOKEN_PRIVILEGES tp;
BOOL res = OpenProcessToken(process, TOKEN_ADJUST_PRIVILEGES, &token);
if(!res){
return FALSE;
}
tp.PrivilegeCount = 1;
tp.Privileges[0].Attributes = is_enable ? SE_PRIVILEGE_ENABLED : 0;
res = LookupPrivilegeValue( NULL, priv_name, &tp.Privileges[0].Luid);
if(!res){
CloseHandle(token);
return FALSE;
}
if (AdjustTokenPrivileges( token, FALSE, &tp, 0, NULL, 0) == ERROR_NOT_ALL_ASSIGNED) {
CloseHandle(token);
return FALSE;
}
return TRUE;
}
bool obtain_lock_memory_priv()
{
HANDLE process = GetCurrentProcess();
return set_privilege(process, SE_LOCK_MEMORY_NAME, TRUE);
}
bool release_lock_memory_priv()
{
HANDLE process = GetCurrentProcess();
return set_privilege(process, SE_LOCK_MEMORY_NAME, FALSE);
}
void* alloc_large_pages(size_t size, const char* hint)
{
void* alloc_addr = NULL;
bool lock_memory_enable = obtain_lock_memory_priv();
if(lock_memory_enable){
size_t page_min = GetLargePageMinimum();
size = myMakeMultiple(size, page_min);
alloc_addr = VirtualAlloc(NULL, size, MEM_RESERVE | MEM_COMMIT | MEM_LARGE_PAGES, PAGE_READWRITE);
release_lock_memory_priv();
if(alloc_addr == NULL){
Print_to_logfile("GC large_page: No required number of large pages found. Please reboot.....");
return NULL;
}else
return alloc_addr;
}else{
Print_to_logfile("GC large_page: Check that you have permissions:\nGC large_page: Control Panel->Administrative Tools->Local Security Settings->->User Rights Assignment->Lock pages in memory.\nGC large_page: Start VM as soon after reboot as possible, because large pages become fragmented and unusable after a while.\nGC large_page: Heap size should be multiple of large page size.");
return NULL;
}
}