* Even though our current heap is a temporary solution, the heap size depends
now on the amount of memory installed in the system. Ie. if you have only 128 MB the kernel heap will be only half in size. * Minor cleanup in vm_page.c, renamed some variables to match our style guide. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@16838 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
parent
93c49610b5
commit
db823da57e
@ -24,7 +24,7 @@ extern "C" {
|
|||||||
|
|
||||||
void *memalign(size_t alignment, size_t size);
|
void *memalign(size_t alignment, size_t size);
|
||||||
|
|
||||||
status_t heap_init(addr_t heapBase);
|
status_t heap_init(addr_t heapBase, size_t heapSize);
|
||||||
status_t heap_init_post_sem(struct kernel_args *args);
|
status_t heap_init_post_sem(struct kernel_args *args);
|
||||||
status_t heap_init_post_thread(struct kernel_args *args);
|
status_t heap_init_post_thread(struct kernel_args *args);
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||||
@ -19,6 +19,7 @@ struct kernel_args;
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
void vm_page_init_num_pages(kernel_args *args);
|
||||||
status_t vm_page_init(struct kernel_args *args);
|
status_t vm_page_init(struct kernel_args *args);
|
||||||
status_t vm_page_init_post_area(struct kernel_args *args);
|
status_t vm_page_init_post_area(struct kernel_args *args);
|
||||||
status_t vm_page_init_post_thread(struct kernel_args *args);
|
status_t vm_page_init_post_thread(struct kernel_args *args);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001, Travis Geiselbrecht. All rights reserved.
|
||||||
@ -315,12 +315,12 @@ dump_bin_list(int argc, char **argv)
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
status_t
|
status_t
|
||||||
heap_init(addr_t heapBase)
|
heap_init(addr_t heapBase, size_t heapSize)
|
||||||
{
|
{
|
||||||
const unsigned int page_entries = B_PAGE_SIZE / sizeof(struct heap_page);
|
const unsigned int page_entries = B_PAGE_SIZE / sizeof(struct heap_page);
|
||||||
// set some global pointers
|
// set some global pointers
|
||||||
heap_alloc_table = (struct heap_page *)heapBase;
|
heap_alloc_table = (struct heap_page *)heapBase;
|
||||||
heap_size = ((uint64)HEAP_SIZE * page_entries / (page_entries + 1)) & ~(B_PAGE_SIZE-1);
|
heap_size = ((uint64)heapSize * page_entries / (page_entries + 1)) & ~(B_PAGE_SIZE-1);
|
||||||
heap_base = (unsigned int)heap_alloc_table + PAGE_ALIGN(heap_size / page_entries);
|
heap_base = (unsigned int)heap_alloc_table + PAGE_ALIGN(heap_size / page_entries);
|
||||||
heap_base_ptr = heap_base;
|
heap_base_ptr = heap_base;
|
||||||
TRACE(("heap_alloc_table = %p, heap_base = 0x%lx, heap_size = 0x%lx\n",
|
TRACE(("heap_alloc_table = %p, heap_base = 0x%lx, heap_size = 0x%lx\n",
|
||||||
|
@ -2228,7 +2228,6 @@ status_t
|
|||||||
vm_init(kernel_args *args)
|
vm_init(kernel_args *args)
|
||||||
{
|
{
|
||||||
struct preloaded_image *image;
|
struct preloaded_image *image;
|
||||||
addr_t heap_base;
|
|
||||||
void *address;
|
void *address;
|
||||||
status_t err = 0;
|
status_t err = 0;
|
||||||
uint32 i;
|
uint32 i;
|
||||||
@ -2242,14 +2241,24 @@ vm_init(kernel_args *args)
|
|||||||
sAreaHashLock = -1;
|
sAreaHashLock = -1;
|
||||||
sAvailableMemoryLock.sem = -1;
|
sAvailableMemoryLock.sem = -1;
|
||||||
|
|
||||||
|
vm_page_init_num_pages(args);
|
||||||
|
sAvailableMemory = vm_page_num_pages() * B_PAGE_SIZE;
|
||||||
|
|
||||||
|
// reduce the heap size if we have not so much RAM
|
||||||
|
size_t heapSize = HEAP_SIZE;
|
||||||
|
if (sAvailableMemory < 100 * 1024 * 1024)
|
||||||
|
heapSize /= 4;
|
||||||
|
else if (sAvailableMemory < 200 * 1024 * 1024)
|
||||||
|
heapSize /= 2;
|
||||||
|
|
||||||
// map in the new heap and initialize it
|
// map in the new heap and initialize it
|
||||||
heap_base = vm_alloc_from_kernel_args(args, HEAP_SIZE, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
addr_t heapBase = vm_alloc_from_kernel_args(args, heapSize,
|
||||||
TRACE(("heap at 0x%lx\n", heap_base));
|
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
heap_init(heap_base);
|
TRACE(("heap at 0x%lx\n", heapBase));
|
||||||
|
heap_init(heapBase, heapSize);
|
||||||
|
|
||||||
// initialize the free page list and physical page mapper
|
// initialize the free page list and physical page mapper
|
||||||
vm_page_init(args);
|
vm_page_init(args);
|
||||||
sAvailableMemory = vm_page_num_pages() * B_PAGE_SIZE;
|
|
||||||
|
|
||||||
// initialize the hash table that stores the pages mapped to caches
|
// initialize the hash table that stores the pages mapped to caches
|
||||||
vm_cache_init(args);
|
vm_cache_init(args);
|
||||||
@ -2272,8 +2281,8 @@ vm_init(kernel_args *args)
|
|||||||
|
|
||||||
// allocate areas to represent stuff that already exists
|
// allocate areas to represent stuff that already exists
|
||||||
|
|
||||||
address = (void *)ROUNDOWN(heap_base, B_PAGE_SIZE);
|
address = (void *)ROUNDOWN(heapBase, B_PAGE_SIZE);
|
||||||
create_area("kernel heap", &address, B_EXACT_ADDRESS, HEAP_SIZE,
|
create_area("kernel heap", &address, B_EXACT_ADDRESS, heapSize,
|
||||||
B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
B_ALREADY_WIRED, B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
|
|
||||||
allocate_kernel_args(args);
|
allocate_kernel_args(args);
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2005, Axel Dörfler, axeld@pinc-software.de.
|
* Copyright 2002-2006, Axel Dörfler, axeld@pinc-software.de.
|
||||||
* Distributed under the terms of the MIT License.
|
* Distributed under the terms of the MIT License.
|
||||||
*
|
*
|
||||||
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
* Copyright 2001-2002, Travis Geiselbrecht. All rights reserved.
|
||||||
@ -46,11 +46,11 @@ static page_queue page_clear_queue;
|
|||||||
static page_queue page_modified_queue;
|
static page_queue page_modified_queue;
|
||||||
static page_queue page_active_queue;
|
static page_queue page_active_queue;
|
||||||
|
|
||||||
static vm_page *all_pages;
|
static vm_page *sPages;
|
||||||
static addr_t physical_page_offset;
|
static addr_t sPhysicalPageOffset;
|
||||||
static unsigned int num_pages;
|
static size_t sNumPages;
|
||||||
|
|
||||||
static spinlock page_lock;
|
static spinlock sPageLock;
|
||||||
|
|
||||||
static sem_id modified_pages_available;
|
static sem_id modified_pages_available;
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ vm_page_write_modified(vm_cache *cache)
|
|||||||
vm_area *area;
|
vm_area *area;
|
||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
if (page->state == PAGE_STATE_MODIFIED) {
|
if (page->state == PAGE_STATE_MODIFIED) {
|
||||||
remove_page_from_queue(&page_modified_queue, page);
|
remove_page_from_queue(&page_modified_queue, page);
|
||||||
@ -186,7 +186,7 @@ vm_page_write_modified(vm_cache *cache)
|
|||||||
gotPage = true;
|
gotPage = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
// We may have a modified page - however, while we're writing it back, the page
|
// We may have a modified page - however, while we're writing it back, the page
|
||||||
@ -238,7 +238,7 @@ vm_page_write_modified(vm_cache *cache)
|
|||||||
// put it into the active queue
|
// put it into the active queue
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
if (page->ref_count > 0)
|
if (page->ref_count > 0)
|
||||||
page->state = PAGE_STATE_ACTIVE;
|
page->state = PAGE_STATE_ACTIVE;
|
||||||
@ -247,7 +247,7 @@ vm_page_write_modified(vm_cache *cache)
|
|||||||
|
|
||||||
enqueue_page(&page_active_queue, page);
|
enqueue_page(&page_active_queue, page);
|
||||||
|
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@ -277,11 +277,11 @@ static int pageout_daemon()
|
|||||||
dprintf("here\n");
|
dprintf("here\n");
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
page = dequeue_page(&page_modified_queue);
|
page = dequeue_page(&page_modified_queue);
|
||||||
page->state = PAGE_STATE_BUSY;
|
page->state = PAGE_STATE_BUSY;
|
||||||
vm_cache_acquire_ref(page->cache_ref, true);
|
vm_cache_acquire_ref(page->cache_ref, true);
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
dprintf("got page %p\n", page);
|
dprintf("got page %p\n", page);
|
||||||
@ -290,10 +290,10 @@ static int pageout_daemon()
|
|||||||
// unless we're in the trimming cycle, dont write out pages
|
// unless we're in the trimming cycle, dont write out pages
|
||||||
// that back anonymous stores
|
// that back anonymous stores
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
enqueue_page(&page_modified_queue, page);
|
enqueue_page(&page_modified_queue, page);
|
||||||
page->state = PAGE_STATE_MODIFIED;
|
page->state = PAGE_STATE_MODIFIED;
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
vm_cache_release_ref(page->cache_ref);
|
vm_cache_release_ref(page->cache_ref);
|
||||||
continue;
|
continue;
|
||||||
@ -323,14 +323,14 @@ static int pageout_daemon()
|
|||||||
vm_put_physical_page((addr_t)vecs->vec[0].iov_base);
|
vm_put_physical_page((addr_t)vecs->vec[0].iov_base);
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
if(page->ref_count > 0) {
|
if(page->ref_count > 0) {
|
||||||
page->state = PAGE_STATE_ACTIVE;
|
page->state = PAGE_STATE_ACTIVE;
|
||||||
} else {
|
} else {
|
||||||
page->state = PAGE_STATE_INACTIVE;
|
page->state = PAGE_STATE_INACTIVE;
|
||||||
}
|
}
|
||||||
enqueue_page(&page_active_queue, page);
|
enqueue_page(&page_active_queue, page);
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
vm_cache_release_ref(page->cache_ref);
|
vm_cache_release_ref(page->cache_ref);
|
||||||
@ -339,14 +339,35 @@ static int pageout_daemon()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
status_t
|
void
|
||||||
vm_page_init(kernel_args *ka)
|
vm_page_init_num_pages(kernel_args *args)
|
||||||
{
|
{
|
||||||
unsigned int i;
|
uint32 i;
|
||||||
|
|
||||||
|
// calculate the size of memory by looking at the physical_memory_range array
|
||||||
|
addr_t physicalPagesEnd = 0;
|
||||||
|
sPhysicalPageOffset = args->physical_memory_range[0].start / B_PAGE_SIZE;
|
||||||
|
|
||||||
|
for (i = 0; i < args->num_physical_memory_ranges; i++) {
|
||||||
|
physicalPagesEnd = (args->physical_memory_range[i].start
|
||||||
|
+ args->physical_memory_range[i].size) / B_PAGE_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
TRACE(("first phys page = 0x%lx, end 0x%x\n", sPhysicalPageOffset,
|
||||||
|
physicalPagesEnd));
|
||||||
|
|
||||||
|
sNumPages = physicalPagesEnd - sPhysicalPageOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
status_t
|
||||||
|
vm_page_init(kernel_args *args)
|
||||||
|
{
|
||||||
|
uint32 i;
|
||||||
|
|
||||||
TRACE(("vm_page_init: entry\n"));
|
TRACE(("vm_page_init: entry\n"));
|
||||||
|
|
||||||
page_lock = 0;
|
sPageLock = 0;
|
||||||
|
|
||||||
// initialize queues
|
// initialize queues
|
||||||
page_free_queue.head = NULL;
|
page_free_queue.head = NULL;
|
||||||
@ -362,42 +383,28 @@ vm_page_init(kernel_args *ka)
|
|||||||
page_active_queue.tail = NULL;
|
page_active_queue.tail = NULL;
|
||||||
page_active_queue.count = 0;
|
page_active_queue.count = 0;
|
||||||
|
|
||||||
// calculate the size of memory by looking at the physical_memory_range array
|
|
||||||
{
|
|
||||||
unsigned int physicalPagesEnd = 0;
|
|
||||||
|
|
||||||
physical_page_offset = ka->physical_memory_range[0].start / B_PAGE_SIZE;
|
|
||||||
for (i = 0; i<ka->num_physical_memory_ranges; i++) {
|
|
||||||
physicalPagesEnd = (ka->physical_memory_range[i].start
|
|
||||||
+ ka->physical_memory_range[i].size) / B_PAGE_SIZE;
|
|
||||||
}
|
|
||||||
TRACE(("first phys page = 0x%lx, end 0x%x\n", physical_page_offset,
|
|
||||||
physicalPagesEnd));
|
|
||||||
num_pages = physicalPagesEnd - physical_page_offset;
|
|
||||||
}
|
|
||||||
|
|
||||||
// map in the new free page table
|
// map in the new free page table
|
||||||
all_pages = (vm_page *)vm_alloc_from_kernel_args(ka, num_pages * sizeof(vm_page),
|
sPages = (vm_page *)vm_alloc_from_kernel_args(args, sNumPages * sizeof(vm_page),
|
||||||
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
|
|
||||||
TRACE(("vm_init: putting free_page_table @ %p, # ents %d (size 0x%x)\n",
|
TRACE(("vm_init: putting free_page_table @ %p, # ents %d (size 0x%x)\n",
|
||||||
all_pages, num_pages, (unsigned int)(num_pages * sizeof(vm_page))));
|
sPages, sNumPages, (unsigned int)(sNumPages * sizeof(vm_page))));
|
||||||
|
|
||||||
// initialize the free page table
|
// initialize the free page table
|
||||||
for (i = 0; i < num_pages; i++) {
|
for (i = 0; i < sNumPages; i++) {
|
||||||
all_pages[i].physical_page_number = physical_page_offset + i;
|
sPages[i].physical_page_number = sPhysicalPageOffset + i;
|
||||||
all_pages[i].type = PAGE_TYPE_PHYSICAL;
|
sPages[i].type = PAGE_TYPE_PHYSICAL;
|
||||||
all_pages[i].state = PAGE_STATE_FREE;
|
sPages[i].state = PAGE_STATE_FREE;
|
||||||
all_pages[i].ref_count = 0;
|
sPages[i].ref_count = 0;
|
||||||
enqueue_page(&page_free_queue, &all_pages[i]);
|
enqueue_page(&page_free_queue, &sPages[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("initialized table\n"));
|
TRACE(("initialized table\n"));
|
||||||
|
|
||||||
// mark some of the page ranges inuse
|
// mark some of the page ranges inuse
|
||||||
for (i = 0; i < ka->num_physical_allocated_ranges; i++) {
|
for (i = 0; i < args->num_physical_allocated_ranges; i++) {
|
||||||
vm_mark_page_range_inuse(ka->physical_allocated_range[i].start / B_PAGE_SIZE,
|
vm_mark_page_range_inuse(args->physical_allocated_range[i].start / B_PAGE_SIZE,
|
||||||
ka->physical_allocated_range[i].size / B_PAGE_SIZE);
|
args->physical_allocated_range[i].size / B_PAGE_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
TRACE(("vm_page_init: exit\n"));
|
TRACE(("vm_page_init: exit\n"));
|
||||||
@ -411,9 +418,9 @@ vm_page_init_post_area(kernel_args *args)
|
|||||||
{
|
{
|
||||||
void *dummy;
|
void *dummy;
|
||||||
|
|
||||||
dummy = all_pages;
|
dummy = sPages;
|
||||||
create_area("page structures", &dummy, B_EXACT_ADDRESS,
|
create_area("page structures", &dummy, B_EXACT_ADDRESS,
|
||||||
PAGE_ALIGN(num_pages * sizeof(vm_page)), B_ALREADY_WIRED,
|
PAGE_ALIGN(sNumPages * sizeof(vm_page)), B_ALREADY_WIRED,
|
||||||
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
B_KERNEL_READ_AREA | B_KERNEL_WRITE_AREA);
|
||||||
|
|
||||||
add_debugger_command("page_stats", &dump_page_stats, "Dump statistics about page usage");
|
add_debugger_command("page_stats", &dump_page_stats, "Dump statistics about page usage");
|
||||||
@ -468,7 +475,7 @@ page_scrubber(void *unused)
|
|||||||
// get some pages from the free queue
|
// get some pages from the free queue
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
for (i = 0; i < SCRUB_SIZE; i++) {
|
for (i = 0; i < SCRUB_SIZE; i++) {
|
||||||
page[i] = dequeue_page(&page_free_queue);
|
page[i] = dequeue_page(&page_free_queue);
|
||||||
@ -476,7 +483,7 @@ page_scrubber(void *unused)
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
// clear them
|
// clear them
|
||||||
@ -488,7 +495,7 @@ page_scrubber(void *unused)
|
|||||||
}
|
}
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
// and put them into the clear queue
|
// and put them into the clear queue
|
||||||
|
|
||||||
@ -497,7 +504,7 @@ page_scrubber(void *unused)
|
|||||||
enqueue_page(&page_clear_queue, page[i]);
|
enqueue_page(&page_clear_queue, page[i]);
|
||||||
}
|
}
|
||||||
|
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -537,21 +544,21 @@ vm_mark_page_range_inuse(addr_t start_page, addr_t length)
|
|||||||
|
|
||||||
TRACE(("vm_mark_page_range_inuse: start 0x%lx, len 0x%lx\n", start_page, length));
|
TRACE(("vm_mark_page_range_inuse: start 0x%lx, len 0x%lx\n", start_page, length));
|
||||||
|
|
||||||
if (physical_page_offset > start_page) {
|
if (sPhysicalPageOffset > start_page) {
|
||||||
dprintf("vm_mark_page_range_inuse: start page %ld is before free list\n", start_page);
|
dprintf("vm_mark_page_range_inuse: start page %ld is before free list\n", start_page);
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
start_page -= physical_page_offset;
|
start_page -= sPhysicalPageOffset;
|
||||||
if (start_page + length > num_pages) {
|
if (start_page + length > sNumPages) {
|
||||||
dprintf("vm_mark_page_range_inuse: range would extend past free list\n");
|
dprintf("vm_mark_page_range_inuse: range would extend past free list\n");
|
||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
for (i = 0; i < length; i++) {
|
for (i = 0; i < length; i++) {
|
||||||
page = &all_pages[start_page + i];
|
page = &sPages[start_page + i];
|
||||||
switch (page->state) {
|
switch (page->state) {
|
||||||
case PAGE_STATE_FREE:
|
case PAGE_STATE_FREE:
|
||||||
case PAGE_STATE_CLEAR:
|
case PAGE_STATE_CLEAR:
|
||||||
@ -570,7 +577,7 @@ vm_mark_page_range_inuse(addr_t start_page, addr_t length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
@ -585,7 +592,7 @@ vm_page_allocate_specific_page(addr_t page_num, int page_state)
|
|||||||
int state;
|
int state;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
p = vm_lookup_page(page_num);
|
p = vm_lookup_page(page_num);
|
||||||
if (p == NULL)
|
if (p == NULL)
|
||||||
@ -614,7 +621,7 @@ vm_page_allocate_specific_page(addr_t page_num, int page_state)
|
|||||||
enqueue_page(&page_active_queue, p);
|
enqueue_page(&page_active_queue, p);
|
||||||
|
|
||||||
out:
|
out:
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
if (p != NULL && page_state == PAGE_STATE_CLEAR
|
if (p != NULL && page_state == PAGE_STATE_CLEAR
|
||||||
@ -648,7 +655,7 @@ vm_page_allocate_page(int page_state)
|
|||||||
}
|
}
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
p = dequeue_page(q);
|
p = dequeue_page(q);
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
@ -676,7 +683,7 @@ vm_page_allocate_page(int page_state)
|
|||||||
|
|
||||||
enqueue_page(&page_active_queue, p);
|
enqueue_page(&page_active_queue, p);
|
||||||
|
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
// if needed take the page from the free queue and zero it out
|
// if needed take the page from the free queue and zero it out
|
||||||
@ -724,16 +731,16 @@ vm_page_allocate_page_run(int page_state, addr_t len)
|
|||||||
start = 0;
|
start = 0;
|
||||||
|
|
||||||
state = disable_interrupts();
|
state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
bool foundit = true;
|
bool foundit = true;
|
||||||
if (start + len > num_pages)
|
if (start + len > sNumPages)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
for (i = 0; i < len; i++) {
|
for (i = 0; i < len; i++) {
|
||||||
if (all_pages[start + i].state != PAGE_STATE_FREE
|
if (sPages[start + i].state != PAGE_STATE_FREE
|
||||||
&& all_pages[start + i].state != PAGE_STATE_CLEAR) {
|
&& sPages[start + i].state != PAGE_STATE_CLEAR) {
|
||||||
foundit = false;
|
foundit = false;
|
||||||
i++;
|
i++;
|
||||||
break;
|
break;
|
||||||
@ -742,14 +749,14 @@ vm_page_allocate_page_run(int page_state, addr_t len)
|
|||||||
if (foundit) {
|
if (foundit) {
|
||||||
// pull the pages out of the appropriate queues
|
// pull the pages out of the appropriate queues
|
||||||
for (i = 0; i < len; i++)
|
for (i = 0; i < len; i++)
|
||||||
vm_page_set_state_nolock(&all_pages[start + i], PAGE_STATE_BUSY);
|
vm_page_set_state_nolock(&sPages[start + i], PAGE_STATE_BUSY);
|
||||||
first_page = &all_pages[start];
|
first_page = &sPages[start];
|
||||||
break;
|
break;
|
||||||
} else {
|
} else {
|
||||||
start += i;
|
start += i;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
return first_page;
|
return first_page;
|
||||||
@ -759,14 +766,14 @@ vm_page_allocate_page_run(int page_state, addr_t len)
|
|||||||
vm_page *
|
vm_page *
|
||||||
vm_lookup_page(addr_t page_num)
|
vm_lookup_page(addr_t page_num)
|
||||||
{
|
{
|
||||||
if (page_num < physical_page_offset)
|
if (page_num < sPhysicalPageOffset)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
page_num -= physical_page_offset;
|
page_num -= sPhysicalPageOffset;
|
||||||
if (page_num >= num_pages)
|
if (page_num >= sNumPages)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
return &all_pages[page_num];
|
return &sPages[page_num];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -830,11 +837,11 @@ vm_page_set_state(vm_page *page, int page_state)
|
|||||||
status_t status;
|
status_t status;
|
||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
cpu_status state = disable_interrupts();
|
||||||
acquire_spinlock(&page_lock);
|
acquire_spinlock(&sPageLock);
|
||||||
|
|
||||||
status = vm_page_set_state_nolock(page, page_state);
|
status = vm_page_set_state_nolock(page, page_state);
|
||||||
|
|
||||||
release_spinlock(&page_lock);
|
release_spinlock(&sPageLock);
|
||||||
restore_interrupts(state);
|
restore_interrupts(state);
|
||||||
|
|
||||||
return status;
|
return status;
|
||||||
@ -844,7 +851,7 @@ vm_page_set_state(vm_page *page, int page_state)
|
|||||||
size_t
|
size_t
|
||||||
vm_page_num_pages(void)
|
vm_page_num_pages(void)
|
||||||
{
|
{
|
||||||
return num_pages;
|
return sNumPages;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -951,11 +958,11 @@ dump_page_stats(int argc, char **argv)
|
|||||||
|
|
||||||
memset(counter, 0, sizeof(counter));
|
memset(counter, 0, sizeof(counter));
|
||||||
|
|
||||||
for (i = 0; i < num_pages; i++) {
|
for (i = 0; i < sNumPages; i++) {
|
||||||
if (all_pages[i].state > 7)
|
if (sPages[i].state > 7)
|
||||||
panic("page %i at %p has invalid state!\n", i, &all_pages[i]);
|
panic("page %i at %p has invalid state!\n", i, &sPages[i]);
|
||||||
|
|
||||||
counter[all_pages[i].state]++;
|
counter[sPages[i].state]++;
|
||||||
}
|
}
|
||||||
|
|
||||||
kprintf("page stats:\n");
|
kprintf("page stats:\n");
|
||||||
|
Loading…
Reference in New Issue
Block a user