Книга: Microsoft Windows Embedded CE 6.0 Exam Preparation Kit

Dynamic Memory Allocation

Dynamic Memory Allocation

Dynamic memory allocation is an allocation technique that relies on structured exception handling to minimize the total number of committed memory pages on the system. This is particularly useful if you must perform large memory allocations. Precommitting an entire allocation can cause the system to run out of committable pages and result in virtual memory allocation failures.

The dynamic memory allocation technique is as follows:

1. Call VirtualAlloc with a base address of NULL to reserve a block of memory. The system reserves this memory block without committing the pages.

2. Try to access a memory page. This raises an exception because you cannot read from or write to a non-committed page. This illegal operation results in a page fault exception. Figure 3-5 and Figure 3-6 show the outcome of an unhandled page fault in an application called PageFault.exe.

3. Implement an exception handler based on a filter function. Commit a page in the filter function from the reserved region. If successful, return EXCEPTION_CONTINUE_EXECUTION to continue thread execution in the __try block at the point where the exception occurred. If the page allocation failed, return EXCEPTION_EXECUTE_HANDLER to invoke the exception handler in the __except block and release the entire region of reserved and committed pages.


Figure 3-5 An unhandled page fault exception from a user's perspective


Figure 3-6 An unhandled page fault exception's debug output over KITL in Visual Studio 2005

The following code snippet illustrates the dynamic memory allocation technique based on page fault exception handling:

#define PAGESTOTAL 42 // Max. number of pages
LPTSTR lpPage;    // Page to commit
DWORD dwPageSize; // Page size, in bytes
INT ExceptionFilter(DWORD dwCode) {
 LPVOID lpvPage;
 if (EXCEPTION_ACCESS_VIOLATION != dwCode) {
  // This is an unexpected exception!
  // Do not return EXCEPTION_EXECUTE_HANDLER
  // to handle this in the application process.
  // Instead, let the operating system handle it.
  return EXCEPTION_CONTINUE_SEARCH;
 }
 // Allocate page for read/write access.
 lpvPage = VirtualAlloc((LPVOID) lpPage,
 dwPageSize, MEM_COMMIT, PAGE_READWRITE);
 if (NULL == lpvPage) {
  // Continue thread execution
  // in __except block.
  return EXCEPTION_EXECUTE_HANDLER;
 }
 // Set lpPage to the next page.
 lpPage = (LPTSTR) ((PCHAR) lpPage + dwPageSize);
 // Continue thread execution in __try block.
 return EXCEPTION_CONTINUE_EXECUTION;
}
VOID DynamicVirtualAlloc() {
 LPVOID lpvMem;
 LPTSTR lpPtr;
 DWORD i;
 BOOL bRet;
 // Get page size on computer.
 SYSTEM_INFO sSysInfo;
 GetSystemInfo(&sSysInfo);
 dwPageSize = sSysInfo.dwPageSize;
 // Reserve memory pages without committing.
 lpvMem = VirtualAlloc(NULL, PAGESTOTAL*dwPageSize,
  MEM_RESERVE, PAGE_NOACCESS);
 lpPtr = lpPage = (LPTSTR) lpvMem;
 // Use structured exception handling when accessing the pages.
 for (i=0; i < PAGESTOTAL*dwPageSize; i++) {
  __try {
   // Write to memory.
   lpPtr[i] = 'x';
  } __except (ExceptionFilter(GetExceptionCode())) {
   // Filter function unsuccessful. Abort mission.
   ExitProcess( GetLastError() );
  }
 }
 // Release the memory.
 bRet = VirtualFree(lpvMem, 0, MEM_RELEASE);
}

Оглавление книги


Генерация: 1.543. Запросов К БД/Cache: 3 / 0
поделиться
Вверх Вниз