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