Refactor vm_page_sleep_if_busy() so that the test for a busy page is

inlined and a procedure call is made in the rare case, i.e., when it is
necessary to sleep.  In this case, inlining the test actually makes the
kernel smaller.
This commit is contained in:
Alan Cox 2006-08-27 19:50:13 +00:00
parent a6c5f81339
commit eb4bbba83a
2 changed files with 41 additions and 25 deletions

View File

@ -484,36 +484,31 @@ vm_page_free_zero(vm_page_t m)
}
/*
* vm_page_sleep_if_busy:
* vm_page_sleep:
*
* Sleep and release the page queues lock if PG_BUSY is set or,
* if also_m_busy is TRUE, busy is non-zero. Returns TRUE if the
* thread slept and the page queues lock was released.
* Otherwise, retains the page queues lock and returns FALSE.
* Sleep and release the page queues lock.
*
* The object containing the given page must be locked.
*/
int
vm_page_sleep_if_busy(vm_page_t m, int also_m_busy, const char *msg)
void
vm_page_sleep(vm_page_t m, const char *msg)
{
VM_OBJECT_LOCK_ASSERT(m->object, MA_OWNED);
if ((m->flags & PG_BUSY) || (also_m_busy && m->busy)) {
if (!mtx_owned(&vm_page_queue_mtx))
vm_page_lock_queues();
vm_page_flag_set(m, PG_REFERENCED);
vm_page_unlock_queues();
if (!mtx_owned(&vm_page_queue_mtx))
vm_page_lock_queues();
vm_page_flag_set(m, PG_REFERENCED);
vm_page_unlock_queues();
/*
* It's possible that while we sleep, the page will get
* unbusied and freed. If we are holding the object
* lock, we will assume we hold a reference to the object
* such that even if m->object changes, we can re-lock
* it.
*/
m->oflags |= VPO_WANTED;
msleep(m, VM_OBJECT_MTX(m->object), PVM, msg, 0);
return (TRUE);
}
return (FALSE);
/*
* It's possible that while we sleep, the page will get
* unbusied and freed. If we are holding the object
* lock, we will assume we hold a reference to the object
* such that even if m->object changes, we can re-lock
* it.
*/
m->oflags |= VPO_WANTED;
msleep(m, VM_OBJECT_MTX(m->object), PVM, msg, 0);
}
/*

View File

@ -314,7 +314,6 @@ void vm_page_hold(vm_page_t mem);
void vm_page_unhold(vm_page_t mem);
void vm_page_free(vm_page_t m);
void vm_page_free_zero(vm_page_t m);
int vm_page_sleep_if_busy(vm_page_t m, int also_m_busy, const char *msg);
void vm_page_dirty(vm_page_t m);
void vm_page_wakeup(vm_page_t m);
@ -342,6 +341,7 @@ vm_page_t vm_page_lookup (vm_object_t, vm_pindex_t);
void vm_page_remove (vm_page_t);
void vm_page_rename (vm_page_t, vm_object_t, vm_pindex_t);
vm_page_t vm_page_select_cache(int);
void vm_page_sleep(vm_page_t m, const char *msg);
vm_page_t vm_page_splay(vm_pindex_t, vm_page_t);
vm_offset_t vm_page_startup(vm_offset_t vaddr);
void vm_page_unmanage (vm_page_t);
@ -360,6 +360,27 @@ void vm_page_cowfault (vm_page_t);
void vm_page_cowsetup (vm_page_t);
void vm_page_cowclear (vm_page_t);
/*
* vm_page_sleep_if_busy:
*
* Sleep and release the page queues lock if PG_BUSY is set or,
* if also_m_busy is TRUE, busy is non-zero. Returns TRUE if the
* thread slept and the page queues lock was released.
* Otherwise, retains the page queues lock and returns FALSE.
*
* The object containing the given page must be locked.
*/
static __inline int
vm_page_sleep_if_busy(vm_page_t m, int also_m_busy, const char *msg)
{
if ((m->flags & PG_BUSY) || (also_m_busy && m->busy)) {
vm_page_sleep(m, msg);
return (TRUE);
}
return (FALSE);
}
/*
* vm_page_undirty:
*