|
|
|
@ -1,3 +1,5 @@
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
=======
|
|
|
|
|
/*!
|
|
|
|
|
什么是共享内存
|
|
|
|
|
顾名思义,共享内存就是允许两个不相关的进程访问同一个物理内存。共享内存是在两个正在运行的进程之间
|
|
|
|
@ -12,6 +14,7 @@
|
|
|
|
|
共享线性区可以由任意的进程创建,每个使用共享线性区都必须经过映射.
|
|
|
|
|
*/
|
|
|
|
|
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
/*
|
|
|
|
|
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
|
|
|
|
|
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
|
|
|
|
@ -69,9 +72,15 @@
|
|
|
|
|
|
|
|
|
|
#ifdef LOSCFG_KERNEL_SHM
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
#define SHM_SEG_FREE 0x2000
|
|
|
|
|
#define SHM_SEG_USED 0x4000
|
|
|
|
|
#define SHM_SEG_REMOVE 0x8000
|
|
|
|
|
=======
|
|
|
|
|
#define SHM_SEG_FREE 0x2000 //空闲未使用
|
|
|
|
|
#define SHM_SEG_USED 0x4000 //已使用
|
|
|
|
|
#define SHM_SEG_REMOVE 0x8000 //删除
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
|
|
|
|
|
#ifndef SHM_M
|
|
|
|
|
#define SHM_M 010000
|
|
|
|
@ -80,17 +89,34 @@
|
|
|
|
|
#ifndef SHM_X
|
|
|
|
|
#define SHM_X 0100
|
|
|
|
|
#endif
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
#ifndef ACCESSPERMS
|
|
|
|
|
#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO)
|
|
|
|
|
#endif
|
|
|
|
|
=======
|
|
|
|
|
#ifndef ACCESSPERMS
|
|
|
|
|
#define ACCESSPERMS (S_IRWXU | S_IRWXG | S_IRWXO)//文件权限值意思就是 用户,用户组,其他可读可写.
|
|
|
|
|
#endif //代表含义U:user G:group O:other
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
|
|
|
|
|
#define SHM_S_IRUGO (S_IRUSR | S_IRGRP | S_IROTH)
|
|
|
|
|
#define SHM_S_IWUGO (S_IWUSR | S_IWGRP | S_IWOTH)
|
|
|
|
|
#define SHM_S_IXUGO (S_IXUSR | S_IXGRP | S_IXOTH)
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
#define SHM_GROUPE_TO_USER 3
|
|
|
|
|
#define SHM_OTHER_TO_USER 6
|
|
|
|
|
|
|
|
|
|
#ifndef LOSCFG_IPC_CONTAINER
|
|
|
|
|
STATIC LosMux g_sysvShmMux;
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
#define SHM_GROUPE_TO_USER 3
|
|
|
|
|
#define SHM_OTHER_TO_USER 6
|
|
|
|
|
#ifndef LOSCFG_IPC_CONTAINER
|
|
|
|
|
STATIC LosMux g_sysvShmMux;
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
/* private data */
|
|
|
|
|
STATIC struct shminfo g_shmInfo;
|
|
|
|
|
STATIC struct shmIDSource *g_shmSegs = NULL;
|
|
|
|
@ -106,6 +132,8 @@ STATIC UINT32 g_shmUsedPageCount;
|
|
|
|
|
#define SYSV_SHM_LOCK() (VOID)LOS_MuxLock(&IPC_SHM_SYS_VSHM_MUTEX, LOS_WAIT_FOREVER)
|
|
|
|
|
#define SYSV_SHM_UNLOCK() (VOID)LOS_MuxUnlock(&IPC_SHM_SYS_VSHM_MUTEX)
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
=======
|
|
|
|
|
#if 0 // @note_#if0
|
|
|
|
|
|
|
|
|
|
//内核为每一个IPC对象保存一个ipc_perm结构体,该结构说明了IPC对象的权限和所有者
|
|
|
|
@ -160,6 +188,7 @@ STATIC UINT32 g_shmUsedPageCount;
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
//共享内存初始化
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UINT32 *shmUsedPageCount)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
@ -168,6 +197,10 @@ struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UIN
|
|
|
|
|
if ((sysvShmMux == NULL) || (shmInfo == NULL) || (shmUsedPageCount == NULL)) {
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
ret = LOS_MuxInit(sysvShmMux, NULL);
|
|
|
|
|
if (ret != LOS_OK) {
|
|
|
|
|
goto ERROR;
|
|
|
|
@ -178,6 +211,10 @@ struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UIN
|
|
|
|
|
shmInfo->shmmni = SHM_MNI;
|
|
|
|
|
shmInfo->shmseg = SHM_SEG;
|
|
|
|
|
shmInfo->shmall = SHM_ALL;
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
struct shmIDSource *shmSegs = LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, sizeof(struct shmIDSource) * shmInfo->shmmni);
|
|
|
|
|
if (shmSegs == NULL) {
|
|
|
|
|
(VOID)LOS_MuxDestroy(sysvShmMux);
|
|
|
|
@ -187,9 +224,15 @@ struct shmIDSource *OsShmCBInit(LosMux *sysvShmMux, struct shminfo *shmInfo, UIN
|
|
|
|
|
0, (sizeof(struct shmIDSource) * shmInfo->shmmni));
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < shmInfo->shmmni; i++) {
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
shmSegs[i].status = SHM_SEG_FREE;
|
|
|
|
|
shmSegs[i].ds.shm_perm.seq = i + 1;
|
|
|
|
|
LOS_ListInit(&shmSegs[i].node);
|
|
|
|
|
=======
|
|
|
|
|
shmSegs[i].status = SHM_SEG_FREE;//节点初始状态为空闲
|
|
|
|
|
shmSegs[i].ds.shm_perm.seq = i + 1;//struct ipc_perm shm_perm;系统为每一个IPC对象保存一个ipc_perm结构体,结构说明了IPC对象的权限和所有者
|
|
|
|
|
LOS_ListInit(&shmSegs[i].node);//初始化节点
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
}
|
|
|
|
|
*shmUsedPageCount = 0;
|
|
|
|
|
|
|
|
|
@ -199,6 +242,10 @@ ERROR:
|
|
|
|
|
VM_ERR("ShmInit fail\n");
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
UINT32 ShmInit(VOID)
|
|
|
|
|
{
|
|
|
|
|
#ifndef LOSCFG_IPC_CONTAINER
|
|
|
|
@ -210,9 +257,14 @@ UINT32 ShmInit(VOID)
|
|
|
|
|
return LOS_OK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE);
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
|
|
|
|
|
LOS_MODULE_INIT(ShmInit, LOS_INIT_LEVEL_VM_COMPLETE);//共享内存模块初始化
|
|
|
|
|
//共享内存反初始化
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
UINT32 ShmDeinit(VOID)
|
|
|
|
|
{
|
|
|
|
|
UINT32 ret;
|
|
|
|
@ -227,7 +279,11 @@ UINT32 ShmDeinit(VOID)
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///给共享段中所有物理页框贴上共享标签
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg)
|
|
|
|
|
{
|
|
|
|
|
LosVmPage *page = NULL;
|
|
|
|
@ -236,7 +292,11 @@ STATIC inline VOID ShmSetSharedFlag(struct shmIDSource *seg)
|
|
|
|
|
OsSetPageShared(page);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///给共享段中所有物理页框撕掉共享标签
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg)
|
|
|
|
|
{
|
|
|
|
|
LosVmPage *page = NULL;
|
|
|
|
@ -245,7 +305,11 @@ STATIC inline VOID ShmClearSharedFlag(struct shmIDSource *seg)
|
|
|
|
|
OsCleanPageShared(page);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///seg下所有共享页引用减少
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC VOID ShmPagesRefDec(struct shmIDSource *seg)
|
|
|
|
|
{
|
|
|
|
|
LosVmPage *page = NULL;
|
|
|
|
@ -255,6 +319,8 @@ STATIC VOID ShmPagesRefDec(struct shmIDSource *seg)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
=======
|
|
|
|
|
/**
|
|
|
|
|
* @brief 为共享段分配物理内存
|
|
|
|
|
例如:参数size = 4097, LOS_Align(size, PAGE_SIZE) = 8192
|
|
|
|
@ -264,6 +330,7 @@ STATIC VOID ShmPagesRefDec(struct shmIDSource *seg)
|
|
|
|
|
* @param shmflg
|
|
|
|
|
* @return STATIC
|
|
|
|
|
*/
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum)
|
|
|
|
|
{
|
|
|
|
|
INT32 i;
|
|
|
|
@ -272,7 +339,11 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum)
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
*size = LOS_Align(*size, PAGE_SIZE);
|
|
|
|
|
=======
|
|
|
|
|
*size = LOS_Align(*size, PAGE_SIZE);//必须对齐
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if ((IPC_SHM_USED_PAGE_COUNT + (*size >> PAGE_SHIFT)) > IPC_SHM_INFO.shmall) {
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
@ -282,10 +353,18 @@ STATIC INT32 ShmAllocSegCheck(key_t key, size_t *size, INT32 *segNum)
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
#endif
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {
|
|
|
|
|
if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) {
|
|
|
|
|
IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE;
|
|
|
|
|
*segNum = i;
|
|
|
|
|
=======
|
|
|
|
|
for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {//试图找到一个空闲段与参数key绑定
|
|
|
|
|
if (IPC_SHM_SEGS[i].status & SHM_SEG_FREE) {//找到空闲段
|
|
|
|
|
IPC_SHM_SEGS[i].status &= ~SHM_SEG_FREE;//变成非空闲状态
|
|
|
|
|
*segNum = i;//标号
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
@ -306,16 +385,45 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg)
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
return ret;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
seg = &IPC_SHM_SEGS[segNum];
|
|
|
|
|
count = LOS_PhysPagesAlloc(size >> PAGE_SHIFT, &seg->node);
|
|
|
|
|
if (count != (size >> PAGE_SHIFT)) {
|
|
|
|
|
(VOID)LOS_PhysPagesFree(&seg->node);
|
|
|
|
|
seg->status = SHM_SEG_FREE;
|
|
|
|
|
=======
|
|
|
|
|
seg = &IPC_SHM_SEGS[segNum];
|
|
|
|
|
count = LOS_PhysPagesAlloc(size >> PAGE_SHIFT, &seg->node);//分配共享页面,函数内部把node都挂好了.
|
|
|
|
|
if (count != (size >> PAGE_SHIFT)) {//当未分配到足够的内存时,处理方式是:不稀罕给那么点,舍弃!
|
|
|
|
|
(VOID)LOS_PhysPagesFree(&seg->node);//释放节点上的物理页框
|
|
|
|
|
seg->status = SHM_SEG_FREE;//共享段变回空闲状态
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
#ifdef LOSCFG_KERNEL_IPC_PLIMIT
|
|
|
|
|
OsIPCLimitShmFree(size);
|
|
|
|
|
#endif
|
|
|
|
|
return -ENOMEM;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
ShmSetSharedFlag(seg);
|
|
|
|
|
IPC_SHM_USED_PAGE_COUNT += size >> PAGE_SHIFT;
|
|
|
|
|
|
|
|
|
|
seg->status |= SHM_SEG_USED;
|
|
|
|
|
seg->ds.shm_perm.mode = (UINT32)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_lpid = 0;
|
|
|
|
|
seg->ds.shm_nattch = 0;
|
|
|
|
|
seg->ds.shm_cpid = LOS_GetCurrProcessID();
|
|
|
|
|
seg->ds.shm_atime = 0;
|
|
|
|
|
seg->ds.shm_dtime = 0;
|
|
|
|
|
seg->ds.shm_ctime = time(NULL);
|
|
|
|
|
=======
|
|
|
|
|
ShmSetSharedFlag(seg);//将node的每个页面设置为共享页
|
|
|
|
|
IPC_SHM_USED_PAGE_COUNT += size >> PAGE_SHIFT;
|
|
|
|
|
|
|
|
|
@ -333,20 +441,31 @@ STATIC INT32 ShmAllocSeg(key_t key, size_t size, INT32 shmflg)
|
|
|
|
|
seg->ds.shm_atime = 0; //访问时间
|
|
|
|
|
seg->ds.shm_dtime = 0; //detach 分离时间 共享内存使用完之后,需要将它从进程地址空间中分离出来;将共享内存分离并不是删除它,只是使该共享内存对当前的进程不再可用
|
|
|
|
|
seg->ds.shm_ctime = time(NULL);//创建时间
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
#ifdef LOSCFG_SHELL
|
|
|
|
|
(VOID)memcpy_s(seg->ownerName, OS_PCB_NAME_LEN, OsCurrProcessGet()->processName, OS_PCB_NAME_LEN);
|
|
|
|
|
#endif
|
|
|
|
|
|
|
|
|
|
return segNum;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///释放seg->node 所占物理页框,seg本身重置
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg, UINT32 *shmUsedPageCount)
|
|
|
|
|
{
|
|
|
|
|
UINT32 count;
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
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)) {//异常,必须要一样
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
VM_ERR("free physical pages failed, count = %d, size = %d", count, seg->ds.shm_segsz >> PAGE_SHIFT);
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
@ -356,31 +475,54 @@ STATIC INLINE VOID ShmFreeSeg(struct shmIDSource *seg, UINT32 *shmUsedPageCount)
|
|
|
|
|
if (shmUsedPageCount != NULL) {
|
|
|
|
|
(*shmUsedPageCount) -= seg->ds.shm_segsz >> PAGE_SHIFT;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
seg->status = SHM_SEG_FREE;
|
|
|
|
|
LOS_ListInit(&seg->node);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
seg->status = SHM_SEG_FREE;//seg恢复自由之身
|
|
|
|
|
LOS_ListInit(&seg->node);//重置node
|
|
|
|
|
}
|
|
|
|
|
///通过key查找 shmId
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC INT32 ShmFindSegByKey(key_t key)
|
|
|
|
|
{
|
|
|
|
|
INT32 i;
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {
|
|
|
|
|
seg = &IPC_SHM_SEGS[i];
|
|
|
|
|
if ((seg->status & SHM_SEG_USED) &&
|
|
|
|
|
(seg->ds.shm_perm.key == key)) {
|
|
|
|
|
=======
|
|
|
|
|
for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {//遍历共享段池,找到与key绑定的共享ID
|
|
|
|
|
seg = &IPC_SHM_SEGS[i];
|
|
|
|
|
if ((seg->status & SHM_SEG_USED) &&
|
|
|
|
|
(seg->ds.shm_perm.key == key)) {//满足两个条件,找到后返回
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
return i;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
STATIC INT32 ShmSegValidCheck(INT32 segNum, size_t size, INT32 shmFlg)
|
|
|
|
|
{
|
|
|
|
|
struct shmIDSource *seg = &IPC_SHM_SEGS[segNum];
|
|
|
|
|
|
|
|
|
|
if (size > seg->ds.shm_segsz) {
|
|
|
|
|
=======
|
|
|
|
|
///共享内存段有效性检查
|
|
|
|
|
STATIC INT32 ShmSegValidCheck(INT32 segNum, size_t size, INT32 shmFlg)
|
|
|
|
|
{
|
|
|
|
|
struct shmIDSource *seg = &IPC_SHM_SEGS[segNum];//拿到shmID
|
|
|
|
|
|
|
|
|
|
if (size > seg->ds.shm_segsz) {//段长
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
return -EINVAL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -391,7 +533,11 @@ STATIC INT32 ShmSegValidCheck(INT32 segNum, size_t size, INT32 shmFlg)
|
|
|
|
|
|
|
|
|
|
return segNum;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///通过ID找到共享内存资源
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC struct shmIDSource *ShmFindSeg(int shmid)
|
|
|
|
|
{
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
@ -409,7 +555,11 @@ STATIC struct shmIDSource *ShmFindSeg(int shmid)
|
|
|
|
|
|
|
|
|
|
return seg;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///共享内存映射
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC VOID ShmVmmMapping(LosVmSpace *space, LOS_DL_LIST *pageList, VADDR_T vaddr, UINT32 regionFlags)
|
|
|
|
|
{
|
|
|
|
|
LosVmPage *vmPage = NULL;
|
|
|
|
@ -417,29 +567,53 @@ STATIC VOID ShmVmmMapping(LosVmSpace *space, LOS_DL_LIST *pageList, VADDR_T vadd
|
|
|
|
|
PADDR_T pa;
|
|
|
|
|
STATUS_T ret;
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
LOS_DL_LIST_FOR_EACH_ENTRY(vmPage, pageList, LosVmPage, node) {
|
|
|
|
|
pa = VM_PAGE_TO_PHYS(vmPage);
|
|
|
|
|
LOS_AtomicInc(&vmPage->refCounts);
|
|
|
|
|
ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, regionFlags);
|
|
|
|
|
=======
|
|
|
|
|
LOS_DL_LIST_FOR_EACH_ENTRY(vmPage, pageList, LosVmPage, node) {//遍历一页一页映射
|
|
|
|
|
pa = VM_PAGE_TO_PHYS(vmPage);//拿到物理地址
|
|
|
|
|
LOS_AtomicInc(&vmPage->refCounts);//自增
|
|
|
|
|
ret = LOS_ArchMmuMap(&space->archMmu, va, pa, 1, regionFlags);//虚实映射
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (ret != 1) {
|
|
|
|
|
VM_ERR("LOS_ArchMmuMap failed, ret = %d", ret);
|
|
|
|
|
}
|
|
|
|
|
va += PAGE_SIZE;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///fork 一个共享线性区
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *newRegion)
|
|
|
|
|
{
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
|
|
|
|
|
|
SYSV_SHM_LOCK();
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
seg = ShmFindSeg(oldRegion->shmid);
|
|
|
|
|
=======
|
|
|
|
|
seg = ShmFindSeg(oldRegion->shmid);//通过老区ID获取对应的共享资源ID结构体
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (seg == NULL) {
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
VM_ERR("shm fork failed!");
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
newRegion->shmid = oldRegion->shmid;
|
|
|
|
|
newRegion->forkFlags = oldRegion->forkFlags;
|
|
|
|
|
ShmVmmMapping(space, &seg->node, newRegion->range.base, newRegion->regionFlags);
|
|
|
|
|
seg->ds.shm_nattch++;
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
newRegion->shmid = oldRegion->shmid;//一样的共享区ID
|
|
|
|
|
newRegion->forkFlags = oldRegion->forkFlags;//forkFlags也一样了
|
|
|
|
|
ShmVmmMapping(space, &seg->node, newRegion->range.base, newRegion->regionFlags);//新线性区与共享内存进行映射
|
|
|
|
@ -447,34 +621,55 @@ VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *new
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
}
|
|
|
|
|
///释放共享线性区
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region)
|
|
|
|
|
{
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
|
|
|
|
|
|
SYSV_SHM_LOCK();
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
seg = ShmFindSeg(region->shmid);
|
|
|
|
|
=======
|
|
|
|
|
seg = ShmFindSeg(region->shmid);//通过线性区ID获取对应的共享资源ID结构体
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (seg == NULL) {
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);
|
|
|
|
|
ShmPagesRefDec(seg);
|
|
|
|
|
seg->ds.shm_nattch--;
|
|
|
|
|
if (seg->ds.shm_nattch <= 0 && (seg->status & SHM_SEG_REMOVE)) {
|
|
|
|
|
ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT);
|
|
|
|
|
=======
|
|
|
|
|
LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);//解除线性区的映射
|
|
|
|
|
ShmPagesRefDec(seg);//ref --
|
|
|
|
|
seg->ds.shm_nattch--;//附在共享线性区上的进程数--
|
|
|
|
|
if (seg->ds.shm_nattch <= 0 && (seg->status & SHM_SEG_REMOVE)) {
|
|
|
|
|
ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT);//就释放掉物理内存!注意是:物理内存
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
} else {
|
|
|
|
|
seg->ds.shm_dtime = time(NULL);
|
|
|
|
|
seg->ds.shm_lpid = LOS_GetCurrProcessID(); /* may not be the space's PID. */
|
|
|
|
|
}
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///是否为共享线性区,是否有标签?
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
BOOL OsIsShmRegion(LosVmMapRegion *region)
|
|
|
|
|
{
|
|
|
|
|
return (region->regionFlags & VM_MAP_REGION_FLAG_SHM) ? TRUE : FALSE;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///获取共享内存池中已被使用的段数量
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC INT32 ShmSegUsedCount(VOID)
|
|
|
|
|
{
|
|
|
|
|
INT32 i;
|
|
|
|
@ -483,16 +678,27 @@ STATIC INT32 ShmSegUsedCount(VOID)
|
|
|
|
|
|
|
|
|
|
for (i = 0; i < IPC_SHM_INFO.shmmni; i++) {
|
|
|
|
|
seg = &IPC_SHM_SEGS[i];
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
if (seg->status & SHM_SEG_USED) {
|
|
|
|
|
=======
|
|
|
|
|
if (seg->status & SHM_SEG_USED) {//找到一个
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
count++;
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
return count;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
STATIC INT32 ShmPermCheck(struct shmIDSource *seg, mode_t mode)
|
|
|
|
|
{
|
|
|
|
|
INT32 uid = LOS_GetUserID();
|
|
|
|
|
=======
|
|
|
|
|
///对共享内存段权限检查
|
|
|
|
|
STATIC INT32 ShmPermCheck(struct shmIDSource *seg, mode_t mode)
|
|
|
|
|
{
|
|
|
|
|
INT32 uid = LOS_GetUserID();//当前进程的用户ID
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
UINT32 tmpMode = 0;
|
|
|
|
|
mode_t privMode = seg->ds.shm_perm.mode;
|
|
|
|
|
mode_t accMode;
|
|
|
|
@ -534,6 +740,8 @@ STATIC INT32 ShmPermCheck(struct shmIDSource *seg, mode_t mode)
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
=======
|
|
|
|
|
/*!
|
|
|
|
|
* @brief ShmGet
|
|
|
|
|
* 得到一个共享内存标识符或创建一个共享内存对象
|
|
|
|
@ -550,6 +758,7 @@ STATIC INT32 ShmPermCheck(struct shmIDSource *seg, mode_t mode)
|
|
|
|
|
*
|
|
|
|
|
* @see
|
|
|
|
|
*/
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
INT32 ShmGet(key_t key, size_t size, INT32 shmflg)
|
|
|
|
|
{
|
|
|
|
|
INT32 ret;
|
|
|
|
@ -560,6 +769,15 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg)
|
|
|
|
|
if (key == IPC_PRIVATE) {
|
|
|
|
|
ret = ShmAllocSeg(key, size, shmflg);
|
|
|
|
|
} else {
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
ret = ShmFindSegByKey(key);
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
if (((UINT32)shmflg & IPC_CREAT) == 0) {
|
|
|
|
|
ret = -ENOENT;
|
|
|
|
|
goto ERROR;
|
|
|
|
|
} else {
|
|
|
|
|
ret = ShmAllocSeg(key, size, shmflg);
|
|
|
|
|
=======
|
|
|
|
|
ret = ShmFindSegByKey(key);//通过key查找资源ID
|
|
|
|
|
if (ret < 0) {
|
|
|
|
|
if (((UINT32)shmflg & IPC_CREAT) == 0) {//
|
|
|
|
@ -567,6 +785,7 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg)
|
|
|
|
|
goto ERROR;
|
|
|
|
|
} else {
|
|
|
|
|
ret = ShmAllocSeg(key, size, shmflg);//分配一个共享内存
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
shmid = ret;
|
|
|
|
@ -575,7 +794,11 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg)
|
|
|
|
|
ret = -EEXIST;
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
ret = ShmPermCheck(ShmFindSeg(shmid), (UINT32)shmflg & ACCESSPERMS);
|
|
|
|
|
=======
|
|
|
|
|
ret = ShmPermCheck(ShmFindSeg(shmid), (UINT32)shmflg & ACCESSPERMS);//对共享内存权限检查
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
ret = -ret;
|
|
|
|
|
goto ERROR;
|
|
|
|
@ -610,13 +833,21 @@ INT32 ShmatParamCheck(const VOID *shmaddr, INT32 shmflg)
|
|
|
|
|
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///分配一个共享线性区并映射好
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
LosVmMapRegion *ShmatVmmAlloc(struct shmIDSource *seg, const VOID *shmaddr,
|
|
|
|
|
INT32 shmflg, UINT32 prot)
|
|
|
|
|
{
|
|
|
|
|
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
|
|
|
|
|
LosVmMapRegion *region = NULL;
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
UINT32 flags = MAP_ANONYMOUS | MAP_SHARED;
|
|
|
|
|
=======
|
|
|
|
|
UINT32 flags = MAP_ANONYMOUS | MAP_SHARED;//本线性区为共享+匿名标签
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
UINT32 mapFlags = flags | MAP_FIXED;
|
|
|
|
|
VADDR_T vaddr;
|
|
|
|
|
UINT32 regionFlags;
|
|
|
|
@ -627,29 +858,48 @@ LosVmMapRegion *ShmatVmmAlloc(struct shmIDSource *seg, const VOID *shmaddr,
|
|
|
|
|
}
|
|
|
|
|
regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags);
|
|
|
|
|
(VOID)LOS_MuxAcquire(&space->regionMux);
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
if (shmaddr == NULL) {
|
|
|
|
|
region = LOS_RegionAlloc(space, 0, seg->ds.shm_segsz, regionFlags, 0);
|
|
|
|
|
} else {
|
|
|
|
|
=======
|
|
|
|
|
if (shmaddr == NULL) {//未指定了共享内存连接到当前进程中的地址位置
|
|
|
|
|
region = LOS_RegionAlloc(space, 0, seg->ds.shm_segsz, regionFlags, 0);//分配线性区
|
|
|
|
|
} else {//指定时,就需要先找地址所在的线性区
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if ((UINT32)shmflg & SHM_RND) {
|
|
|
|
|
vaddr = ROUNDDOWN((VADDR_T)(UINTPTR)shmaddr, SHMLBA);
|
|
|
|
|
} else {
|
|
|
|
|
vaddr = (VADDR_T)(UINTPTR)shmaddr;
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
}
|
|
|
|
|
=======
|
|
|
|
|
}//找到线性区并重新映射,当指定地址时需贴上重新映射的标签
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (!((UINT32)shmflg & SHM_REMAP) && (LOS_RegionFind(space, vaddr) ||
|
|
|
|
|
LOS_RegionFind(space, vaddr + seg->ds.shm_segsz - 1) ||
|
|
|
|
|
LOS_RegionRangeFind(space, vaddr, seg->ds.shm_segsz - 1))) {
|
|
|
|
|
ret = EINVAL;
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
vaddr = (VADDR_T)LOS_MMap(vaddr, seg->ds.shm_segsz, prot, mapFlags, -1, 0);
|
|
|
|
|
region = LOS_RegionFind(space, vaddr);
|
|
|
|
|
=======
|
|
|
|
|
vaddr = (VADDR_T)LOS_MMap(vaddr, seg->ds.shm_segsz, prot, mapFlags, -1, 0);//做好映射
|
|
|
|
|
region = LOS_RegionFind(space, vaddr);//重新查找线性区,用于返回.
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (region == NULL) {
|
|
|
|
|
ret = ENOMEM;
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
ShmVmmMapping(space, &seg->node, region->range.base, regionFlags);
|
|
|
|
|
=======
|
|
|
|
|
ShmVmmMapping(space, &seg->node, region->range.base, regionFlags);//共享内存映射
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
(VOID)LOS_MuxRelease(&space->regionMux);
|
|
|
|
|
return region;
|
|
|
|
|
ERROR:
|
|
|
|
@ -658,6 +908,8 @@ ERROR:
|
|
|
|
|
return NULL;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
=======
|
|
|
|
|
/*!
|
|
|
|
|
* @brief ShmAt
|
|
|
|
|
* 用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。
|
|
|
|
@ -669,6 +921,7 @@ ERROR:
|
|
|
|
|
shmid 就是个索引,就跟进程和线程的ID一样 g_shmSegs[shmid] shmid > 192个
|
|
|
|
|
* @see
|
|
|
|
|
*/
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg)
|
|
|
|
|
{
|
|
|
|
|
INT32 ret;
|
|
|
|
@ -677,13 +930,21 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg)
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
|
LosVmMapRegion *r = NULL;
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
ret = ShmatParamCheck(shmaddr, shmflg);
|
|
|
|
|
=======
|
|
|
|
|
ret = ShmatParamCheck(shmaddr, shmflg);//参数检查
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
set_errno(ret);
|
|
|
|
|
return (VOID *)-1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
if ((UINT32)shmflg & SHM_EXEC) {
|
|
|
|
|
=======
|
|
|
|
|
if ((UINT32)shmflg & SHM_EXEC) {//flag 转换
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
prot |= PROT_EXEC;
|
|
|
|
|
acc_mode |= SHM_S_IXUGO;
|
|
|
|
|
} else if (((UINT32)shmflg & SHM_RDONLY) == 0) {
|
|
|
|
@ -692,7 +953,11 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
SYSV_SHM_LOCK();
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
seg = ShmFindSeg(shmid);
|
|
|
|
|
=======
|
|
|
|
|
seg = ShmFindSeg(shmid);//找到段
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (seg == NULL) {
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
return (VOID *)-1;
|
|
|
|
@ -703,18 +968,30 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg)
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
seg->ds.shm_nattch++;
|
|
|
|
|
r = ShmatVmmAlloc(seg, shmaddr, shmflg, prot);
|
|
|
|
|
=======
|
|
|
|
|
seg->ds.shm_nattch++;//ds上记录有一个进程绑定上来
|
|
|
|
|
r = ShmatVmmAlloc(seg, shmaddr, shmflg, prot);//在当前进程空间分配一个线性区并映射到共享内存
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (r == NULL) {
|
|
|
|
|
seg->ds.shm_nattch--;
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
return (VOID *)-1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
r->shmid = shmid;
|
|
|
|
|
r->regionFlags |= VM_MAP_REGION_FLAG_SHM;
|
|
|
|
|
seg->ds.shm_atime = time(NULL);
|
|
|
|
|
seg->ds.shm_lpid = LOS_GetCurrProcessID();
|
|
|
|
|
=======
|
|
|
|
|
r->shmid = shmid;//把ID给线性区的shmid
|
|
|
|
|
r->regionFlags |= VM_MAP_REGION_FLAG_SHM;//这是一个共享线性区
|
|
|
|
|
seg->ds.shm_atime = time(NULL);//访问时间
|
|
|
|
|
seg->ds.shm_lpid = LOS_GetCurrProcessID();//进程ID
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
|
|
|
|
|
return (VOID *)(UINTPTR)r->range.base;
|
|
|
|
@ -725,6 +1002,8 @@ ERROR:
|
|
|
|
|
return (VOID *)-1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
=======
|
|
|
|
|
/*!
|
|
|
|
|
* @brief ShmCtl
|
|
|
|
|
* 此函数可以对shmid指定的共享存储进行多种操作(删除、取信息、加锁、解锁等)
|
|
|
|
@ -738,6 +1017,7 @@ ERROR:
|
|
|
|
|
*
|
|
|
|
|
* @see
|
|
|
|
|
*/
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
|
|
|
|
|
{
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
@ -750,7 +1030,11 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
|
|
|
|
|
SYSV_SHM_LOCK();
|
|
|
|
|
|
|
|
|
|
if ((cmd != IPC_INFO) && (cmd != SHM_INFO)) {
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
seg = ShmFindSeg(shmid);
|
|
|
|
|
=======
|
|
|
|
|
seg = ShmFindSeg(shmid);//通过索引ID找到seg
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (seg == NULL) {
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
return -1;
|
|
|
|
@ -764,13 +1048,21 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
|
|
|
|
|
|
|
|
|
|
switch (cmd) {
|
|
|
|
|
case IPC_STAT:
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
case SHM_STAT:
|
|
|
|
|
=======
|
|
|
|
|
case SHM_STAT://取段结构
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
ret = ShmPermCheck(seg, SHM_S_IRUGO);
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
ret = LOS_ArchCopyToUser(buf, &seg->ds, sizeof(struct shmid_ds));
|
|
|
|
|
=======
|
|
|
|
|
ret = LOS_ArchCopyToUser(buf, &seg->ds, sizeof(struct shmid_ds));//把内核空间的共享页数据拷贝到用户空间
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
ret = EFAULT;
|
|
|
|
|
goto ERROR;
|
|
|
|
@ -779,13 +1071,21 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
|
|
|
|
|
ret = (unsigned int)((unsigned int)seg->ds.shm_perm.seq << 16) | (unsigned int)((unsigned int)shmid & 0xffff); /* 16: use the seq as the upper 16 bits */
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
case IPC_SET:
|
|
|
|
|
=======
|
|
|
|
|
case IPC_SET://重置共享段
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
ret = ShmPermCheck(seg, SHM_M);
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
ret = EPERM;
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
//从用户空间拷贝数据到内核空间
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
ret = LOS_ArchCopyFromUser(&shm_perm, &buf->shm_perm, sizeof(struct ipc_perm));
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
ret = EFAULT;
|
|
|
|
@ -794,14 +1094,22 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
|
|
|
|
|
seg->ds.shm_perm.uid = shm_perm.uid;
|
|
|
|
|
seg->ds.shm_perm.gid = shm_perm.gid;
|
|
|
|
|
seg->ds.shm_perm.mode = (seg->ds.shm_perm.mode & ~ACCESSPERMS) |
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
(shm_perm.mode & ACCESSPERMS);
|
|
|
|
|
=======
|
|
|
|
|
(shm_perm.mode & ACCESSPERMS);//可访问
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
seg->ds.shm_ctime = time(NULL);
|
|
|
|
|
#ifdef LOSCFG_SHELL
|
|
|
|
|
(VOID)memcpy_s(seg->ownerName, OS_PCB_NAME_LEN, OS_PCB_FROM_PID(shm_perm.uid)->processName,
|
|
|
|
|
OS_PCB_NAME_LEN);
|
|
|
|
|
#endif
|
|
|
|
|
break;
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
case IPC_RMID:
|
|
|
|
|
=======
|
|
|
|
|
case IPC_RMID://删除共享段
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
ret = ShmPermCheck(seg, SHM_M);
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
ret = EPERM;
|
|
|
|
@ -809,11 +1117,19 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
seg->status |= SHM_SEG_REMOVE;
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
if (seg->ds.shm_nattch <= 0) {
|
|
|
|
|
ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case IPC_INFO:
|
|
|
|
|
=======
|
|
|
|
|
if (seg->ds.shm_nattch <= 0) {//没有任何进程在使用了
|
|
|
|
|
ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case IPC_INFO://把内核空间的共享页数据拷贝到用户空间
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
ret = LOS_ArchCopyToUser(buf, &IPC_SHM_INFO, sizeof(struct shminfo));
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
ret = EFAULT;
|
|
|
|
@ -827,8 +1143,13 @@ INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf)
|
|
|
|
|
shmInfo.shm_tot = 0;
|
|
|
|
|
shmInfo.swap_attempts = 0;
|
|
|
|
|
shmInfo.swap_successes = 0;
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
shmInfo.used_ids = ShmSegUsedCount();
|
|
|
|
|
ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info));
|
|
|
|
|
=======
|
|
|
|
|
shmInfo.used_ids = ShmSegUsedCount();//在使用的seg数
|
|
|
|
|
ret = LOS_ArchCopyToUser(buf, &shmInfo, sizeof(struct shm_info));//把内核空间的共享页数据拷贝到用户空间
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (ret != 0) {
|
|
|
|
|
ret = EFAULT;
|
|
|
|
|
goto ERROR;
|
|
|
|
@ -851,6 +1172,11 @@ ERROR:
|
|
|
|
|
return -1;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
INT32 ShmDt(const VOID *shmaddr)
|
|
|
|
|
{
|
|
|
|
|
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
|
|
|
|
|
=======
|
|
|
|
|
/**
|
|
|
|
|
* @brief 当对共享存储的操作已经结束时,则调用shmdt与该存储段分离
|
|
|
|
|
如果shmat成功执行,那么内核将使与该共享存储相关的shmid_ds结构中的shm_nattch计数器值减1
|
|
|
|
@ -862,30 +1188,56 @@ ERROR:
|
|
|
|
|
INT32 ShmDt(const VOID *shmaddr)
|
|
|
|
|
{
|
|
|
|
|
LosVmSpace *space = OsCurrProcessGet()->vmSpace;//获取进程空间
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
|
LosVmMapRegion *region = NULL;
|
|
|
|
|
INT32 shmid;
|
|
|
|
|
INT32 ret;
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
if (IS_PAGE_ALIGNED(shmaddr) == 0) {
|
|
|
|
|
=======
|
|
|
|
|
if (IS_PAGE_ALIGNED(shmaddr) == 0) {//地址是否对齐
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
ret = EINVAL;
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
(VOID)LOS_MuxAcquire(&space->regionMux);
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)shmaddr);
|
|
|
|
|
=======
|
|
|
|
|
region = LOS_RegionFind(space, (VADDR_T)(UINTPTR)shmaddr);//找到线性区
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (region == NULL) {
|
|
|
|
|
ret = EINVAL;
|
|
|
|
|
goto ERROR_WITH_LOCK;
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
shmid = region->shmid;
|
|
|
|
|
|
|
|
|
|
if (region->range.base != (VADDR_T)(UINTPTR)shmaddr) {
|
|
|
|
|
ret = EINVAL;
|
|
|
|
|
=======
|
|
|
|
|
shmid = region->shmid;//线性区共享ID
|
|
|
|
|
|
|
|
|
|
if (region->range.base != (VADDR_T)(UINTPTR)shmaddr) {//这是用户空间和内核空间的一次解绑
|
|
|
|
|
ret = EINVAL; //shmaddr 必须要等于region->range.base
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
goto ERROR_WITH_LOCK;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/* remove it from aspace */
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode);
|
|
|
|
|
LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);
|
|
|
|
|
(VOID)LOS_MuxRelease(&space->regionMux);
|
|
|
|
|
/* free it */
|
|
|
|
|
free(region);
|
|
|
|
|
|
|
|
|
|
SYSV_SHM_LOCK();
|
|
|
|
|
seg = ShmFindSeg(shmid);
|
|
|
|
|
=======
|
|
|
|
|
LOS_RbDelNode(&space->regionRbTree, ®ion->rbNode);//从红黑树和链表中摘除节点
|
|
|
|
|
LOS_ArchMmuUnmap(&space->archMmu, region->range.base, region->range.size >> PAGE_SHIFT);//解除线性区的映射
|
|
|
|
|
(VOID)LOS_MuxRelease(&space->regionMux);
|
|
|
|
@ -894,12 +1246,23 @@ INT32 ShmDt(const VOID *shmaddr)
|
|
|
|
|
|
|
|
|
|
SYSV_SHM_LOCK();
|
|
|
|
|
seg = ShmFindSeg(shmid);//找到seg,线性区和共享段的关系是 1:N 的关系,其他空间的线性区也会绑在共享段上
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
if (seg == NULL) {
|
|
|
|
|
ret = EINVAL;
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
goto ERROR;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
ShmPagesRefDec(seg);
|
|
|
|
|
seg->ds.shm_nattch--;
|
|
|
|
|
if ((seg->ds.shm_nattch <= 0) &&
|
|
|
|
|
(seg->status & SHM_SEG_REMOVE)) {
|
|
|
|
|
ShmFreeSeg(seg, &IPC_SHM_USED_PAGE_COUNT);
|
|
|
|
|
} else {
|
|
|
|
|
seg->ds.shm_dtime = time(NULL);
|
|
|
|
|
seg->ds.shm_lpid = LOS_GetCurrProcessID();
|
|
|
|
|
=======
|
|
|
|
|
ShmPagesRefDec(seg);//页面引用数 --
|
|
|
|
|
seg->ds.shm_nattch--;//使用共享内存的进程数少了一个
|
|
|
|
|
if ((seg->ds.shm_nattch <= 0) && //无任何进程使用共享内存
|
|
|
|
@ -908,6 +1271,7 @@ INT32 ShmDt(const VOID *shmaddr)
|
|
|
|
|
} else {
|
|
|
|
|
seg->ds.shm_dtime = time(NULL);//记录分离的时间
|
|
|
|
|
seg->ds.shm_lpid = LOS_GetCurrProcessID();//记录操作进程ID
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
}
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
|
|
|
|
@ -963,6 +1327,10 @@ STATIC VOID OsShmInfoCmd(VOID)
|
|
|
|
|
}
|
|
|
|
|
SYSV_SHM_UNLOCK();
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
STATIC VOID OsShmDeleteCmd(INT32 shmid)
|
|
|
|
|
{
|
|
|
|
|
struct shmIDSource *seg = NULL;
|
|
|
|
@ -991,7 +1359,11 @@ STATIC VOID OsShmCmdUsage(VOID)
|
|
|
|
|
"\t-r [shmid], Recycle the specified shared memory about shmid\n"
|
|
|
|
|
"\t-h | --help, print shm command usage\n");
|
|
|
|
|
}
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
///共享内存
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|
UINT32 OsShellCmdShm(INT32 argc, const CHAR *argv[])
|
|
|
|
|
{
|
|
|
|
|
INT32 shmid;
|
|
|
|
@ -1026,3 +1398,7 @@ DONE:
|
|
|
|
|
SHELLCMD_ENTRY(shm_shellcmd, CMD_TYPE_SHOW, "shm", 2, (CmdCallBackFunc)OsShellCmdShm);
|
|
|
|
|
#endif
|
|
|
|
|
#endif
|
|
|
|
|
<<<<<<< HEAD
|
|
|
|
|
|
|
|
|
|
=======
|
|
|
|
|
>>>>>>> remotes/origin/main
|
|
|
|
|