* There is no need for the sPageLock to be a spinlock - a mutex should do. This
should improve the kernel latencies, as things like vm_page_allocate_page_run() is very expensive. git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@33807 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright 2002-2008, Axel Dörfler, [email protected].
|
* Copyright 2002-2009, Axel Dörfler, [email protected].
|
||||||
* 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.
|
||||||
@@ -77,7 +77,7 @@ static vint32 sPageDeficit;
|
|||||||
static size_t sModifiedTemporaryPages;
|
static size_t sModifiedTemporaryPages;
|
||||||
|
|
||||||
static ConditionVariable sFreePageCondition;
|
static ConditionVariable sFreePageCondition;
|
||||||
static spinlock sPageLock;
|
static mutex sPageLock = MUTEX_INITIALIZER("pages");
|
||||||
|
|
||||||
static sem_id sWriterWaitSem;
|
static sem_id sWriterWaitSem;
|
||||||
|
|
||||||
@@ -851,7 +851,7 @@ page_scrubber(void *unused)
|
|||||||
if (sFreePageQueue.count == 0)
|
if (sFreePageQueue.count == 0)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
// Since we temporarily remove pages from the free pages reserve,
|
// Since we temporarily remove pages from the free pages reserve,
|
||||||
// we must make sure we don't cause a violation of the page
|
// we must make sure we don't cause a violation of the page
|
||||||
@@ -933,7 +933,7 @@ remove_page_marker(struct vm_page &marker)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
remove_page_from_queue(queue, &marker);
|
remove_page_from_queue(queue, &marker);
|
||||||
|
|
||||||
marker.state = PAGE_STATE_UNUSED;
|
marker.state = PAGE_STATE_UNUSED;
|
||||||
@@ -943,7 +943,7 @@ remove_page_marker(struct vm_page &marker)
|
|||||||
static vm_page *
|
static vm_page *
|
||||||
next_modified_page(struct vm_page &marker)
|
next_modified_page(struct vm_page &marker)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
vm_page *page;
|
vm_page *page;
|
||||||
|
|
||||||
if (marker.state == PAGE_STATE_MODIFIED) {
|
if (marker.state == PAGE_STATE_MODIFIED) {
|
||||||
@@ -1327,7 +1327,7 @@ PageWriterRun::Go()
|
|||||||
fWrappers[checkIndex++].CheckRemoveFromShrunkenCache();
|
fWrappers[checkIndex++].CheckRemoveFromShrunkenCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
for (uint32 j = 0; j < transfer.PageCount(); j++)
|
for (uint32 j = 0; j < transfer.PageCount(); j++)
|
||||||
fWrappers[wrapperIndex++].Done(transfer.Status());
|
fWrappers[wrapperIndex++].Done(transfer.Status());
|
||||||
|
|
||||||
@@ -1461,7 +1461,7 @@ page_writer(void* /*unused*/)
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
// state might have changed while we were locking the cache
|
// state might have changed while we were locking the cache
|
||||||
if (page->state != PAGE_STATE_MODIFIED) {
|
if (page->state != PAGE_STATE_MODIFIED) {
|
||||||
@@ -1518,7 +1518,7 @@ page_writer(void* /*unused*/)
|
|||||||
static vm_page *
|
static vm_page *
|
||||||
find_page_candidate(struct vm_page &marker, bool stealActive)
|
find_page_candidate(struct vm_page &marker, bool stealActive)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
page_queue *queue;
|
page_queue *queue;
|
||||||
vm_page *page;
|
vm_page *page;
|
||||||
|
|
||||||
@@ -1605,7 +1605,7 @@ steal_page(vm_page *page, bool stealActive)
|
|||||||
|
|
||||||
page->cache->RemovePage(page);
|
page->cache->RemovePage(page);
|
||||||
|
|
||||||
InterruptsSpinLocker _(sPageLock);
|
MutexLocker _(sPageLock);
|
||||||
remove_page_from_queue(page->state == PAGE_STATE_ACTIVE
|
remove_page_from_queue(page->state == PAGE_STATE_ACTIVE
|
||||||
? &sActivePageQueue : &sInactivePageQueue, page);
|
? &sActivePageQueue : &sInactivePageQueue, page);
|
||||||
return true;
|
return true;
|
||||||
@@ -1633,7 +1633,7 @@ steal_pages(vm_page **pages, size_t count, bool reserve)
|
|||||||
|
|
||||||
if (steal_page(page, false)) {
|
if (steal_page(page, false)) {
|
||||||
if (reserve || stolen >= maxCount) {
|
if (reserve || stolen >= maxCount) {
|
||||||
InterruptsSpinLocker _(sPageLock);
|
MutexLocker _(sPageLock);
|
||||||
enqueue_page(&sFreePageQueue, page);
|
enqueue_page(&sFreePageQueue, page);
|
||||||
page->state = PAGE_STATE_FREE;
|
page->state = PAGE_STATE_FREE;
|
||||||
|
|
||||||
@@ -1649,7 +1649,7 @@ steal_pages(vm_page **pages, size_t count, bool reserve)
|
|||||||
|
|
||||||
remove_page_marker(marker);
|
remove_page_marker(marker);
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
if ((reserve && sReservedPages <= free_page_queue_count())
|
if ((reserve && sReservedPages <= free_page_queue_count())
|
||||||
|| count == 0
|
|| count == 0
|
||||||
@@ -1743,7 +1743,7 @@ vm_page_write_modified_page_range(struct VMCache* cache, uint32 firstPage,
|
|||||||
bool dequeuedPage = false;
|
bool dequeuedPage = false;
|
||||||
if (page != NULL) {
|
if (page != NULL) {
|
||||||
if (page->state == PAGE_STATE_MODIFIED) {
|
if (page->state == PAGE_STATE_MODIFIED) {
|
||||||
InterruptsSpinLocker locker(&sPageLock);
|
MutexLocker locker(&sPageLock);
|
||||||
remove_page_from_queue(&sModifiedPageQueue, page);
|
remove_page_from_queue(&sModifiedPageQueue, page);
|
||||||
dequeuedPage = true;
|
dequeuedPage = true;
|
||||||
} else if (page->state == PAGE_STATE_BUSY
|
} else if (page->state == PAGE_STATE_BUSY
|
||||||
@@ -1787,7 +1787,7 @@ vm_page_write_modified_page_range(struct VMCache* cache, uint32 firstPage,
|
|||||||
wrappers[i]->CheckRemoveFromShrunkenCache();
|
wrappers[i]->CheckRemoveFromShrunkenCache();
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptsSpinLocker locker(&sPageLock);
|
MutexLocker locker(&sPageLock);
|
||||||
|
|
||||||
for (int32 i = 0; i < usedWrappers; i++)
|
for (int32 i = 0; i < usedWrappers; i++)
|
||||||
wrappers[i]->Done(status);
|
wrappers[i]->Done(status);
|
||||||
@@ -2001,8 +2001,7 @@ vm_mark_page_range_inuse(addr_t startPage, addr_t length)
|
|||||||
return B_BAD_VALUE;
|
return B_BAD_VALUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
cpu_status state = disable_interrupts();
|
MutexLocker _(sPageLock);
|
||||||
acquire_spinlock(&sPageLock);
|
|
||||||
|
|
||||||
for (addr_t i = 0; i < length; i++) {
|
for (addr_t i = 0; i < length; i++) {
|
||||||
vm_page *page = &sPages[startPage + i];
|
vm_page *page = &sPages[startPage + i];
|
||||||
@@ -2026,9 +2025,6 @@ vm_mark_page_range_inuse(addr_t startPage, addr_t length)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
release_spinlock(&sPageLock);
|
|
||||||
restore_interrupts(state);
|
|
||||||
|
|
||||||
return B_OK;
|
return B_OK;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2044,7 +2040,7 @@ vm_page_unreserve_pages(uint32 count)
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
ASSERT(sReservedPages >= count);
|
ASSERT(sReservedPages >= count);
|
||||||
|
|
||||||
T(UnreservePages(count));
|
T(UnreservePages(count));
|
||||||
@@ -2067,7 +2063,7 @@ vm_page_reserve_pages(uint32 count)
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
T(ReservePages(count));
|
T(ReservePages(count));
|
||||||
|
|
||||||
@@ -2091,7 +2087,7 @@ vm_page_try_reserve_pages(uint32 count)
|
|||||||
if (count == 0)
|
if (count == 0)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
T(ReservePages(count));
|
T(ReservePages(count));
|
||||||
|
|
||||||
@@ -2125,7 +2121,7 @@ vm_page_allocate_page(int pageState, bool reserved)
|
|||||||
return NULL; // invalid
|
return NULL; // invalid
|
||||||
}
|
}
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
T(AllocatePage(reserved));
|
T(AllocatePage(reserved));
|
||||||
|
|
||||||
@@ -2210,7 +2206,7 @@ vm_page_allocate_page_run(int pageState, addr_t base, addr_t length)
|
|||||||
vm_page *firstPage = NULL;
|
vm_page *firstPage = NULL;
|
||||||
uint32 start = base >> PAGE_SHIFT;
|
uint32 start = base >> PAGE_SHIFT;
|
||||||
|
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
if (free_page_queue_count() - sReservedPages < length) {
|
if (free_page_queue_count() - sReservedPages < length) {
|
||||||
// TODO: add more tries, ie. free some inactive, ...
|
// TODO: add more tries, ie. free some inactive, ...
|
||||||
@@ -2266,7 +2262,7 @@ vm_page_allocate_page_run(int pageState, addr_t base, addr_t length)
|
|||||||
vm_page *
|
vm_page *
|
||||||
vm_page_allocate_page_run_no_base(int pageState, addr_t count)
|
vm_page_allocate_page_run_no_base(int pageState, addr_t count)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker locker(sPageLock);
|
MutexLocker locker(sPageLock);
|
||||||
|
|
||||||
if (free_page_queue_count() - sReservedPages < count) {
|
if (free_page_queue_count() - sReservedPages < count) {
|
||||||
// TODO: add more tries, ie. free some inactive, ...
|
// TODO: add more tries, ie. free some inactive, ...
|
||||||
@@ -2370,7 +2366,7 @@ vm_lookup_page(addr_t pageNumber)
|
|||||||
void
|
void
|
||||||
vm_page_free(vm_cache *cache, vm_page *page)
|
vm_page_free(vm_cache *cache, vm_page *page)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker _(sPageLock);
|
MutexLocker _(sPageLock);
|
||||||
|
|
||||||
if (page->cache == NULL && page->state == PAGE_STATE_MODIFIED
|
if (page->cache == NULL && page->state == PAGE_STATE_MODIFIED
|
||||||
&& cache->temporary) {
|
&& cache->temporary) {
|
||||||
@@ -2384,7 +2380,7 @@ vm_page_free(vm_cache *cache, vm_page *page)
|
|||||||
status_t
|
status_t
|
||||||
vm_page_set_state(vm_page *page, int pageState)
|
vm_page_set_state(vm_page *page, int pageState)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker _(sPageLock);
|
MutexLocker _(sPageLock);
|
||||||
|
|
||||||
return set_page_state_nolock(page, pageState);
|
return set_page_state_nolock(page, pageState);
|
||||||
}
|
}
|
||||||
@@ -2396,7 +2392,7 @@ vm_page_set_state(vm_page *page, int pageState)
|
|||||||
void
|
void
|
||||||
vm_page_requeue(struct vm_page *page, bool tail)
|
vm_page_requeue(struct vm_page *page, bool tail)
|
||||||
{
|
{
|
||||||
InterruptsSpinLocker _(sPageLock);
|
MutexLocker _(sPageLock);
|
||||||
page_queue *queue = NULL;
|
page_queue *queue = NULL;
|
||||||
|
|
||||||
switch (page->state) {
|
switch (page->state) {
|
||||||
|
|||||||
Reference in New Issue
Block a user