/* Allocate a region of memory of al least size bytes, at or above minAddress. * If the attempt fails, answer null. If the attempt succeeds, answer the * start of the region and assign its size through allocatedSizePointer. */ void * sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto(sqInt size, void *minAddress, sqInt *allocatedSizePointer) { void *alloc; long bytes = roundUpToPage(size); *allocatedSizePointer = bytes; #if 0 /* It appears VirtualAlloc answers low memory by default. */ alloc = VirtualAlloc(0, bytes, MEM_COMMIT, PAGE_READWRITE); if (!alloc) { sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), "Unable to VirtualAlloc committed memory (%d bytes requested)", bytes); return NULL; } if ((unsigned long)alloc >= (unsigned long)minAddress) return alloc; if (!VirtualFree(alloc, bytes, MEM_RELEASE)) sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Warning:"), "Unable to VirtualFree committed memory (%d bytes requested)", bytes); #endif /* 0 */ alloc = VirtualAlloc(0, bytes, MEM_COMMIT+MEM_TOP_DOWN, PAGE_READWRITE); if ((unsigned long)alloc >= (unsigned long)minAddress) return alloc; if (!VirtualFree(alloc, bytes, MEM_RELEASE)) sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Warning:"), "Unable to VirtualFree committed memory (%d bytes requested)", bytes); sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), "Unable to VirtualAlloc committed memory at desired address (%d bytes requested at or above %p)", bytes, minAddress); return NULL; }
/* Deallocate a region of memory previously allocated by * sqAllocateMemorySegmentOfSizeAboveAllocatedSizeInto. Cannot fail. */ void sqDeallocateMemorySegmentAtOfSize(void *addr, sqInt sz) { if (!VirtualFree(addr, sz, MEM_RELEASE)) sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Warning:"), "Unable to VirtualFree committed memory (%d bytes requested)", sz); }
void *sqAllocateMemory(usqInt minHeapSize, usqInt desiredHeapSize) { SYSTEM_INFO sysInfo; DWORD initialCommit, commit; /* determine page boundaries */ GetSystemInfo(&sysInfo); pageSize = sysInfo.dwPageSize; pageMask = ~(pageSize - 1); /* round the requested size up to the next page boundary */ nowReserved = (desiredHeapSize + pageSize) & pageMask; /* round the initial commited size up to the next page boundary */ initialCommit = (minHeapSize + pageSize) & pageMask; /* Here, we only reserve the maximum memory to be used It will later be committed during actual access */ maxReserved = fAddressSpaceLimit * 1024 * 1024; do { pageBase = VirtualAlloc(NULL,maxReserved,MEM_RESERVE, PAGE_NOACCESS); if(!pageBase) { if(maxReserved == nowReserved) break; /* make it smaller in steps of 128MB */ maxReserved -= 128*1024*1024; if(maxReserved < nowReserved) maxReserved = nowReserved; } } while(!pageBase); if(!pageBase) { sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), "Unable to allocate memory (%d bytes requested)", maxReserved); return pageBase; } /* commit initial memory as requested */ commit = nowReserved; if(!VirtualAlloc(pageBase, commit, MEM_COMMIT, PAGE_READWRITE)) { sqMessageBox(MB_OK | MB_ICONSTOP, TEXT("VM Error:"), "Unable to commit memory (%d bytes requested)", commit); return NULL; } pageLimit = pageBase + commit; usedMemory += commit; return pageBase; }
size_t sqImageFileRead(void *ptr, size_t sz, size_t count, sqImageFile h) { DWORD dwReallyRead; int position; position = sqImageFilePosition(h); ReadFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyRead, NULL); while(dwReallyRead != (DWORD)(count*sz)) { DWORD err = GetLastError(); if(sqMessageBox(MB_ABORTRETRYIGNORE, TEXT("Squeak Warning"),"Image file read problem (%d out of %d bytes read)", dwReallyRead, count*sz) == IDABORT) return (dwReallyRead / sz); sqImageFileSeek(h, position); ReadFile((HANDLE)(h-1), (LPVOID) ptr, count*sz, &dwReallyRead, NULL); } return (int)(dwReallyRead / sz); }