diff --git a/kernel/base/vm/los_vm_phys.c b/kernel/base/vm/los_vm_phys.c index c6fcb061415f8dd98265b4339b3c4a161943a46d..acc23e362d4a4326f152cb68ebe13b08aa0d6439 100644 --- a/kernel/base/vm/los_vm_phys.c +++ b/kernel/base/vm/los_vm_phys.c @@ -336,7 +336,7 @@ VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order) OsVmPhysFreeListAdd(page, order);//伙伴算法 空闲节点增加 } - +//连续的释放物理页框, 如果8页连在一块是一起释放的,取决于使用了伙伴算法的order VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages) { paddr_t pa; @@ -551,7 +551,7 @@ UINT32 OsVmPagesToOrder(size_t nPages) return order; } - +//释放双链表中的所有节点内存,本质是回归到伙伴orderlist中 size_t LOS_PhysPagesFree(LOS_DL_LIST *list) { UINT32 intSave; @@ -564,16 +564,16 @@ size_t LOS_PhysPagesFree(LOS_DL_LIST *list) return 0; } - LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) { - LOS_ListDelete(&page->node); - if (LOS_AtomicDecRet(&page->refCounts) <= 0) { - seg = &g_vmPhysSeg[page->segID]; - LOS_SpinLockSave(&seg->freeListLock, &intSave); - OsVmPhysPagesFreeContiguous(page, ONE_PAGE); - LOS_AtomicSet(&page->refCounts, 0); - LOS_SpinUnlockRestore(&seg->freeListLock, intSave); + LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) {//宏循环 + LOS_ListDelete(&page->node);//先把自己摘出去 + if (LOS_AtomicDecRet(&page->refCounts) <= 0) {//无引用 + seg = &g_vmPhysSeg[page->segID];//获取物理段 + LOS_SpinLockSave(&seg->freeListLock, &intSave);//锁住freeList + OsVmPhysPagesFreeContiguous(page, ONE_PAGE);//连续释放,注意这里的ONE_PAGE其实有误导,让人以为是释放4K,其实是指连续的物理页框,如果3页连在一块是一起释放的. + LOS_AtomicSet(&page->refCounts, 0);//引用重置为0 + LOS_SpinUnlockRestore(&seg->freeListLock, intSave);//恢复锁 } - count++; + count++;//继续取下一个node } return count; diff --git a/kernel/base/vm/shm.c b/kernel/base/vm/shm.c index bc1e11a806fdebf366f181e9af9545756c21b42f..d4d6796103d2644735954f87737a4c20ef158e54 100644 --- a/kernel/base/vm/shm.c +++ b/kernel/base/vm/shm.c @@ -144,7 +144,7 @@ INT32 ShmDeinit(VOID) return 0; } -//设置共享flag +//给共享段中所有物理页框贴上共享标签 STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg) { LosVmPage *page = NULL; @@ -153,7 +153,7 @@ STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg) OsSetPageShared(page); } } - +//给共享段中所有物理页框撕掉共享标签 STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg) { LosVmPage *page = NULL; @@ -210,35 +210,35 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, int shmflg) seg->ds.shm_perm.mode = (unsigned int)shmflg & ACCESSPERMS; seg->ds.shm_perm.key = key; seg->ds.shm_segsz = size; - seg->ds.shm_perm.cuid = LOS_GetUserID(); - seg->ds.shm_perm.uid = LOS_GetUserID(); - seg->ds.shm_perm.cgid = LOS_GetGroupID(); - seg->ds.shm_perm.gid = LOS_GetGroupID(); + seg->ds.shm_perm.cuid = LOS_GetUserID(); //设置用户ID + seg->ds.shm_perm.uid = LOS_GetUserID(); //设置用户ID + seg->ds.shm_perm.cgid = LOS_GetGroupID(); //设置组ID + seg->ds.shm_perm.gid = LOS_GetGroupID(); //设置组ID seg->ds.shm_lpid = 0; - seg->ds.shm_nattch = 0; - seg->ds.shm_cpid = LOS_GetCurrProcessID(); + seg->ds.shm_nattch = 0; + seg->ds.shm_cpid = LOS_GetCurrProcessID(); //获取进程ID seg->ds.shm_atime = 0; seg->ds.shm_dtime = 0; seg->ds.shm_ctime = time(NULL); return segNum; } - +//释放seg->node 所占物理页框,seg本身重置 STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg) { UINT32 count; - ShmClearSharedFlag(seg); - count = LOS_PhysPagesFree(&seg->node); - if (count != (seg->ds.shm_segsz >> PAGE_SHIFT)) { + ShmClearSharedFlag(seg);//先撕掉 seg->node 中vmpage的共享标签 + count = LOS_PhysPagesFree(&seg->node);//再挨个删除物理页框 + if (count != (seg->ds.shm_segsz >> PAGE_SHIFT)) {//异常,必须要一样 VM_ERR("free physical pages failed, count = %d, size = %d", count, seg->ds.shm_segsz >> PAGE_SHIFT); return; } - seg->status = SHM_SEG_FREE; - LOS_ListInit(&seg->node); + seg->status = SHM_SEG_FREE;//seg恢复自由之身 + LOS_ListInit(&seg->node);//重置node } - +//通过key查找 shmId STATIC INT32 ShmFindSegByKey(key_t key) { INT32 i; @@ -583,15 +583,15 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) { struct shmIDSource *seg = NULL; INT32 ret = 0; - struct shm_info shmInfo; - struct ipc_perm shm_perm; + struct shm_info shmInfo;//前往查看结构体内容 ..\vendor_hisi_hi3861_hi3861\hi3861\platform\os\Huawei_LiteOS\components\lib\libc\musl\arch\generic\bits\shm.h + struct ipc_perm shm_perm;//前往查看结构体内容 ..\vendor_hisi_hi3861_hi3861\hi3861\platform\os\Huawei_LiteOS\components\lib\libc\musl\arch\generic\bits\ipc.h cmd = ((UINT32)cmd & ~IPC_64); SYSV_SHM_LOCK(); if ((cmd != IPC_INFO) && (cmd != SHM_INFO)) { - seg = ShmFindSeg(shmid); + seg = ShmFindSeg(shmid);//通过索引ID找到seg if (seg == NULL) { SYSV_SHM_UNLOCK(); return -1; @@ -664,7 +664,7 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) shmInfo.shm_tot = 0; shmInfo.swap_attempts = 0; shmInfo.swap_successes = 0; - shmInfo.used_ids = ShmSegUsedCount(); + shmInfo.used_ids = ShmSegUsedCount();//在使用的seg数 ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info));//把内核空间的共享页数据拷贝到用户空间 if (ret != 0) { ret = EFAULT;