aboutsummaryrefslogtreecommitdiff
path: root/kernel/vm/shadow.c
diff options
context:
space:
mode:
Diffstat (limited to 'kernel/vm/shadow.c')
-rw-r--r--kernel/vm/shadow.c53
1 files changed, 22 insertions, 31 deletions
diff --git a/kernel/vm/shadow.c b/kernel/vm/shadow.c
index e0a8674..ca20ab0 100644
--- a/kernel/vm/shadow.c
+++ b/kernel/vm/shadow.c
@@ -119,58 +119,49 @@ void shadow_collapse(mobj_t *o)
// NOT_YET_IMPLEMENTED("VM: shadow_collapse");
mobj_shadow_t *so = MOBJ_TO_SO(o);
- mobj_t *shadowed = so->shadowed;
-
- if (shadowed->mo_type != MOBJ_SHADOW)
- {
- return;
- }
-
- dbg(DBG_PRINT, "shadow_collapse: refcount bottom: %d\n", so->bottom_mobj->mo_refcount);
-
- while (shadowed && shadowed->mo_type == MOBJ_SHADOW)
+ mobj_t *next = so->shadowed;
+ while(next && next->mo_type==MOBJ_SHADOW)
{
- // mobj_shadow_t *so_shadowed = MOBJ_TO_SO(shadowed);
- mobj_t *shadowed_shadowed = MOBJ_TO_SO(shadowed)->shadowed;
- // if the refcount is not 1, then we can't collapse
- if (shadowed_shadowed->mo_refcount != 1)
+ // check if the shadowed object is collapsable
+ if (next->mo_refcount != 1)
{
- // continue down the shadow chain
- shadowed = shadowed_shadowed;
+ // continue on the shadow chain
+ so = MOBJ_TO_SO(next);
+ next = MOBJ_TO_SO(next)->shadowed;
continue;
}
- mobj_lock(shadowed_shadowed);
- list_iterate(&shadowed_shadowed->mo_pframes, pf, pframe_t, pf_link)
+ // migrate the pframes from o's shadowed object to o
+ // mobj_lock(next); // lock before iterover
+ list_iterate(&next->mo_pframes, pf, pframe_t, pf_link)
{
pframe_t *pf_shadow = NULL;
- mobj_find_pframe(shadowed_shadowed, pf->pf_pagenum, &pf_shadow);
+ mobj_lock(&so->mobj);
+ mobj_find_pframe(&so->mobj, pf->pf_pagenum, &pf_shadow);
+ mobj_unlock(&so->mobj);
if (!pf_shadow)
{
list_remove(&pf->pf_link);
- // append to the list of pframes
- list_insert_tail(&shadowed_shadowed->mo_pframes, &pf->pf_link);
+ // by migrate, just add to the list of pframes
+ list_insert_tail(&so->mobj.mo_pframes, &pf->pf_link);
}
else
{
+ // if it exists, just release it
pframe_release(&pf_shadow);
}
}
- // get the pointer to the shadowed object
- mobj_shadow_t *so_shadowed_shadowed = MOBJ_TO_SO(shadowed_shadowed);
- so->shadowed = shadowed_shadowed;
+ // update the pointer to the shadowed object
+ so->shadowed = MOBJ_TO_SO(next)->shadowed;
- mobj_lock(so->shadowed);
+ // update the refcounts
mobj_ref(so->shadowed);
- mobj_unlock(so->shadowed);
-
- // put the shadowed object
- mobj_put(&shadowed);
+ mobj_put(&next);
- // continue down the shadow chain
- shadowed = shadowed_shadowed;
+ // update next
+ next = so->shadowed;
}
}