void* NdbMem_Allocate(size_t size) { // Address Windowing Extensions struct AWEINFO* pAWEinfo; HANDLE hProcess; SYSTEM_INFO sysinfo; if(!gNdbMem_pAWEinfo) { gNdbMem_pAWEinfo = VirtualAlloc(0, sizeof(struct AWEINFO)*cNdbMem_nMaxAWEinfo, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); } assert(gNdbMem_nAWEinfo < cNdbMem_nMaxAWEinfo); pAWEinfo = gNdbMem_pAWEinfo+gNdbMem_nAWEinfo++; hProcess = GetCurrentProcess(); GetSystemInfo(&sysinfo); pAWEinfo->nNumberOfPagesRequested = (size+sysinfo.dwPageSize-1)/sysinfo.dwPageSize; pAWEinfo->pnPhysicalMemoryPageArray = VirtualAlloc(0, sizeof(ULONG_PTR)*pAWEinfo->nNumberOfPagesRequested, MEM_COMMIT|MEM_RESERVE, PAGE_READWRITE); pAWEinfo->nNumberOfPagesActual = pAWEinfo->nNumberOfPagesRequested; if(!AllocateUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesActual), pAWEinfo->pnPhysicalMemoryPageArray)) { ShowLastError("NdbMem_Allocate", "AllocateUserPhysicalPages"); return 0; } if(pAWEinfo->nNumberOfPagesRequested != pAWEinfo->nNumberOfPagesActual) { ShowLastError("NdbMem_Allocate", "nNumberOfPagesRequested != nNumberOfPagesActual"); return 0; } pAWEinfo->dwSizeInBytesRequested = size; pAWEinfo->pRegionReserved = VirtualAlloc(0, pAWEinfo->dwSizeInBytesRequested, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE); if(!pAWEinfo->pRegionReserved) { ShowLastError("NdbMem_Allocate", "VirtualAlloc"); return 0; } if(!MapUserPhysicalPages(pAWEinfo->pRegionReserved, pAWEinfo->nNumberOfPagesActual, pAWEinfo->pnPhysicalMemoryPageArray)) { ShowLastError("NdbMem_Allocate", "MapUserPhysicalPages"); return 0; } /* printf("allocate AWE memory: %lu bytes, %lu pages, address %lx\n", pAWEinfo->dwSizeInBytesRequested, pAWEinfo->nNumberOfPagesActual, pAWEinfo->pRegionReserved); */ return pAWEinfo->pRegionReserved; }
void GMem_Create(void) { if(bGMemIsActive) return; SYSTEM_INFO SystemInfo; GetSystemInfo(&SystemInfo); dwGMemPhyPageSize = SystemInfo.dwPageSize; dwGMemUsedPhyBytes = ((dwGMemTotalBytes / SystemInfo.dwAllocationGranularity) + (DWORD)(0 < (dwGMemTotalBytes % SystemInfo.dwAllocationGranularity))) * SystemInfo.dwAllocationGranularity; dwGMemUsedPhyPageNumber = (ULONG_PTR)(dwGMemUsedPhyBytes / dwGMemPhyPageSize + (DWORD)(0 < (dwGMemUsedPhyBytes % dwGMemPhyPageSize))); pulGMemUsedPhyPageArray = new ULONG_PTR[dwGMemUsedPhyPageNumber]; SetPrivilege(TRUE); BOOL bFlag = AllocateUserPhysicalPages(GetCurrentProcess(), &dwGMemUsedPhyPageNumber, pulGMemUsedPhyPageArray); SetPrivilege(FALSE); if(!bFlag) { delete pulGMemUsedPhyPageArray; return; } dwGMemUsedPhyBytes = dwGMemUsedPhyPageNumber * dwGMemPhyPageSize; dwGMemPageNumber = (DWORD)(dwGMemUsedPhyBytes / dwGMemPageSize); dwGMemTotalBytes = dwGMemPageNumber * dwGMemPageSize; pGMemAddrHead = VirtualAlloc(NULL, dwGMemUsedPhyBytes, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE); /* DWORD dwerr = GetLastError();*/ if(!pGMemAddrHead) { FreeUserPhysicalPages(GetCurrentProcess(), &dwGMemUsedPhyPageNumber, pulGMemUsedPhyPageArray); delete pulGMemUsedPhyPageArray; return; } pGMemAddrTail = ((char *)pGMemAddrHead + dwGMemTotalBytes); if(!MapUserPhysicalPages(pGMemAddrHead, dwGMemUsedPhyPageNumber, pulGMemUsedPhyPageArray)) { FreeUserPhysicalPages(GetCurrentProcess(), &dwGMemUsedPhyPageNumber, pulGMemUsedPhyPageArray); VirtualFree(pGMemAddrHead, 0, MEM_RELEASE); delete pulGMemUsedPhyPageArray; return; } dwGMemSysUsedBytes = dwGMemUsedPhyPageNumber * sizeof(ULONG_PTR); CopyMemory(pGMemAddrHead, pulGMemUsedPhyPageArray, dwGMemSysUsedBytes); delete pulGMemUsedPhyPageArray; pulGMemUsedPhyPageArray = (PULONG_PTR)pGMemAddrHead; pmbGMemUsedFlag = (PGMEM_BLOCK*)(((char*)pGMemAddrHead) + dwGMemSysUsedBytes); dwGMemSysUsedBytes += (dwGMemPageNumber * sizeof(PGMEM_BLOCK)); ZeroMemory(pmbGMemUsedFlag, dwGMemPageNumber * sizeof(PGMEM_BLOCK)); pmbGMemNodePool = (PGMEM_BLOCK)(((char*)pGMemAddrHead) + dwGMemSysUsedBytes); dwGMemSysUsedBytes += (dwGMemPageNumber * sizeof(GMEM_BLOCK)); DWORD i; PGMEM_BLOCK pmbBlock; pmbBlock = pmbGMemNodePool; pmbBlock->pPrior = NULL; for(i = 1; i < dwGMemPageNumber; i++) { pmbBlock->pNext = &(pmbGMemNodePool[i]); pmbBlock = pmbBlock->pNext ; } pmbBlock->pNext = NULL; dwGMemUsedBytes = dwGMemPhyPageSize * ((dwGMemSysUsedBytes / dwGMemPhyPageSize) + (0 < (dwGMemSysUsedBytes % dwGMemPhyPageSize))); dwGMemSysUsedBytes = dwGMemUsedBytes; pmbGMemList = pmbGMemNodePool; pmbGMemNodePool = pmbGMemNodePool->pNext; pmbGMemList->pPrior = NULL; pmbGMemList->pNext = NULL; pmbGMemList->pFreePrior = NULL; pmbGMemList->pFreeNext = NULL; pmbGMemList->bIsFree = TRUE; pmbGMemList->pAddr = (PGMEM_BLOCK)(((char*)pGMemAddrHead) + dwGMemUsedBytes); pmbGMemList->dwSize = dwGMemTotalBytes - dwGMemUsedBytes; pmbGMemFreeList = pmbGMemList; bGMemIsActive = TRUE; InitializeCriticalSection(&csGMemCritical); }
int _cdecl main(int argc, char** argv) { BOOL bResult; // generic Boolean value ULONG_PTR NumberOfPages; // number of pages to request ULONG_PTR NumberOfPagesInitial; // initial number of pages requested ULONG_PTR *aPFNs; // page info; holds opaque data PVOID lpMemReserved; // AWE window SYSTEM_INFO sSysInfo; // useful system information int PFNArraySize; // memory to request for PFN array int i; // iterator int bytes; // Number of bytes to request if (argc != 2) { printf ("Usage: %s <number_of_bytes_to_allocate>\n", argv[0]); return 1; } bytes = atoi(argv[1]); printf("Attempting to allocate %d bytes.\n", bytes); GetSystemInfo(&sSysInfo); // fill the system information structure printf("This computer has page size %d.\n", sSysInfo.dwPageSize); // Calculate the number of pages of memory to request. NumberOfPages = bytes/sSysInfo.dwPageSize; printf ("Requesting %d pages of memory.\n", NumberOfPages); // Calculate the size of the user PFN array. PFNArraySize = NumberOfPages * sizeof (ULONG_PTR); printf ("Requesting a PFN array of %d bytes.\n", PFNArraySize); aPFNs = (ULONG_PTR *) HeapAlloc(GetProcessHeap(), 0, PFNArraySize); if (aPFNs == NULL) { printf ("Failed to allocate on heap.\n"); return 1; } // Enable the privilege. if( ! LoggedSetLockPagesPrivilege( GetCurrentProcess(), TRUE ) ) { return 1; } // Allocate the physical memory. NumberOfPagesInitial = NumberOfPages; bResult = AllocateUserPhysicalPages( GetCurrentProcess(), &NumberOfPages, aPFNs ); if( bResult != TRUE ) { printf("Cannot allocate physical pages (%u)\n", GetLastError() ); return 1; } if( NumberOfPagesInitial != NumberOfPages ) { printf("Allocated only %p pages.\n", NumberOfPages ); return 1; } // Reserve the virtual memory. lpMemReserved = VirtualAlloc( NULL, bytes, MEM_RESERVE | MEM_PHYSICAL, PAGE_READWRITE ); if( lpMemReserved == NULL ) { printf("Cannot reserve memory.\n"); return 1; } // Map the physical memory into the window. bResult = MapUserPhysicalPages( lpMemReserved, NumberOfPages, aPFNs ); if( bResult != TRUE ) { printf("MapUserPhysicalPages failed (%u)\n", GetLastError() ); return 1; } while (1) Sleep(30); return 0; }
ibool os_awe_allocate_physical_mem( /*=========================*/ /* out: TRUE if success */ os_awe_t** page_info, /* out, own: array of opaque data containing the info for allocated physical memory pages; each allocated 4 kB physical memory page has one slot of type os_awe_t in the array */ ulint n_megabytes) /* in: number of megabytes to allocate */ { #ifdef UNIV_SIMULATE_AWE os_awe_simulate_page_info = ut_malloc (sizeof(os_awe_t) * n_megabytes * ((1024 * 1024) / OS_AWE_X86_PAGE_SIZE)); os_awe_simulate_mem = ut_align(ut_malloc(4096 + 1024 * 1024 * n_megabytes), 4096); os_awe_simulate_mem_size = n_megabytes * 1024 * 1024; *page_info = os_awe_simulate_page_info; return(TRUE); #elif defined(__WIN2000__) BOOL bResult; os_awe_t NumberOfPages; /* Question: why does Windows use the name ULONG_PTR for a scalar integer type? Maybe because we may also refer to &NumberOfPages? */ os_awe_t NumberOfPagesInitial; SYSTEM_INFO sSysInfo; int PFNArraySize; if (n_megabytes > 64 * 1024) { fprintf(stderr, "InnoDB: AWE: Error: tried to allocate %lu MB.\n" "InnoDB: AWE cannot allocate more than" " 64 GB in any computer.\n", n_megabytes); return(FALSE); } GetSystemInfo(&sSysInfo); /* fill the system information structure */ if ((ulint)OS_AWE_X86_PAGE_SIZE != (ulint)sSysInfo.dwPageSize) { fprintf(stderr, "InnoDB: AWE: Error: this computer has a page size" " of %lu.\n" "InnoDB: Should be 4096 bytes for" " InnoDB AWE support to work.\n", (ulint)sSysInfo.dwPageSize); return(FALSE); } /* Calculate the number of pages of memory to request */ NumberOfPages = n_megabytes * ((1024 * 1024) / OS_AWE_X86_PAGE_SIZE); /* Calculate the size of page_info for allocated physical pages */ PFNArraySize = NumberOfPages * sizeof(os_awe_t); *page_info = (os_awe_t*)HeapAlloc(GetProcessHeap(), 0, PFNArraySize); if (*page_info == NULL) { fprintf(stderr, "InnoDB: AWE: Failed to allocate page info" " array from process heap, error %lu\n", (ulint)GetLastError()); return(FALSE); } ut_total_allocated_memory += PFNArraySize; /* Enable this process' privilege to lock pages to physical memory */ if (!os_awe_enable_lock_pages_in_mem()) { return(FALSE); } /* Allocate the physical memory */ NumberOfPagesInitial = NumberOfPages; os_awe_page_info = *page_info; os_awe_n_pages = (ulint)NumberOfPages; /* Compilation note: if the compiler complains the function is not defined, see the note at the start of this file */ bResult = AllocateUserPhysicalPages(GetCurrentProcess(), &NumberOfPages, *page_info); if (bResult != TRUE) { fprintf(stderr, "InnoDB: AWE: Cannot allocate physical pages," " error %lu.\n", (ulint)GetLastError()); return(FALSE); } if (NumberOfPagesInitial != NumberOfPages) { fprintf(stderr, "InnoDB: AWE: Error: allocated only %lu pages" " of %lu requested.\n" "InnoDB: Check that you have enough free RAM.\n" "InnoDB: In Windows XP Professional and" " 2000 Professional\n" "InnoDB: Windows PAE size is max 4 GB." " In 2000 and .NET\n" "InnoDB: Advanced Servers and 2000 Datacenter Server" " it is 32 GB,\n" "InnoDB: and in .NET Datacenter Server it is 64 GB.\n" "InnoDB: A Microsoft web page said that" " the processor must be an Intel\n" "InnoDB: processor.\n", (ulint)NumberOfPages, (ulint)NumberOfPagesInitial); return(FALSE); } fprintf(stderr, "InnoDB: Using Address Windowing Extensions (AWE);" " allocated %lu MB\n", n_megabytes); return(TRUE); #else UT_NOT_USED(n_megabytes); UT_NOT_USED(page_info); return(FALSE); #endif }