* register_low_memory_handler() was called too early by several kernel

components - now, we divide the initialization of that service into two parts
  which allows this (before, most handlers were gone after boot).
* Added debugger command that dumps the low memory handlers.
* The slab allocator now registers its low memory handler with a higher
  priority, so that it'll run before the potentially heavier ones.


git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@22374 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Axel Dörfler 2007-09-29 15:46:40 +00:00
parent 2a88281a61
commit b062823d81
4 changed files with 50 additions and 15 deletions

View File

@ -1,5 +1,5 @@
/*
* Copyright 2005, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Copyright 2005-2007, Axel Dörfler, axeld@pinc-software.de. All rights reserved.
* Distributed under the terms of the MIT License.
*/
#ifndef _KERNEL_VM_LOW_MEMORY_H
@ -24,6 +24,7 @@ extern "C" {
#endif
status_t vm_low_memory_init(void);
status_t vm_low_memory_init_post_thread(void);
int32 vm_low_memory_state(void);
void vm_low_memory(size_t requirements);

View File

@ -449,7 +449,7 @@ object_cache_init(object_cache *cache, const char *name, size_t objectSize,
cache->free_pages = area_free_pages;
}
register_low_memory_handler(object_cache_low_memory, cache, 0);
register_low_memory_handler(object_cache_low_memory, cache, 5);
BenaphoreLocker _(sObjectCacheListLock);
sObjectCaches.Add(cache);

View File

@ -3405,6 +3405,8 @@ vm_init(kernel_args *args)
TRACE(("heap at 0x%lx\n", heapBase));
heap_init(heapBase, heapSize);
vm_low_memory_init();
size_t slabInitialSize = 2 * B_PAGE_SIZE;
addr_t slabInitialBase = vm_allocate_early(args, slabInitialSize,
slabInitialSize, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
@ -3525,7 +3527,7 @@ vm_init_post_thread(kernel_args *args)
{
vm_page_init_post_thread(args);
vm_daemon_init();
vm_low_memory_init();
vm_low_memory_init_post_thread();
return heap_init_post_thread(args);
}

View File

@ -4,18 +4,20 @@
*/
#include <KernelExport.h>
#include <vm_low_memory.h>
#include <vm_page.h>
#include <lock.h>
#include <util/DoublyLinkedList.h>
#include <util/AutoLock.h>
#include <new>
#include <signal.h>
#include <stdlib.h>
#include <KernelExport.h>
#include <elf.h>
#include <lock.h>
#include <util/AutoLock.h>
#include <util/DoublyLinkedList.h>
#include <vm_page.h>
//#define TRACE_LOW_MEMORY
#ifdef TRACE_LOW_MEMORY
@ -110,6 +112,30 @@ low_memory(void *)
}
static int
dump_handlers(int argc, char **argv)
{
HandlerList::Iterator iterator = sLowMemoryHandlers.GetIterator();
kprintf("function data prio function-name\n");
while (iterator.HasNext()) {
low_memory_handler *handler = iterator.Next();
const char* symbol = NULL;
elf_debug_lookup_symbol_address((addr_t)handler->function, NULL,
&symbol, NULL, NULL);
kprintf("%p %p %3ld %s\n", handler->function, handler->data,
handler->priority, symbol);
}
return 0;
}
// #pragma mark - private kernel API
void
vm_low_memory(size_t requirements)
{
@ -129,8 +155,17 @@ vm_low_memory_state(void)
status_t
vm_low_memory_init(void)
{
thread_id thread;
new(&sLowMemoryHandlers) HandlerList;
// static initializers do not work in the kernel,
// so we have to do it here, manually
return B_OK;
}
status_t
vm_low_memory_init_post_thread(void)
{
if (mutex_init(&sLowMemoryMutex, "low memory") < B_OK)
return B_ERROR;
@ -138,14 +173,11 @@ vm_low_memory_init(void)
if (sLowMemoryWaitSem < B_OK)
return sLowMemoryWaitSem;
new(&sLowMemoryHandlers) HandlerList;
// static initializers do not work in the kernel,
// so we have to do it here, manually
thread = spawn_kernel_thread(&low_memory, "low memory handler",
thread_id thread = spawn_kernel_thread(&low_memory, "low memory handler",
B_LOW_PRIORITY, NULL);
send_signal_etc(thread, SIGCONT, B_DO_NOT_RESCHEDULE);
add_debugger_command("low_memory", &dump_handlers, "Dump list of low memory handlers");
return B_OK;
}