LiteIPC 注释完善, 它内核提供的一种新型IPC通讯机制

    百图画鸿蒙 + 百文说内核 + 百万注源码  => 挖透鸿蒙内核源码
    鸿蒙研究站 | http://weharmonyos.com (国内)
              | https://weharmony.github.io (国外)
    oschina | https://my.oschina.net/weharmony
    博客园 | https://www.cnblogs.com/weharmony/
    知乎 | https://www.zhihu.com/people/weharmonyos
    csdn | https://blog.csdn.net/kuangyufei
    51cto | https://harmonyos.51cto.com/column/34
    掘金 | https://juejin.cn/user/756888642000808
    公众号 | 鸿蒙研究站 (weharmonyos)
上级 f9f06080
...@@ -132,19 +132,19 @@ int CheckProcessFd(int procFd) ...@@ -132,19 +132,19 @@ int CheckProcessFd(int procFd)
///获取绑定的系统描述符 ///获取绑定的系统描述符
int GetAssociatedSystemFd(int procFd) int GetAssociatedSystemFd(int procFd)
{ {
struct fd_table_s *fdt = GetFdTable(); struct fd_table_s *fdt = GetFdTable();//获取当前进程FD表
if (!IsValidProcessFd(fdt, procFd)) { if (!IsValidProcessFd(fdt, procFd)) {
return VFS_ERROR; return VFS_ERROR;
} }
FileTableLock(fdt); FileTableLock(fdt);//锁表
if (fdt->ft_fds[procFd].sysFd < 0) { if (fdt->ft_fds[procFd].sysFd < 0) {
FileTableUnLock(fdt); FileTableUnLock(fdt);
return VFS_ERROR; return VFS_ERROR;
} }
int sysFd = fdt->ft_fds[procFd].sysFd;//进程FD捆绑系统FD int sysFd = fdt->ft_fds[procFd].sysFd;//进程FD捆绑系统FD
FileTableUnLock(fdt); FileTableUnLock(fdt);//解锁表
return sysFd; return sysFd;
} }
...@@ -374,7 +374,7 @@ static struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId) ...@@ -374,7 +374,7 @@ static struct fd_table_s *GetProcessFTable(unsigned int pid, sem_t *semId)
return procFiles->fdt; return procFiles->fdt;
} }
///拷贝一个进程FD给指定的进程 ///拷贝一个进程FD给指定的进程,使两个进程的FD都指向同一个系统FD
int CopyFdToProc(int fd, unsigned int targetPid) int CopyFdToProc(int fd, unsigned int targetPid)
{ {
#if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS) #if !defined(LOSCFG_NET_LWIP_SACK) && !defined(LOSCFG_COMPAT_POSIX) && !defined(LOSCFG_FS_VFS)
......
...@@ -452,10 +452,10 @@ STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB) ...@@ -452,10 +452,10 @@ STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB)
return FALSE; return FALSE;
} }
/// 任务是否不再活 /// 任务是否不再活
STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB) STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
{ {
if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {//三个标签有一个代表不在活动 if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {//三个标签有一个 代表不在活动
return TRUE; return TRUE;
} }
......
...@@ -270,7 +270,7 @@ STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion* region) ...@@ -270,7 +270,7 @@ STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion* region)
{ {
region->regionType = VM_MAP_REGION_TYPE_ANON; region->regionType = VM_MAP_REGION_TYPE_ANON;
} }
/// 虚拟地址是否在用户空间 /// 虚拟地址是否在用户空间, 真为在用户空间
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr) STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
{ {
return ((vaddr >= USER_ASPACE_BASE) && return ((vaddr >= USER_ASPACE_BASE) &&
......
...@@ -4,7 +4,7 @@ ...@@ -4,7 +4,7 @@
* @link * @link
@verbatim @verbatim
什么是共享内存 什么是共享内存
顾名思义,共享内存就是允许两个不相关的进程访问同一个逻辑内存。共享内存是在两个正在运行的进程之间 顾名思义,共享内存就是允许两个不相关的进程访问同一个物理内存。共享内存是在两个正在运行的进程之间
共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同 共享和传递数据的一种非常有效的方式。不同进程之间共享的内存通常安排为同一段物理内存。进程可以将同
一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言 一段共享内存连接到它们自己的地址空间中,所有进程都可以访问共享内存中的地址,就好像它们是由用C语言
函数malloc()分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段 函数malloc()分配的内存一样。而如果某个进程向共享内存写入数据,所做的改动将立即影响到可以访问同一段
...@@ -145,7 +145,7 @@ struct shminfo { ...@@ -145,7 +145,7 @@ struct shminfo {
struct shmIDSource {//共享内存描述符 struct shmIDSource {//共享内存描述符
struct shmid_ds ds; //是内核为每一个共享内存段维护的数据结构 struct shmid_ds ds; //是内核为每一个共享内存段维护的数据结构
UINT32 status; //状态 SHM_SEG_FREE ... UINT32 status; //状态 SHM_SEG_FREE ...
LOS_DL_LIST node; //节点,挂vmPage LOS_DL_LIST node; //节点,挂VmPage
#ifdef LOSCFG_SHELL #ifdef LOSCFG_SHELL
CHAR ownerName[OS_PCB_NAME_LEN]; CHAR ownerName[OS_PCB_NAME_LEN];
#endif #endif
...@@ -522,13 +522,13 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg) ...@@ -522,13 +522,13 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg)
if (key == IPC_PRIVATE) { if (key == IPC_PRIVATE) {
ret = ShmAllocSeg(key, size, shmflg); ret = ShmAllocSeg(key, size, shmflg);
} else { } else {
ret = ShmFindSegByKey(key); ret = ShmFindSegByKey(key);//通过key查找资源ID
if (ret < 0) { if (ret < 0) {
if (((UINT32)shmflg & IPC_CREAT) == 0) { if (((UINT32)shmflg & IPC_CREAT) == 0) {//
ret = -ENOENT; ret = -ENOENT;
goto ERROR; goto ERROR;
} else { } else {
ret = ShmAllocSeg(key, size, shmflg); ret = ShmAllocSeg(key, size, shmflg);//分配一个共享内存
} }
} else { } else {
shmid = ret; shmid = ret;
...@@ -537,7 +537,7 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg) ...@@ -537,7 +537,7 @@ INT32 ShmGet(key_t key, size_t size, INT32 shmflg)
ret = -EEXIST; ret = -EEXIST;
goto ERROR; goto ERROR;
} }
ret = ShmPermCheck(ShmFindSeg(shmid), (UINT32)shmflg & ACCESSPERMS); ret = ShmPermCheck(ShmFindSeg(shmid), (UINT32)shmflg & ACCESSPERMS);//对共享内存权限检查
if (ret != 0) { if (ret != 0) {
ret = -ret; ret = -ret;
goto ERROR; goto ERROR;
...@@ -572,7 +572,7 @@ INT32 ShmatParamCheck(const VOID *shmaddr, INT32 shmflg) ...@@ -572,7 +572,7 @@ INT32 ShmatParamCheck(const VOID *shmaddr, INT32 shmflg)
return 0; return 0;
} }
///分配一个共享线性区 ///分配一个共享线性区并映射好
LosVmMapRegion *ShmatVmmAlloc(struct shmIDSource *seg, const VOID *shmaddr, LosVmMapRegion *ShmatVmmAlloc(struct shmIDSource *seg, const VOID *shmaddr,
INT32 shmflg, UINT32 prot) INT32 shmflg, UINT32 prot)
{ {
...@@ -622,8 +622,7 @@ ERROR: ...@@ -622,8 +622,7 @@ ERROR:
/*! /*!
* @brief ShmAt * @brief ShmAt
* 第一次创建完共享内存时,它还不能被任何进程访问,shmat()函数的作用就是用来启动对该共享内存的访问, * 用来启动对该共享内存的访问,并把共享内存连接到当前进程的地址空间。
并把共享内存连接到当前进程的地址空间。
* @param shm_flg 是一组标志位,通常为0。 * @param shm_flg 是一组标志位,通常为0。
* @param shmaddr 指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。 * @param shmaddr 指定共享内存连接到当前进程中的地址位置,通常为空,表示让系统来选择共享内存的地址。
* @param shmid 是shmget()函数返回的共享内存标识符 * @param shmid 是shmget()函数返回的共享内存标识符
...@@ -667,7 +666,7 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg) ...@@ -667,7 +666,7 @@ VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg)
} }
seg->ds.shm_nattch++;//ds上记录有一个进程绑定上来 seg->ds.shm_nattch++;//ds上记录有一个进程绑定上来
r = ShmatVmmAlloc(seg, shmaddr, shmflg, prot);//在当前进程空间分配一个线性区用于映射共享空间 r = ShmatVmmAlloc(seg, shmaddr, shmflg, prot);//在当前进程空间分配一个线性区并映射到共享内存
if (r == NULL) { if (r == NULL) {
seg->ds.shm_nattch--; seg->ds.shm_nattch--;
SYSV_SHM_UNLOCK(); SYSV_SHM_UNLOCK();
......
...@@ -47,7 +47,7 @@ extern "C" { ...@@ -47,7 +47,7 @@ extern "C" {
#define OS_CPUP_HISTORY_RECORD_NUM 11 #define OS_CPUP_HISTORY_RECORD_NUM 11
typedef struct { typedef struct {
UINT64 allTime; /**< Total running time */ UINT64 allTime; /**< Total running time | 总运行时间*/
UINT64 startTime; /**< Time before a task is invoked */ UINT64 startTime; /**< Time before a task is invoked */
UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM + 1]; /**< Historical running time, the last one saves zero */ UINT64 historyTime[OS_CPUP_HISTORY_RECORD_NUM + 1]; /**< Historical running time, the last one saves zero */
} OsCpupBase; } OsCpupBase;
......
...@@ -755,33 +755,33 @@ LITE_OS_SEC_TEXT STATIC BOOL IsCmsTask(UINT32 taskID) ...@@ -755,33 +755,33 @@ LITE_OS_SEC_TEXT STATIC BOOL IsCmsTask(UINT32 taskID)
(VOID)LOS_MuxUnlock(&g_serviceHandleMapMux); (VOID)LOS_MuxUnlock(&g_serviceHandleMapMux);
return ret; return ret;
} }
/// 任务是否活跃
LITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID) LITE_OS_SEC_TEXT STATIC BOOL IsTaskAlive(UINT32 taskID)
{ {
LosTaskCB *tcb = NULL; LosTaskCB *tcb = NULL;
if (OS_TID_CHECK_INVALID(taskID)) { if (OS_TID_CHECK_INVALID(taskID)) { //检查是否存在
return FALSE; return FALSE;
} }
tcb = OS_TCB_FROM_TID(taskID); tcb = OS_TCB_FROM_TID(taskID); //获取任务控制块
if (!OsProcessIsUserMode(OS_PCB_FROM_PID(tcb->processID))) { if (!OsProcessIsUserMode(OS_PCB_FROM_PID(tcb->processID))) {//判断是否为用户进程
return FALSE; return FALSE;
} }
if (OsTaskIsInactive(tcb)) { if (OsTaskIsInactive(tcb)) {//任务是否活跃
return FALSE; return FALSE;
} }
return TRUE; return TRUE;
} }
/// 按句柄方式处理, 参数 processID 往往不是当前进程
LITE_OS_SEC_TEXT STATIC UINT32 HandleFd(UINT32 processID, SpecialObj *obj, BOOL isRollback) LITE_OS_SEC_TEXT STATIC UINT32 HandleFd(UINT32 processID, SpecialObj *obj, BOOL isRollback)
{ {
int ret; int ret;
if (isRollback == FALSE) { if (isRollback == FALSE) { // 不回滚
ret = CopyFdToProc(obj->content.fd, processID); ret = CopyFdToProc(obj->content.fd, processID);//两个不同进程fd都指向同一个系统fd
if (ret < 0) { if (ret < 0) {//返回 processID 的 新 fd
return ret; return ret;
} }
obj->content.fd = ret; obj->content.fd = ret; // 记录 processID 的新FD, 可用于回滚
} else { } else {// 回滚时关闭进程FD
ret = CloseProcFd(obj->content.fd, processID); ret = CloseProcFd(obj->content.fd, processID);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
...@@ -790,7 +790,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandleFd(UINT32 processID, SpecialObj *obj, BOOL ...@@ -790,7 +790,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandleFd(UINT32 processID, SpecialObj *obj, BOOL
return LOS_OK; return LOS_OK;
} }
/// 按指针方式处理
LITE_OS_SEC_TEXT STATIC UINT32 HandlePtr(UINT32 processID, SpecialObj *obj, BOOL isRollback) LITE_OS_SEC_TEXT STATIC UINT32 HandlePtr(UINT32 processID, SpecialObj *obj, BOOL isRollback)
{ {
VOID *buf = NULL; VOID *buf = NULL;
...@@ -799,28 +799,28 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandlePtr(UINT32 processID, SpecialObj *obj, BOOL ...@@ -799,28 +799,28 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandlePtr(UINT32 processID, SpecialObj *obj, BOOL
return -EINVAL; return -EINVAL;
} }
if (isRollback == FALSE) { if (isRollback == FALSE) {
if (LOS_IsUserAddress((vaddr_t)(UINTPTR)(obj->content.ptr.buff)) == FALSE) { if (LOS_IsUserAddress((vaddr_t)(UINTPTR)(obj->content.ptr.buff)) == FALSE) { // 判断是否为用户空间地址
PRINT_ERR("Liteipc Bad ptr address\n"); PRINT_ERR("Liteipc Bad ptr address\n"); //不在用户空间时
return -EINVAL; return -EINVAL;
} }
buf = LiteIpcNodeAlloc(processID, obj->content.ptr.buffSz); buf = LiteIpcNodeAlloc(processID, obj->content.ptr.buffSz);//在内核空间分配内存
if (buf == NULL) { if (buf == NULL) {
PRINT_ERR("Liteipc DealPtr alloc mem failed\n"); PRINT_ERR("Liteipc DealPtr alloc mem failed\n");
return -EINVAL; return -EINVAL;
} }
ret = copy_from_user(buf, obj->content.ptr.buff, obj->content.ptr.buffSz); ret = copy_from_user(buf, obj->content.ptr.buff, obj->content.ptr.buffSz);//从用户空间拷贝数据到内核空间
if (ret != LOS_OK) { if (ret != LOS_OK) {
LiteIpcNodeFree(processID, buf); LiteIpcNodeFree(processID, buf);
return ret; return ret;
} }
obj->content.ptr.buff = (VOID *)GetIpcUserAddr(processID, (INTPTR)buf); obj->content.ptr.buff = (VOID *)GetIpcUserAddr(processID, (INTPTR)buf);//获取进程 processID 的用户空间地址
EnableIpcNodeFreeByUser(processID, (VOID *)buf); EnableIpcNodeFreeByUser(processID, (VOID *)buf);//创建一个IPC节点,挂到已读取链表上
} else { } else {
(VOID)LiteIpcNodeFree(processID, (VOID *)GetIpcKernelAddr(processID, (INTPTR)obj->content.ptr.buff)); (VOID)LiteIpcNodeFree(processID, (VOID *)GetIpcKernelAddr(processID, (INTPTR)obj->content.ptr.buff));//在内核空间释放IPC节点
} }
return LOS_OK; return LOS_OK;
} }
/// 按服务的方式处理
LITE_OS_SEC_TEXT STATIC UINT32 HandleSvc(UINT32 dstTid, const SpecialObj *obj, BOOL isRollback) LITE_OS_SEC_TEXT STATIC UINT32 HandleSvc(UINT32 dstTid, const SpecialObj *obj, BOOL isRollback)
{ {
UINT32 taskID = 0; UINT32 taskID = 0;
...@@ -850,10 +850,10 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandleObj(UINT32 dstTid, SpecialObj *obj, BOOL is ...@@ -850,10 +850,10 @@ LITE_OS_SEC_TEXT STATIC UINT32 HandleObj(UINT32 dstTid, SpecialObj *obj, BOOL is
case OBJ_FD://fd:文件描述符 case OBJ_FD://fd:文件描述符
ret = HandleFd(processID, obj, isRollback); ret = HandleFd(processID, obj, isRollback);
break; break;
case OBJ_PTR://指针 case OBJ_PTR://指针方式
ret = HandlePtr(processID, obj, isRollback); ret = HandlePtr(processID, obj, isRollback);
break; break;
case OBJ_SVC: case OBJ_SVC://服务方式
ret = HandleSvc(dstTid, (const SpecialObj *)obj, isRollback); ret = HandleSvc(dstTid, (const SpecialObj *)obj, isRollback);
break; break;
default: default:
......
...@@ -102,26 +102,26 @@ typedef struct { ...@@ -102,26 +102,26 @@ typedef struct {
} IpcTaskInfo; } IpcTaskInfo;
typedef enum { typedef enum {
OBJ_FD, OBJ_FD, ///< 文件句柄
OBJ_PTR, OBJ_PTR, ///< 指针
OBJ_SVC OBJ_SVC ///< 服务
} ObjType; } ObjType;
typedef struct { typedef struct {
UINT32 buffSz; UINT32 buffSz; //大小
VOID *buff; VOID *buff; //内容
} BuffPtr; } BuffPtr;
/// svc 是啥哩? @note_thinking /// SVC(service)服务身份证
typedef struct { typedef struct {
UINT32 handle; UINT32 handle; //一般为任务ID | taskid
UINT32 token; UINT32 token;
UINT32 cookie; UINT32 cookie;
} SvcIdentity; } SvcIdentity;
/// 对象内容体 /// 对象内容体,注意是个联合体
typedef union { typedef union {
UINT32 fd; ///< 文件描述符 UINT32 fd; ///< 文件描述符
BuffPtr ptr;///< 缓存的开始地址,即:指针 BuffPtr ptr; ///< 缓存的开始地址,即:指针
SvcIdentity svc; SvcIdentity svc; ///< 服务身份
} ObjContent; } ObjContent;
/// 特殊对象 /// 特殊对象
typedef struct { typedef struct {
...@@ -154,17 +154,17 @@ typedef enum { ...@@ -154,17 +154,17 @@ typedef enum {
} CmsCmd; } CmsCmd;
typedef struct { typedef struct {
CmsCmd cmd; CmsCmd cmd; /// 命令
UINT32 taskID; UINT32 taskID;
UINT32 serviceHandle; UINT32 serviceHandle;
} CmsCmdContent; } CmsCmdContent;
typedef enum { typedef enum {
LITEIPC_FLAG_DEFAULT = 0, // send and reply LITEIPC_FLAG_DEFAULT = 0, // send and reply | 发送并回复
LITEIPC_FLAG_ONEWAY, // send message only LITEIPC_FLAG_ONEWAY, // send message only | 仅发送信息
} IpcFlag; } IpcFlag;
typedef struct { typedef struct {//IPC 消息结构体
MsgType type; /**< cmd type, decide the data structure below | 命令类型,决定下面的数据结构*/ MsgType type; /**< cmd type, decide the data structure below | 命令类型,决定下面的数据结构*/
SvcIdentity target; /**< serviceHandle or targetTaskId, depending on type | 因命令类型不同而异*/ SvcIdentity target; /**< serviceHandle or targetTaskId, depending on type | 因命令类型不同而异*/
UINT32 code; /**< service function code | 服务功能代码*/ UINT32 code; /**< service function code | 服务功能代码*/
......
git add -A git add -A
git commit -m ' 同步官方代码,本次官方对测试用例和MMU做了较大调整 git commit -m ' LiteIPC 注释完善, 它内核提供的一种新型IPC通讯机制
百图画鸿蒙 + 百文说内核 + 百万注源码 => 挖透鸿蒙内核源码 百图画鸿蒙 + 百文说内核 + 百万注源码 => 挖透鸿蒙内核源码
鸿蒙研究站 | http://weharmonyos.com (国内) 鸿蒙研究站 | http://weharmonyos.com (国内)
| https://weharmony.github.io (国外) | https://weharmony.github.io (国外)
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册