void GMem_Destroy(void) { bGMemIsActive = FALSE; if(!pGMemAddrHead) return; pulGMemUsedPhyPageArray = new ULONG_PTR[dwGMemUsedPhyPageNumber]; CopyMemory(pulGMemUsedPhyPageArray, pGMemAddrHead, dwGMemUsedPhyPageNumber * sizeof(ULONG_PTR)); MapUserPhysicalPages(pGMemAddrHead, dwGMemUsedPhyPageNumber, NULL); FreeUserPhysicalPages(GetCurrentProcess(), &dwGMemUsedPhyPageNumber, pulGMemUsedPhyPageArray); VirtualFree(pGMemAddrHead, 0, MEM_RELEASE); delete pulGMemUsedPhyPageArray; dwGMemUsedPhyPageNumber = 0; dwGMemUsedPhyBytes = 0; pulGMemUsedPhyPageArray = NULL; dwGMemUsedBytes = 0; dwGMemSysUsedBytes = 0; pGMemAddrHead = NULL; pGMemAddrTail = NULL; pmbGMemNodePool = NULL; pmbGMemList = NULL; pmbGMemUsedFlag = NULL; pmbGMemFreeList = NULL; DeleteCriticalSection(&csGMemCritical); }
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; }
BOOL My_MapUserPhysicalPages() { PVOID VirtualAddress=NULL; ULONG_PTR NumberOfPages=NULL; PULONG_PTR PageArray=NULL; BOOL returnVal_Real = NULL; BOOL returnVal_Intercepted = NULL; DWORD error_Real = 0; DWORD error_Intercepted = 0; __try{ disableInterception(); returnVal_Real = MapUserPhysicalPages (VirtualAddress,NumberOfPages,PageArray); error_Real = GetLastError(); enableInterception(); returnVal_Intercepted = MapUserPhysicalPages (VirtualAddress,NumberOfPages,PageArray); error_Intercepted = GetLastError(); }__except(puts("in filter"), 1){puts("exception caught");} return ((returnVal_Real == returnVal_Intercepted) && (error_Real == error_Intercepted)); }
void NdbMem_Free(void* ptr) { // VirtualFree(ptr, 0, MEM_DECOMMIT|MEM_RELEASE); // Address Windowing Extensions struct AWEINFO* pAWEinfo = 0; size_t i; HANDLE hProcess; for(i=0; i<gNdbMem_nAWEinfo; ++i) { if(ptr==gNdbMem_pAWEinfo[i].pRegionReserved) { pAWEinfo = gNdbMem_pAWEinfo+i; } } if(!pAWEinfo) { ShowLastError("NdbMem_Free", "ptr is not AWE memory"); } hProcess = GetCurrentProcess(); if(!MapUserPhysicalPages(ptr, pAWEinfo->nNumberOfPagesActual, 0)) { ShowLastError("NdbMem_Free", "MapUserPhysicalPages"); } if(!VirtualFree(ptr, 0, MEM_RELEASE)) { ShowLastError("NdbMem_Free", "VirtualFree"); } pAWEinfo->nNumberOfPagesFreed = pAWEinfo->nNumberOfPagesActual; if(!FreeUserPhysicalPages(hProcess, &(pAWEinfo->nNumberOfPagesFreed), pAWEinfo->pnPhysicalMemoryPageArray)) { ShowLastError("NdbMem_Free", "FreeUserPhysicalPages"); } VirtualFree(pAWEinfo->pnPhysicalMemoryPageArray, 0, MEM_DECOMMIT|MEM_RELEASE); }
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_map_physical_mem_to_window( /*==============================*/ /* out: TRUE if success; the function calls exit(1) in case of an error */ byte* ptr, /* in: a page-aligned pointer to somewhere in the virtual address space window; we map the physical mem pages here */ ulint n_mem_pages, /* in: number of 4 kB mem pages to map */ os_awe_t* page_info) /* in: array of page infos for those pages; each page has one slot in the array */ { #ifdef UNIV_SIMULATE_AWE ulint i; byte** map; byte* page; byte* phys_page; ut_a(ptr >= os_awe_simulate_window); ut_a(ptr < os_awe_simulate_window + os_awe_simulate_window_size); ut_a(page_info >= os_awe_simulate_page_info); ut_a(page_info < os_awe_simulate_page_info + (os_awe_simulate_mem_size / 4096)); /* First look if some other 'physical pages' are mapped at ptr, and copy them back to where they were if yes */ map = os_awe_simulate_map + ((ulint)(ptr - os_awe_simulate_window)) / 4096; page = ptr; for (i = 0; i < n_mem_pages; i++) { if (*map != NULL) { ut_memcpy(*map, page, 4096); } map++; page += 4096; } /* Then copy to ptr the 'physical pages' determined by page_info; we assume page_info is a segment of the array we created at the start */ phys_page = os_awe_simulate_mem + (ulint)(page_info - os_awe_simulate_page_info) * 4096; ut_memcpy(ptr, phys_page, n_mem_pages * 4096); /* Update the map */ map = os_awe_simulate_map + ((ulint)(ptr - os_awe_simulate_window)) / 4096; for (i = 0; i < n_mem_pages; i++) { *map = phys_page; map++; phys_page += 4096; } return(TRUE); #elif defined(__WIN2000__) BOOL bResult; os_awe_t n_pages; n_pages = (os_awe_t)n_mem_pages; if (!(ptr >= os_awe_window)) { fprintf(stderr, "InnoDB: AWE: Error: trying to map to address %lx" " but AWE window start %lx\n", (ulint)ptr, (ulint)os_awe_window); ut_a(0); } if (!(ptr <= os_awe_window + os_awe_window_size - UNIV_PAGE_SIZE)) { fprintf(stderr, "InnoDB: AWE: Error: trying to map to address %lx" " but AWE window end %lx\n", (ulint)ptr, (ulint)os_awe_window + os_awe_window_size); ut_a(0); } if (!(page_info >= os_awe_page_info)) { fprintf(stderr, "InnoDB: AWE: Error: trying to map page info" " at %lx but array start %lx\n", (ulint)page_info, (ulint)os_awe_page_info); ut_a(0); } if (!(page_info <= os_awe_page_info + (os_awe_n_pages - 4))) { fprintf(stderr, "InnoDB: AWE: Error: trying to map page info" " at %lx but array end %lx\n", (ulint)page_info, (ulint)(os_awe_page_info + os_awe_n_pages)); ut_a(0); } bResult = MapUserPhysicalPages((PVOID)ptr, n_pages, page_info); if (bResult != TRUE) { ut_print_timestamp(stderr); fprintf(stderr, " InnoDB: AWE: Mapping of %lu physical pages" " to address %lx failed,\n" "InnoDB: error %lu.\n" "InnoDB: Cannot continue operation.\n", n_mem_pages, (ulint)ptr, (ulint)GetLastError()); exit(1); } return(TRUE); #else UT_NOT_USED(ptr); UT_NOT_USED(n_mem_pages); UT_NOT_USED(page_info); return(FALSE); #endif }