Made Haiku behave better when you have more memory:

* with 1 GB or more, the semaphore limit is now 131072 instead of 65536.
* double the heap when there is 1 GB or more (64 MB).
* the low memory handler now also watches semaphore usage; in the end,
  we need a low resource handler, not a low memory handler.
* create_sem_etc() no longer calls vfs_free_unused_vnodes() directly as
  this could actually deadlock (at least because the address space is a
  R/W lock, not a recursive lock).


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@23538 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2008-01-15 16:47:26 +00:00
parent dba557e4e7
commit c87ef6db88
3 changed files with 23 additions and 6 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
@ -67,7 +67,7 @@ struct sem_entry {
} u;
};
static const int32 kMaxSemaphores = 65536;
static const int32 kMaxSemaphores = 131072;
static int32 sMaxSems = 4096;
// Final value is computed based on the amount of available memory
static int32 sUsedSems = 0;
@ -350,7 +350,8 @@ sem_init(kernel_args *args)
// compute maximal number of semaphores depending on the available memory
// 128 MB -> 16384 semaphores, 448 kB fixed array size
// 256 MB -> 32768, 896 kB
// 512 MB and more -> 1.75 MB
// 512 MB -> 65536, 1.75 MB
// 1024 MB and more -> 131072, 3.5 MB
i = vm_page_num_pages() / 2;
while (sMaxSems < i && sMaxSems < kMaxSemaphores)
sMaxSems <<= 1;
@ -399,6 +400,9 @@ create_sem_etc(int32 count, const char *name, team_id owner)
if (sSemsActive == false)
return B_NO_MORE_SEMS;
#if 0
// TODO: the code below might cause unwanted deadlocks,
// we need an asynchronously running low resource handler.
if (sUsedSems == sMaxSems) {
// The vnode cache may have collected lots of semaphores.
// Freeing some unused vnodes should improve our situation.
@ -410,6 +414,7 @@ create_sem_etc(int32 count, const char *name, team_id owner)
// try again with more enthusiasm
vfs_free_unused_vnodes(B_LOW_MEMORY_CRITICAL);
}
#endif
if (sUsedSems == sMaxSems)
return B_NO_MORE_SEMS;

View File

@ -1,5 +1,5 @@
/*
* Copyright 2002-2007, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2002-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
@ -3468,6 +3468,8 @@ vm_init(kernel_args *args)
heapSize /= 4;
else if (sAvailableMemory < 200 * 1024 * 1024)
heapSize /= 2;
else if (sAvailableMemory >= 1024 * 1024 * 1024)
heapSize *= 2;
// map in the new heap and initialize it
addr_t heapBase = vm_allocate_early(args, heapSize, heapSize,

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de.
* Copyright 2005-2008, Axel Dörfler, axeld@pinc-software.de.
* Distributed under the terms of the MIT License.
*/
@ -14,6 +14,7 @@
#include <elf.h>
#include <lock.h>
#include <sem.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
#include <vm_page.h>
@ -74,13 +75,22 @@ compute_state(void)
sLastMeasurement = system_time();
uint32 freePages = vm_page_num_free_pages();
if (freePages > kNoteLimit) {
// TODO: work-around for a missing general low resource handler
if (sem_used_sems() * 6 > sem_max_sems() * 5)
return B_LOW_MEMORY_WARNING;
if (sem_used_sems() * 3 > sem_max_sems() * 2)
return B_LOW_MEMORY_NOTE;
}
if (freePages >= kNoteLimit)
return B_NO_LOW_MEMORY;
// specify low memory level
if (freePages < kCriticalLimit)
return B_LOW_MEMORY_CRITICAL;
else if (freePages < kWarnLimit)
if (freePages < kWarnLimit)
return B_LOW_MEMORY_WARNING;
return B_LOW_MEMORY_NOTE;