diff options
Diffstat (limited to 'kernel/vm/shadow.c')
-rw-r--r-- | kernel/vm/shadow.c | 83 |
1 files changed, 20 insertions, 63 deletions
diff --git a/kernel/vm/shadow.c b/kernel/vm/shadow.c index 91b1fce..06cf20d 100644 --- a/kernel/vm/shadow.c +++ b/kernel/vm/shadow.c @@ -71,6 +71,7 @@ mobj_t *shadow_create(mobj_t *shadowed) } // initialize the mobj_shadow_t + so->shadowed = shadowed; // set the bottom_mobj based on the two cases if (shadowed->mo_type == MOBJ_SHADOW) @@ -82,12 +83,11 @@ mobj_t *shadow_create(mobj_t *shadowed) so->bottom_mobj = shadowed; } // init the other fields - so->shadowed = shadowed; - mobj_init(&so->mobj, MOBJ_SHADOW, &shadow_mobj_ops); mobj_ref(so->shadowed); mobj_ref(so->bottom_mobj); - // lock the shadow object + // init and lock the shadow object + mobj_init(&so->mobj, MOBJ_SHADOW, &shadow_mobj_ops); mobj_lock(&so->mobj); // return the shadow object @@ -110,52 +110,7 @@ mobj_t *shadow_create(mobj_t *shadowed) */ void shadow_collapse(mobj_t *o) { - // NOT_YET_IMPLEMENTED("VM: shadow_collapse"); - - // get the mobj_shadow_t and it's mobj - mobj_shadow_t *so = MOBJ_TO_SO(o); - mobj_t *iter = so->shadowed; - // iterate through the shadow chain - while (iter && so->shadowed->mo_type == MOBJ_SHADOW) - { - // check to see if the refcount is not 1. if so, continue to next shadowed object - if (so->shadowed->mo_refcount != 1) - { - iter = so->shadowed; - continue; - } - // else, go over the shadowed object's pframes - - // iterate through the pframes - mobj_lock(&so->shadowed); - list_iterate(&so->shadowed->mo_pframes, pframe, pframe_t, pf_link) - { - // get the pframe from the shadow object - pframe_t *spf = NULL; - - mobj_lock(iter); // lock before getting the pframe - mobj_find_pframe(o, pframe->pf_pagenum, &spf); - mobj_unlock(iter); - - // check if the pframe is not in the shadow object when migrating - if (spf == NULL) - { - // if not, remove the pframe from the shadowed object - // and insert it into out iterated shadow object - list_remove(&pframe->pf_link); - list_insert_tail(&iter->mo_pframes, &pframe->pf_link); - } - else - { - // if it is, release the pframe we found - pframe_release(&spf); - } - } - - // put locked the shadowed object after iterating through it - mobj_put_locked(&so->shadowed); - // FIXME: this is probably wrong - } + NOT_YET_IMPLEMENTED("VM: shadow_collapse"); } /* @@ -210,7 +165,7 @@ static long shadow_get_pframe(mobj_t *o, size_t pagenum, long forwrite, while (iter && iter->mo_type == MOBJ_SHADOW) { mobj_lock(iter); - mobj_find_pframe(o, pagenum, &pf); + mobj_find_pframe(iter, pagenum, &pf); mobj_unlock(iter); if (pf) { @@ -218,14 +173,15 @@ static long shadow_get_pframe(mobj_t *o, size_t pagenum, long forwrite, return 0; } // update the iterator - iter = MOBJ_TO_SO(iter)->shadowed; + so = MOBJ_TO_SO(iter); + iter = so->shadowed; } // if no shadow objects have the page, call mobj_get_pframe() to get the page from the bottom object // at this point, iter is the bottom object - mobj_lock(iter); - long ret = mobj_get_pframe(iter, pagenum, forwrite, pfp); - mobj_unlock(iter); + mobj_lock(so->bottom_mobj); + long ret = mobj_get_pframe(so->bottom_mobj, pagenum, forwrite, pfp); + mobj_unlock(so->bottom_mobj); return ret; } @@ -252,7 +208,7 @@ static long shadow_get_pframe(mobj_t *o, size_t pagenum, long forwrite, */ static long shadow_fill_pframe(mobj_t *o, pframe_t *pf) { - // NOT_YET_IMPLEMENTED("VM: shadow_fill_pframe"); + // NOT_YET_IMPLEMENTEDshadow_fill_pframe"); // get the mobj_shadow_t mobj_shadow_t *so = MOBJ_TO_SO(o); @@ -263,7 +219,7 @@ static long shadow_fill_pframe(mobj_t *o, pframe_t *pf) // get the pframe from the shadow object pframe_t *spf = NULL; mobj_lock(iter); - mobj_find_pframe(o, pf->pf_pagenum, &spf); + mobj_find_pframe(iter, pf->pf_pagenum, &spf); mobj_unlock(iter); // if the pframe is found, copy the contents into pf @@ -276,19 +232,20 @@ static long shadow_fill_pframe(mobj_t *o, pframe_t *pf) } // update the iterator - iter = MOBJ_TO_SO(iter)->shadowed; + so = MOBJ_TO_SO(iter); + iter = so->shadowed; } // if none of the shadow objects have a copy of the frame, use mobj_get_pframe on the bottom object pframe_t *spf = NULL; - mobj_lock(iter); - long ret = mobj_get_pframe(iter, pf->pf_pagenum, 0, &spf); - mobj_unlock(iter); + mobj_lock(so->bottom_mobj); + long ret = mobj_get_pframe(so->bottom_mobj, pf->pf_pagenum, 0, &spf); + mobj_unlock(so->bottom_mobj); // check if the operation was sucessful, memcpy the contents into pf // and release the pframe - if (ret == 0) + if (ret >= 0) { - memcpy(pf->pf_addr, pf->pf_addr, PAGE_SIZE); + memcpy(pf->pf_addr, spf->pf_addr, PAGE_SIZE); pframe_release(&spf); } @@ -336,4 +293,4 @@ static void shadow_destructor(mobj_t *o) // free the slab slab_obj_free(shadow_allocator, so); -} +}
\ No newline at end of file |