fn create_child(
        &mut self,
        offset: usize,
        len: usize,
        lock_ref: &Arc<Mutex<()>>,
    ) -> ZxResult<Arc<VMObjectPaged>> {
        // clone contiguous vmo is no longer permitted
        // https://fuchsia.googlesource.com/fuchsia/+/e6b4c6751bbdc9ed2795e81b8211ea294f139a45
        if self.is_contiguous() {
            return Err(ZxError::INVALID_ARGS);
        }
        if self.cache_policy != CachePolicy::Cached || self.pin_count != 0 {
            return Err(ZxError::BAD_STATE);
        }
        // create child VMO
        let child = VMObjectPaged::wrap(
            VMObjectPagedInner {
                owner: new_owner_id(),
                type_: VMOType::Snapshot,
                parent: None, // set later
                parent_offset: offset,
                parent_limit: (offset + len).min(self.size),
                size: len,
                frames: HashMap::new(),
                mappings: Vec::new(),
                cache_policy: CachePolicy::Cached,
                contiguous: false,
                self_ref: Default::default(),
                pin_count: 0,
            },
            Some(lock_ref.clone()),
        );
        // construct a hidden VMO as shared parent
        let hidden = VMObjectPaged::wrap(
            VMObjectPagedInner {
                owner: self.owner,
                type_: VMOType::Hidden {
                    left: self.self_ref.clone(),
                    right: Arc::downgrade(&child),
                },
                parent: self.parent.clone(),
                parent_offset: self.parent_offset,
                parent_limit: self.parent_limit,
                size: self.size,
                frames: core::mem::take(&mut self.frames),
                mappings: Vec::new(),
                cache_policy: CachePolicy::Cached,
                contiguous: self.contiguous,
                self_ref: Default::default(),
                pin_count: self.pin_count,
            },
            Some(lock_ref.clone()),
        );
        // update parent's child
        if let Some(parent) = self.parent.take() {
            if let VMOType::Hidden { left, right, .. } = &mut parent.inner.borrow_mut().type_ {
                if left.ptr_eq(&self.self_ref) {
                    *left = Arc::downgrade(&hidden);
                } else if right.ptr_eq(&self.self_ref) {
                    *right = Arc::downgrade(&hidden);
                } else {
                    panic!();
                }
            }
        }
        // update children's parent
        self.parent = Some(hidden.clone());
        self.parent_offset = 0;
        self.parent_limit = self.size;
        child.inner.borrow_mut().parent = Some(hidden);
        // update mappings
        for map in self.mappings.iter() {
            if let Some(map) = map.upgrade() {
                map.range_change(pages(offset), pages(len), RangeChangeOp::RemoveWrite);
                //用于写时复制
            }
        }
        Ok(child)
    }
/// Create a snapshot child VMO.
Create a snapshot child VMO.
Create a snapshot child VMO .
fn create_child(
        &mut self,
        offset: usize,
        len: usize,
        lock_ref: &Arc<Mutex<()>>,
    ) -> ZxResult<Arc<VMObjectPaged>> {
        // clone contiguous vmo is no longer permitted
        // https://fuchsia.googlesource.com/fuchsia/+/e6b4c6751bbdc9ed2795e81b8211ea294f139a45
        if self.is_contiguous() {
            return Err(ZxError::INVALID_ARGS);
        }
        if self.cache_policy != CachePolicy::Cached || self.pin_count != 0 {
            return Err(ZxError::BAD_STATE);
        }
        // create child VMO
        let child = VMObjectPaged::wrap(
            VMObjectPagedInner {
                owner: new_owner_id(),
                type_: VMOType::Snapshot,
                parent: None, // set later
                parent_offset: offset,
                parent_limit: (offset + len).min(self.size),
                size: len,
                frames: HashMap::new(),
                mappings: Vec::new(),
                cache_policy: CachePolicy::Cached,
                contiguous: false,
                self_ref: Default::default(),
                pin_count: 0,
            },
            Some(lock_ref.clone()),
        );
        // construct a hidden VMO as shared parent
        let hidden = VMObjectPaged::wrap(
            VMObjectPagedInner {
                owner: self.owner,
                type_: VMOType::Hidden {
                    left: self.self_ref.clone(),
                    right: Arc::downgrade(&child),
                },
                parent: self.parent.clone(),
                parent_offset: self.parent_offset,
                parent_limit: self.parent_limit,
                size: self.size,
                frames: core::mem::take(&mut self.frames),
                mappings: Vec::new(),
                cache_policy: CachePolicy::Cached,
                contiguous: self.contiguous,
                self_ref: Default::default(),
                pin_count: self.pin_count,
            },
            Some(lock_ref.clone()),
        );
        // update parent's child
        if let Some(parent) = self.parent.take() {
            if let VMOType::Hidden { left, right, .. } = &mut parent.inner.borrow_mut().type_ {
                if left.ptr_eq(&self.self_ref) {
                    *left = Arc::downgrade(&hidden);
                } else if right.ptr_eq(&self.self_ref) {
                    *right = Arc::downgrade(&hidden);
                } else {
                    panic!();
                }
            }
        }
        // update children's parent
        self.parent = Some(hidden.clone());
        self.parent_offset = 0;
        self.parent_limit = self.size;
        child.inner.borrow_mut().parent = Some(hidden);
        // update mappings
        for map in self.mappings.iter() {
            if let Some(map) = map.upgrade() {
                map.range_change(pages(offset), pages(len), RangeChangeOp::RemoveWrite);
                //用于写时复制
            }
        }
        Ok(child)
    }
fn create_child ( & mut self , offset : usize , len : usize , lock_ref : & Arc < Mutex < ( ) > > , ) -> ZxResult < Arc < VMObjectPaged > > { // clone contiguous vmo is no longer permitted // https://fuchsia.googlesource.com/fuchsia/+/e6b4c6751bbdc9ed2795e81b8211ea294f139a45 if self . is_contiguous ( ) { return Err ( ZxError :: INVALID_ARGS ) ; } if self . cache_policy != CachePolicy :: Cached || self . pin_count != 0 { return Err ( ZxError :: BAD_STATE ) ; } // create child VMO let child = VMObjectPaged :: wrap ( VMObjectPagedInner { owner : new_owner_id ( ) , type_ : VMOType :: Snapshot , parent : None , // set later parent_offset : offset , parent_limit : ( offset + len ) . min ( self . size ) , size : len , frames : HashMap :: new ( ) , mappings : Vec :: new ( ) , cache_policy : CachePolicy :: Cached , contiguous : false , self_ref : Default :: default ( ) , pin_count : 0 , } , Some ( lock_ref . clone ( ) ) , ) ; // construct a hidden VMO as shared parent let hidden = VMObjectPaged :: wrap ( VMObjectPagedInner { owner : self . owner , type_ : VMOType :: Hidden { left : self . self_ref . clone ( ) , right : Arc :: downgrade ( & child ) , } , parent : self . parent . clone ( ) , parent_offset : self . parent_offset , parent_limit : self . parent_limit , size : self . size , frames : core :: mem :: take ( & mut self . frames ) , mappings : Vec :: new ( ) , cache_policy : CachePolicy :: Cached , contiguous : self . contiguous , self_ref : Default :: default ( ) , pin_count : self . pin_count , } , Some ( lock_ref . clone ( ) ) , ) ; // update parent's child if let Some ( parent ) = self . parent . take ( ) { if let VMOType :: Hidden { left , right , .. } = & mut parent . inner . borrow_mut ( ) . type_ { if left . ptr_eq ( & self . self_ref ) { * left = Arc :: downgrade ( & hidden ) ; } else if right . ptr_eq ( & self . self_ref ) { * right = Arc :: downgrade ( & hidden ) ; } else { panic ! ( ) ; } } } // update children's parent self . parent = Some ( hidden . clone ( ) ) ; self . parent_offset = 0 ; self . parent_limit = self . size ; child . inner . borrow_mut ( ) . parent = Some ( hidden ) ; // update mappings for map in self . mappings . iter ( ) { if let Some ( map ) = map . upgrade ( ) { map . range_change ( pages ( offset ) , pages ( len ) , RangeChangeOp :: RemoveWrite ) ; //用于写时复制 } } Ok ( child ) }
Create a snapshot child VMO.
Create a snapshot child VMO .
&mut self
offset
usize
len
usize
lock_ref
&Arc<Mutex<()>>
&mut self
offset
usize
len
usize
lock_ref
&Arc<Mutex<()>>