* The system now holds back a small reserve of committable memory and pages. The
memory and page reservation functions have a new "priority" parameter that indicates how deep the function may tap into that reserve. The currently existing priority levels are "user", "system", and "VIP". The idea is that user programs should never be able to cause a state that gets the kernel into trouble due to heavy battling for memory. The "VIP" level (not really used yet) is intended for allocations that are required to free memory eventually (in the page writer). More levels are thinkable in the future, like "user real time" or "user system server". * Added "priority" parameters to several VMCache methods. * Replaced the map_backing_store() "unmapAddressRange" parameter by a "flags" parameter. * Added area creation flag CREATE_AREA_PRIORITY_VIP and slab allocator flag CACHE_PRIORITY_VIP indicating the importance of the request. * Changed most code to pass the right priorities/flags. These changes already significantly improve the behavior in low memory situations. I've tested a bit with 64 MB (virtual) RAM and, while not particularly fast and responsive, the system remains at least usable under high memory pressure. As a side effect the slab allocator can now be used as general memory allocator. Not done by default yet, though. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35295 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1181,8 +1181,11 @@ MemoryManager::_AllocateArea(uint32 flags, Area*& _area)
|
||||
|
||||
if (sKernelArgs == NULL) {
|
||||
// create an area
|
||||
uint32 areaCreationFlags = (flags & CACHE_PRIORITY_VIP) != 0
|
||||
? CREATE_AREA_PRIORITY_VIP : 0;
|
||||
area_id areaID = vm_create_null_area(B_SYSTEM_TEAM, kSlabAreaName,
|
||||
(void**)&area, B_ANY_KERNEL_BLOCK_ADDRESS, SLAB_AREA_SIZE);
|
||||
(void**)&area, B_ANY_KERNEL_BLOCK_ADDRESS, SLAB_AREA_SIZE,
|
||||
areaCreationFlags);
|
||||
if (areaID < 0) {
|
||||
mutex_lock(&sLock);
|
||||
return areaID;
|
||||
@@ -1315,8 +1318,10 @@ MemoryManager::_MapChunk(VMArea* vmArea, addr_t address, size_t size,
|
||||
VMTranslationMap* translationMap = addressSpace->TranslationMap();
|
||||
|
||||
// reserve memory for the chunk
|
||||
int priority = (flags & CACHE_PRIORITY_VIP) != 0
|
||||
? VM_PRIORITY_VIP : VM_PRIORITY_SYSTEM;
|
||||
size_t reservedMemory = size + reserveAdditionalMemory;
|
||||
status_t error = vm_try_reserve_memory(size,
|
||||
status_t error = vm_try_reserve_memory(size, priority,
|
||||
(flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0 ? 0 : 1000000);
|
||||
if (error != B_OK)
|
||||
return error;
|
||||
@@ -1325,12 +1330,12 @@ MemoryManager::_MapChunk(VMArea* vmArea, addr_t address, size_t size,
|
||||
size_t reservedPages = size / B_PAGE_SIZE
|
||||
+ translationMap->MaxPagesNeededToMap(address, address + size - 1);
|
||||
if ((flags & CACHE_DONT_WAIT_FOR_MEMORY) != 0) {
|
||||
if (!vm_page_try_reserve_pages(reservedPages)) {
|
||||
if (!vm_page_try_reserve_pages(reservedPages, priority)) {
|
||||
vm_unreserve_memory(reservedMemory);
|
||||
return B_WOULD_BLOCK;
|
||||
}
|
||||
} else
|
||||
vm_page_reserve_pages(reservedPages);
|
||||
vm_page_reserve_pages(reservedPages, priority);
|
||||
|
||||
VMCache* cache = vm_area_get_locked_cache(vmArea);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user