From a27bbe631191814fe02990afccd9fe0565f6bdc5 Mon Sep 17 00:00:00 2001 From: sotech117 Date: Wed, 15 May 2024 02:13:46 +0000 Subject: it works! --- kernel/vm/shadow.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 61 insertions(+), 1 deletion(-) (limited to 'kernel') diff --git a/kernel/vm/shadow.c b/kernel/vm/shadow.c index bf04bc9..4166597 100644 --- a/kernel/vm/shadow.c +++ b/kernel/vm/shadow.c @@ -116,7 +116,67 @@ mobj_t *shadow_create(mobj_t *shadowed) */ void shadow_collapse(mobj_t *o) { - NOT_YET_IMPLEMENTED("VM: shadow_collapse"); + // 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->mo_type == MOBJ_SHADOW) + { + mobj_shadow_t *so_shadowed = MOBJ_TO_SO(shadowed); + mobj_t *shadowed_shadowed = so_shadowed->shadowed; + + // if the refcount is not 1, then we can't collapse + if (shadowed_shadowed->mo_refcount != 1) + { + // continue down the shadow chain + shadowed = shadowed_shadowed; + continue; + } + + mobj_lock(shadowed_shadowed); + list_iterate(&shadowed_shadowed->mo_pframes, pf, pframe_t, pf_link) + { + pframe_t *pf_shadow = NULL; + mobj_find_pframe(shadowed_shadowed, pf->pf_pagenum, &pf_shadow); + if (!pf_shadow) + { + list_remove(&pf->pf_link); + // append to the list of pframes + list_insert_tail(&shadowed_shadowed->mo_pframes, &pf->pf_link); + } + else + { + pframe_release(&pf_shadow); + } + } + mobj_unlock(shadowed_shadowed); + + if (shadowed_shadowed->mo_type != MOBJ_SHADOW) + { + // put the shadowed object + mobj_put(&shadowed); + break; + } + + // get the pointer to the shadowed object + mobj_shadow_t *so_shadowed_shadowed = MOBJ_TO_SO(shadowed_shadowed); + so->shadowed = shadowed_shadowed; + mobj_ref(so->shadowed); + + // put the shadowed object + mobj_put(&shadowed); + + // continue down the shadow chain + shadowed = shadowed_shadowed; + } } -- cgit v1.2.3-70-g09d2