提交 eec4a52e 编写于 作者: 鸿蒙内核源码分析's avatar 鸿蒙内核源码分析
上级 2f73237a
...@@ -336,7 +336,7 @@ VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order) ...@@ -336,7 +336,7 @@ VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order)
OsVmPhysFreeListAdd(page, order);//伙伴算法 空闲节点增加 OsVmPhysFreeListAdd(page, order);//伙伴算法 空闲节点增加
} }
//连续的释放物理页框, 如果8页连在一块是一起释放的,取决于使用了伙伴算法的order
VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages) VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages)
{ {
paddr_t pa; paddr_t pa;
...@@ -551,7 +551,7 @@ UINT32 OsVmPagesToOrder(size_t nPages) ...@@ -551,7 +551,7 @@ UINT32 OsVmPagesToOrder(size_t nPages)
return order; return order;
} }
//释放双链表中的所有节点内存,本质是回归到伙伴orderlist中
size_t LOS_PhysPagesFree(LOS_DL_LIST *list) size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
{ {
UINT32 intSave; UINT32 intSave;
...@@ -564,16 +564,16 @@ size_t LOS_PhysPagesFree(LOS_DL_LIST *list) ...@@ -564,16 +564,16 @@ size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
return 0; return 0;
} }
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) { LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) {//宏循环
LOS_ListDelete(&page->node); LOS_ListDelete(&page->node);//先把自己摘出去
if (LOS_AtomicDecRet(&page->refCounts) <= 0) { if (LOS_AtomicDecRet(&page->refCounts) <= 0) {//无引用
seg = &g_vmPhysSeg[page->segID]; seg = &g_vmPhysSeg[page->segID];//获取物理段
LOS_SpinLockSave(&seg->freeListLock, &intSave); LOS_SpinLockSave(&seg->freeListLock, &intSave);//锁住freeList
OsVmPhysPagesFreeContiguous(page, ONE_PAGE); OsVmPhysPagesFreeContiguous(page, ONE_PAGE);//连续释放,注意这里的ONE_PAGE其实有误导,让人以为是释放4K,其实是指连续的物理页框,如果3页连在一块是一起释放的.
LOS_AtomicSet(&page->refCounts, 0); LOS_AtomicSet(&page->refCounts, 0);//引用重置为0
LOS_SpinUnlockRestore(&seg->freeListLock, intSave); LOS_SpinUnlockRestore(&seg->freeListLock, intSave);//恢复锁
} }
count++; count++;//继续取下一个node
} }
return count; return count;
......
...@@ -144,7 +144,7 @@ INT32 ShmDeinit(VOID) ...@@ -144,7 +144,7 @@ INT32 ShmDeinit(VOID)
return 0; return 0;
} }
//设置共享flag //给共享段中所有物理页框贴上共享标签
STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg) STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg)
{ {
LosVmPage *page = NULL; LosVmPage *page = NULL;
...@@ -153,7 +153,7 @@ STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg) ...@@ -153,7 +153,7 @@ STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg)
OsSetPageShared(page); OsSetPageShared(page);
} }
} }
//给共享段中所有物理页框撕掉共享标签
STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg) STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg)
{ {
LosVmPage *page = NULL; LosVmPage *page = NULL;
...@@ -210,35 +210,35 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, int shmflg) ...@@ -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.mode = (unsigned int)shmflg & ACCESSPERMS;
seg->ds.shm_perm.key = key; seg->ds.shm_perm.key = key;
seg->ds.shm_segsz = size; seg->ds.shm_segsz = size;
seg->ds.shm_perm.cuid = LOS_GetUserID(); seg->ds.shm_perm.cuid = LOS_GetUserID(); //设置用户ID
seg->ds.shm_perm.uid = LOS_GetUserID(); seg->ds.shm_perm.uid = LOS_GetUserID(); //设置用户ID
seg->ds.shm_perm.cgid = LOS_GetGroupID(); seg->ds.shm_perm.cgid = LOS_GetGroupID(); //设置组ID
seg->ds.shm_perm.gid = LOS_GetGroupID(); seg->ds.shm_perm.gid = LOS_GetGroupID(); //设置组ID
seg->ds.shm_lpid = 0; seg->ds.shm_lpid = 0;
seg->ds.shm_nattch = 0; seg->ds.shm_nattch = 0;
seg->ds.shm_cpid = LOS_GetCurrProcessID(); seg->ds.shm_cpid = LOS_GetCurrProcessID(); //获取进程ID
seg->ds.shm_atime = 0; seg->ds.shm_atime = 0;
seg->ds.shm_dtime = 0; seg->ds.shm_dtime = 0;
seg->ds.shm_ctime = time(NULL); seg->ds.shm_ctime = time(NULL);
return segNum; return segNum;
} }
//释放seg->node 所占物理页框,seg本身重置
STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg) STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg)
{ {
UINT32 count; UINT32 count;
ShmClearSharedFlag(seg); ShmClearSharedFlag(seg);//先撕掉 seg->node 中vmpage的共享标签
count = LOS_PhysPagesFree(&seg->node); count = LOS_PhysPagesFree(&seg->node);//再挨个删除物理页框
if (count != (seg->ds.shm_segsz >> PAGE_SHIFT)) { 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); VM_ERR("free physical pages failed, count = %d, size = %d", count, seg->ds.shm_segsz >> PAGE_SHIFT);
return; return;
} }
seg->status = SHM_SEG_FREE; seg->status = SHM_SEG_FREE;//seg恢复自由之身
LOS_ListInit(&seg->node); LOS_ListInit(&seg->node);//重置node
} }
//通过key查找 shmId
STATIC INT32 ShmFindSegByKey(key_t key) STATIC INT32 ShmFindSegByKey(key_t key)
{ {
INT32 i; INT32 i;
...@@ -583,15 +583,15 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) ...@@ -583,15 +583,15 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
{ {
struct shmIDSource *seg = NULL; struct shmIDSource *seg = NULL;
INT32 ret = 0; INT32 ret = 0;
struct shm_info shmInfo; 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; 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); cmd = ((UINT32)cmd & ~IPC_64);
SYSV_SHM_LOCK(); SYSV_SHM_LOCK();
if ((cmd != IPC_INFO) && (cmd != SHM_INFO)) { if ((cmd != IPC_INFO) && (cmd != SHM_INFO)) {
seg = ShmFindSeg(shmid); seg = ShmFindSeg(shmid);//通过索引ID找到seg
if (seg == NULL) { if (seg == NULL) {
SYSV_SHM_UNLOCK(); SYSV_SHM_UNLOCK();
return -1; return -1;
...@@ -664,7 +664,7 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf) ...@@ -664,7 +664,7 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
shmInfo.shm_tot = 0; shmInfo.shm_tot = 0;
shmInfo.swap_attempts = 0; shmInfo.swap_attempts = 0;
shmInfo.swap_successes = 0; shmInfo.swap_successes = 0;
shmInfo.used_ids = ShmSegUsedCount(); shmInfo.used_ids = ShmSegUsedCount();//在使用的seg数
ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info));//把内核空间的共享页数据拷贝到用户空间 ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info));//把内核空间的共享页数据拷贝到用户空间
if (ret != 0) { if (ret != 0) {
ret = EFAULT; ret = EFAULT;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册