加了两个时序图 #40

Closed
pzac9rny2 wants to merge 30 commits from zhouxuyang_branchV2.0 into main

@ -1,3 +1,8 @@
<<<<<<< HEAD
# Iot_Cs_best
=======
# Brief Intro
LMFAO, we do this shit just for fun :)
LMFAO, we do this shit just for fun :)
>>>>>>> remotes/origin/main

Binary file not shown.

@ -54,13 +54,21 @@ int main(int argc, char * const *argv)
const char *shellPath = "/bin/mksh";
#ifdef LOSCFG_QUICK_START
<<<<<<< HEAD
const char *samplePath = "/dev/shm/sample_quickstart";
=======
const char *samplePath = "/dev/shm/sample_quickstart";
>>>>>>> remotes/origin/main
ret = fork();
if (ret < 0) {
printf("Failed to fork for sample_quickstart\n");
} else if (ret == 0) {
<<<<<<< HEAD
(void)execve(samplePath, NULL, NULL);
=======
(void)execve(samplePath, NULL, NULL); // 执行可执行文件
>>>>>>> remotes/origin/main
exit(0);
}
@ -72,24 +80,43 @@ int main(int argc, char * const *argv)
close(fd);
}
#endif
<<<<<<< HEAD
ret = fork();
if (ret < 0) {
printf("Failed to fork for shell\n");
} else if (ret == 0) {
gid = getpgrp();
=======
ret = fork(); // 创建第一个程序来跑shell
if (ret < 0) {
printf("Failed to fork for shell\n");
} else if (ret == 0) {
gid = getpgrp(); // 返回进程组ID
>>>>>>> remotes/origin/main
if (gid < 0) {
printf("get group id failed, pgrpid %d, errno %d\n", gid, errno);
exit(0);
}
<<<<<<< HEAD
ret = tcsetpgrp(STDIN_FILENO, gid);
=======
ret = tcsetpgrp(STDIN_FILENO, gid);
>>>>>>> remotes/origin/main
if (ret != 0) {
printf("tcsetpgrp failed, errno %d\n", errno);
exit(0);
}
<<<<<<< HEAD
(void)execve(shellPath, NULL, NULL);
exit(0);
}
=======
(void)execve(shellPath, NULL, NULL); // 正常执行命令行程序可执行文件
exit(0);
}
// ret > 0
>>>>>>> remotes/origin/main
while (1) {
ret = waitpid(-1, 0, WNOHANG);
if (ret == 0) {

@ -2311,7 +2311,11 @@ diff -Nupr old/fs/jffs2/erase.c new/fs/jffs2/erase.c
diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
--- old/fs/jffs2/file.c 2022-05-09 17:22:53.000000000 +0800
+++ new/fs/jffs2/file.c 2022-05-10 09:43:14.250000000 +0800
<<<<<<< HEAD
@@ -9,335 +9,30 @@
=======
@@ -9,334 +9,31 @@
>>>>>>> remotes/origin/main
* For licensing information, see the file 'LICENCE' in this directory.
*
*/
@ -2348,7 +2352,11 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
+ /* FIXME: This works only with one file system mounted at a time */
int ret;
<<<<<<< HEAD
-
=======
>>>>>>> remotes/origin/main
- ret = file_write_and_wait_range(filp, start, end);
+ ret = jffs2_read_inode_range(c, f, gc_buffer,
+ offset & ~(PAGE_SIZE-1), PAGE_SIZE);
@ -2361,10 +2369,15 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- inode_unlock(inode);
-
- return 0;
<<<<<<< HEAD
-}
-
=======
+ return ERR_PTR(ret);
+ return gc_buffer;
}
>>>>>>> remotes/origin/main
-const struct file_operations jffs2_file_operations =
-{
- .llseek = generic_file_llseek,
@ -2389,10 +2402,14 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
-};
-
-const struct address_space_operations jffs2_file_address_operations =
<<<<<<< HEAD
-{
=======
+void jffs2_gc_release_page(struct jffs2_sb_info *c,
+ unsigned char *ptr,
+ unsigned long *priv)
{
>>>>>>> remotes/origin/main
- .readpage = jffs2_readpage,
- .write_begin = jffs2_write_begin,
- .write_end = jffs2_write_end,
@ -2448,29 +2465,57 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- ret = jffs2_do_readpage_unlock(pg->mapping->host, pg);
- mutex_unlock(&f->sem);
- return ret;
<<<<<<< HEAD
+ return ERR_PTR(ret);
+ return gc_buffer;
}
-static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
+void jffs2_gc_release_page(struct jffs2_sb_info *c,
+ unsigned char *ptr,
+ unsigned long *priv)
{
=======
-}
-
-static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
- loff_t pos, unsigned len, unsigned flags,
- struct page **pagep, void **fsdata)
-{
>>>>>>> remotes/origin/main
- struct page *pg;
- struct inode *inode = mapping->host;
- struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
- struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
- pgoff_t index = pos >> PAGE_SHIFT;
<<<<<<< HEAD
- uint32_t pageofs = index << PAGE_SHIFT;
=======
>>>>>>> remotes/origin/main
- int ret = 0;
-
- jffs2_dbg(1, "%s()\n", __func__);
-
<<<<<<< HEAD
- if (pageofs > inode->i_size) {
- /* Make new hole frag from old EOF to new page */
=======
- if (pos > inode->i_size) {
- /* Make new hole frag from old EOF to new position */
>>>>>>> remotes/origin/main
- struct jffs2_raw_inode ri;
- struct jffs2_full_dnode *fn;
- uint32_t alloc_len;
-
<<<<<<< HEAD
- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new page\n",
- (unsigned int)inode->i_size, pageofs);
=======
- jffs2_dbg(1, "Writing new hole frag 0x%x-0x%x between current EOF and new position\n",
- (unsigned int)inode->i_size, (uint32_t)pos);
>>>>>>> remotes/origin/main
-
- ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
- ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
@ -2490,10 +2535,17 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- ri.mode = cpu_to_jemode(inode->i_mode);
- ri.uid = cpu_to_je16(i_uid_read(inode));
- ri.gid = cpu_to_je16(i_gid_read(inode));
<<<<<<< HEAD
- ri.isize = cpu_to_je32(max((uint32_t)inode->i_size, pageofs));
- ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW());
- ri.offset = cpu_to_je32(inode->i_size);
- ri.dsize = cpu_to_je32(pageofs - inode->i_size);
=======
- ri.isize = cpu_to_je32((uint32_t)pos);
- ri.atime = ri.ctime = ri.mtime = cpu_to_je32(JFFS2_NOW());
- ri.offset = cpu_to_je32(inode->i_size);
- ri.dsize = cpu_to_je32((uint32_t)pos - inode->i_size);
>>>>>>> remotes/origin/main
- ri.csize = cpu_to_je32(0);
- ri.compr = JFFS2_COMPR_ZERO;
- ri.node_crc = cpu_to_je32(crc32(0, &ri, sizeof(ri)-8));
@ -2523,7 +2575,11 @@ diff -Nupr old/fs/jffs2/file.c new/fs/jffs2/file.c
- goto out_err;
- }
- jffs2_complete_reservation(c);
<<<<<<< HEAD
- inode->i_size = pageofs;
=======
- inode->i_size = pos;
>>>>>>> remotes/origin/main
- mutex_unlock(&f->sem);
- }
-

@ -33,6 +33,18 @@
#include "los_printf.h"
#include "los_toolchain.h"
<<<<<<< HEAD
#define OS_BITMAP_MASK 0x1FU
#define OS_BITMAP_WORD_MASK ~0UL
/* find first zero bit starting from LSB */
STATIC INLINE UINT16 Ffz(UINTPTR x)
{
return __builtin_ffsl(~x) - 1;
}
=======
/*
function:
@ -59,12 +71,18 @@ STATIC INLINE UINT16 Ffz(UINTPTR x)
interpretation:
*/
>>>>>>> remotes/origin/main
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
return;
}
<<<<<<< HEAD
*bitmap |= 1U << (pos & OS_BITMAP_MASK);
}
=======
*bitmap |= 1U << (pos & OS_BITMAP_MASK); //00011111
}
@ -73,6 +91,7 @@ VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
interpretation:
*/
>>>>>>> remotes/origin/main
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
{
if (bitmap == NULL) {
@ -82,9 +101,12 @@ VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));
}
<<<<<<< HEAD
=======
/*
function:
*/
>>>>>>> remotes/origin/main
UINT16 LOS_HighBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
@ -94,9 +116,12 @@ UINT16 LOS_HighBitGet(UINT32 bitmap)
return (OS_BITMAP_MASK - CLZ(bitmap));
}
<<<<<<< HEAD
=======
/*
function: 1
*/
>>>>>>> remotes/origin/main
UINT16 LOS_LowBitGet(UINT32 bitmap)
{
if (bitmap == 0) {
@ -106,9 +131,12 @@ UINT16 LOS_LowBitGet(UINT32 bitmap)
return CTZ(bitmap);
}
<<<<<<< HEAD
=======
/*
function: startnumsSetbit 1
*/
>>>>>>> remotes/origin/main
VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet)
{
UINTPTR *p = bitmap + BITMAP_WORD(start);
@ -129,9 +157,12 @@ VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet)
}
}
<<<<<<< HEAD
=======
/*
fuction: start numsSetbit0 ,0
*/
>>>>>>> remotes/origin/main
VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear)
{
UINTPTR *p = bitmap + BITMAP_WORD(start);
@ -151,9 +182,13 @@ VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear)
*p &= ~maskToClear;
}
}
<<<<<<< HEAD
=======
/*
fuction: numBits0
*/
>>>>>>> remotes/origin/main
INT32 LOS_BitmapFfz(UINTPTR *bitmap, UINT32 numBits)
{
INT32 bit, i;

@ -32,10 +32,15 @@
#include "los_task_pri.h"
#include "los_vm_dump.h"
<<<<<<< HEAD
STATIC UINT32 GetCurrParentPid(UINT32 pid, const LosProcessCB *processCB)
{
=======
// 得到父进程的pid
STATIC UINT32 GetCurrParentPid(UINT32 pid, const LosProcessCB *processCB)
{
// 如果没有父进程
>>>>>>> remotes/origin/main
if (processCB->parentProcess == NULL) {
return 0;
}
@ -52,7 +57,10 @@ STATIC UINT32 GetCurrParentPid(UINT32 pid, const LosProcessCB *processCB)
return processCB->parentProcess->processID;
}
<<<<<<< HEAD
=======
// 得到当前任务ID
>>>>>>> remotes/origin/main
STATIC INLINE UINT32 GetCurrTid(const LosTaskCB *taskCB)
{
#ifdef LOSCFG_PID_CONTAINER
@ -63,7 +71,10 @@ STATIC INLINE UINT32 GetCurrTid(const LosTaskCB *taskCB)
return taskCB->taskID;
}
<<<<<<< HEAD
=======
// 得到进程的状态
>>>>>>> remotes/origin/main
STATIC UINT16 GetProcessStatus(LosProcessCB *processCB)
{
UINT16 status;
@ -80,7 +91,10 @@ STATIC UINT16 GetProcessStatus(LosProcessCB *processCB)
return status;
}
<<<<<<< HEAD
=======
// 得到进程的信息
>>>>>>> remotes/origin/main
STATIC VOID GetProcessInfo(ProcessInfo *pcbInfo, const LosProcessCB *processCB)
{
SchedParam param = {0};
@ -138,7 +152,10 @@ STATIC VOID GetProcessMemInfo(ProcessInfo *pcbInfo, const LosProcessCB *processC
}
#endif
<<<<<<< HEAD
=======
// 得到线程的信息
>>>>>>> remotes/origin/main
STATIC VOID GetThreadInfo(ProcessThreadInfo *threadInfo, LosProcessCB *processCB)
{
SchedParam param = {0};

File diff suppressed because it is too large Load Diff

@ -40,7 +40,11 @@
#ifdef LOSCFG_KERNEL_SMP
STATIC struct SmpOps *g_smpOps = NULL;
<<<<<<< HEAD
=======
/// 多核中次级CPU核初始化,每个核都会调用一次
>>>>>>> remotes/origin/main
STATIC VOID OsSmpSecondaryInit(VOID *arg)
{
UNUSED(arg);
@ -56,7 +60,11 @@ STATIC VOID OsSmpSecondaryInit(VOID *arg)
OsSchedStart();
}
<<<<<<< HEAD
=======
/// 设置多核操作接口, 通过外部注册
>>>>>>> remotes/origin/main
VOID LOS_SmpOpsSet(struct SmpOps *ops)
{
g_smpOps = ops;

@ -28,6 +28,9 @@
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
<<<<<<< HEAD
=======
/*基本概念
TickTick
@ -84,6 +87,7 @@
使
Tick*/
>>>>>>> remotes/origin/main
#include "los_swtmr_pri.h"
#include "los_init.h"
#include "los_process_pri.h"
@ -106,6 +110,16 @@ LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Han
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */
/* spinlock for swtmr module, only available on SMP mode */
<<<<<<< HEAD
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);
#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))
#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))
typedef struct {
SortLinkAttribute swtmrSortLink;
LosTaskCB *swtmrTask; /* software timer task id */
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id */
=======
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_swtmrSpin);//初始化软件钟自旋锁只有SMP情况才需要只要是自旋锁都是由于CPU多核的同步
#define SWTMR_LOCK(state) LOS_SpinLockSave(&g_swtmrSpin, &(state))//持有软时钟自旋锁
#define SWTMR_UNLOCK(state) LOS_SpinUnlockRestore(&g_swtmrSpin, (state))//释放软时钟自旋锁
@ -114,6 +128,7 @@ typedef struct {
SortLinkAttribute swtmrSortLink;
LosTaskCB *swtmrTask; /* software timer task id *///定时器任务ID
LOS_DL_LIST swtmrHandlerQueue; /* software timer timeout queue id *///定时器超时队列
>>>>>>> remotes/origin/main
} SwtmrRunqueue;
STATIC SwtmrRunqueue g_swtmrRunqueue[LOSCFG_KERNEL_CORE_NUM];
@ -309,7 +324,11 @@ STATIC INLINE VOID ScanSwtmrTimeList(SwtmrRunqueue *srq)
LOS_SpinUnlockRestore(&swtmrSortLink->spinLock, intSave);
return;
}
<<<<<<< HEAD
=======
//软时钟的入口函数拥有任务的最高优先级0级
>>>>>>> remotes/origin/main
STATIC VOID SwtmrTask(VOID)
{
SwtmrHandlerItem swtmrHandle;
@ -318,7 +337,11 @@ STATIC VOID SwtmrTask(VOID)
SwtmrRunqueue *srq = &g_swtmrRunqueue[ArchCurrCpuid()];
LOS_DL_LIST *head = &srq->swtmrHandlerQueue;
<<<<<<< HEAD
for (;;) {
=======
for (;;) {//死循环获取队列item一直读干净为止
>>>>>>> remotes/origin/main
waitTime = OsSortLinkGetNextExpireTime(OsGetCurrSchedTimeCycle(), &srq->swtmrSortLink);
if (waitTime != 0) {
SCHEDULER_LOCK(intSave);
@ -334,18 +357,39 @@ STATIC VOID SwtmrTask(VOID)
LOS_ListDelete(&swtmrHandlePtr->node);
(VOID)memcpy_s(&swtmrHandle, sizeof(SwtmrHandlerItem), swtmrHandlePtr, sizeof(SwtmrHandlerItem));
<<<<<<< HEAD
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);
=======
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);//静态释放内存,注意在鸿蒙内核只有软时钟注册用到了静态内存
>>>>>>> remotes/origin/main
SwtmrHandler(&swtmrHandle);
}
}
}
<<<<<<< HEAD
=======
//创建软时钟任务每个cpu core都可以拥有自己的软时钟任务
>>>>>>> remotes/origin/main
STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
{
UINT32 ret;
TSK_INIT_PARAM_S swtmrTask;
<<<<<<< HEAD
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
swtmrTask.pcName = "Swt_Task";
swtmrTask.usTaskPrio = 0;
swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;
#ifdef LOSCFG_KERNEL_SMP
swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);
#endif
ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);
if (ret == LOS_OK) {
OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
=======
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));//清0
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)SwtmrTask;//入口函数
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;//16k默认内核任务栈
@ -358,6 +402,7 @@ STATIC UINT32 SwtmrTaskCreate(UINT16 cpuid, UINT32 *swtmrTaskID)
ret = LOS_TaskCreate(swtmrTaskID, &swtmrTask);//创建任务并申请调度
if (ret == LOS_OK) {
OS_TCB_FROM_TID(*swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;//告知这是个任务系统
>>>>>>> remotes/origin/main
}
return ret;
@ -375,6 +420,18 @@ BOOL OsIsSwtmrTask(const LosTaskCB *taskCB)
}
return FALSE;
}
<<<<<<< HEAD
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID)
{
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {
if (g_swtmrCBArray[index].uwOwnerPid == ownerID) {
LOS_SwtmrDelete(index);
}
}
}
=======
//回收指定进程的软时钟
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID)
{
@ -385,6 +442,7 @@ LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINTPTR ownerID)
}
}
//软时钟初始化注意函数在多CPU情况下会执行多次
>>>>>>> remotes/origin/main
STATIC UINT32 SwtmrBaseInit(VOID)
{
UINT32 ret;
@ -394,6 +452,17 @@ STATIC UINT32 SwtmrBaseInit(VOID)
return LOS_ERRNO_SWTMR_NO_MEMORY;
}
<<<<<<< HEAD
(VOID)memset_s(swtmr, size, 0, size);
g_swtmrCBArray = swtmr;
LOS_ListInit(&g_swtmrFreeList);
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
swtmr->usTimerID = index;
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
}
size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);
=======
(VOID)memset_s(swtmr, size, 0, size);//清0
g_swtmrCBArray = swtmr;//软时钟
LOS_ListInit(&g_swtmrFreeList);//初始化空间链表
@ -403,6 +472,7 @@ STATIC UINT32 SwtmrBaseInit(VOID)
}
//想要用静态内存池管理就必须要使用LOS_MEMBOX_SIZE来计算申请列表的内存大小因为需要点前缀内存承载头部信息
size = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);//规划一片内存区域作为软时钟处理函数的静态内存池
>>>>>>> remotes/origin/main
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, size); /* system resident resource */
if (g_swtmrHandlerPool == NULL) {
return LOS_ERRNO_SWTMR_NO_MEMORY;
@ -530,6 +600,16 @@ STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
if ((swtmr->uwOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
(swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
<<<<<<< HEAD
(swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {
ticks = swtmr->uwExpiry;
} else {
ticks = swtmr->uwInterval;
}
swtmr->ucState = OS_SWTMR_STATUS_TICKING;
UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;
=======
(swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {//如果是一次性的定时器
ticks = swtmr->uwExpiry;//获取定时间隔
} else {
@ -538,6 +618,7 @@ STATIC UINT64 SwtmrToStart(SWTMR_CTRL_S *swtmr, UINT16 cpuid)
swtmr->ucState = OS_SWTMR_STATUS_TICKING;//获取周期性定时器时间间隔
UINT64 period = (UINT64)ticks * OS_CYCLE_PER_TICK;//计数状态
>>>>>>> remotes/origin/main
UINT64 responseTime = swtmr->startTime + period;
UINT64 currTime = OsGetCurrSchedTimeCycle();
if (responseTime < currTime) {
@ -578,7 +659,11 @@ STATIC INLINE VOID SwtmrStart(SWTMR_CTRL_S *swtmr)
STATIC INLINE VOID SwtmrDelete(SWTMR_CTRL_S *swtmr)
{
/* insert to free list */
<<<<<<< HEAD
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
=======
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);//直接插入空闲链表中,回收再利用
>>>>>>> remotes/origin/main
swtmr->ucState = OS_SWTMR_STATUS_UNUSED;
swtmr->uwOwnerPid = OS_INVALID_VALUE;
@ -697,7 +782,11 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
}
return (UINT32)time;
}
<<<<<<< HEAD
=======
//创建定时器设置定时器的定时时长、定时模式、回调函数、并返回定时器ID
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
UINT8 mode,
SWTMR_PROC_FUNC handler,
@ -726,7 +815,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
}
SWTMR_LOCK(intSave);
<<<<<<< HEAD
if (LOS_ListEmpty(&g_swtmrFreeList)) {
=======
if (LOS_ListEmpty(&g_swtmrFreeList)) {//空闲列表不能为空
>>>>>>> remotes/origin/main
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_MAXSIZE;
}
@ -737,6 +830,15 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
SWTMR_UNLOCK(intSave);
swtmr->uwOwnerPid = (UINTPTR)OsCurrProcessGet();
<<<<<<< HEAD
swtmr->pfnHandler = handler;
swtmr->ucMode = mode;
swtmr->uwOverrun = 0;
swtmr->uwInterval = interval;
swtmr->uwExpiry = interval;
swtmr->uwArg = arg;
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
=======
swtmr->pfnHandler = handler;//时间到了的回调函数
swtmr->ucMode = mode;//定时模式
swtmr->uwOverrun = 0;
@ -744,12 +846,17 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
swtmr->uwExpiry = interval;//一次性超时间隔
swtmr->uwArg = arg;//回调函数的参数
swtmr->ucState = OS_SWTMR_STATUS_CREATED;//已创建状态
>>>>>>> remotes/origin/main
SET_SORTLIST_VALUE(&swtmr->stSortList, OS_SORT_LINK_INVALID_TIME);
*swtmrID = swtmr->usTimerID;
OsHookCall(LOS_HOOK_TYPE_SWTMR_CREATE, swtmr);
return LOS_OK;
}
<<<<<<< HEAD
=======
//接口函数 启动定时器 参数定时任务ID
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -761,15 +868,37 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID;
}
<<<<<<< HEAD
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {
=======
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {//ID必须一样
>>>>>>> remotes/origin/main
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_ID_INVALID;
}
<<<<<<< HEAD
switch (swtmr->ucState) {
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break;
/*
* If the status of swtmr is timing, it should stop the swtmr first,
* then start the swtmr again.
*/
case OS_SWTMR_STATUS_TICKING:
SwtmrStop(swtmr);
/* fall-through */
case OS_SWTMR_STATUS_CREATED:
=======
switch (swtmr->ucState) {//判断定时器状态
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
@ -782,6 +911,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
SwtmrStop(swtmr);//先停止定时器注意这里没有break在OsSwtmrStop中状态将会回到了OS_SWTMR_STATUS_CRWEATED接下来就是执行启动了
/* fall-through */
case OS_SWTMR_STATUS_CREATED://已经创建好了
>>>>>>> remotes/origin/main
SwtmrStart(swtmr);
break;
default:
@ -793,7 +923,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_START, swtmr);
return ret;
}
<<<<<<< HEAD
=======
//接口函数 停止计时器 参加定时任务ID
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -805,15 +939,34 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID;
}
<<<<<<< HEAD
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {
=======
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {//ID必须一样
>>>>>>> remotes/origin/main
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_ID_INVALID;
}
<<<<<<< HEAD
switch (swtmr->ucState) {
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break;
case OS_SWTMR_STATUS_CREATED:
ret = LOS_ERRNO_SWTMR_NOT_STARTED;
break;
case OS_SWTMR_STATUS_TICKING:
SwtmrStop(swtmr);
=======
switch (swtmr->ucState) {//判断定时器状态
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;//返回没有创建
@ -823,6 +976,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
break;
case OS_SWTMR_STATUS_TICKING://正在计数
SwtmrStop(swtmr);//执行正在停止计时器操作
>>>>>>> remotes/origin/main
break;
default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
@ -833,7 +987,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
OsHookCall(LOS_HOOK_TYPE_SWTMR_STOP, swtmr);
return ret;
}
<<<<<<< HEAD
=======
//接口函数 获得软件定时器剩余Tick数 通过 *tick 带走
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -849,11 +1007,19 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
return LOS_ERRNO_SWTMR_TICK_PTR_NULL;
}
<<<<<<< HEAD
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {
=======
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {//ID必须一样
>>>>>>> remotes/origin/main
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_ID_INVALID;
}
@ -864,8 +1030,13 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
case OS_SWTMR_STATUS_CREATED:
ret = LOS_ERRNO_SWTMR_NOT_STARTED;
break;
<<<<<<< HEAD
case OS_SWTMR_STATUS_TICKING:
*tick = OsSwtmrTimeGet(swtmr);
=======
case OS_SWTMR_STATUS_TICKING://正在计数的定时器
*tick = OsSwtmrTimeGet(swtmr);//获取
>>>>>>> remotes/origin/main
break;
default:
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
@ -874,7 +1045,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
SWTMR_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
//接口函数 删除定时器
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
{
SWTMR_CTRL_S *swtmr = NULL;
@ -886,11 +1061,19 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
return LOS_ERRNO_SWTMR_ID_INVALID;
}
<<<<<<< HEAD
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
swtmr = g_swtmrCBArray + swtmrCBID;
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {
=======
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;//取模
swtmr = g_swtmrCBArray + swtmrCBID;//获取定时器控制结构体
SWTMR_LOCK(intSave);
if (swtmr->usTimerID != swtmrID) {//ID必须一样
>>>>>>> remotes/origin/main
SWTMR_UNLOCK(intSave);
return LOS_ERRNO_SWTMR_ID_INVALID;
}
@ -899,10 +1082,17 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
case OS_SWTMR_STATUS_UNUSED:
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
break;
<<<<<<< HEAD
case OS_SWTMR_STATUS_TICKING:
SwtmrStop(swtmr);
/* fall-through */
case OS_SWTMR_STATUS_CREATED:
=======
case OS_SWTMR_STATUS_TICKING://正在计数就先停止在删除这里没有break
SwtmrStop(swtmr);
/* fall-through */
case OS_SWTMR_STATUS_CREATED://再删除定时器
>>>>>>> remotes/origin/main
SwtmrDelete(swtmr);
break;
default:
@ -915,4 +1105,8 @@ LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
return ret;
}
#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */
<<<<<<< HEAD
#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */
=======
#endif /* LOSCFG_BASE_CORE_SWTMR_ENABLE */
>>>>>>> remotes/origin/main

File diff suppressed because it is too large Load Diff

@ -37,30 +37,51 @@
#endif
<<<<<<< HEAD
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock;
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond;
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale;
/* spinlock for task module */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin);
=======
LITE_OS_SEC_DATA_INIT UINT32 g_sysClock; //系统时钟,绝大部分部件工作的时钟源,以及所有外设的始终来源
LITE_OS_SEC_DATA_INIT UINT32 g_tickPerSecond; //每秒Tick数harmony默认为每秒100次即10ms
LITE_OS_SEC_BSS DOUBLE g_cycle2NsScale; //将周期转为纳秒级
/* spinlock for task module */
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_tickSpin); //节拍器自旋锁
>>>>>>> remotes/origin/main
/*
* Description : Tick interruption handler
*/
<<<<<<< HEAD
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
=======
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)//节拍中断处理函数harmony默认1ms触发一次
>>>>>>> remotes/origin/main
{
#ifdef LOSCFG_SCHED_TICK_DEBUG
OsSchedDebugRecordData();
#endif
#ifdef LOSCFG_KERNEL_VDSO
<<<<<<< HEAD
OsVdsoTimevalUpdate();
=======
OsVdsoTimevalUpdate(); //更新vdso数据页时间vsdo可以直接在用户进程空间绕过系统调用获取系统时间
>>>>>>> remotes/origin/main
#endif
#ifdef LOSCFG_BASE_CORE_TICK_HW_TIME
HalClockIrqClear(); /* diff from every platform */
#endif
<<<<<<< HEAD
OsSchedTick();
=======
OsSchedTick();//由时钟发起的调度
>>>>>>> remotes/origin/main
}

@ -57,10 +57,17 @@
typedef enum {
CONTAINER = 0,
<<<<<<< HEAD
PID_CONTAINER,
PID_CHILD_CONTAINER,
UTS_CONTAINER,
MNT_CONTAINER,
=======
PID_CONTAINER, //进程容器
PID_CHILD_CONTAINER, //子进程容器
UTS_CONTAINER, //
MNT_CONTAINER, //挂载容器
>>>>>>> remotes/origin/main
IPC_CONTAINER,
USER_CONTAINER,
TIME_CONTAINER,
@ -70,6 +77,31 @@ typedef enum {
} ContainerType;
typedef struct Container {
<<<<<<< HEAD
Atomic rc;
#ifdef LOSCFG_PID_CONTAINER
struct PidContainer *pidContainer;
struct PidContainer *pidForChildContainer;
#endif
#ifdef LOSCFG_UTS_CONTAINER
struct UtsContainer *utsContainer;
#endif
#ifdef LOSCFG_MNT_CONTAINER
struct MntContainer *mntContainer;
#endif
#ifdef LOSCFG_IPC_CONTAINER
struct IpcContainer *ipcContainer;
#endif
#ifdef LOSCFG_TIME_CONTAINER
struct TimeContainer *timeContainer;
struct TimeContainer *timeForChildContainer;
#endif
#ifdef LOSCFG_NET_CONTAINER
struct NetContainer *netContainer;
#endif
} Container;
=======
Atomic rc; //原子操作
#ifdef LOSCFG_PID_CONTAINER
struct PidContainer *pidContainer; //进程容器
@ -93,6 +125,7 @@ typedef struct Container {
#endif
} Container;
//容器数量上限
>>>>>>> remotes/origin/main
typedef struct TagContainerLimit {
#ifdef LOSCFG_PID_CONTAINER
UINT32 pidLimit;

@ -40,21 +40,92 @@ extern "C" {
#endif /* __cplusplus */
#endif /* __cplusplus */
<<<<<<< HEAD
/**
* @ingroup los_err
* Define the error magic word.
*/
#define OS_ERR_MAGIC_WORD 0xa1b2c3f8
/**
* @ingroup los_err
* @brief Error handling macro capable of returning error codes.
*
* @par Description:
* This API is used to call the error handling function by using an error code and return the same error code.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param errNo [IN] Error code.
*
* @retval errNo
* @par Dependency:
* <ul><li>los_err_pri.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
=======
#define OS_ERR_MAGIC_WORD 0xa1b2c3f8
>>>>>>> remotes/origin/main
#define OS_RETURN_ERROR(errNo) do { \
(VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, errNo, 0, NULL); \
return errNo; \
} while (0)
<<<<<<< HEAD
/**
* @ingroup los_err
* @brief Error handling macro capable of returning error codes.
*
* @par Description:
* This API is used to call the error handling function by using an error code and the line number of
* the erroneous line, and return the same error code.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param errLine [IN] Line number of the erroneous line.
* @param errNo [IN] Error code.
*
* @retval errNo
* @par Dependency:
* <ul><li>los_err_pri.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
=======
>>>>>>> remotes/origin/main
#define OS_RETURN_ERROR_P2(errLine, errNo) do { \
(VOID)LOS_ErrHandle("os_unspecific_file", errLine, errNo, 0, NULL); \
return errNo; \
} while (0)
<<<<<<< HEAD
/**
* @ingroup los_err
* @brief Macro for jumping to error handler.
*
* @par Description:
* This API is used to call the error handling function by using an error code.
* @attention
* <ul>
* <li>None.</li>
* </ul>
*
* @param errorNo [IN] Error code.
*
* @retval None.
* @par Dependency:
* <ul><li>los_err_pri.h: the header file that contains the API declaration.</li></ul>
* @see None.
*/
=======
>>>>>>> remotes/origin/main
#define OS_GOTO_ERR_HANDLER(errorNo) do { \
errNo = errorNo; \
errLine = OS_ERR_MAGIC_WORD; \

@ -33,16 +33,35 @@
#define _LOS_FUTEX_PRI_H
#include "los_list.h"
<<<<<<< HEAD
#define FUTEX_WAIT 0
#define FUTEX_WAKE 1
#define FUTEX_REQUEUE 3
#define FUTEX_WAKE_OP 5
=======
#define FUTEX_WAIT 0 ///< 原子性的检查 uaddr 中计数器的值是否为 val如果是则让任务休眠直到 FUTEX_WAKE 或者超时time-out
//也就是把任务挂到 uaddr 相对应的等待队列上去。
#define FUTEX_WAKE 1 ///< 最多唤醒 val 个等待在 uaddr 上任务。
#define FUTEX_REQUEUE 3 ///< 调整指定锁在Futex表中的位置
#define FUTEX_WAKE_OP 5
>>>>>>> remotes/origin/main
#define FUTEX_LOCK_PI 6
#define FUTEX_UNLOCK_PI 7
#define FUTEX_TRYLOCK_PI 8
#define FUTEX_WAIT_BITSET 9
<<<<<<< HEAD
#define FUTEX_PRIVATE 128
#define FUTEX_MASK 0x3U
typedef struct {
UINTPTR key; /* private:uvaddr shared:paddr */
UINT32 index; /* hash bucket index */
UINT32 pid; /* private:process id shared:OS_INVALID(-1) */
LOS_DL_LIST pendList; /* point to pendList in TCB struct */
LOS_DL_LIST queueList; /* thread list blocked by this lock */
LOS_DL_LIST futexList; /* point to the next FutexNode */
=======
#define FUTEX_PRIVATE 128 //私有快锁(以虚拟地址进行哈希)
#define FUTEX_MASK 0x3U
/// 每个futex node对应一个被挂起的task key值唯一标识一把用户态锁具有相同key值的node被queue_list串联起来表示被同一把锁阻塞的task队列。
@ -54,6 +73,7 @@ typedef struct {
LOS_DL_LIST queueList; /* thread list blocked by this lock | 挂等待这把锁的任务其实这里挂到是FutexNode.queueList ,
queueList pendList , pendList*/
LOS_DL_LIST futexList; /* point to the next FutexNode | 下一把Futex锁*/
>>>>>>> remotes/origin/main
} FutexNode;
extern UINT32 OsFutexInit(VOID);

@ -42,6 +42,15 @@ typedef struct TagQueueCB LosQueueCB;
typedef struct OsMux LosMux;
typedef LosMux pthread_mutex_t;
typedef struct ProcessCB LosProcessCB;
<<<<<<< HEAD
typedef struct IpcContainer {
Atomic rc;
LosQueueCB *allQueue;
LOS_DL_LIST freeQueueList;
fd_set queueFdSet;
struct mqarray queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT];
=======
//IPC容器
typedef struct IpcContainer {
Atomic rc;
@ -49,6 +58,7 @@ typedef struct IpcContainer {
LOS_DL_LIST freeQueueList;//空闲队列链表
fd_set queueFdSet;
struct mqarray queueTable[LOSCFG_BASE_IPC_QUEUE_LIMIT];//队列池
>>>>>>> remotes/origin/main
pthread_mutex_t mqueueMutex;
struct mqpersonal *mqPrivBuf[MAX_MQ_FD];
struct shminfo shmInfo;

@ -42,7 +42,11 @@ extern "C" {
#endif /* __cplusplus */
typedef struct {
<<<<<<< HEAD
UINT32 memUsed;
=======
UINT32 memUsed; ///< 记录任务内存使用量
>>>>>>> remotes/origin/main
} TskMemUsedInfo;
extern VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID);
@ -53,7 +57,11 @@ extern VOID OsTaskMemClear(UINT32 taskID);
#ifdef LOS_MEM_SLAB
typedef struct {
<<<<<<< HEAD
UINT32 slabUsed;
=======
UINT32 slabUsed; ///< 任务占用以slab分配方式内存量
>>>>>>> remotes/origin/main
} TskSlabUsedInfo;
extern VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID);

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:

@ -43,9 +43,15 @@ extern "C" {
#ifdef LOSCFG_KERNEL_SMP
typedef enum {
<<<<<<< HEAD
CPU_RUNNING = 0, /* cpu is running */
CPU_HALT, /* cpu in the halt */
CPU_EXC /* cpu in the exc */
=======
CPU_RUNNING = 0, ///< cpu is running | CPU正在运行状态
CPU_HALT, ///< cpu in the halt | CPU处于暂停状态
CPU_EXC ///< cpu in the exc | CPU处于异常状态
>>>>>>> remotes/origin/main
} ExcFlag;
typedef struct {
@ -55,6 +61,16 @@ typedef struct {
#endif
} Percpu;
<<<<<<< HEAD
/* the kernel per-cpu structure */
extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];
STATIC INLINE Percpu *OsPercpuGet(VOID)
{
return &g_percpu[ArchCurrCpuid()];
}
=======
/*! the kernel per-cpu structure | 每个cpu的内核描述符 */
extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];
/*! 获得当前运行CPU的信息 */
@ -63,6 +79,7 @@ STATIC INLINE Percpu *OsPercpuGet(VOID)
return &g_percpu[ArchCurrCpuid()];
}
/*! 获得参数CPU的信息 */
>>>>>>> remotes/origin/main
STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid)
{
return &g_percpu[cpuid];

@ -38,6 +38,31 @@ typedef struct TagTaskCB LosTaskCB;
typedef struct ProcessCB LosProcessCB;
struct ProcessGroup;
struct Container;
<<<<<<< HEAD
typedef struct {
UINT32 vid; /* Virtual ID */
UINT32 vpid; /* Virtual parent ID */
UINTPTR cb; /* Control block */
LosProcessCB *realParent; /* process real parent */
LOS_DL_LIST node;
} ProcessVid;
#define PID_CONTAINER_LEVEL_LIMIT 3
typedef struct PidContainer {
Atomic rc;
Atomic level;
Atomic lock;
BOOL referenced;
UINT32 containerID;
struct PidContainer *parent;
struct ProcessGroup *rootPGroup;
LOS_DL_LIST tidFreeList;
ProcessVid tidArray[LOSCFG_BASE_CORE_TSK_LIMIT];
LOS_DL_LIST pidFreeList;
ProcessVid pidArray[LOSCFG_BASE_CORE_PROCESS_LIMIT];
=======
//虚拟进程/任务 信息
typedef struct {
UINT32 vid; /* Virtual ID | 虚拟ID*/
@ -61,6 +86,7 @@ typedef struct PidContainer {
ProcessVid tidArray[LOSCFG_BASE_CORE_TSK_LIMIT];//虚拟任务池
LOS_DL_LIST pidFreeList; //进程空闲链表
ProcessVid pidArray[LOSCFG_BASE_CORE_PROCESS_LIMIT];//虚拟进程池
>>>>>>> remotes/origin/main
} PidContainer;
#define OS_PID_CONTAINER_FROM_PCB(processCB) ((processCB)->container->pidContainer)

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -65,6 +69,84 @@ extern "C" {
#ifdef LOSCFG_SECURITY_CAPABILITY
#define OS_GROUPS_NUMBER_MAX 256
<<<<<<< HEAD
typedef struct {
UINT32 userID;
UINT32 effUserID;
UINT32 gid;
UINT32 effGid;
UINT32 groupNumber;
UINT32 groups[1];
} User;
#endif
typedef struct ProcessGroup {
UINTPTR pgroupLeader; /**< Process group leader is the the process that created the group */
LOS_DL_LIST processList; /**< List of processes under this process group */
LOS_DL_LIST exitProcessList; /**< List of closed processes (zombie processes) under this group */
LOS_DL_LIST groupList; /**< Process group list */
} ProcessGroup;
typedef struct ProcessCB {
CHAR processName[OS_PCB_NAME_LEN]; /**< Process name */
UINT32 processID; /**< Process ID */
UINT16 processStatus; /**< [15:4] Process Status; [3:0] The number of threads currently
running in the process */
UINT16 consoleID; /**< The console id of task belongs */
UINT16 processMode; /**< Kernel Mode:0; User Mode:1; */
struct ProcessCB *parentProcess; /**< Parent process */
UINT32 exitCode; /**< Process exit status */
LOS_DL_LIST pendList; /**< Block list to which the process belongs */
LOS_DL_LIST childrenList; /**< Children process list */
LOS_DL_LIST exitChildList; /**< Exit children process list */
LOS_DL_LIST siblingList; /**< Linkage in parent's children list */
ProcessGroup *pgroup; /**< Process group to which a process belongs */
LOS_DL_LIST subordinateGroupList; /**< Linkage in group list */
LosTaskCB *threadGroup;
LOS_DL_LIST threadSiblingList; /**< List of threads under this process */
volatile UINT32 threadNumber; /**< Number of threads alive under this process */
UINT32 threadCount; /**< Total number of threads created under this process */
LOS_DL_LIST waitList; /**< The process holds the waitLits to support wait/waitpid */
#ifdef LOSCFG_KERNEL_SMP
UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */
#endif
UINTPTR sigHandler; /**< Signal handler */
sigset_t sigShare; /**< Signal share bit */
#ifdef LOSCFG_KERNEL_LITEIPC
ProcIpcInfo *ipcInfo; /**< Memory pool for lite ipc */
#endif
#ifdef LOSCFG_KERNEL_VM
LosVmSpace *vmSpace; /**< VMM space for processes */
#endif
#ifdef LOSCFG_FS_VFS
struct files_struct *files; /**< Files held by the process */
#endif
timer_t timerID; /**< ITimer */
#ifdef LOSCFG_SECURITY_CAPABILITY
User *user;
UINT32 capability;
#endif
#ifdef LOSCFG_SECURITY_VID
TimerIdMap timerIdMap;
#endif
#ifdef LOSCFG_DRIVERS_TZDRIVER
struct Vnode *execVnode; /**< Exec bin of the process */
#endif
mode_t umask;
#ifdef LOSCFG_KERNEL_CPUP
OsCpupBase *processCpup; /**< Process cpu usage */
#endif
struct rlimit *resourceLimit;
#ifdef LOSCFG_KERNEL_CONTAINER
Container *container;
#ifdef LOSCFG_USER_CONTAINER
struct Credentials *credentials;
#endif
#endif
#ifdef LOSCFG_PROC_PROCESS_DIR
struct ProcDirEntry *procDir;
=======
/*! 用户描述体*/
typedef struct {
UINT32 userID; ///<用户ID [0,60000],0为root用户
@ -145,6 +227,7 @@ typedef struct ProcessCB {
#endif
#ifdef LOSCFG_PROC_PROCESS_DIR
struct ProcDirEntry *procDir; ///< 目录文件项
>>>>>>> remotes/origin/main
#endif
#ifdef LOSCFG_KERNEL_PLIMITS
ProcLimiterSet *plimits;
@ -165,8 +248,13 @@ extern UINT32 g_processMaxNum;
#define OS_PCB_FROM_TCB(taskCB) ((LosProcessCB *)((taskCB)->processCB))
#define OS_PCB_FROM_TID(taskID) ((LosProcessCB *)(OS_TCB_FROM_TID(taskID)->processCB))
#define OS_GET_PGROUP_LEADER(pgroup) ((LosProcessCB *)((pgroup)->pgroupLeader))
<<<<<<< HEAD
#define OS_PCB_FROM_SIBLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, siblingList)
#define OS_PCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, pendList)
=======
#define OS_PCB_FROM_SIBLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, siblingList)///< 通过siblingList节点找到 LosProcessCB
#define OS_PCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY((ptr), LosProcessCB, pendList) ///< 通过pendlist节点找到 LosProcessCB
>>>>>>> remotes/origin/main
/**
* @ingroup los_process
@ -206,7 +294,11 @@ extern UINT32 g_processMaxNum;
*
* The process is run out but the resources occupied by the process are not recovered.
*/
<<<<<<< HEAD
#define OS_PROCESS_STATUS_ZOMBIES 0x0100U
=======
#define OS_PROCESS_STATUS_ZOMBIES 0x0100U ///< 进程状态: 僵死
>>>>>>> remotes/origin/main
/**
* @ingroup los_process
@ -215,7 +307,11 @@ extern UINT32 g_processMaxNum;
* The process status equal this is process control block unused,
* coexisting with OS_PROCESS_STATUS_ZOMBIES means that the control block is not recovered.
*/
<<<<<<< HEAD
#define OS_PROCESS_FLAG_UNUSED 0x0200U
=======
#define OS_PROCESS_FLAG_UNUSED 0x0200U ///< 进程未使用标签,一般用于进程的初始状态 freelist里面都是这种标签
>>>>>>> remotes/origin/main
/**
* @ingroup los_process
@ -223,7 +319,11 @@ extern UINT32 g_processMaxNum;
*
* The process has been call exit, it only works with multiple cores.
*/
<<<<<<< HEAD
#define OS_PROCESS_FLAG_EXIT 0x0400U
=======
#define OS_PROCESS_FLAG_EXIT 0x0400U ///< 进程退出标签,退出的进程进入回收链表等待回收资源
>>>>>>> remotes/origin/main
/**
* @ingroup los_process
@ -231,7 +331,11 @@ extern UINT32 g_processMaxNum;
*
* The process is the leader of the process group.
*/
<<<<<<< HEAD
#define OS_PROCESS_FLAG_GROUP_LEADER 0x0800U
=======
#define OS_PROCESS_FLAG_GROUP_LEADER 0x0800U ///< 进程当了进程组领导标签
>>>>>>> remotes/origin/main
/**
* @ingroup los_process
@ -239,21 +343,34 @@ extern UINT32 g_processMaxNum;
*
* The process has performed the exec operation.
*/
<<<<<<< HEAD
#define OS_PROCESS_FLAG_ALREADY_EXEC 0x1000U
=======
#define OS_PROCESS_FLAG_ALREADY_EXEC 0x1000U ///< 进程已执行exec操作 load elf时使用
>>>>>>> remotes/origin/main
/**
* @ingroup los_process
* Flag that indicates the process or process control block status.
*
* The process is dying or already dying.
<<<<<<< HEAD
*/
#define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES)
=======
*/ /// 进程不活跃状态定义: 身上贴有退出便签且状态为僵死的进程
#define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES)
>>>>>>> remotes/origin/main
/**
* @ingroup los_process
* Used to check if the process control block is unused.
*/
<<<<<<< HEAD
STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)
=======
STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)//查下进程是否还在使用?
>>>>>>> remotes/origin/main
{
return ((processCB->processStatus & OS_PROCESS_FLAG_UNUSED) != 0);
}
@ -261,8 +378,13 @@ STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)//查下进
/**
* @ingroup los_process
* Used to check if the process is inactive.
<<<<<<< HEAD
*/
STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)
=======
*/ /// 进程不活跃函数定义:身上贴有不使用且不活跃标签的进程
STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)//查下进程是否不活跃?
>>>>>>> remotes/origin/main
{
return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_INACTIVE)) != 0);
}
@ -270,8 +392,13 @@ STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)//查下进
/**
* @ingroup los_process
* Used to check if the process is dead.
<<<<<<< HEAD
*/
STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)
=======
*/ /// 进程死啦死啦的定义: 身上贴有不使用且状态为僵死的进程
STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)//查下进程是否死啦死啦滴?
>>>>>>> remotes/origin/main
{
return ((processCB->processStatus & OS_PROCESS_STATUS_ZOMBIES) != 0);
}
@ -286,6 +413,62 @@ STATIC INLINE BOOL OsProcessIsPGroupLeader(const LosProcessCB *processCB)
return ((processCB->processStatus & OS_PROCESS_FLAG_GROUP_LEADER) != 0);
}
<<<<<<< HEAD
/**
* @ingroup los_process
* The highest priority of a kernel mode process.
*/
#define OS_PROCESS_PRIORITY_HIGHEST 0
/**
* @ingroup los_process
* The lowest priority of a kernel mode process
*/
#define OS_PROCESS_PRIORITY_LOWEST 31
/**
* @ingroup los_process
* The highest priority of a user mode process.
*/
#define OS_USER_PROCESS_PRIORITY_HIGHEST 10
/**
* @ingroup los_process
* The lowest priority of a user mode process
*/
#define OS_USER_PROCESS_PRIORITY_LOWEST OS_PROCESS_PRIORITY_LOWEST
/**
* @ingroup los_process
* User state root process default priority
*/
#define OS_PROCESS_USERINIT_PRIORITY 28
/**
* @ingroup los_process
* ID of the kernel idle process
*/
#define OS_KERNEL_IDLE_PROCESS_ID 0U
/**
* @ingroup los_process
* ID of the user root process
*/
#define OS_USER_ROOT_PROCESS_ID 1U
/**
* @ingroup los_process
* ID of the kernel root process
*/
#define OS_KERNEL_ROOT_PROCESS_ID 2U
#define OS_TASK_DEFAULT_STACK_SIZE 0x2000
#define OS_USER_TASK_SYSCALL_STACK_SIZE 0x3000
#define OS_USER_TASK_STACK_SIZE 0x100000
#define OS_KERNEL_MODE 0x0U
#define OS_USER_MODE 0x1U
=======
#define OS_PROCESS_PRIORITY_HIGHEST 0 ///< 进程最高优先级
@ -316,14 +499,21 @@ STATIC INLINE BOOL OsProcessIsPGroupLeader(const LosProcessCB *processCB)
#define OS_KERNEL_MODE 0x0U ///< 内核态
#define OS_USER_MODE 0x1U ///< 用户态
/*! 用户态进程*/
>>>>>>> remotes/origin/main
STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
{
return (processCB->processMode == OS_USER_MODE);
}
<<<<<<< HEAD
#define LOS_PRIO_PROCESS 0U
#define LOS_PRIO_PGRP 1U
#define LOS_PRIO_USER 2U
=======
#define LOS_PRIO_PROCESS 0U ///< 进程标识
#define LOS_PRIO_PGRP 1U ///< 进程组标识
#define LOS_PRIO_USER 2U ///< 用户标识
>>>>>>> remotes/origin/main
#define OS_USER_PRIVILEGE_PROCESS_GROUP ((UINTPTR)OsGetUserInitProcess())
#define OS_KERNEL_PROCESS_GROUP ((UINTPTR)OsGetKernelInitProcess())
@ -333,6 +523,25 @@ STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
* 31 15 8 7 0
* | | exit code | core dump | signal |
*/
<<<<<<< HEAD
#define OS_PRO_EXIT_OK 0
STATIC INLINE VOID OsProcessExitCodeCoreDumpSet(LosProcessCB *processCB)
{
processCB->exitCode |= 0x80U;
}
STATIC INLINE VOID OsProcessExitCodeSignalSet(LosProcessCB *processCB, UINT32 signal)
{
processCB->exitCode |= signal & 0x7FU;
}
STATIC INLINE VOID OsProcessExitCodeSignalClear(LosProcessCB *processCB)
{
processCB->exitCode &= (~0x7FU);
}
=======
#define OS_PRO_EXIT_OK 0 ///< 进程正常退出
/// 置进程退出码第七位为1
STATIC INLINE VOID OsProcessExitCodeCoreDumpSet(LosProcessCB *processCB)
@ -350,23 +559,36 @@ STATIC INLINE VOID OsProcessExitCodeSignalClear(LosProcessCB *processCB)
processCB->exitCode &= (~0x7FU);// 低7位全部清0
}
/// 进程退出码是否被设置过,默认是 0 ,如果 & 0x7FU 还是 0 ,说明没有被设置过.
>>>>>>> remotes/origin/main
STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB)
{
return (processCB->exitCode) & 0x7FU;
}
<<<<<<< HEAD
=======
/// 设置进程退出号(8 ~ 15)
>>>>>>> remotes/origin/main
STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code)
{
processCB->exitCode |= ((code & 0x000000FFU) << 8U) & 0x0000FF00U; /* 8: Move 8 bits to the left, exitCode */
}
#define OS_PID_CHECK_INVALID(pid) (((UINT32)(pid)) >= g_processMaxNum)
<<<<<<< HEAD
=======
/*! 内联函数 进程ID是否有效 */
>>>>>>> remotes/origin/main
STATIC INLINE BOOL OsProcessIDUserCheckInvalid(UINT32 pid)
{
return ((pid >= g_processMaxNum) || (pid == 0));
}
<<<<<<< HEAD
=======
/*! 获取当前进程PCB */
>>>>>>> remotes/origin/main
STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID)
{
UINT32 intSave;
@ -378,7 +600,10 @@ STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID)
}
#ifdef LOSCFG_SECURITY_CAPABILITY
<<<<<<< HEAD
=======
/*! 获取当前进程的所属用户 */
>>>>>>> remotes/origin/main
STATIC INLINE User *OsCurrUserGet(VOID)
{
User *user = NULL;
@ -450,14 +675,22 @@ STATIC INLINE UINT32 OsGetRootPid(const LosProcessCB *processCB)
/*
* return immediately if no child has exited.
*/
<<<<<<< HEAD
#define LOS_WAIT_WNOHANG (1 << 0U)
=======
#define LOS_WAIT_WNOHANG (1 << 0U) ///< 如果没有孩子进程退出,则立即返回,而不是阻塞在这个函数上等待;如果结束了,则返回该子进程的进程号。
>>>>>>> remotes/origin/main
/*
* return if a child has stopped (but not traced via ptrace(2)).
* Status for traced children which have stopped is provided even
* if this option is not specified.
*/
<<<<<<< HEAD
#define LOS_WAIT_WUNTRACED (1 << 1U)
=======
#define LOS_WAIT_WUNTRACED (1 << 1U) ///< 如果子进程进入暂停情况则马上返回不予以理会结束状态。untraced
>>>>>>> remotes/origin/main
#define LOS_WAIT_WSTOPPED (1 << 1U)
/*
@ -469,7 +702,11 @@ STATIC INLINE UINT32 OsGetRootPid(const LosProcessCB *processCB)
* return if a stopped child has been resumed by delivery of SIGCONT.
* (For Linux-only options, see below.)
*/
<<<<<<< HEAD
#define LOS_WAIT_WCONTINUED (1 << 3U)
=======
#define LOS_WAIT_WCONTINUED (1 << 3U) ///< 可获取子进程恢复执行的状态也就是可获取continued状态 continued
>>>>>>> remotes/origin/main
/*
* Leave the child in a waitable state;
@ -480,21 +717,44 @@ STATIC INLINE UINT32 OsGetRootPid(const LosProcessCB *processCB)
/*
* Indicates that you are already in a wait state
*/
<<<<<<< HEAD
#define OS_PROCESS_WAIT (1 << 15U)
=======
#define OS_PROCESS_WAIT (1 << 15U) ///< 表示已经处于等待状态
>>>>>>> remotes/origin/main
/*
* Wait for any child process to finish
*/
<<<<<<< HEAD
#define OS_PROCESS_WAIT_ANY OS_TASK_WAIT_ANYPROCESS
=======
#define OS_PROCESS_WAIT_ANY OS_TASK_WAIT_ANYPROCESS ///< 等待任意子进程完成
>>>>>>> remotes/origin/main
/*
* Wait for the child process specified by the pid to finish
*/
<<<<<<< HEAD
#define OS_PROCESS_WAIT_PRO OS_TASK_WAIT_PROCESS
=======
#define OS_PROCESS_WAIT_PRO OS_TASK_WAIT_PROCESS ///< 等待pid指定的子进程完成
>>>>>>> remotes/origin/main
/*
* Waits for any child process in the specified process group to finish.
*/
<<<<<<< HEAD
#define OS_PROCESS_WAIT_GID OS_TASK_WAIT_GID
#define OS_PROCESS_INFO_ALL 1
#define OS_PROCESS_DEFAULT_UMASK 0022
extern UINTPTR __user_init_entry;
extern UINTPTR __user_init_bss;
extern UINTPTR __user_init_end;
extern UINTPTR __user_init_load_addr;
=======
#define OS_PROCESS_WAIT_GID OS_TASK_WAIT_GID ///< 等待指定进程组中的任意子进程完成
#define OS_PROCESS_INFO_ALL 1
@ -504,6 +764,7 @@ extern UINTPTR __user_init_entry; ///< 第一个用户态进程(init)的入口
extern UINTPTR __user_init_bss; ///< 查看 LITE_USER_SEC_BSS ,赋值由liteos.ld完成
extern UINTPTR __user_init_end; ///< init 进程的用户空间初始化结束地址
extern UINTPTR __user_init_load_addr;///< init 进程的加载地址 ,由链接器赋值
>>>>>>> remotes/origin/main
extern UINT32 OsProcessInit(VOID);
extern UINT32 OsSystemProcessCreate(VOID);
extern VOID OsProcessNaturalExit(LosProcessCB *processCB, UINT32 status);

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -40,7 +44,10 @@
#include "los_exc.h"
#endif
<<<<<<< HEAD
=======
/// 初始化一个事件控制块
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
{
UINT32 intSave;
@ -49,6 +56,16 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
return LOS_ERRNO_EVENT_PTR_NULL;
}
<<<<<<< HEAD
intSave = LOS_IntLock();
eventCB->uwEventID = 0;
LOS_ListInit(&eventCB->stEventList);
LOS_IntRestore(intSave);
OsHookCall(LOS_HOOK_TYPE_EVENT_INIT, eventCB);
return LOS_OK;
}
=======
intSave = LOS_IntLock();//锁中断
eventCB->uwEventID = 0;//事件类型初始化
LOS_ListInit(&eventCB->stEventList);//事件链表初始化
@ -57,6 +74,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
return LOS_OK;
}
///事件参数检查
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMask, UINT32 mode)
{
if (ptr == NULL) {
@ -78,11 +96,26 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMa
}
return LOS_OK;
}
<<<<<<< HEAD
=======
///根据用户传入的事件值、事件掩码及校验模式,返回用户传入的事件是否符合预期
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode)
{
UINT32 ret = 0;
<<<<<<< HEAD
LOS_ASSERT(OsIntLocked());
LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));
if (mode & LOS_WAITMODE_OR) {
if ((*eventID & eventMask) != 0) {
ret = *eventID & eventMask;
}
} else {
if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) {
=======
LOS_ASSERT(OsIntLocked());//断言不允许中断了
LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));//任务自旋锁
@ -92,27 +125,54 @@ LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mo
}
} else {//等待全部事件发生
if ((eventMask != 0) && (eventMask == (*eventID & eventMask))) {//必须满足全部事件发生
>>>>>>> remotes/origin/main
ret = *eventID & eventMask;
}
}
<<<<<<< HEAD
if (ret && (mode & LOS_WAITMODE_CLR)) {
=======
if (ret && (mode & LOS_WAITMODE_CLR)) {//读取完成后清除事件
>>>>>>> remotes/origin/main
*eventID = *eventID & ~ret;
}
return ret;
}
<<<<<<< HEAD
=======
///检查读事件
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode)
{
UINT32 ret;
LosTaskCB *runTask = NULL;
<<<<<<< HEAD
ret = OsEventParamCheck(eventCB, eventMask, mode);
=======
ret = OsEventParamCheck(eventCB, eventMask, mode);//事件参数检查
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
return ret;
}
<<<<<<< HEAD
if (OS_INT_ACTIVE) {
return LOS_ERRNO_EVENT_READ_IN_INTERRUPT;
}
runTask = OsCurrTaskGet();
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
OsBackTrace();
return LOS_ERRNO_EVENT_READ_IN_SYSTEM_TASK;
}
return LOS_OK;
}
=======
if (OS_INT_ACTIVE) {//中断正在进行
return LOS_ERRNO_EVENT_READ_IN_INTERRUPT;//不能在中断发送时读事件
}
@ -125,6 +185,7 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT3
return LOS_OK;
}
/// 读取指定事件类型的实现函数超时时间为相对时间单位为Tick
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode,
UINT32 timeout, BOOL once)
{
@ -133,6 +194,24 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM
OsHookCall(LOS_HOOK_TYPE_EVENT_READ, eventCB, eventMask, mode, timeout);
if (once == FALSE) {
<<<<<<< HEAD
ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode);
}
if (ret == 0) {
if (timeout == 0) {
return ret;
}
if (!OsPreemptableInSched()) {
return LOS_ERRNO_EVENT_READ_IN_LOCK;
}
runTask->eventMask = eventMask;
runTask->eventMode = mode;
runTask->taskEvent = eventCB;
OsTaskWaitSetPendMask(OS_TASK_WAIT_EVENT, eventMask, timeout);
=======
ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode);//检测事件是否符合预期
}
@ -149,28 +228,56 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventM
runTask->eventMode = mode; //事件模式
runTask->taskEvent = eventCB; //事件控制块
OsTaskWaitSetPendMask(OS_TASK_WAIT_EVENT, eventMask, timeout);//任务进入等待状态,等待事件的到来并设置时长和掩码
>>>>>>> remotes/origin/main
ret = runTask->ops->wait(runTask, &eventCB->stEventList, timeout);
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
return LOS_ERRNO_EVENT_READ_TIMEOUT;
}
<<<<<<< HEAD
ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode);
}
return ret;
}
=======
ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode);//检测事件是否符合预期
}
return ret;
}
///读取指定事件类型超时时间为相对时间单位为Tick
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout,
BOOL once)
{
UINT32 ret;
UINT32 intSave;
<<<<<<< HEAD
ret = OsEventReadCheck(eventCB, eventMask, mode);
=======
ret = OsEventReadCheck(eventCB, eventMask, mode);//读取事件检查
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
return ret;
}
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
ret = OsEventReadImp(eventCB, eventMask, mode, timeout, once);
SCHEDULER_UNLOCK(intSave);
return ret;
}
LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT_CB_S eventCB, UINT32 events)
{
UINT8 exitFlag = 0;
if (((resumedTask->eventMode & LOS_WAITMODE_OR) && ((resumedTask->eventMask & events) != 0)) ||
((resumedTask->eventMode & LOS_WAITMODE_AND) &&
((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) {
exitFlag = 1;
=======
ret = OsEventReadImp(eventCB, eventMask, mode, timeout, once);//读事件实现函数
SCHEDULER_UNLOCK(intSave);
return ret;
@ -184,6 +291,7 @@ LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT
((resumedTask->eventMode & LOS_WAITMODE_AND) &&
((resumedTask->eventMask & eventCB->uwEventID) == resumedTask->eventMask))) {//逻辑与 和 逻辑或 的处理
exitFlag = 1;
>>>>>>> remotes/origin/main
resumedTask->taskEvent = NULL;
OsTaskWakeClearPendMask(resumedTask);
@ -192,13 +300,39 @@ LITE_OS_SEC_TEXT STATIC UINT8 OsEventResume(LosTaskCB *resumedTask, const PEVENT
return exitFlag;
}
<<<<<<< HEAD
=======
///以不安全的方式写事件
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag)
{
LosTaskCB *resumedTask = NULL;
LosTaskCB *nextTask = NULL;
BOOL schedFlag = FALSE;
OsHookCall(LOS_HOOK_TYPE_EVENT_WRITE, eventCB, events);
<<<<<<< HEAD
eventCB->uwEventID |= events;
if (!LOS_ListEmpty(&eventCB->stEventList)) {
for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList);
&resumedTask->pendList != &eventCB->stEventList;) {
nextTask = LOS_DL_LIST_ENTRY(resumedTask->pendList.pstNext, LosTaskCB, pendList);
if (OsEventResume(resumedTask, eventCB, events)) {
schedFlag = TRUE;
}
if (once == TRUE) {
break;
}
resumedTask = nextTask;
}
}
if ((exitFlag != NULL) && (schedFlag == TRUE)) {
*exitFlag = 1;
}
}
=======
eventCB->uwEventID |= events;//对应位贴上标签
if (!LOS_ListEmpty(&eventCB->stEventList)) {//等待事件链表判断,处理等待事件的任务
for (resumedTask = LOS_DL_LIST_ENTRY((&eventCB->stEventList)->pstNext, LosTaskCB, pendList);
@ -219,6 +353,7 @@ LITE_OS_SEC_TEXT VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOO
}
}
///写入事件
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once)
{
UINT32 intSave;
@ -232,6 +367,19 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events,
return LOS_ERRNO_EVENT_SETBIT_INVALID;
}
<<<<<<< HEAD
SCHEDULER_LOCK(intSave);
OsEventWriteUnsafe(eventCB, events, once, &exitFlag);
SCHEDULER_UNLOCK(intSave);
if (exitFlag == 1) {
LOS_MpSchedule(OS_MP_CPU_ALL);
LOS_Schedule();
}
return LOS_OK;
}
=======
SCHEDULER_LOCK(intSave); //禁止调度
OsEventWriteUnsafe(eventCB, events, once, &exitFlag);//写入事件
SCHEDULER_UNLOCK(intSave); //允许调度
@ -243,43 +391,72 @@ LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events,
return LOS_OK;
}
///根据用户传入的事件值、事件掩码及校验模式,返回用户传入的事件是否符合预期
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode)
{
UINT32 ret;
UINT32 intSave;
<<<<<<< HEAD
=======
//事件参数检查
>>>>>>> remotes/origin/main
ret = OsEventParamCheck((VOID *)eventID, eventMask, mode);
if (ret != LOS_OK) {
return ret;
}
<<<<<<< HEAD
SCHEDULER_LOCK(intSave);
=======
SCHEDULER_LOCK(intSave);//申请任务自旋锁
>>>>>>> remotes/origin/main
ret = OsEventPoll(eventID, eventMask, mode);
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
///读取指定事件类型超时时间为相对时间单位为Tick
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
{
return OsEventRead(eventCB, eventMask, mode, timeout, FALSE);
}
<<<<<<< HEAD
=======
///写指定的事件类型
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
{
return OsEventWrite(eventCB, events, FALSE);
}
<<<<<<< HEAD
=======
///只读一次事件
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode,
UINT32 timeout)
{
return OsEventRead(eventCB, eventMask, mode, timeout, TRUE);
}
<<<<<<< HEAD
=======
///只写一次事件
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events)
{
return OsEventWrite(eventCB, events, TRUE);
}
<<<<<<< HEAD
=======
///销毁指定的事件控制块
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
{
UINT32 intSave;
@ -300,7 +477,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
OsHookCall(LOS_HOOK_TYPE_EVENT_DESTROY, eventCB);
return LOS_OK;
}
<<<<<<< HEAD
=======
///清除指定的事件类型
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMask)
{
UINT32 intSave;
@ -315,7 +496,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 eventMa
return LOS_OK;
}
<<<<<<< HEAD
=======
///有条件式读事件
>>>>>>> remotes/origin/main
#ifdef LOSCFG_COMPAT_POSIX
LITE_OS_SEC_TEXT UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB,
UINT32 eventMask, UINT32 mode, UINT32 timeout)

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -43,6 +47,30 @@
#ifdef LOSCFG_KERNEL_VM
<<<<<<< HEAD
#define OS_FUTEX_FROM_FUTEXLIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, futexList)
#define OS_FUTEX_FROM_QUEUELIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, queueList)
#define OS_FUTEX_KEY_BASE USER_ASPACE_BASE
#define OS_FUTEX_KEY_MAX (USER_ASPACE_BASE + USER_ASPACE_SIZE)
/* private: 0~63 hash index_num
* shared: 64~79 hash index_num */
#define FUTEX_INDEX_PRIVATE_MAX 64
#define FUTEX_INDEX_SHARED_MAX 16
#define FUTEX_INDEX_MAX (FUTEX_INDEX_PRIVATE_MAX + FUTEX_INDEX_SHARED_MAX)
#define FUTEX_INDEX_SHARED_POS FUTEX_INDEX_PRIVATE_MAX
#define FUTEX_HASH_PRIVATE_MASK (FUTEX_INDEX_PRIVATE_MAX - 1)
#define FUTEX_HASH_SHARED_MASK (FUTEX_INDEX_SHARED_MAX - 1)
typedef struct {
LosMux listLock;
LOS_DL_LIST lockList;
} FutexHash;
FutexHash g_futexHash[FUTEX_INDEX_MAX];
=======
#define OS_FUTEX_FROM_FUTEXLIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, futexList) // 通过快锁节点找到结构体
#define OS_FUTEX_FROM_QUEUELIST(ptr) LOS_DL_LIST_ENTRY(ptr, FutexNode, queueList) // 通过队列节点找到结构体
#define OS_FUTEX_KEY_BASE USER_ASPACE_BASE ///< 进程用户空间基址
@ -67,6 +95,7 @@ typedef struct {
FutexHash g_futexHash[FUTEX_INDEX_MAX];///< 80个哈希桶
/// 对互斥锁封装
>>>>>>> remotes/origin/main
STATIC INT32 OsFutexLock(LosMux *lock)
{
UINT32 ret = LOS_MuxLock(lock, LOS_WAIT_FOREVER);
@ -86,15 +115,26 @@ STATIC INT32 OsFutexUnlock(LosMux *lock)
}
return LOS_OK;
}
<<<<<<< HEAD
=======
///< 初始化Futex(Fast userspace mutex用户态快速互斥锁)模块
>>>>>>> remotes/origin/main
UINT32 OsFutexInit(VOID)
{
INT32 count;
UINT32 ret;
<<<<<<< HEAD
for (count = 0; count < FUTEX_INDEX_MAX; count++) {
LOS_ListInit(&g_futexHash[count].lockList);
ret = LOS_MuxInit(&(g_futexHash[count].listLock), NULL);
=======
// 初始化 80个哈希桶
for (count = 0; count < FUTEX_INDEX_MAX; count++) {
LOS_ListInit(&g_futexHash[count].lockList); // 初始化双向链表,上面挂 FutexNode
ret = LOS_MuxInit(&(g_futexHash[count].listLock), NULL);//初始化互斥锁
>>>>>>> remotes/origin/main
if (ret) {
return ret;
}
@ -103,7 +143,11 @@ UINT32 OsFutexInit(VOID)
return LOS_OK;
}
<<<<<<< HEAD
LOS_MODULE_INIT(OsFutexInit, LOS_INIT_LEVEL_KMOD_EXTENDED);
=======
LOS_MODULE_INIT(OsFutexInit, LOS_INIT_LEVEL_KMOD_EXTENDED);///< 注册Futex模块
>>>>>>> remotes/origin/main
#ifdef LOS_FUTEX_DEBUG
STATIC VOID OsFutexShowTaskNodeAttr(const LOS_DL_LIST *futexList)
@ -154,19 +198,41 @@ VOID OsFutexHashShow(VOID)
}
}
#endif
<<<<<<< HEAD
=======
/// 通过用户空间地址获取哈希key
>>>>>>> remotes/origin/main
STATIC INLINE UINTPTR OsFutexFlagsToKey(const UINT32 *userVaddr, const UINT32 flags)
{
UINTPTR futexKey;
if (flags & FUTEX_PRIVATE) {
<<<<<<< HEAD
futexKey = (UINTPTR)userVaddr;
} else {
futexKey = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr);
=======
futexKey = (UINTPTR)userVaddr;//私有锁(以虚拟地址进行哈希)
} else {
futexKey = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr);//共享锁(以物理地址进行哈希)
>>>>>>> remotes/origin/main
}
return futexKey;
}
<<<<<<< HEAD
STATIC INLINE UINT32 OsFutexKeyToIndex(const UINTPTR futexKey, const UINT32 flags)
{
UINT32 index = LOS_HashFNV32aBuf(&futexKey, sizeof(UINTPTR), FNV1_32A_INIT);
if (flags & FUTEX_PRIVATE) {
index &= FUTEX_HASH_PRIVATE_MASK;
} else {
index &= FUTEX_HASH_SHARED_MASK;
index += FUTEX_INDEX_SHARED_POS;
=======
/// 通过哈希key获取索引
STATIC INLINE UINT32 OsFutexKeyToIndex(const UINTPTR futexKey, const UINT32 flags)
{
@ -177,10 +243,21 @@ STATIC INLINE UINT32 OsFutexKeyToIndex(const UINTPTR futexKey, const UINT32 flag
} else {
index &= FUTEX_HASH_SHARED_MASK;
index += FUTEX_INDEX_SHARED_POS;//共享锁索引,将index锁定在 64 ~ 79号
>>>>>>> remotes/origin/main
}
return index;
}
<<<<<<< HEAD
STATIC INLINE VOID OsFutexSetKey(UINTPTR futexKey, UINT32 flags, FutexNode *node)
{
node->key = futexKey;
node->index = OsFutexKeyToIndex(futexKey, flags);
node->pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID;
}
=======
/// 设置快锁哈希key
STATIC INLINE VOID OsFutexSetKey(UINTPTR futexKey, UINT32 flags, FutexNode *node)
{
@ -189,12 +266,26 @@ STATIC INLINE VOID OsFutexSetKey(UINTPTR futexKey, UINT32 flags, FutexNode *node
node->pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID;//获取进程ID,共享快锁时 快锁节点没有进程ID
}
//析构参数节点
>>>>>>> remotes/origin/main
STATIC INLINE VOID OsFutexDeinitFutexNode(FutexNode *node)
{
node->index = OS_INVALID_VALUE;
node->pid = 0;
LOS_ListDelete(&node->queueList);
}
<<<<<<< HEAD
STATIC INLINE VOID OsFutexReplaceQueueListHeadNode(FutexNode *oldHeadNode, FutexNode *newHeadNode)
{
LOS_DL_LIST *futexList = oldHeadNode->futexList.pstPrev;
LOS_ListDelete(&oldHeadNode->futexList);
LOS_ListHeadInsert(futexList, &newHeadNode->futexList);
if ((newHeadNode->queueList.pstNext == NULL) || (newHeadNode->queueList.pstPrev == NULL)) {
LOS_ListInit(&newHeadNode->queueList);
}
}
=======
/// 新旧两个节点交换 futexList 位置
STATIC INLINE VOID OsFutexReplaceQueueListHeadNode(FutexNode *oldHeadNode, FutexNode *newHeadNode)
{
@ -206,11 +297,16 @@ STATIC INLINE VOID OsFutexReplaceQueueListHeadNode(FutexNode *oldHeadNode, Futex
}
}
/// 将参数节点从futexList上摘除
>>>>>>> remotes/origin/main
STATIC INLINE VOID OsFutexDeleteKeyFromFutexList(FutexNode *node)
{
LOS_ListDelete(&node->futexList);
}
<<<<<<< HEAD
=======
/// 从哈希桶中删除快锁节点
>>>>>>> remotes/origin/main
STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags)
{
FutexNode *nextNode = NULL;
@ -219,8 +315,13 @@ STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, Fut
return;
}
<<<<<<< HEAD
if (LOS_ListEmpty(&node->queueList)) {
OsFutexDeleteKeyFromFutexList(node);
=======
if (LOS_ListEmpty(&node->queueList)) {//如果没有任务在等锁
OsFutexDeleteKeyFromFutexList(node);//从快锁链表上摘除
>>>>>>> remotes/origin/main
if (queueFlags != NULL) {
*queueFlags = TRUE;
}
@ -228,10 +329,17 @@ STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, Fut
}
/* FutexList is not NULL, but the header node of queueList */
<<<<<<< HEAD
if (node->futexList.pstNext != NULL) {
if (isDeleteHead == TRUE) {
nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&node->queueList));
OsFutexReplaceQueueListHeadNode(node, nextNode);
=======
if (node->futexList.pstNext != NULL) {//是头节点
if (isDeleteHead == TRUE) {//是否要删除头节点
nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&node->queueList));//取出第一个快锁节点
OsFutexReplaceQueueListHeadNode(node, nextNode);//两个节点交换位置
>>>>>>> remotes/origin/main
if (headNode != NULL) {
*headNode = nextNode;
}
@ -244,22 +352,38 @@ EXIT:
OsFutexDeinitFutexNode(node);
return;
}
<<<<<<< HEAD
VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags)
{
FutexHash *hashNode = NULL;
=======
/// 从哈希桶上删除快锁
VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags)
{
FutexHash *hashNode = NULL;
//通过key找到桶号
>>>>>>> remotes/origin/main
UINT32 index = OsFutexKeyToIndex(node->key, (node->pid == OS_INVALID) ? 0 : FUTEX_PRIVATE);
if (index >= FUTEX_INDEX_MAX) {
return;
}
<<<<<<< HEAD
hashNode = &g_futexHash[index];
=======
hashNode = &g_futexHash[index];//找到hash桶
>>>>>>> remotes/origin/main
if (OsMuxLockUnsafe(&hashNode->listLock, LOS_WAIT_FOREVER)) {
return;
}
<<<<<<< HEAD
if (node->index != index) {
=======
if (node->index != index) {//快锁节点桶号需和哈希桶号一致
>>>>>>> remotes/origin/main
goto EXIT;
}
@ -272,6 +396,10 @@ EXIT:
return;
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
STATIC FutexNode *OsFutexDeleteAlreadyWakeTaskAndGetNext(const FutexNode *node, FutexNode **headNode, BOOL isDeleteHead)
{
FutexNode *tempNode = (FutexNode *)node;
@ -293,7 +421,11 @@ STATIC FutexNode *OsFutexDeleteAlreadyWakeTaskAndGetNext(const FutexNode *node,
return tempNode;
}
<<<<<<< HEAD
=======
/// 插入一把新Futex锁到哈希桶中,只有是新的key时才会插入,因为其实存在多个FutexNode是一个key
>>>>>>> remotes/origin/main
STATIC VOID OsFutexInsertNewFutexKeyToHash(FutexNode *node)
{
FutexNode *headNode = NULL;
@ -323,16 +455,27 @@ STATIC VOID OsFutexInsertNewFutexKeyToHash(FutexNode *node)
futexList != &(hashNode->lockList);
futexList = futexList->pstNext) {
headNode = OS_FUTEX_FROM_FUTEXLIST(futexList);
<<<<<<< HEAD
if (node->key <= headNode->key) {
LOS_ListTailInsert(&(headNode->futexList), &(node->futexList));
break;
}
=======
if (node->key <= headNode->key) {
LOS_ListTailInsert(&(headNode->futexList), &(node->futexList));
break;
}
>>>>>>> remotes/origin/main
}
EXIT:
return;
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
STATIC INT32 OsFutexInsertFindFormBackToFront(LOS_DL_LIST *queueList, const LosTaskCB *runTask, FutexNode *node)
{
LOS_DL_LIST *listHead = queueList;
@ -408,15 +551,49 @@ STATIC INT32 OsFutexRecycleAndFindHeadNode(FutexNode *headNode, FutexNode *node,
return LOS_OK;
}
<<<<<<< HEAD
STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node, const LosTaskCB *run)
{
LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&((*firstNode)->pendList)));
=======
///< 将快锁挂到任务的阻塞链表上
STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node, const LosTaskCB *run)
{
LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&((*firstNode)->pendList)));//获取阻塞链表首个任务
>>>>>>> remotes/origin/main
LOS_DL_LIST *queueList = &((*firstNode)->queueList);
INT32 ret1 = OsSchedParamCompare(run, taskHead);
if (ret1 < 0) {
/* The one with the highest priority is inserted at the top of the queue */
<<<<<<< HEAD
LOS_ListTailInsert(queueList, &(node->queueList));
OsFutexReplaceQueueListHeadNode(*firstNode, node);
*firstNode = node;
return LOS_OK;
}
if (LOS_ListEmpty(queueList) && (ret1 >= 0)) {
/* Insert the next position in the queue with equal priority */
LOS_ListHeadInsert(queueList, &(node->queueList));
return LOS_OK;
}
FutexNode *tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList));
LosTaskCB *taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tailNode->pendList)));
INT32 ret2 = OsSchedParamCompare(taskTail, run);
if ((ret2 <= 0) || (ret1 > ret2)) {
return OsFutexInsertFindFormBackToFront(queueList, run, node);
}
return OsFutexInsertFindFromFrontToBack(queueList, run, node);
}
STATIC FutexNode *OsFindFutexNode(const FutexNode *node)
{
FutexHash *hashNode = &g_futexHash[node->index];
=======
LOS_ListTailInsert(queueList, &(node->queueList));//查到queueList的尾部
OsFutexReplaceQueueListHeadNode(*firstNode, node);//同时交换futexList链表上的位置
*firstNode = node;
@ -442,20 +619,34 @@ STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node,
STATIC FutexNode *OsFindFutexNode(const FutexNode *node)
{
FutexHash *hashNode = &g_futexHash[node->index];//先找到所在哈希桶
>>>>>>> remotes/origin/main
LOS_DL_LIST *futexList = &(hashNode->lockList);
FutexNode *headNode = NULL;
for (futexList = futexList->pstNext;
<<<<<<< HEAD
futexList != &(hashNode->lockList);
futexList = futexList->pstNext) {
headNode = OS_FUTEX_FROM_FUTEXLIST(futexList);
if ((headNode->key == node->key) && (headNode->pid == node->pid)) {
return headNode;
}
=======
futexList != &(hashNode->lockList);//判断循环结束条件,相等时说明跑完一轮了
futexList = futexList->pstNext) {
headNode = OS_FUTEX_FROM_FUTEXLIST(futexList);//拿到快锁节点实体
if ((headNode->key == node->key) && (headNode->pid == node->pid)) {//已经存在这个节点,注意这里的比较
return headNode;//是key和pid 一起比较,因为只有这样才能确定唯一性
>>>>>>> remotes/origin/main
}
return NULL;
}
<<<<<<< HEAD
=======
///< 查找快锁并插入哈希桶中
>>>>>>> remotes/origin/main
STATIC INT32 OsFindAndInsertToHash(FutexNode *node)
{
FutexNode *headNode = NULL;
@ -464,7 +655,11 @@ STATIC INT32 OsFindAndInsertToHash(FutexNode *node)
INT32 ret;
headNode = OsFindFutexNode(node);
<<<<<<< HEAD
if (headNode == NULL) {
=======
if (headNode == NULL) {//没有找到,说明这是一把新锁
>>>>>>> remotes/origin/main
OsFutexInsertNewFutexKeyToHash(node);
LOS_ListInit(&(node->queueList));
return LOS_OK;
@ -483,14 +678,23 @@ STATIC INT32 OsFindAndInsertToHash(FutexNode *node)
return ret;
}
<<<<<<< HEAD
=======
/// 共享内存检查
>>>>>>> remotes/origin/main
STATIC INT32 OsFutexKeyShmPermCheck(const UINT32 *userVaddr, const UINT32 flags)
{
PADDR_T paddr;
/* Check whether the futexKey is a shared lock */
<<<<<<< HEAD
if (!(flags & FUTEX_PRIVATE)) {
paddr = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr);
=======
if (!(flags & FUTEX_PRIVATE)) {//非私有快锁
paddr = (UINTPTR)LOS_PaddrQuery((UINT32 *)userVaddr);//能否查询到物理地址
>>>>>>> remotes/origin/main
if (paddr == 0) return LOS_NOK;
}
@ -549,6 +753,15 @@ STATIC INT32 OsFutexDeleteTimeoutTaskNode(FutexHash *hashNode, FutexNode *node)
}
return LOS_ETIMEDOUT;
}
<<<<<<< HEAD
STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const UINTPTR futexKey, const UINT32 flags)
{
INT32 ret;
*taskCB = OsCurrTaskGet();
*node = &((*taskCB)->futex);
OsFutexSetKey(futexKey, flags, *node);
=======
/// 将快锁节点插入任务
STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const UINTPTR futexKey, const UINT32 flags)
{
@ -556,6 +769,7 @@ STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const
*taskCB = OsCurrTaskGet(); //获取当前任务
*node = &((*taskCB)->futex); //获取当前任务的快锁节点
OsFutexSetKey(futexKey, flags, *node);//设置参数 key index pid
>>>>>>> remotes/origin/main
ret = OsFindAndInsertToHash(*node);
if (ret) {
@ -565,13 +779,28 @@ STATIC INT32 OsFutexInsertTaskToHash(LosTaskCB **taskCB, FutexNode **node, const
LOS_ListInit(&((*node)->pendList));
return LOS_OK;
}
<<<<<<< HEAD
=======
/// 将当前任务挂入等待链表中
>>>>>>> remotes/origin/main
STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const UINT32 val, const UINT32 timeout)
{
INT32 futexRet;
UINT32 intSave, lockVal;
LosTaskCB *taskCB = NULL;
FutexNode *node = NULL;
<<<<<<< HEAD
UINTPTR futexKey = OsFutexFlagsToKey(userVaddr, flags);
UINT32 index = OsFutexKeyToIndex(futexKey, flags);
FutexHash *hashNode = &g_futexHash[index];
if (OsFutexLock(&hashNode->listLock)) {
return LOS_EINVAL;
}
if (LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32))) {
=======
UINTPTR futexKey = OsFutexFlagsToKey(userVaddr, flags);//通过地址和flags 找到 key
UINT32 index = OsFutexKeyToIndex(futexKey, flags);//通过key找到哈希桶
FutexHash *hashNode = &g_futexHash[index];
@ -581,17 +810,27 @@ STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const
}
//userVaddr必须是用户空间虚拟地址
if (LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32))) {//将值拷贝到内核空间
>>>>>>> remotes/origin/main
PRINT_ERR("Futex wait param check failed! copy from user failed!\n");
futexRet = LOS_EINVAL;
goto EXIT_ERR;
}
<<<<<<< HEAD
if (lockVal != val) {
futexRet = LOS_EBADF;
goto EXIT_ERR;
}
if (OsFutexInsertTaskToHash(&taskCB, &node, futexKey, flags)) {
=======
if (lockVal != val) {//对参数内部逻辑检查
futexRet = LOS_EBADF;
goto EXIT_ERR;
}
//注意第二个参数 FutexNode *node = NULL
if (OsFutexInsertTaskToHash(&taskCB, &node, futexKey, flags)) {// node = taskCB->futex
>>>>>>> remotes/origin/main
futexRet = LOS_NOK;
goto EXIT_ERR;
}
@ -602,7 +841,11 @@ STATIC INT32 OsFutexWaitTask(const UINT32 *userVaddr, const UINT32 flags, const
taskCB->ops->wait(taskCB, &(node->pendList), timeout);
LOS_SpinUnlock(&g_taskSpin);
<<<<<<< HEAD
futexRet = OsFutexUnlock(&hashNode->listLock);
=======
futexRet = OsFutexUnlock(&hashNode->listLock);//
>>>>>>> remotes/origin/main
if (futexRet) {
OsSchedUnlock();
LOS_IntRestore(intSave);
@ -632,12 +875,27 @@ EXIT_ERR:
EXIT_UNLOCK_ERR:
return futexRet;
}
<<<<<<< HEAD
=======
/// 设置线程等待 | 向Futex表中插入代表被阻塞的线程的node
>>>>>>> remotes/origin/main
INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime)
{
INT32 ret;
UINT32 timeout = LOS_WAIT_FOREVER;
<<<<<<< HEAD
ret = OsFutexWaitParamCheck(userVaddr, flags, absTime);
if (ret) {
return ret;
}
if (absTime != LOS_WAIT_FOREVER) {
timeout = OsNS2Tick((UINT64)absTime * OS_SYS_NS_PER_US);
}
return OsFutexWaitTask(userVaddr, flags, val, timeout);
=======
ret = OsFutexWaitParamCheck(userVaddr, flags, absTime);//参数检查
if (ret) {
return ret;
@ -647,6 +905,7 @@ INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absT
}
return OsFutexWaitTask(userVaddr, flags, val, timeout);//将任务挂起 timeOut 时长
>>>>>>> remotes/origin/main
}
STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags)
@ -657,12 +916,20 @@ STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags)
PRINT_ERR("Futex wake param check failed! error flags: 0x%x\n", flags);
return LOS_EINVAL;
}
<<<<<<< HEAD
=======
//地址必须在用户空间
>>>>>>> remotes/origin/main
if ((vaddr % sizeof(INT32)) || (vaddr < OS_FUTEX_KEY_BASE) || (vaddr >= OS_FUTEX_KEY_MAX)) {
PRINT_ERR("Futex wake param check failed! error userVaddr: 0x%x\n", userVaddr);
return LOS_EINVAL;
}
<<<<<<< HEAD
=======
//必须得是个共享内存地址
>>>>>>> remotes/origin/main
if (flags && (OsFutexKeyShmPermCheck(userVaddr, flags) != LOS_OK)) {
PRINT_ERR("Futex wake param check failed! error shared memory perm userVaddr: 0x%x\n", userVaddr);
return LOS_EINVAL;
@ -672,8 +939,12 @@ STATIC INT32 OsFutexWakeParamCheck(const UINT32 *userVaddr, UINT32 flags)
}
/* Check to see if the task to be awakened has timed out
<<<<<<< HEAD
* if time out, to weak next pend task.
=======
* if time out, to weak next pend task.
* | ,
>>>>>>> remotes/origin/main
*/
STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNumber,
FutexHash *hashNode, FutexNode **nextNode, BOOL *wakeAny)
@ -708,7 +979,10 @@ STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNum
}
return;
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, FutexNode **newHeadNode, BOOL *wakeAny)
{
@ -717,13 +991,21 @@ STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, F
FutexNode *headNode = NULL;
UINT32 index = OsFutexKeyToIndex(futexKey, flags);
FutexHash *hashNode = &g_futexHash[index];
<<<<<<< HEAD
FutexNode tempNode = {
=======
FutexNode tempNode = { //先组成一个临时快锁节点,目的是为了找到哈希桶中是否有这个节点
>>>>>>> remotes/origin/main
.key = futexKey,
.index = index,
.pid = (flags & FUTEX_PRIVATE) ? LOS_GetCurrProcessID() : OS_INVALID,
};
<<<<<<< HEAD
node = OsFindFutexNode(&tempNode);
=======
node = OsFindFutexNode(&tempNode);//找快锁节点
>>>>>>> remotes/origin/main
if (node == NULL) {
return LOS_EBADF;
}
@ -731,7 +1013,11 @@ STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, F
headNode = node;
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
OsFutexCheckAndWakePendTask(headNode, wakeNumber, hashNode, newHeadNode, wakeAny);
=======
OsFutexCheckAndWakePendTask(headNode, wakeNumber, hashNode, newHeadNode, wakeAny);//再找到等这把锁的唤醒指向数量的任务
>>>>>>> remotes/origin/main
if ((*newHeadNode) != NULL) {
OsFutexReplaceQueueListHeadNode(headNode, *newHeadNode);
OsFutexDeinitFutexNode(headNode);
@ -743,7 +1029,11 @@ STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, UINT32 flags, INT32 wakeNumber, F
return LOS_OK;
}
<<<<<<< HEAD
=======
/// 唤醒一个被指定锁阻塞的线程
>>>>>>> remotes/origin/main
INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber)
{
INT32 ret, futexRet;
@ -752,11 +1042,19 @@ INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber)
FutexHash *hashNode = NULL;
FutexNode *headNode = NULL;
BOOL wakeAny = FALSE;
<<<<<<< HEAD
if (OsFutexWakeParamCheck(userVaddr, flags)) {
return LOS_EINVAL;
}
=======
//1.检查参数
if (OsFutexWakeParamCheck(userVaddr, flags)) {
return LOS_EINVAL;
}
//2.找到指定用户空间地址对应的桶
>>>>>>> remotes/origin/main
futexKey = OsFutexFlagsToKey(userVaddr, flags);
index = OsFutexKeyToIndex(futexKey, flags);
@ -764,7 +1062,11 @@ INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber)
if (OsFutexLock(&hashNode->listLock)) {
return LOS_EINVAL;
}
<<<<<<< HEAD
=======
//3.换起等待该锁的进程
>>>>>>> remotes/origin/main
ret = OsFutexWakeTask(futexKey, flags, wakeNumber, &headNode, &wakeAny);
if (ret) {
goto EXIT_ERR;
@ -778,7 +1080,11 @@ INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber)
if (futexRet) {
goto EXIT_UNLOCK_ERR;
}
<<<<<<< HEAD
=======
//4.根据指定参数决定是否发起调度
>>>>>>> remotes/origin/main
if (wakeAny == TRUE) {
LOS_MpSchedule(OS_MP_CPU_ALL);
LOS_Schedule();
@ -887,7 +1193,11 @@ STATIC VOID OsFutexRequeueSplitTwoLists(FutexHash *oldHashNode, FutexNode *oldHe
tailNode->queueList.pstNext = &newHeadNode->queueList;
return;
}
<<<<<<< HEAD
=======
/// 删除旧key并获取头节点
>>>>>>> remotes/origin/main
STATIC FutexNode *OsFutexRequeueRemoveOldKeyAndGetHead(UINTPTR oldFutexKey, UINT32 flags, INT32 wakeNumber,
UINTPTR newFutexKey, INT32 requeueCount, BOOL *wakeAny)
{
@ -923,7 +1233,11 @@ STATIC FutexNode *OsFutexRequeueRemoveOldKeyAndGetHead(UINTPTR oldFutexKey, UINT
return oldHeadNode;
}
<<<<<<< HEAD
=======
/// 检查锁在Futex表中的状态
>>>>>>> remotes/origin/main
STATIC INT32 OsFutexRequeueParamCheck(const UINT32 *oldUserVaddr, UINT32 flags, const UINT32 *newUserVaddr)
{
VADDR_T oldVaddr = (VADDR_T)(UINTPTR)oldUserVaddr;
@ -932,12 +1246,20 @@ STATIC INT32 OsFutexRequeueParamCheck(const UINT32 *oldUserVaddr, UINT32 flags,
if (oldVaddr == newVaddr) {
return LOS_EINVAL;
}
<<<<<<< HEAD
=======
//检查标记
>>>>>>> remotes/origin/main
if ((flags & (~FUTEX_PRIVATE)) != FUTEX_REQUEUE) {
PRINT_ERR("Futex requeue param check failed! error flags: 0x%x\n", flags);
return LOS_EINVAL;
}
<<<<<<< HEAD
=======
//检查地址范围,必须在用户空间
>>>>>>> remotes/origin/main
if ((oldVaddr % sizeof(INT32)) || (oldVaddr < OS_FUTEX_KEY_BASE) || (oldVaddr >= OS_FUTEX_KEY_MAX)) {
PRINT_ERR("Futex requeue param check failed! error old userVaddr: 0x%x\n", oldUserVaddr);
return LOS_EINVAL;
@ -950,7 +1272,11 @@ STATIC INT32 OsFutexRequeueParamCheck(const UINT32 *oldUserVaddr, UINT32 flags,
return LOS_OK;
}
<<<<<<< HEAD
=======
/// 调整指定锁在Futex表中的位置
>>>>>>> remotes/origin/main
INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, INT32 count, const UINT32 *newUserVaddr)
{
INT32 ret;
@ -967,12 +1293,21 @@ INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, IN
return LOS_EINVAL;
}
<<<<<<< HEAD
oldFutexKey = OsFutexFlagsToKey(userVaddr, flags);
newFutexKey = OsFutexFlagsToKey(newUserVaddr, flags);
oldIndex = OsFutexKeyToIndex(oldFutexKey, flags);
newIndex = OsFutexKeyToIndex(newFutexKey, flags);
oldHashNode = &g_futexHash[oldIndex];
=======
oldFutexKey = OsFutexFlagsToKey(userVaddr, flags);//先拿key
newFutexKey = OsFutexFlagsToKey(newUserVaddr, flags);
oldIndex = OsFutexKeyToIndex(oldFutexKey, flags);//再拿所在哈希桶位置,共有80个哈希桶
newIndex = OsFutexKeyToIndex(newFutexKey, flags);
oldHashNode = &g_futexHash[oldIndex];//拿到对应哈希桶实体
>>>>>>> remotes/origin/main
if (OsFutexLock(&oldHashNode->listLock)) {
return LOS_EINVAL;
}

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -40,19 +44,32 @@
#ifdef LOSCFG_BASE_IPC_MUX
#define MUTEXATTR_TYPE_MASK 0x0FU
<<<<<<< HEAD
=======
///互斥属性初始化
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrInit(LosMuxAttr *attr)
{
if (attr == NULL) {
return LOS_EINVAL;
}
<<<<<<< HEAD
attr->protocol = LOS_MUX_PRIO_INHERIT;
attr->prioceiling = OS_TASK_PRIORITY_LOWEST;
attr->type = LOS_MUX_DEFAULT;
return LOS_OK;
}
=======
attr->protocol = LOS_MUX_PRIO_INHERIT; //协议默认用继承方式, A(4)task等B(19)释放锁时,B的调度优先级直接升到(4)
attr->prioceiling = OS_TASK_PRIORITY_LOWEST;//最低优先级
attr->type = LOS_MUX_DEFAULT; //默认 LOS_MUX_RECURSIVE
return LOS_OK;
}
/// ????? 销毁互斥属 ,这里啥也没干呀
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr)
{
if (attr == NULL) {
@ -61,7 +78,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr)
return LOS_OK;
}
<<<<<<< HEAD
=======
///获取互斥锁的类型属性,由outType接走,不送!
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType)
{
INT32 type;
@ -79,7 +100,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outTyp
return LOS_OK;
}
<<<<<<< HEAD
=======
///设置互斥锁的类型属性
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type)
{
if ((attr == NULL) || (type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) {
@ -89,7 +114,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type)
attr->type = (UINT8)((attr->type & ~MUTEXATTR_TYPE_MASK) | (UINT32)type);
return LOS_OK;
}
<<<<<<< HEAD
=======
///获取互斥锁的类型属性
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol)
{
if ((attr != NULL) && (protocol != NULL)) {
@ -100,7 +129,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *pr
return LOS_OK;
}
<<<<<<< HEAD
=======
///设置互斥锁属性的协议
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol)
{
if (attr == NULL) {
@ -117,7 +150,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol)
return LOS_EINVAL;
}
}
<<<<<<< HEAD
=======
///获取互斥锁属性优先级
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling)
{
if (attr == NULL) {
@ -130,7 +167,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32
return LOS_OK;
}
<<<<<<< HEAD
=======
///设置互斥锁属性的优先级的上限
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling)
{
if ((attr == NULL) ||
@ -143,7 +184,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioce
return LOS_OK;
}
<<<<<<< HEAD
=======
///设置互斥锁的优先级的上限,老优先级由oldPrioceiling带走
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling)
{
INT32 ret;
@ -172,7 +217,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling,
return ret;
}
<<<<<<< HEAD
=======
///获取互斥锁的优先级的上限
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling)
{
if ((mutex != NULL) && (prioceiling != NULL) && (mutex->magic == OS_MUX_MAGIC)) {
@ -182,7 +231,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioce
return LOS_EINVAL;
}
<<<<<<< HEAD
=======
///互斥锁是否有效
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex)
{
if ((mutex != NULL) && (mutex->magic == OS_MUX_MAGIC)) {
@ -191,7 +244,11 @@ LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex)
return FALSE;
}
<<<<<<< HEAD
=======
///检查互斥锁属性是否OK,否则 no ok :|)
>>>>>>> remotes/origin/main
STATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr)
{
if (((INT8)(attr->type) < LOS_MUX_NORMAL) || (attr->type > LOS_MUX_ERRORCHECK)) {
@ -205,7 +262,11 @@ STATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr)
}
return LOS_OK;
}
<<<<<<< HEAD
=======
/// 初始化互斥锁
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
{
UINT32 intSave;
@ -215,6 +276,26 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
}
if (attr == NULL) {
<<<<<<< HEAD
(VOID)LOS_MuxAttrInit(&mutex->attr);
} else {
(VOID)memcpy_s(&mutex->attr, sizeof(LosMuxAttr), attr, sizeof(LosMuxAttr));
}
if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {
return LOS_EINVAL;
}
SCHEDULER_LOCK(intSave);
mutex->muxCount = 0;
mutex->owner = NULL;
LOS_ListInit(&mutex->muxList);
mutex->magic = OS_MUX_MAGIC;
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
=======
(VOID)LOS_MuxAttrInit(&mutex->attr);//属性初始化
} else {
(VOID)memcpy_s(&mutex->attr, sizeof(LosMuxAttr), attr, sizeof(LosMuxAttr));//把attr 拷贝到 mutex->attr
@ -233,6 +314,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
return LOS_OK;
}
///销毁互斥锁
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
{
UINT32 intSave;
@ -241,13 +323,30 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
return LOS_EINVAL;
}
<<<<<<< HEAD
SCHEDULER_LOCK(intSave);
if (mutex->magic != OS_MUX_MAGIC) {
SCHEDULER_UNLOCK(intSave);
=======
SCHEDULER_LOCK(intSave); //保存调度自旋锁
if (mutex->magic != OS_MUX_MAGIC) {
SCHEDULER_UNLOCK(intSave);//释放调度自旋锁
>>>>>>> remotes/origin/main
return LOS_EBADF;
}
if (mutex->muxCount != 0) {
<<<<<<< HEAD
SCHEDULER_UNLOCK(intSave);
return LOS_EBUSY;
}
(VOID)memset_s(mutex, sizeof(LosMux), 0, sizeof(LosMux));
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
=======
SCHEDULER_UNLOCK(intSave);//释放调度自旋锁
return LOS_EBUSY;
}
@ -257,6 +356,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
return LOS_OK;
}
///设置互斥锁位图
>>>>>>> remotes/origin/main
STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask)
{
if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) {
@ -271,7 +371,11 @@ STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask)
owner->ops->priorityInheritance(owner, &param);
}
}
<<<<<<< HEAD
=======
///恢复互斥锁位图
>>>>>>> remotes/origin/main
VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosTaskCB *runTask)
{
if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) {
@ -284,11 +388,26 @@ VOID OsMuxBitmapRestore(const LosMux *mutex, const LOS_DL_LIST *list, const LosT
owner->ops->priorityRestore(owner, list, &param);
}
<<<<<<< HEAD
=======
/// 最坏情况就是拿锁失败,让出CPU,变成阻塞任务,等别的任务释放锁后排到自己了接着执行.
>>>>>>> remotes/origin/main
STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
{
UINT32 ret;
<<<<<<< HEAD
if ((mutex->muxList.pstPrev == NULL) || (mutex->muxList.pstNext == NULL)) {
/* This is for mutex macro initialization. */
mutex->muxCount = 0;
mutex->owner = NULL;
LOS_ListInit(&mutex->muxList);
}
if (mutex->muxCount == 0) {
mutex->muxCount++;
mutex->owner = (VOID *)runTask;
=======
if ((mutex->muxList.pstPrev == NULL) || (mutex->muxList.pstNext == NULL)) {//列表为空时的处理
/* This is for mutex macro initialization. */
mutex->muxCount = 0;//锁计数器清0
@ -299,6 +418,7 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
if (mutex->muxCount == 0) {//无task用锁时,肯定能拿到锁了.在里面返回
mutex->muxCount++; //互斥锁计数器加1
mutex->owner = (VOID *)runTask; //当前任务拿到锁
>>>>>>> remotes/origin/main
LOS_ListTailInsert(&runTask->lockList, &mutex->holdList);
if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) {
SchedParam param = { 0 };
@ -308,6 +428,25 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
}
return LOS_OK;
}
<<<<<<< HEAD
if (((LosTaskCB *)mutex->owner == runTask) && (mutex->attr.type == LOS_MUX_RECURSIVE)) {
mutex->muxCount++;
return LOS_OK;
}
if (!timeout) {
return LOS_EINVAL;
}
if (!OsPreemptableInSched()) {
return LOS_EDEADLK;
}
OsMuxBitmapSet(mutex, runTask);
runTask->taskMux = (VOID *)mutex;
=======
//递归锁muxCount>0 如果是递归锁就要处理两种情况 1.runtask持有锁 2.锁被别的任务拿走了
if (((LosTaskCB *)mutex->owner == runTask) && (mutex->attr.type == LOS_MUX_RECURSIVE)) {//第一种情况 runtask是锁持有方
mutex->muxCount++; //递归锁计数器加1,递归锁的目的是防止死锁,鸿蒙默认用的就是递归锁(LOS_MUX_DEFAULT = LOS_MUX_RECURSIVE)
@ -325,6 +464,7 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
OsMuxBitmapSet(mutex, runTask);//设置锁位图,尽可能的提高锁持有任务的优先级
runTask->taskMux = (VOID *)mutex; //记下当前任务在等待这把锁
>>>>>>> remotes/origin/main
LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &mutex->muxList);
if (node == NULL) {
ret = LOS_NOK;
@ -333,10 +473,17 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
OsTaskWaitSetPendMask(OS_TASK_WAIT_MUTEX, (UINTPTR)mutex, timeout);
ret = runTask->ops->wait(runTask, node, timeout);
<<<<<<< HEAD
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
OsMuxBitmapRestore(mutex, NULL, runTask);
runTask->taskMux = NULL;
ret = LOS_ETIMEDOUT;
=======
if (ret == LOS_ERRNO_TSK_TIMEOUT) {//这行代码虽和OsTaskWait挨在一起,但要过很久才会执行到,因为在OsTaskWait中CPU切换了任务上下文
OsMuxBitmapRestore(mutex, NULL, runTask);
runTask->taskMux = NULL;// 所以重新回到这里时可能已经超时了
ret = LOS_ETIMEDOUT;//返回超时
>>>>>>> remotes/origin/main
}
return ret;
@ -344,7 +491,11 @@ STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout)
{
<<<<<<< HEAD
LosTaskCB *runTask = OsCurrTaskGet();
=======
LosTaskCB *runTask = OsCurrTaskGet();//获取当前任务
>>>>>>> remotes/origin/main
if (mutex->magic != OS_MUX_MAGIC) {
return LOS_EBADF;
@ -353,13 +504,29 @@ UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout)
if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {
return LOS_EINVAL;
}
<<<<<<< HEAD
=======
//LOS_MUX_ERRORCHECK 时 muxCount是要等于0 ,当前任务持有锁就不能再lock了. 鸿蒙默认用的是递归锁LOS_MUX_RECURSIVE
>>>>>>> remotes/origin/main
if ((mutex->attr.type == LOS_MUX_ERRORCHECK) && (mutex->owner == (VOID *)runTask)) {
return LOS_EDEADLK;
}
return OsMuxPendOp(runTask, mutex, timeout);
}
<<<<<<< HEAD
UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout)
{
LosTaskCB *runTask = OsCurrTaskGet();
if (mutex->magic != OS_MUX_MAGIC) {
return LOS_EBADF;
}
if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {
=======
/// 尝试加锁,
UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout)
{
@ -370,6 +537,7 @@ UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout)
}
if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {//检查互斥锁属性
>>>>>>> remotes/origin/main
return LOS_EINVAL;
}
@ -378,9 +546,15 @@ UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout)
return LOS_EBUSY;
}
<<<<<<< HEAD
return OsMuxPendOp(runTask, mutex, timeout);
}
=======
return OsMuxPendOp(runTask, mutex, timeout);//当前任务去拿锁,拿不到就等timeout
}
/// 拿互斥锁,
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
{
LosTaskCB *runTask = NULL;
@ -395,6 +569,21 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
return LOS_EINTR;
}
<<<<<<< HEAD
runTask = (LosTaskCB *)OsCurrTaskGet();
/* DO NOT Call blocking API in system tasks */
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__);
OsBackTrace();
}
SCHEDULER_LOCK(intSave);
ret = OsMuxLockUnsafe(mutex, timeout);
SCHEDULER_UNLOCK(intSave);
return ret;
}
=======
runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前任务
/* DO NOT Call blocking API in system tasks */
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//不要在内核任务里用mux锁
@ -408,6 +597,7 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
return ret;
}
///尝试要锁,没拿到也不等,直接返回,不纠结
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex)
{
LosTaskCB *runTask = NULL;
@ -422,28 +612,59 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex)
return LOS_EINTR;
}
<<<<<<< HEAD
runTask = (LosTaskCB *)OsCurrTaskGet();
/* DO NOT Call blocking API in system tasks */
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
=======
runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前执行的任务
/* DO NOT Call blocking API in system tasks */
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//系统任务不能
>>>>>>> remotes/origin/main
PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__);
OsBackTrace();
}
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
ret = OsMuxTrylockUnsafe(mutex, 0);
=======
ret = OsMuxTrylockUnsafe(mutex, 0);//timeout = 0,不等待,没拿到锁就算了
>>>>>>> remotes/origin/main
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
{
if (LOS_ListEmpty(&mutex->muxList)) {
LOS_ListDelete(&mutex->holdList);
=======
STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
{
if (LOS_ListEmpty(&mutex->muxList)) {//如果互斥锁列表为空
LOS_ListDelete(&mutex->holdList);//把持有互斥锁的节点摘掉
>>>>>>> remotes/origin/main
mutex->owner = NULL;
return LOS_OK;
}
<<<<<<< HEAD
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList)));
OsMuxBitmapRestore(mutex, &mutex->muxList, resumedTask);
mutex->muxCount = 1;
mutex->owner = (VOID *)resumedTask;
LOS_ListDelete(&mutex->holdList);
LOS_ListTailInsert(&resumedTask->lockList, &mutex->holdList);
OsTaskWakeClearPendMask(resumedTask);
resumedTask->ops->wake(resumedTask);
resumedTask->taskMux = NULL;
if (needSched != NULL) {
*needSched = TRUE;
=======
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList)));//拿到等待互斥锁链表的第一个任务实体,接下来要唤醒任务
OsMuxBitmapRestore(mutex, &mutex->muxList, resumedTask);
@ -456,6 +677,7 @@ STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
resumedTask->taskMux = NULL;
if (needSched != NULL) {//如果不为空
*needSched = TRUE;//就走起再次调度流程
>>>>>>> remotes/origin/main
}
return LOS_OK;
@ -478,21 +700,37 @@ UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
if (mutex->muxCount == 0) {
return LOS_EPERM;
}
<<<<<<< HEAD
if ((--mutex->muxCount != 0) && (mutex->attr.type == LOS_MUX_RECURSIVE)) {
return LOS_OK;
}
if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) {
=======
//注意 --mutex->muxCount 先执行了-- 操作.
if ((--mutex->muxCount != 0) && (mutex->attr.type == LOS_MUX_RECURSIVE)) {//属性类型为LOS_MUX_RECURSIVE时,muxCount是可以不为0的
return LOS_OK;
}
if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) {//属性协议为保护时
>>>>>>> remotes/origin/main
SchedParam param = { 0 };
taskCB->ops->schedParamGet(taskCB, &param);
taskCB->ops->priorityRestore(taskCB, NULL, &param);
}
<<<<<<< HEAD
/* Whether a task block the mutex lock. */
return OsMuxPostOp(taskCB, mutex, needSched);
}
=======
/* Whether a task block the mutex lock. *///任务是否阻塞互斥锁
return OsMuxPostOp(taskCB, mutex, needSched);//一个任务去唤醒另一个在等锁的任务
}
///释放锁
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
{
LosTaskCB *runTask = NULL;
@ -508,9 +746,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
return LOS_EINTR;
}
<<<<<<< HEAD
runTask = (LosTaskCB *)OsCurrTaskGet();
/* DO NOT Call blocking API in system tasks */
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
=======
runTask = (LosTaskCB *)OsCurrTaskGet();//获取当前任务
/* DO NOT Call blocking API in system tasks */
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {//不能在系统任务里调用,因为很容易让系统任务发生死锁
>>>>>>> remotes/origin/main
PRINTK("Warning: DO NOT call %s in system tasks.\n", __FUNCTION__);
OsBackTrace();
}
@ -518,12 +762,22 @@ LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
SCHEDULER_LOCK(intSave);
ret = OsMuxUnlockUnsafe(runTask, mutex, &needSched);
SCHEDULER_UNLOCK(intSave);
<<<<<<< HEAD
if (needSched == TRUE) {
LOS_MpSchedule(OS_MP_CPU_ALL);
LOS_Schedule();
=======
if (needSched == TRUE) {//需要调度的情况
LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU发送调度指令
LOS_Schedule();//发起调度
>>>>>>> remotes/origin/main
}
return ret;
}
<<<<<<< HEAD
#endif /* LOSCFG_BASE_IPC_MUX */
=======
#endif /* (LOSCFG_BASE_IPC_MUX == YES) */
>>>>>>> remotes/origin/main

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -47,8 +51,13 @@
#endif /* LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0 */
#ifndef LOSCFG_IPC_CONTAINER
<<<<<<< HEAD
LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL;
LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;
=======
LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL;///< 消息队列池
LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;///< 空闲队列链表,管分配的,需要队列从这里申请
>>>>>>> remotes/origin/main
#define FREE_QUEUE_LIST g_freeQueueList
#endif
@ -83,6 +92,13 @@ LITE_OS_SEC_TEXT_INIT LosQueueCB *OsAllQueueCBInit(LOS_DL_LIST *freeQueueList)
return allQueue;
}
<<<<<<< HEAD
/*
* Description : queue initial
* Return : LOS_OK on success or error code on failure
*/
=======
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)
{
#ifndef LOSCFG_IPC_CONTAINER
@ -93,7 +109,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)
#endif
return LOS_OK;
}
<<<<<<< HEAD
=======
///创建一个队列,根据用户传入队列长度和消息节点大小来开辟相应的内存空间以供该队列使用参数queueID带走队列ID
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 *queueID,
UINT32 flags, UINT16 maxMsgSize)
{
@ -110,7 +130,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32
return LOS_ERRNO_QUEUE_CREAT_PTR_NULL;
}
<<<<<<< HEAD
if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) {
=======
if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) {// maxMsgSize上限 为啥要减去 sizeof(UINT32) ,因为前面存的是队列的大小
>>>>>>> remotes/origin/main
return LOS_ERRNO_QUEUE_SIZE_TOO_BIG;
}
@ -118,6 +142,61 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32
return LOS_ERRNO_QUEUE_PARA_ISZERO;
}
<<<<<<< HEAD
msgSize = maxMsgSize + sizeof(UINT32);
/*
* Memory allocation is time-consuming, to shorten the time of disable interrupt,
* move the memory allocation to here.
*/
queue = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, (UINT32)len * msgSize);
if (queue == NULL) {
return LOS_ERRNO_QUEUE_CREATE_NO_MEMORY;
}
SCHEDULER_LOCK(intSave);
if (LOS_ListEmpty(&FREE_QUEUE_LIST)) {
SCHEDULER_UNLOCK(intSave);
OsQueueCheckHook();
(VOID)LOS_MemFree(m_aucSysMem1, queue);
return LOS_ERRNO_QUEUE_CB_UNAVAILABLE;
}
unusedQueue = LOS_DL_LIST_FIRST(&FREE_QUEUE_LIST);
LOS_ListDelete(unusedQueue);
queueCB = GET_QUEUE_LIST(unusedQueue);
queueCB->queueLen = len;
queueCB->queueSize = msgSize;
queueCB->queueHandle = queue;
queueCB->queueState = OS_QUEUE_INUSED;
queueCB->readWriteableCnt[OS_QUEUE_READ] = 0;
queueCB->readWriteableCnt[OS_QUEUE_WRITE] = len;
queueCB->queueHead = 0;
queueCB->queueTail = 0;
LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_READ]);
LOS_ListInit(&queueCB->readWriteList[OS_QUEUE_WRITE]);
LOS_ListInit(&queueCB->memList);
OsQueueDbgUpdateHook(queueCB->queueID, OsCurrTaskGet()->taskEntry);
SCHEDULER_UNLOCK(intSave);
*queueID = queueCB->queueID;
OsHookCall(LOS_HOOK_TYPE_QUEUE_CREATE, queueCB);
return LOS_OK;
}
STATIC LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, const VOID *bufferAddr,
const UINT32 *bufferSize, UINT32 timeout)
{
if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
return LOS_ERRNO_QUEUE_INVALID;
}
if ((bufferAddr == NULL) || (bufferSize == NULL)) {
return LOS_ERRNO_QUEUE_READ_PTR_NULL;
}
if ((*bufferSize == 0) || (*bufferSize > (OS_NULL_SHORT - sizeof(UINT32)))) {
return LOS_ERRNO_QUEUE_READSIZE_IS_INVALID;
=======
msgSize = maxMsgSize + sizeof(UINT32);//总size = 消息体内容长度 + 消息大小(UINT32)
/*
* Memory allocation is time-consuming, to shorten the time of disable interrupt,
@ -171,17 +250,39 @@ STATIC LITE_OS_SEC_TEXT UINT32 OsQueueReadParameterCheck(UINT32 queueID, const V
if ((*bufferSize == 0) || (*bufferSize > (OS_NULL_SHORT - sizeof(UINT32)))) {//限制了读取数据的上限64K, sizeof(UINT32)代表的是队列的长度
return LOS_ERRNO_QUEUE_READSIZE_IS_INVALID; //所以要减去
>>>>>>> remotes/origin/main
}
OsQueueDbgTimeUpdateHook(queueID);
<<<<<<< HEAD
if (timeout != LOS_NO_WAIT) {
if (OS_INT_ACTIVE) {
return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT;
=======
if (timeout != LOS_NO_WAIT) {//等待一定时间再读取
if (OS_INT_ACTIVE) {//如果碰上了硬中断
return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT;//意思是:硬中断发生时是不能读消息队列的
>>>>>>> remotes/origin/main
}
}
return LOS_OK;
}
<<<<<<< HEAD
STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const VOID *bufferAddr,
const UINT32 *bufferSize, UINT32 timeout)
{
if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
return LOS_ERRNO_QUEUE_INVALID;
}
if (bufferAddr == NULL) {
return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
}
if (*bufferSize == 0) {
=======
///写队列参数检查
STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const VOID *bufferAddr,
const UINT32 *bufferSize, UINT32 timeout)
@ -195,6 +296,7 @@ STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const
}
if (*bufferSize == 0) {//这里没有限制写队列的大小,如果写入一个很大buf 会怎样?
>>>>>>> remotes/origin/main
return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO;
}
@ -207,13 +309,32 @@ STATIC LITE_OS_SEC_TEXT UINT32 OsQueueWriteParameterCheck(UINT32 queueID, const
}
return LOS_OK;
}
<<<<<<< HEAD
=======
///队列buf操作,注意队列数据是按顺序来读取的,要不从头,要不从尾部,不会出现从中间读写,所有可由 head 和 tail 来管理队列.
>>>>>>> remotes/origin/main
STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize)
{
UINT8 *queueNode = NULL;
UINT32 msgDataSize;
UINT16 queuePosition;
<<<<<<< HEAD
/* get the queue position */
switch (OS_QUEUE_OPERATE_GET(operateType)) {
case OS_QUEUE_READ_HEAD:
queuePosition = queueCB->queueHead;
((queueCB->queueHead + 1) == queueCB->queueLen) ? (queueCB->queueHead = 0) : (queueCB->queueHead++);
break;
case OS_QUEUE_WRITE_HEAD:
(queueCB->queueHead == 0) ? (queueCB->queueHead = queueCB->queueLen - 1) : (--queueCB->queueHead);
queuePosition = queueCB->queueHead;
break;
case OS_QUEUE_WRITE_TAIL:
queuePosition = queueCB->queueTail;
((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++);
=======
/* get the queue position | 先找到队列的位置*/
switch (OS_QUEUE_OPERATE_GET(operateType)) {//获取操作类型
case OS_QUEUE_READ_HEAD://从列队头开始读
@ -227,26 +348,50 @@ STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *
case OS_QUEUE_WRITE_TAIL://从列队尾部开始写
queuePosition = queueCB->queueTail;//设置队列位置为尾部位置
((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++);//调整队列尾部位置
>>>>>>> remotes/origin/main
break;
default: /* read tail, reserved. */
PRINT_ERR("invalid queue operate type!\n");
return;
}
<<<<<<< HEAD
queueNode = &(queueCB->queueHandle[(queuePosition * (queueCB->queueSize))]);
if (OS_QUEUE_IS_READ(operateType)) {
if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32),
sizeof(UINT32)) != EOK) {
=======
//queueHandle是create队列时,由外界参数申请的一块内存. 用于copy 使用
queueNode = &(queueCB->queueHandle[(queuePosition * (queueCB->queueSize))]);//拿到队列节点
if (OS_QUEUE_IS_READ(operateType)) {//读操作处理,读队列分两步走
if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32),
sizeof(UINT32)) != EOK) {//1.先读出队列大小,由队列头四个字节表示
>>>>>>> remotes/origin/main
PRINT_ERR("get msgdatasize failed\n");
return;
}
msgDataSize = (*bufferSize < msgDataSize) ? *bufferSize : msgDataSize;
<<<<<<< HEAD
if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) {
=======
if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) {//2.读表示读走已有数据,所以相当于bufferAddr接着了queueNode的数据
>>>>>>> remotes/origin/main
PRINT_ERR("copy message to buffer failed\n");
return;
}
<<<<<<< HEAD
*bufferSize = msgDataSize;
} else {
if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) {
PRINT_ERR("store message failed\n");
return;
}
if (memcpy_s(queueNode + queueCB->queueSize - sizeof(UINT32), sizeof(UINT32), bufferSize,
sizeof(UINT32)) != EOK) {
=======
*bufferSize = msgDataSize;//通过入参 带走消息的大小
} else {//只有读写两种操作,这里就是写队列了.写也分两步走 , @note_thinking 这里建议鸿蒙加上 OS_QUEUE_IS_WRITE 判断
if (memcpy_s(queueNode, queueCB->queueSize, bufferAddr, *bufferSize) != EOK) {//1.写入消息内容
@ -255,11 +400,24 @@ STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *
}
if (memcpy_s(queueNode + queueCB->queueSize - sizeof(UINT32), sizeof(UINT32), bufferSize,
sizeof(UINT32)) != EOK) {//2.写入消息数据的长度,sizeof(UINT32)
>>>>>>> remotes/origin/main
PRINT_ERR("store message size failed\n");
return;
}
}
}
<<<<<<< HEAD
STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID,
UINT32 operateType, const UINT32 *bufferSize)
{
if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
return LOS_ERRNO_QUEUE_NOT_CREATE;
}
if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {
return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG;
=======
///队列操作参数检查
STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID,
UINT32 operateType, const UINT32 *bufferSize)
@ -270,31 +428,79 @@ STATIC UINT32 OsQueueOperateParamCheck(const LosQueueCB *queueCB, UINT32 queueID
if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {//写时判断
return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG;//塞进来的数据太大,大于队列节点能承受的范围
>>>>>>> remotes/origin/main
}
return LOS_OK;
}
<<<<<<< HEAD
UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout)
{
UINT32 ret;
UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);
=======
UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout)
{
UINT32 ret;
UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);//获取读/写操作标识
>>>>>>> remotes/origin/main
UINT32 intSave;
OsHookCall(LOS_HOOK_TYPE_QUEUE_READ, (LosQueueCB *)GET_QUEUE_HANDLE(queueID), operateType, *bufferSize, timeout);
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize);
=======
LosQueueCB *queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//获取对应的队列控制块
ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize);//参数检查
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
goto QUEUE_END;
}
<<<<<<< HEAD
if (queueCB->readWriteableCnt[readWrite] == 0) {
if (timeout == LOS_NO_WAIT) {
=======
if (queueCB->readWriteableCnt[readWrite] == 0) {//根据readWriteableCnt判断队列是否有消息读/写
if (timeout == LOS_NO_WAIT) {//不等待直接退出
>>>>>>> remotes/origin/main
ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL;
goto QUEUE_END;
}
<<<<<<< HEAD
if (!OsPreemptableInSched()) {
ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK;
goto QUEUE_END;
}
LosTaskCB *runTask = OsCurrTaskGet();
OsTaskWaitSetPendMask(OS_TASK_WAIT_QUEUE, queueCB->queueID, timeout);
ret = runTask->ops->wait(runTask, &queueCB->readWriteList[readWrite], timeout);
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
ret = LOS_ERRNO_QUEUE_TIMEOUT;
goto QUEUE_END;
}
} else {
queueCB->readWriteableCnt[readWrite]--;
}
OsQueueBufferOperate(queueCB, operateType, bufferAddr, bufferSize);
if (!LOS_ListEmpty(&queueCB->readWriteList[!readWrite])) {
LosTaskCB *resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));
OsTaskWakeClearPendMask(resumedTask);
resumedTask->ops->wake(resumedTask);
SCHEDULER_UNLOCK(intSave);
LOS_MpSchedule(OS_MP_CPU_ALL);
LOS_Schedule();
return LOS_OK;
} else {
queueCB->readWriteableCnt[!readWrite]++;
=======
if (!OsPreemptableInSched()) {//不支持抢占式调度
ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK;
goto QUEUE_END;
@ -323,13 +529,18 @@ UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT
return LOS_OK;
} else {
queueCB->readWriteableCnt[!readWrite]++;//对应队列读/写中计数器++
>>>>>>> remotes/origin/main
}
QUEUE_END:
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
///接口函数定时读取消息队列
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID,
VOID *bufferAddr,
UINT32 *bufferSize,
@ -338,15 +549,26 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID,
UINT32 ret;
UINT32 operateType;
<<<<<<< HEAD
ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout);
=======
ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout);//参数检查
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
return ret;
}
<<<<<<< HEAD
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);
return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout);
}
=======
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);//从头开始读
return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout);//定时执行读操作
}
///接口函数从队列头开始写
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID,
VOID *bufferAddr,
UINT32 bufferSize,
@ -355,15 +577,26 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID,
UINT32 ret;
UINT32 operateType;
<<<<<<< HEAD
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
=======
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);//参数检查
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
return ret;
}
<<<<<<< HEAD
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
}
=======
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);//从头开始写
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);//执行写操作
}
///接口函数 从队列尾部开始写
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID,
VOID *bufferAddr,
UINT32 bufferSize,
@ -372,16 +605,27 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID,
UINT32 ret;
UINT32 operateType;
<<<<<<< HEAD
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
=======
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);//参数检查
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
return ret;
}
<<<<<<< HEAD
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
}
=======
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);//从尾部开始写
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);//执行写操作
}
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
{
return LOS_QueueReadCopy(queueID, bufferAddr, &bufferSize, timeout);
@ -396,7 +640,10 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32
return LOS_QueueWriteCopy(queueID, &bufferAddr, bufferSize, timeout);
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID,
VOID *bufferAddr,
UINT32 bufferSize,
@ -409,7 +656,10 @@ LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID,
return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, bufferSize, timeout);
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID)
{
LosQueueCB *queueCB = NULL;
@ -422,33 +672,65 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID)
}
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
=======
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//拿到队列实体
>>>>>>> remotes/origin/main
if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
ret = LOS_ERRNO_QUEUE_NOT_CREATE;
goto QUEUE_END;
}
<<<<<<< HEAD
if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) {
=======
if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) {//尚有任务要读数据
>>>>>>> remotes/origin/main
ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
goto QUEUE_END;
}
<<<<<<< HEAD
if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) {
=======
if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) {//尚有任务要写数据
>>>>>>> remotes/origin/main
ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
goto QUEUE_END;
}
<<<<<<< HEAD
if (!LOS_ListEmpty(&queueCB->memList)) {
=======
if (!LOS_ListEmpty(&queueCB->memList)) {//
>>>>>>> remotes/origin/main
ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
goto QUEUE_END;
}
if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) !=
<<<<<<< HEAD
queueCB->queueLen) {
=======
queueCB->queueLen) {//读写队列的内容长度不等于总长度
>>>>>>> remotes/origin/main
ret = LOS_ERRNO_QUEUE_IN_TSKWRITE;
goto QUEUE_END;
}
<<<<<<< HEAD
queue = queueCB->queueHandle;
queueCB->queueHandle = NULL;
queueCB->queueState = OS_QUEUE_UNUSED;
queueCB->queueID = SET_QUEUE_ID(GET_QUEUE_COUNT(queueCB->queueID) + 1, GET_QUEUE_INDEX(queueCB->queueID));
OsQueueDbgUpdateHook(queueCB->queueID, NULL);
LOS_ListTailInsert(&FREE_QUEUE_LIST, &queueCB->readWriteList[OS_QUEUE_WRITE]);
SCHEDULER_UNLOCK(intSave);
OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB);
ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue);
=======
queue = queueCB->queueHandle; //队列buf
queueCB->queueHandle = NULL; //
queueCB->queueState = OS_QUEUE_UNUSED;//重置队列状态
@ -459,13 +741,18 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID)
SCHEDULER_UNLOCK(intSave);
OsHookCall(LOS_HOOK_TYPE_QUEUE_DELETE, queueCB);
ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue);//释放队列句柄
>>>>>>> remotes/origin/main
return ret;
QUEUE_END:
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
///外部接口, 获取队列信息,用queueInfo 把 LosQueueCB数据接走,QUEUE_INFO_S对内部数据的封装
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo)
{
UINT32 intSave;
@ -477,6 +764,16 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que
return LOS_ERRNO_QUEUE_PTR_NULL;
}
<<<<<<< HEAD
if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
return LOS_ERRNO_QUEUE_INVALID;
}
(VOID)memset_s((VOID *)queueInfo, sizeof(QUEUE_INFO_S), 0, sizeof(QUEUE_INFO_S));
SCHEDULER_LOCK(intSave);
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
=======
if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {//1024
return LOS_ERRNO_QUEUE_INVALID;
}
@ -485,6 +782,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que
SCHEDULER_LOCK(intSave);
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);//通过队列ID获取 QCB
>>>>>>> remotes/origin/main
if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
ret = LOS_ERRNO_QUEUE_NOT_CREATE;
goto QUEUE_END;
@ -495,6 +793,21 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que
queueInfo->usQueueSize = queueCB->queueSize;
queueInfo->usQueueHead = queueCB->queueHead;
queueInfo->usQueueTail = queueCB->queueTail;
<<<<<<< HEAD
queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ];
queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE];
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_READ], LosTaskCB, pendList) {
queueInfo->uwWaitReadTask |= 1ULL << tskCB->taskID;
}
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->readWriteList[OS_QUEUE_WRITE], LosTaskCB, pendList) {
queueInfo->uwWaitWriteTask |= 1ULL << tskCB->taskID;
}
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) {
queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID;
=======
queueInfo->usReadableCnt = queueCB->readWriteableCnt[OS_QUEUE_READ];//可读数
queueInfo->usWritableCnt = queueCB->readWriteableCnt[OS_QUEUE_WRITE];//可写数
@ -508,6 +821,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *que
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &queueCB->memList, LosTaskCB, pendList) {//同上
queueInfo->uwWaitMemTask |= 1ULL << tskCB->taskID; //MailBox模块使用
>>>>>>> remotes/origin/main
}
QUEUE_END:
@ -515,5 +829,9 @@ QUEUE_END:
return ret;
}
<<<<<<< HEAD
#endif /* LOSCFG_BASE_IPC_QUEUE */
=======
#endif /* (LOSCFG_BASE_IPC_QUEUE == YES) */
>>>>>>> remotes/origin/main

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -37,10 +41,16 @@
#include "los_exc.h"
#include "los_sched_pri.h"
<<<<<<< HEAD
#ifdef LOSCFG_BASE_IPC_RWLOCK
#define RWLOCK_COUNT_MASK 0x00FFFFFFU
=======
#ifdef LOSCFG_BASE_IPC_RWLOCK
#define RWLOCK_COUNT_MASK 0x00FFFFFFU
/// 判断读写锁有效性
>>>>>>> remotes/origin/main
BOOL LOS_RwlockIsValid(const LosRwlock *rwlock)
{
if ((rwlock != NULL) && ((rwlock->magic & RWLOCK_COUNT_MASK) == OS_RWLOCK_MAGIC)) {
@ -49,7 +59,11 @@ BOOL LOS_RwlockIsValid(const LosRwlock *rwlock)
return FALSE;
}
<<<<<<< HEAD
=======
/// 创建读写锁,初始化锁信息
>>>>>>> remotes/origin/main
UINT32 LOS_RwlockInit(LosRwlock *rwlock)
{
UINT32 intSave;
@ -72,7 +86,11 @@ UINT32 LOS_RwlockInit(LosRwlock *rwlock)
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
<<<<<<< HEAD
=======
/// 删除指定的读写锁
>>>>>>> remotes/origin/main
UINT32 LOS_RwlockDestroy(LosRwlock *rwlock)
{
UINT32 intSave;
@ -96,18 +114,30 @@ UINT32 LOS_RwlockDestroy(LosRwlock *rwlock)
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
<<<<<<< HEAD
=======
/// 读写锁检查
>>>>>>> remotes/origin/main
STATIC UINT32 OsRwlockCheck(const LosRwlock *rwlock)
{
if (rwlock == NULL) {
return LOS_EINVAL;
}
<<<<<<< HEAD
if (OS_INT_ACTIVE) {
return LOS_EINTR;
}
/* DO NOT Call blocking API in system tasks */
=======
if (OS_INT_ACTIVE) { // 读写锁不能在中断服务程序中使用。请想想为什么 ?
return LOS_EINTR;
}
/* DO NOT Call blocking API in system tasks | 系统任务不能使用读写锁 */
>>>>>>> remotes/origin/main
LosTaskCB *runTask = (LosTaskCB *)OsCurrTaskGet();
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
return LOS_EPERM;
@ -115,23 +145,36 @@ STATIC UINT32 OsRwlockCheck(const LosRwlock *rwlock)
return LOS_OK;
}
<<<<<<< HEAD
STATIC BOOL OsRwlockPriCompare(LosTaskCB *runTask, LOS_DL_LIST *rwList)
{
if (!LOS_ListEmpty(rwList)) {
LosTaskCB *highestTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(rwList));
if (OsSchedParamCompare(runTask, highestTask) < 0) {
=======
/// 指定任务优先级优先级是否低于 写锁任务最高优先级
STATIC BOOL OsRwlockPriCompare(LosTaskCB *runTask, LOS_DL_LIST *rwList)
{
if (!LOS_ListEmpty(rwList)) {
LosTaskCB *highestTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(rwList));//首个写锁任务优先级是最高的
if (OsSchedParamCompare(runTask, highestTask) < 0) {//如果当前任务优先级低于等待写锁任务
>>>>>>> remotes/origin/main
return TRUE;
}
return FALSE;
}
return TRUE;
}
<<<<<<< HEAD
=======
/* 申请读模式下的锁,分三种情况:
1.
2.
3.
*/
>>>>>>> remotes/origin/main
STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 timeout)
{
UINT32 ret;
@ -140,12 +183,21 @@ STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim
* When the rwlock mode is read mode or free mode and the priority of the current read task
* is higher than the first pended write task. current read task can obtain this rwlock.
*/
<<<<<<< HEAD
if (rwlock->rwCount >= 0) {
if (OsRwlockPriCompare(runTask, &(rwlock->writeList))) {
if (rwlock->rwCount == INT8_MAX) {
return LOS_EINVAL;
}
rwlock->rwCount++;
=======
if (rwlock->rwCount >= 0) {//第一和第二种情况
if (OsRwlockPriCompare(runTask, &(rwlock->writeList))) {//读优先级低于写优先级,意思就是必须先写再读
if (rwlock->rwCount == INT8_MAX) {//读锁任务达到上限
return LOS_EINVAL;
}
rwlock->rwCount++;//拿读锁成功
>>>>>>> remotes/origin/main
return LOS_OK;
}
}
@ -154,6 +206,14 @@ STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim
return LOS_EINVAL;
}
<<<<<<< HEAD
if (!OsPreemptableInSched()) {
return LOS_EDEADLK;
}
/* The current task is not allowed to obtain the write lock when it obtains the read lock. */
if ((LosTaskCB *)(rwlock->writeOwner) == runTask) {
=======
if (!OsPreemptableInSched()) {//不可抢占时
return LOS_EDEADLK;
}
@ -161,29 +221,50 @@ STATIC UINT32 OsRwlockRdPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim
/* The current task is not allowed to obtain the write lock when it obtains the read lock.
| */
if ((LosTaskCB *)(rwlock->writeOwner) == runTask) { //拥有写锁任务是否为当前任务
>>>>>>> remotes/origin/main
return LOS_EINVAL;
}
/*
* When the rwlock mode is write mode or the priority of the current read task
* is lower than the first pended write task, current read task will be pended.
<<<<<<< HEAD
*/
LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->readList));
ret = runTask->ops->wait(runTask, node, timeout);
=======
| rwlock
*/
LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->readList));//找到要挂入的位置
//例如现有链表内任务优先级为 0 3 8 9 23 当前为 10 时, 返回的是 9 这个节点
ret = runTask->ops->wait(runTask, node, timeout);//从尾部插入读锁链表 由此变成了 0 3 8 9 10 23
>>>>>>> remotes/origin/main
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
return LOS_ETIMEDOUT;
}
return ret;
}
<<<<<<< HEAD
=======
/// 申请写模式下的锁
>>>>>>> remotes/origin/main
STATIC UINT32 OsRwlockWrPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 timeout)
{
UINT32 ret;
<<<<<<< HEAD
/* When the rwlock is free mode, current write task can obtain this rwlock. */
if (rwlock->rwCount == 0) {
rwlock->rwCount = -1;
rwlock->writeOwner = (VOID *)runTask;
return LOS_OK;
}
/* Current write task can use one rwlock once again if the rwlock owner is it. */
=======
/* When the rwlock is free mode, current write task can obtain this rwlock.
| */
if (rwlock->rwCount == 0) {
@ -194,11 +275,16 @@ STATIC UINT32 OsRwlockWrPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim
/* Current write task can use one rwlock once again if the rwlock owner is it.
| rwlock 使*/
>>>>>>> remotes/origin/main
if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) == runTask)) {
if (rwlock->rwCount == INT8_MIN) {
return LOS_EINVAL;
}
<<<<<<< HEAD
rwlock->rwCount--;
=======
rwlock->rwCount--;//注意再次拥有算是两把写锁了.
>>>>>>> remotes/origin/main
return LOS_OK;
}
@ -212,9 +298,15 @@ STATIC UINT32 OsRwlockWrPendOp(LosTaskCB *runTask, LosRwlock *rwlock, UINT32 tim
/*
* When the rwlock is read mode or other write task obtains this rwlock, current
<<<<<<< HEAD
* write task will be pended.
*/
LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->writeList));
=======
* write task will be pended. | rwlock rwlock
*/
LOS_DL_LIST *node = OsSchedLockPendFindPos(runTask, &(rwlock->writeList));//找到要挂入的位置
>>>>>>> remotes/origin/main
ret = runTask->ops->wait(runTask, node, timeout);
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
ret = LOS_ETIMEDOUT;
@ -276,22 +368,36 @@ UINT32 OsRwlockTryWrUnsafe(LosRwlock *rwlock, UINT32 timeout)
return LOS_EBADF;
}
<<<<<<< HEAD
/* When the rwlock is read mode, current write task will be pended. */
=======
/* When the rwlock is read mode, current write task will be pended.
| rwlock */
>>>>>>> remotes/origin/main
if (rwlock->rwCount > 0) {
return LOS_EBUSY;
}
<<<<<<< HEAD
/* When other write task obtains this rwlock, current write task will be pended. */
=======
/* When other write task obtains this rwlock, current write task will be pended.
| rwlock*/
>>>>>>> remotes/origin/main
LosTaskCB *runTask = OsCurrTaskGet();
if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) {
return LOS_EBUSY;
}
<<<<<<< HEAD
return OsRwlockWrPendOp(runTask, rwlock, timeout);
}
=======
return OsRwlockWrPendOp(runTask, rwlock, timeout);//
}
/// 申请指定的读模式下的锁
>>>>>>> remotes/origin/main
UINT32 LOS_RwlockRdLock(LosRwlock *rwlock, UINT32 timeout)
{
UINT32 intSave;
@ -306,7 +412,11 @@ UINT32 LOS_RwlockRdLock(LosRwlock *rwlock, UINT32 timeout)
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
/// 尝试申请指定的读模式下的锁
>>>>>>> remotes/origin/main
UINT32 LOS_RwlockTryRdLock(LosRwlock *rwlock)
{
UINT32 intSave;
@ -317,11 +427,19 @@ UINT32 LOS_RwlockTryRdLock(LosRwlock *rwlock)
}
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
ret = OsRwlockTryRdUnsafe(rwlock, 0);
SCHEDULER_UNLOCK(intSave);
return ret;
}
=======
ret = OsRwlockTryRdUnsafe(rwlock, 0);//所谓尝试就是没锁爷就返回,不等待,不纠结.当前任务也不会被挂起
SCHEDULER_UNLOCK(intSave);
return ret;
}
/// 申请指定的写模式下的锁
>>>>>>> remotes/origin/main
UINT32 LOS_RwlockWrLock(LosRwlock *rwlock, UINT32 timeout)
{
UINT32 intSave;
@ -336,7 +454,11 @@ UINT32 LOS_RwlockWrLock(LosRwlock *rwlock, UINT32 timeout)
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
/// 尝试申请指定的写模式下的锁
>>>>>>> remotes/origin/main
UINT32 LOS_RwlockTryWrLock(LosRwlock *rwlock)
{
UINT32 intSave;
@ -347,15 +469,32 @@ UINT32 LOS_RwlockTryWrLock(LosRwlock *rwlock)
}
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
ret = OsRwlockTryWrUnsafe(rwlock, 0);
SCHEDULER_UNLOCK(intSave);
return ret;
}
=======
ret = OsRwlockTryWrUnsafe(rwlock, 0);//所谓尝试就是没锁爷就返回,不等待,不纠结.当前任务也不会被挂起
SCHEDULER_UNLOCK(intSave);
return ret;
}
/// 获取读写锁模式
>>>>>>> remotes/origin/main
STATIC UINT32 OsRwlockGetMode(LOS_DL_LIST *readList, LOS_DL_LIST *writeList)
{
BOOL isReadEmpty = LOS_ListEmpty(readList);
BOOL isWriteEmpty = LOS_ListEmpty(writeList);
<<<<<<< HEAD
if (isReadEmpty && isWriteEmpty) {
return RWLOCK_NONE_MODE;
}
if (!isReadEmpty && isWriteEmpty) {
return RWLOCK_READ_MODE;
}
if (isReadEmpty && !isWriteEmpty) {
=======
if (isReadEmpty && isWriteEmpty) { //读写链表都没有内容
return RWLOCK_NONE_MODE; //自由模式
}
@ -363,16 +502,25 @@ STATIC UINT32 OsRwlockGetMode(LOS_DL_LIST *readList, LOS_DL_LIST *writeList)
return RWLOCK_READ_MODE;
}
if (isReadEmpty && !isWriteEmpty) { //写链表有数据,读链表没有数据
>>>>>>> remotes/origin/main
return RWLOCK_WRITE_MODE;
}
LosTaskCB *pendedReadTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(readList));
LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(writeList));
if (OsSchedParamCompare(pendedWriteTask, pendedReadTask) <= 0) {
<<<<<<< HEAD
return RWLOCK_WRITEFIRST_MODE;
}
return RWLOCK_READFIRST_MODE;
}
=======
return RWLOCK_WRITEFIRST_MODE; //写的优先级高时,为写优先模式
}
return RWLOCK_READFIRST_MODE; //读的优先级高时,为读优先模式
}
/// 释放锁
>>>>>>> remotes/origin/main
STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched)
{
UINT32 rwlockMode;
@ -380,6 +528,17 @@ STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched)
rwlock->rwCount = 0;
rwlock->writeOwner = NULL;
<<<<<<< HEAD
rwlockMode = OsRwlockGetMode(&(rwlock->readList), &(rwlock->writeList));
if (rwlockMode == RWLOCK_NONE_MODE) {
return LOS_OK;
}
/* In this case, rwlock will wake the first pended write task. */
if ((rwlockMode == RWLOCK_WRITE_MODE) || (rwlockMode == RWLOCK_WRITEFIRST_MODE)) {
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList)));
rwlock->rwCount = -1;
rwlock->writeOwner = (VOID *)resumedTask;
=======
rwlockMode = OsRwlockGetMode(&(rwlock->readList), &(rwlock->writeList));//先获取模式
if (rwlockMode == RWLOCK_NONE_MODE) {//自由模式则正常返回
return LOS_OK;
@ -389,6 +548,7 @@ STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched)
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList)));//获取任务实体
rwlock->rwCount = -1;//直接干成-1,注意这里并不是 --
rwlock->writeOwner = (VOID *)resumedTask;//有锁了则唤醒等锁的任务(写模式)
>>>>>>> remotes/origin/main
resumedTask->ops->wake(resumedTask);
if (needSched != NULL) {
*needSched = TRUE;
@ -396,30 +556,51 @@ STATIC UINT32 OsRwlockPostOp(LosRwlock *rwlock, BOOL *needSched)
return LOS_OK;
}
<<<<<<< HEAD
rwlock->rwCount = 1;
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList)));
resumedTask->ops->wake(resumedTask);
while (!LOS_ListEmpty(&(rwlock->readList))) {
=======
rwlock->rwCount = 1; //直接干成1,因为是释放操作
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList)));
resumedTask->ops->wake(resumedTask);
while (!LOS_ListEmpty(&(rwlock->readList))) {//遍历读链表,目的是要唤醒其他读模式的任务(优先级得要高于pendedWriteTaskPri才行)
>>>>>>> remotes/origin/main
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->readList)));
if (rwlockMode == RWLOCK_READFIRST_MODE) {
LosTaskCB *pendedWriteTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(rwlock->writeList)));
if (OsSchedParamCompare(resumedTask, pendedWriteTask) >= 0) {
<<<<<<< HEAD
break;
}
=======
break;//跳出循环
}
>>>>>>> remotes/origin/main
}
if (rwlock->rwCount == INT8_MAX) {
return EINVAL;
}
<<<<<<< HEAD
rwlock->rwCount++;
resumedTask->ops->wake(resumedTask);
=======
rwlock->rwCount++;//读锁任务数量增加
resumedTask->ops->wake(resumedTask);//不断唤醒读锁任务,由此实现了允许多个读操作并发,因为在多核情况下resumedTask很大可能
//与当前任务并不在同一个核上运行, 此处非常有意思,点赞! @note_good
>>>>>>> remotes/origin/main
}
if (needSched != NULL) {
*needSched = TRUE;
}
return LOS_OK;
}
<<<<<<< HEAD
=======
/// 释放锁,唤醒任务
>>>>>>> remotes/origin/main
UINT32 OsRwlockUnlockUnsafe(LosRwlock *rwlock, BOOL *needSched)
{
if ((rwlock->magic & RWLOCK_COUNT_MASK) != OS_RWLOCK_MAGIC) {
@ -431,28 +612,45 @@ UINT32 OsRwlockUnlockUnsafe(LosRwlock *rwlock, BOOL *needSched)
}
LosTaskCB *runTask = OsCurrTaskGet();
<<<<<<< HEAD
if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) {
=======
if ((rwlock->rwCount < 0) && ((LosTaskCB *)(rwlock->writeOwner) != runTask)) {//写模式时,当前任务未持有锁
>>>>>>> remotes/origin/main
return LOS_EPERM;
}
/*
* When the rwCount of the rwlock more than 1 or less than -1, the rwlock mode will
* not changed after current unlock operation, so pended tasks can not be waken.
<<<<<<< HEAD
*/
if (rwlock->rwCount > 1) {
=======
| rwlock rwCount 1 -1 rwlock
*/
if (rwlock->rwCount > 1) {//读模式
>>>>>>> remotes/origin/main
rwlock->rwCount--;
return LOS_OK;
}
<<<<<<< HEAD
if (rwlock->rwCount < -1) {
=======
if (rwlock->rwCount < -1) {//写模式
>>>>>>> remotes/origin/main
rwlock->rwCount++;
return LOS_OK;
}
return OsRwlockPostOp(rwlock, needSched);
}
<<<<<<< HEAD
=======
/// 释放指定读写锁
>>>>>>> remotes/origin/main
UINT32 LOS_RwlockUnLock(LosRwlock *rwlock)
{
UINT32 intSave;
@ -466,9 +664,15 @@ UINT32 LOS_RwlockUnLock(LosRwlock *rwlock)
SCHEDULER_LOCK(intSave);
ret = OsRwlockUnlockUnsafe(rwlock, &needSched);
SCHEDULER_UNLOCK(intSave);
<<<<<<< HEAD
LOS_MpSchedule(OS_MP_CPU_ALL);
if (needSched == TRUE) {
LOS_Schedule();
=======
LOS_MpSchedule(OS_MP_CPU_ALL);//设置调度CPU的方式,所有CPU参与调度
if (needSched == TRUE) {//是否需要调度
LOS_Schedule();//产生调度,切换任务执行
>>>>>>> remotes/origin/main
}
return ret;
}

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -40,18 +44,29 @@
#include "los_percpu_pri.h"
#include "los_hook.h"
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
#ifdef LOSCFG_BASE_IPC_SEM
#if (LOSCFG_BASE_IPC_SEM_LIMIT <= 0)
#error "sem maxnum cannot be zero"
#endif /* LOSCFG_BASE_IPC_SEM_LIMIT <= 0 */
<<<<<<< HEAD
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList;
LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL;
/*
* Description : Initialize the semaphore doubly linked list
=======
LITE_OS_SEC_DATA_INIT STATIC LOS_DL_LIST g_unusedSemList; ///< 可用的信号量列表,干嘛不用freeList? 可以看出这里是另一个人写的代码
LITE_OS_SEC_BSS LosSemCB *g_allSem = NULL; ///< 信号池,一次分配 LOSCFG_BASE_IPC_SEM_LIMIT 个信号量
/*
* Description : Initialize the semaphore doubly linked list |
>>>>>>> remotes/origin/main
* Return : LOS_OK on success, or error code on failure
*/
LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
@ -59,18 +74,31 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
LosSemCB *semNode = NULL;
UINT32 index;
<<<<<<< HEAD
LOS_ListInit(&g_unusedSemList);
/* system resident memory, don't free */
g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));
=======
LOS_ListInit(&g_unusedSemList);//初始化链表,链表上挂未使用的信号量,用于分配信号量,鸿蒙信号量的个数是有限的,默认1024个
/* system resident memory, don't free */
g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));//分配信号池
>>>>>>> remotes/origin/main
if (g_allSem == NULL) {
return LOS_ERRNO_SEM_NO_MEMORY;
}
for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) {
<<<<<<< HEAD
semNode = ((LosSemCB *)g_allSem) + index;
semNode->semID = SET_SEM_ID(0, index);
semNode->semStat = OS_SEM_UNUSED;
LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);
=======
semNode = ((LosSemCB *)g_allSem) + index;//拿信号控制块, 可以直接g_allSem[index]来嘛
semNode->semID = SET_SEM_ID(0, index);//保存ID
semNode->semStat = OS_SEM_UNUSED;//标记未使用
LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);//通过semList把 信号块挂到空闲链表上
>>>>>>> remotes/origin/main
}
if (OsSemDbgInitHook() != LOS_OK) {
@ -79,7 +107,17 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
return LOS_OK;
}
<<<<<<< HEAD
/*
* Description : Create a semaphore,
* Input : count --- semaphore count,
* maxCount --- Max number of available semaphores,
* semHandle --- Index of semaphore,
* Return : LOS_OK on success ,or error code on failure
*/
=======
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle)
{
UINT32 intSave;
@ -92,6 +130,15 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *
return LOS_ERRNO_SEM_PTR_NULL;
}
<<<<<<< HEAD
if (count > maxCount) {
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW);
}
SCHEDULER_LOCK(intSave);
if (LOS_ListEmpty(&g_unusedSemList)) {
=======
if (count > maxCount) {//信号量不能大于最大值,两参数都是外面给的
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW);
}
@ -99,11 +146,25 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *
SCHEDULER_LOCK(intSave);//进入临界区,拿自旋锁
if (LOS_ListEmpty(&g_unusedSemList)) {//没有可分配的空闲信号提供
>>>>>>> remotes/origin/main
SCHEDULER_UNLOCK(intSave);
OsSemInfoGetFullDataHook();
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_ALL_BUSY);
}
<<<<<<< HEAD
unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList);
LOS_ListDelete(unusedSem);
SCHEDULER_UNLOCK(intSave);
semCreated = GET_SEM_LIST(unusedSem);
semCreated->semCount = count;
semCreated->semStat = OS_SEM_USED;
semCreated->maxSemCount = maxCount;
LOS_ListInit(&semCreated->semList);
*semHandle = semCreated->semID;
OsHookCall(LOS_HOOK_TYPE_SEM_CREATE, semCreated);
OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count);
=======
unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList);//从未使用信号量池中取首个
LOS_ListDelete(unusedSem);//从空闲链表上摘除
SCHEDULER_UNLOCK(intSave);
@ -116,22 +177,35 @@ LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *
OsHookCall(LOS_HOOK_TYPE_SEM_CREATE, semCreated);
OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count);
>>>>>>> remotes/origin/main
return LOS_OK;
ERR_HANDLER:
OS_RETURN_ERROR_P2(errLine, errNo);
}
<<<<<<< HEAD
=======
///对外接口 创建信号量
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle)
{
return OsSemCreate(count, OS_SEM_COUNT_MAX, semHandle);
}
<<<<<<< HEAD
=======
///对外接口 创建二值信号量其计数值最大为1可以当互斥锁用
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle)
{
return OsSemCreate(count, OS_SEM_BINARY_COUNT_MAX, semHandle);
}
<<<<<<< HEAD
=======
///对外接口 删除指定的信号量,参数就是 semID
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
{
UINT32 intSave;
@ -143,15 +217,33 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID);
}
<<<<<<< HEAD
semDeleted = GET_SEM(semHandle);
SCHEDULER_LOCK(intSave);
if ((semDeleted->semStat == OS_SEM_UNUSED) || (semDeleted->semID != semHandle)) {
=======
semDeleted = GET_SEM(semHandle);//通过ID拿到信号量实体
SCHEDULER_LOCK(intSave);
if ((semDeleted->semStat == OS_SEM_UNUSED) || (semDeleted->semID != semHandle)) {//参数判断
>>>>>>> remotes/origin/main
SCHEDULER_UNLOCK(intSave);
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID);
}
<<<<<<< HEAD
if (!LOS_ListEmpty(&semDeleted->semList)) {
SCHEDULER_UNLOCK(intSave);
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED);
}
LOS_ListTailInsert(&g_unusedSemList, &semDeleted->semList);
semDeleted->semStat = OS_SEM_UNUSED;
semDeleted->semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->semID) + 1, GET_SEM_INDEX(semDeleted->semID));
=======
if (!LOS_ListEmpty(&semDeleted->semList)) {//当前还有任务挂在这个信号上面,当然不能删除
SCHEDULER_UNLOCK(intSave);
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_PENDED);//这个宏很有意思,里面goto到ERR_HANDLER
@ -160,6 +252,7 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
LOS_ListTailInsert(&g_unusedSemList, &semDeleted->semList);//通过semList从尾部插入空闲链表
semDeleted->semStat = OS_SEM_UNUSED;//状态变成了未使用
semDeleted->semID = SET_SEM_ID(GET_SEM_COUNT(semDeleted->semID) + 1, GET_SEM_INDEX(semDeleted->semID));//设置ID
>>>>>>> remotes/origin/main
OsHookCall(LOS_HOOK_TYPE_SEM_DELETE, semDeleted);
OsSemDbgUpdateHook(semDeleted->semID, NULL, 0);
@ -170,11 +263,19 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
ERR_HANDLER:
OS_RETURN_ERROR_P2(errLine, errNo);
}
<<<<<<< HEAD
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
{
UINT32 intSave;
LosSemCB *semPended = GET_SEM(semHandle);
=======
///对外接口 申请指定的信号量,并设置超时时间
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
{
UINT32 intSave;
LosSemCB *semPended = GET_SEM(semHandle);//通过ID拿到信号体
>>>>>>> remotes/origin/main
UINT32 retErr = LOS_OK;
LosTaskCB *runTask = NULL;
@ -188,7 +289,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
return LOS_ERRNO_SEM_PEND_INTERR;
}
<<<<<<< HEAD
runTask = OsCurrTaskGet();
=======
runTask = OsCurrTaskGet();//获取当前任务
>>>>>>> remotes/origin/main
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
OsBackTrace();
return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK;
@ -200,6 +305,15 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
retErr = LOS_ERRNO_SEM_INVALID;
goto OUT;
}
<<<<<<< HEAD
/* Update the operate time, no matter the actual Pend success or not */
OsSemDbgTimeUpdateHook(semHandle);
if (semPended->semCount > 0) {
semPended->semCount--;
OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout);
goto OUT;
=======
/* Update the operate time, no matter the actual Pend success or not */
OsSemDbgTimeUpdateHook(semHandle);
@ -208,12 +322,17 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
semPended->semCount--;//资源少了一个
OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout);
goto OUT;//注意这里 retErr = LOS_OK ,所以返回是OK的
>>>>>>> remotes/origin/main
} else if (!timeout) {
retErr = LOS_ERRNO_SEM_UNAVAILABLE;
goto OUT;
}
<<<<<<< HEAD
if (!OsPreemptableInSched()) {
=======
if (!OsPreemptableInSched()) {//不能申请调度 (不能调度的原因是因为没有持有调度任务自旋锁)
>>>>>>> remotes/origin/main
PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n");
OsBackTrace();
retErr = LOS_ERRNO_SEM_PEND_IN_LOCK;
@ -223,7 +342,11 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
OsHookCall(LOS_HOOK_TYPE_SEM_PEND, semPended, runTask, timeout);
OsTaskWaitSetPendMask(OS_TASK_WAIT_SEM, semPended->semID, timeout);
retErr = runTask->ops->wait(runTask, &semPended->semList, timeout);
<<<<<<< HEAD
if (retErr == LOS_ERRNO_TSK_TIMEOUT) {
=======
if (retErr == LOS_ERRNO_TSK_TIMEOUT) {//注意:这里是涉及到task切换的,把自己挂起,唤醒其他task
>>>>>>> remotes/origin/main
retErr = LOS_ERRNO_SEM_TIMEOUT;
}
@ -231,7 +354,11 @@ OUT:
SCHEDULER_UNLOCK(intSave);
return retErr;
}
<<<<<<< HEAD
=======
///以不安全的方式释放指定的信号量,所谓不安全指的是不用自旋锁
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched)
{
LosTaskCB *resumedTask = NULL;
@ -243,6 +370,20 @@ LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched)
/* Update the operate time, no matter the actual Post success or not */
OsSemDbgTimeUpdateHook(semHandle);
<<<<<<< HEAD
if (semPosted->semCount == OS_SEM_COUNT_MAX) {
return LOS_ERRNO_SEM_OVERFLOW;
}
if (!LOS_ListEmpty(&semPosted->semList)) {
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(semPosted->semList)));
OsTaskWakeClearPendMask(resumedTask);
resumedTask->ops->wake(resumedTask);
if (needSched != NULL) {
*needSched = TRUE;
}
} else {
semPosted->semCount++;
=======
if (semPosted->semCount == OS_SEM_COUNT_MAX) {//当前信号资源不能大于最大资源量
return LOS_ERRNO_SEM_OVERFLOW;
}
@ -255,11 +396,16 @@ LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched)
}
} else {//当前没有任务挂在semList上,
semPosted->semCount++;//信号资源多一个
>>>>>>> remotes/origin/main
}
OsHookCall(LOS_HOOK_TYPE_SEM_POST, semPosted, resumedTask);
return LOS_OK;
}
<<<<<<< HEAD
=======
///对外接口 释放指定的信号量
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle)
{
UINT32 intSave;
@ -269,15 +415,29 @@ LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle)
if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) {
return LOS_ERRNO_SEM_INVALID;
}
<<<<<<< HEAD
SCHEDULER_LOCK(intSave);
ret = OsSemPostUnsafe(semHandle, &needSched);
SCHEDULER_UNLOCK(intSave);
if (needSched) {
LOS_MpSchedule(OS_MP_CPU_ALL);
LOS_Schedule();
=======
SCHEDULER_LOCK(intSave);
ret = OsSemPostUnsafe(semHandle, &needSched);
SCHEDULER_UNLOCK(intSave);
if (needSched) {//需要调度的情况
LOS_MpSchedule(OS_MP_CPU_ALL);//向所有CPU发送调度指令
LOS_Schedule();////发起调度
>>>>>>> remotes/origin/main
}
return ret;
}
<<<<<<< HEAD
#endif /* LOSCFG_BASE_IPC_SEM */
=======
#endif /* (LOSCFG_BASE_IPC_SEM == YES) */
>>>>>>> remotes/origin/main

@ -78,11 +78,19 @@ STATIC VOID OsSemPendedTaskNamePrint(LosSemCB *semNode)
#ifdef LOSCFG_DEBUG_SEMAPHORE
typedef struct {
<<<<<<< HEAD
UINT16 origSemCount; /* Number of original available semaphores */
UINT64 lastAccessTime; /* The last operation time */
TSK_ENTRY_FUNC creator; /* The task entry who created this sem */
} SemDebugCB;
STATIC SemDebugCB *g_semDebugArray = NULL;
=======
UINT16 origSemCount; /* Number of orignal available semaphores *///原始可用信号量数
UINT64 lastAccessTime; /* The last operation time */ //最后操作时间
TSK_ENTRY_FUNC creator; /* The task entry who created this sem */ //由哪个task的入口函数创建了这个任务
} SemDebugCB;
STATIC SemDebugCB *g_semDebugArray = NULL;//默认1024个SemDebugCB debug信号量池
>>>>>>> remotes/origin/main
STATIC BOOL SemCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right)
{
@ -102,6 +110,25 @@ UINT32 OsSemDbgInit(VOID)
(VOID)memset_s(g_semDebugArray, size, 0, size);
return LOS_OK;
}
<<<<<<< HEAD
VOID OsSemDbgTimeUpdate(UINT32 semID)
{
SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)];
semDebug->lastAccessTime = LOS_TickCountGet();
return;
}
VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creator, UINT16 count)
{
SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)];
semDebug->creator = creator;
semDebug->lastAccessTime = LOS_TickCountGet();
semDebug->origSemCount = count;
return;
}
=======
///更新最后访问时间
VOID OsSemDbgTimeUpdate(UINT32 semID)
{
@ -119,6 +146,7 @@ VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creator, UINT16 count)
return;
}
///按信号量访问时间排序
>>>>>>> remotes/origin/main
STATIC VOID OsSemSort(UINT32 *semIndexArray, UINT32 usedCount)
{
UINT32 i, intSave;
@ -296,6 +324,10 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSemInfoGet(UINT32 argc, const CHAR **arg
return ret;
}
<<<<<<< HEAD
SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet);
=======
SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet);//采用shell命令静态注册方式
>>>>>>> remotes/origin/main
#endif

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2023 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -53,6 +57,17 @@ int raise(int sig)
#define GETUNMASKSET(procmask, pendFlag) ((~(procmask)) & (sigset_t)(pendFlag))
#define UINT64_BIT_SIZE 64
<<<<<<< HEAD
int OsSigIsMember(const sigset_t *set, int signo)
{
int ret = LOS_NOK;
/* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
signo -= 1;
/* Verify the signal */
if (GOOD_SIGNO(signo)) {
/* Check if the signal is in the set */
ret = ((*set & SIGNO2SET((unsigned int)signo)) != 0);
=======
int OsSigIsMember(const sigset_t *set, int signo)
{
@ -64,6 +79,7 @@ int OsSigIsMember(const sigset_t *set, int signo)
if (GOOD_SIGNO(signo)) {//有效信号判断
/* Check if the signal is in the set */
ret = ((*set & SIGNO2SET((unsigned int)signo)) != 0);//检查信号是否还在集合中
>>>>>>> remotes/origin/main
}
return ret;
@ -122,6 +138,10 @@ VOID OsClearSigInfoTmpList(sig_cb *sigcb)
(VOID)LOS_MemFree(m_aucSysMem0, tmpInfoNode);
}
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo)
{
sig_cb *sigcb = &taskCB->sig;
@ -133,14 +153,22 @@ STATIC INLINE VOID OsSigWaitTaskWake(LosTaskCB *taskCB, INT32 signo)
OsSigEmptySet(&sigcb->sigwaitmask);
}
}
<<<<<<< HEAD
=======
///< 唤醒被挂起的处于等待指定信号的任务
>>>>>>> remotes/origin/main
STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo)
{
if (!OsTaskIsPending(taskCB) || !OsProcessIsUserMode(OS_PCB_FROM_TCB(taskCB))) {
return 0;
}
<<<<<<< HEAD
if ((signo != SIGKILL) && (taskCB->waitFlag != OS_TASK_WAIT_SIGNAL)) {
=======
if ((signo != SIGKILL) && (taskCB->waitFlag != OS_TASK_WAIT_SIGNAL)) { // @note_thinking 这个判断会不会有问题 ?
>>>>>>> remotes/origin/main
return 0;
}
@ -154,6 +182,18 @@ STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo)
OsTaskWakeClearPendMask(taskCB);
taskCB->ops->wake(taskCB);
break;
<<<<<<< HEAD
case OS_TASK_WAIT_SIGNAL:
OsSigWaitTaskWake(taskCB, signo);
break;
case OS_TASK_WAIT_LITEIPC:
OsTaskWakeClearPendMask(taskCB);
taskCB->ops->wake(taskCB);
break;
case OS_TASK_WAIT_FUTEX:
OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL);
OsTaskWakeClearPendMask(taskCB);
=======
case OS_TASK_WAIT_SIGNAL://等待普通信号
OsSigWaitTaskWake(taskCB, signo);
break;
@ -164,6 +204,7 @@ STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo)
case OS_TASK_WAIT_FUTEX://等待快锁信号
OsFutexNodeDeleteFromFutexHash(&taskCB->futex, TRUE, NULL, NULL);//从哈希桶中删除快锁
OsTaskWakeClearPendMask(taskCB);//重置任务的等待信息
>>>>>>> remotes/origin/main
taskCB->ops->wake(taskCB);
break;
default:
@ -172,7 +213,11 @@ STATIC UINT32 OsPendingTaskWake(LosTaskCB *taskCB, INT32 signo)
return 0;
}
<<<<<<< HEAD
=======
///给任务(线程)发送一个信号
>>>>>>> remotes/origin/main
int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info)
{
bool masked = FALSE;
@ -180,6 +225,21 @@ int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info)
OS_RETURN_IF_NULL(sigcb);
/* If signo is 0, not send signal, just check process or pthread exist */
<<<<<<< HEAD
if (info->si_signo == 0) {
return 0;
}
masked = (bool)OsSigIsMember(&sigcb->sigprocmask, info->si_signo);
if (masked) {
/* If signal is in wait list and mask list, need unblock it */
if (LOS_ListEmpty(&sigcb->waitList) ||
(!LOS_ListEmpty(&sigcb->waitList) && !OsSigIsMember(&sigcb->sigwaitmask, info->si_signo))) {
OsSigAddSet(&sigcb->sigPendFlag, info->si_signo);
}
} else {
/* unmasked signal actions */
OsSigAddSet(&sigcb->sigFlag, info->si_signo);
=======
if (info->si_signo == 0) {//如果信号为0,则不发送信号,只是作为检查进程和线程是否还存在.
return 0;
}
@ -193,6 +253,7 @@ int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info)
} else {//信号没有被屏蔽的处理
/* unmasked signal actions */
OsSigAddSet(&sigcb->sigFlag, info->si_signo);//不屏蔽的信号集
>>>>>>> remotes/origin/main
}
if (OsAddSigInfoToTmpList(sigcb, info) == LOS_NOK) {
@ -207,6 +268,16 @@ void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set)
sigset_t unmaskset;
rtcb->sig.sigprocmask = set;
<<<<<<< HEAD
unmaskset = GETUNMASKSET(rtcb->sig.sigprocmask, rtcb->sig.sigPendFlag);
if (unmaskset != NULL_SIGNAL_SET) {
/* pendlist do */
rtcb->sig.sigFlag |= unmaskset;
rtcb->sig.sigPendFlag ^= unmaskset;
}
}
=======
unmaskset = GETUNMASKSET(rtcb->sig.sigprocmask, rtcb->sig.sigPendFlag);//过滤出没有被屏蔽的信号集
if (unmaskset != NULL_SIGNAL_SET) {
/* pendlist do */
@ -216,6 +287,7 @@ void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set)
}
>>>>>>> remotes/origin/main
int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl)
{
LosTaskCB *spcb = NULL;
@ -225,11 +297,19 @@ int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl)
SCHEDULER_LOCK(intSave);
spcb = OsCurrTaskGet();
<<<<<<< HEAD
/* If requested, copy the old mask to user. */
if (oldsetl != NULL) {
*(sigset_t *)oldsetl = spcb->sig.sigprocmask;
}
/* If requested, modify the current signal mask. */
=======
/* If requested, copy the old mask to user. | 如果需要,请将旧掩码复制给用户*/
if (oldsetl != NULL) {
*(sigset_t *)oldsetl = spcb->sig.sigprocmask;
}
/* If requested, modify the current signal mask. | 如有要求,修改当前信号屏蔽*/
>>>>>>> remotes/origin/main
if (setl != NULL) {
set = *(sigset_t *)setl;
/* Okay, determine what we are supposed to do */
@ -238,35 +318,68 @@ int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldsetl)
* set pointed to by set as the new sigprocmask.
*/
case SIG_BLOCK:
<<<<<<< HEAD
spcb->sig.sigprocmask |= set;
=======
spcb->sig.sigprocmask |= set;//增加信号屏蔽位
>>>>>>> remotes/origin/main
break;
/* Set the intersection of the current set and the
* signal set pointed to by set as the new sigprocmask.
*/
case SIG_UNBLOCK:
<<<<<<< HEAD
spcb->sig.sigprocmask &= ~(set);
break;
/* Set the signal set pointed to by set as the new sigprocmask. */
case SIG_SETMASK:
spcb->sig.sigprocmask = set;
=======
spcb->sig.sigprocmask &= ~(set);//解除信号屏蔽位
break;
/* Set the signal set pointed to by set as the new sigprocmask. */
case SIG_SETMASK:
spcb->sig.sigprocmask = set;//设置一个新的屏蔽掩码
>>>>>>> remotes/origin/main
break;
default:
ret = -EINVAL;
break;
}
/* If pending mask not in sigmask, need set sigflag. */
<<<<<<< HEAD
OsSigMaskSwitch(spcb, spcb->sig.sigprocmask);
=======
OsSigMaskSwitch(spcb, spcb->sig.sigprocmask);//更新与屏蔽信号相关的变量
>>>>>>> remotes/origin/main
}
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
///让进程的每一个task执行参数函数
>>>>>>> remotes/origin/main
int OsSigProcessForeachChild(LosProcessCB *spcb, ForEachTaskCB handler, void *arg)
{
int ret;
/* Visit the main thread last (if present) */
<<<<<<< HEAD
LosTaskCB *taskCB = NULL;
LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &(spcb->threadSiblingList), LosTaskCB, threadList) {
ret = handler(taskCB, arg);
OS_RETURN_IF(ret != 0, ret);
}
return LOS_OK;
}
static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg)
{
struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;
=======
LosTaskCB *taskCB = NULL;//遍历进程的 threadList 链表,里面存放的都是task节点
LOS_DL_LIST_FOR_EACH_ENTRY(taskCB, &(spcb->threadSiblingList), LosTaskCB, threadList) {//遍历进程的任务列表
ret = handler(taskCB, arg);//回调参数函数
@ -278,6 +391,7 @@ int OsSigProcessForeachChild(LosProcessCB *spcb, ForEachTaskCB handler, void *ar
static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg)
{
struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;//先把参数解出来
>>>>>>> remotes/origin/main
int ret;
int isMember;
@ -285,6 +399,15 @@ static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg)
return 0;
}
<<<<<<< HEAD
/* If the default tcb is not set, then set this one as default. */
if (!info->defaultTcb) {
info->defaultTcb = tcb;
}
isMember = OsSigIsMember(&tcb->sig.sigwaitmask, info->sigInfo->si_signo);
if (isMember && (!info->awakenedTcb)) {
=======
/* If the default tcb is not setted, then set this one as default. */
if (!info->defaultTcb) {//如果没有默认发送方的任务,即默认参数任务.
info->defaultTcb = tcb;
@ -292,69 +415,131 @@ static int SigProcessSignalHandler(LosTaskCB *tcb, void *arg)
isMember = OsSigIsMember(&tcb->sig.sigwaitmask, info->sigInfo->si_signo);//任务是否在等待这个信号
if (isMember && (!info->awakenedTcb)) {//是在等待,并尚未向该任务时发送信号时
>>>>>>> remotes/origin/main
/* This means the task is waiting for this signal. Stop looking for it and use this tcb.
* The requirement is: if more than one task in this task group is waiting for the signal,
* then only one indeterminate task in the group will receive the signal.
*/
<<<<<<< HEAD
ret = OsTcbDispatch(tcb, info->sigInfo);
OS_RETURN_IF(ret < 0, ret);
=======
ret = OsTcbDispatch(tcb, info->sigInfo);//发送信号,注意这是给其他任务发送信号,tcb不是当前任务
OS_RETURN_IF(ret < 0, ret);//这种写法很有意思
>>>>>>> remotes/origin/main
/* set this tcb as awakenedTcb */
info->awakenedTcb = tcb;
OS_RETURN_IF(info->receivedTcb != NULL, SIG_STOP_VISIT); /* Stop search */
}
/* Is this signal unblocked on this thread? */
<<<<<<< HEAD
isMember = OsSigIsMember(&tcb->sig.sigprocmask, info->sigInfo->si_signo);
if ((!isMember) && (!info->receivedTcb) && (tcb != info->awakenedTcb)) {
/* if unblockedTcb of this signal is not set, then set it. */
=======
isMember = OsSigIsMember(&tcb->sig.sigprocmask, info->sigInfo->si_signo);//任务是否屏蔽了这个信号
if ((!isMember) && (!info->receivedTcb) && (tcb != info->awakenedTcb)) {//没有屏蔽,有唤醒任务没有接收任务.
/* if unblockedTcb of this signal is not setted, then set it. */
>>>>>>> remotes/origin/main
if (!info->unblockedTcb) {
info->unblockedTcb = tcb;
}
<<<<<<< HEAD
ret = OsTcbDispatch(tcb, info->sigInfo);
OS_RETURN_IF(ret < 0, ret);
/* set this tcb as receivedTcb */
info->receivedTcb = tcb;
=======
ret = OsTcbDispatch(tcb, info->sigInfo);//向任务发送信号
OS_RETURN_IF(ret < 0, ret);
/* set this tcb as receivedTcb */
info->receivedTcb = tcb;//设置这个任务为接收任务
>>>>>>> remotes/origin/main
OS_RETURN_IF(info->awakenedTcb != NULL, SIG_STOP_VISIT); /* Stop search */
}
return 0; /* Keep searching */
}
<<<<<<< HEAD
static int SigProcessKillSigHandler(LosTaskCB *tcb, void *arg)
{
struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;
=======
///进程收到 SIGKILL 信号后,通知任务tcb处理.
static int SigProcessKillSigHandler(LosTaskCB *tcb, void *arg)
{
struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;//转参
>>>>>>> remotes/origin/main
return OsPendingTaskWake(tcb, info->sigInfo->si_signo);
}
<<<<<<< HEAD
=======
//处理信号发送
>>>>>>> remotes/origin/main
static void SigProcessLoadTcb(struct ProcessSignalInfo *info, siginfo_t *sigInfo)
{
LosTaskCB *tcb = NULL;
<<<<<<< HEAD
if (info->awakenedTcb == NULL && info->receivedTcb == NULL) {
if (info->unblockedTcb) {
tcb = info->unblockedTcb;
} else if (info->defaultTcb) {
=======
if (info->awakenedTcb == NULL && info->receivedTcb == NULL) {//信号即没有指定接收task 也没有指定被唤醒task
if (info->unblockedTcb) {//如果进程信号信息体中有阻塞task
tcb = info->unblockedTcb;//
} else if (info->defaultTcb) {//如果有默认的发送方task
>>>>>>> remotes/origin/main
tcb = info->defaultTcb;
} else {
return;
}
/* Deliver the signal to the selected task */
<<<<<<< HEAD
(void)OsTcbDispatch(tcb, sigInfo);
}
}
=======
(void)OsTcbDispatch(tcb, sigInfo);//向所选任务发送信号
}
}
///给参数进程发送参数信号
>>>>>>> remotes/origin/main
int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo)
{
int ret;
struct ProcessSignalInfo info = {
<<<<<<< HEAD
.sigInfo = sigInfo,
.defaultTcb = NULL,
=======
.sigInfo = sigInfo, //信号内容
.defaultTcb = NULL, //以下四个值将在OsSigProcessForeachChild中根据条件完善
>>>>>>> remotes/origin/main
.unblockedTcb = NULL,
.awakenedTcb = NULL,
.receivedTcb = NULL
};
<<<<<<< HEAD
if (info.sigInfo == NULL) {
return -EFAULT;
}
/* visit all taskcb and dispatch signal */
if (info.sigInfo->si_signo == SIGKILL) {
OsSigAddSet(&spcb->sigShare, info.sigInfo->si_signo);
(void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info);
return 0;
} else {
ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info);
=======
//总之是要从进程中找个至少一个任务来接受这个信号,优先级
//awakenedTcb > receivedTcb > unblockedTcb > defaultTcb
if (info.sigInfo == NULL){
@ -367,20 +552,37 @@ int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo)
return 0;
} else {
ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info);//进程通知所有task处理信号
>>>>>>> remotes/origin/main
}
if (ret < 0) {
return ret;
}
<<<<<<< HEAD
SigProcessLoadTcb(&info, sigInfo);
return 0;
}
=======
SigProcessLoadTcb(&info, sigInfo);//确保能给一个任务发送信号
return 0;
}
///信号集全部清0
>>>>>>> remotes/origin/main
int OsSigEmptySet(sigset_t *set)
{
*set = NULL_SIGNAL_SET;
return 0;
}
<<<<<<< HEAD
/* Privilege process can't send to kernel and privilege process */
static int OsSignalPermissionToCheck(const LosProcessCB *spcb)
{
UINTPTR gid = (UINTPTR)OS_GET_PGROUP_LEADER(spcb->pgroup);
if (gid == OS_KERNEL_PROCESS_GROUP) {
return -EPERM;
} else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) {
=======
/* Privilege process can't send to kernel and privilege process */ //内核进程组和用户特权进程组无法发送
static int OsSignalPermissionToCheck(const LosProcessCB *spcb)
{
@ -389,18 +591,33 @@ static int OsSignalPermissionToCheck(const LosProcessCB *spcb)
if (gid == OS_KERNEL_PROCESS_GROUP) {//内核进程组
return -EPERM;
} else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) {//用户特权进程组
>>>>>>> remotes/origin/main
return -EPERM;
}
return 0;
}
<<<<<<< HEAD
=======
///信号分发,发送信号权限/进程组过滤.
>>>>>>> remotes/origin/main
STATIC int SendSigPermissionCheck(LosProcessCB *spcb, int permission)
{
if (spcb == NULL) {
return -ESRCH;
}
<<<<<<< HEAD
if (OsProcessIsUnused(spcb)) {
return -ESRCH;
}
#ifdef LOSCFG_SECURITY_CAPABILITY
LosProcessCB *current = OsCurrProcessGet();
/* Kernel process always has kill permission and user process should check permission */
if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) {
=======
if (OsProcessIsUnused(spcb)) {//进程是否还在使用,不一定是当前进程但必须是个有效进程
return -ESRCH;
}
@ -409,6 +626,7 @@ STATIC int SendSigPermissionCheck(LosProcessCB *spcb, int permission)
LosProcessCB *current = OsCurrProcessGet();//获取当前进程,检查当前进程是否有发送信号的权限.
/* Kernel process always has kill permission and user process should check permission *///内核进程总是有kill权限用户进程需要检查权限
if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) {//用户进程检查能力范围
>>>>>>> remotes/origin/main
if ((current != spcb) && (!IsCapPermit(CAP_KILL)) && (current->user->userID != spcb->user->userID)) {
return -EPERM;
}
@ -441,7 +659,11 @@ int OsSendSigToProcess(LosProcessCB *spcb, int sig, int permission)
info.si_code = SI_USER;
info.si_value.sival_ptr = NULL;
<<<<<<< HEAD
return OsSigProcessSend(spcb, &info);
=======
return OsSigProcessSend(spcb, &info);//给参数进程发送信号
>>>>>>> remotes/origin/main
}
int OsDispatch(pid_t pid, siginfo_t *info, int permission)
@ -474,14 +696,24 @@ int OsKill(pid_t pid, int sig, int permission)
return -EINVAL;
}
<<<<<<< HEAD
/* Create the siginfo structure */
info.si_signo = sig;
info.si_code = SI_USER;
=======
/* Create the siginfo structure */ //创建信号结构体
info.si_signo = sig; //信号编号
info.si_code = SI_USER; //来自用户进程信号
>>>>>>> remotes/origin/main
info.si_value.sival_ptr = NULL;
if (pid > 0) {
/* Send the signal to the specify process */
<<<<<<< HEAD
ret = OsDispatch(pid, &info, permission);
=======
ret = OsDispatch(pid, &info, permission);//发送信号
>>>>>>> remotes/origin/main
} else if (pid == -1) {
/* Send SIG to all processes */
ret = OsSendSignalToAllProcess(&info, permission);
@ -493,17 +725,29 @@ int OsKill(pid_t pid, int sig, int permission)
}
return ret;
}
<<<<<<< HEAD
=======
///给发送信号过程加锁
>>>>>>> remotes/origin/main
int OsKillLock(pid_t pid, int sig)
{
int ret;
unsigned int intSave;
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
ret = OsKill(pid, sig, OS_USER_KILL_PERMISSION);
SCHEDULER_UNLOCK(intSave);
return ret;
}
=======
ret = OsKill(pid, sig, OS_USER_KILL_PERMISSION);//用户权限向进程发送信号
SCHEDULER_UNLOCK(intSave);
return ret;
}
>>>>>>> remotes/origin/main
INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo)
{
siginfo_t info;
@ -522,7 +766,11 @@ INT32 OsTaskKillUnsafe(UINT32 taskID, INT32 signo)
* dispatch rules. */
return OsTcbDispatch(taskCB, &info);
}
<<<<<<< HEAD
=======
///发送信号
>>>>>>> remotes/origin/main
int OsPthreadKill(UINT32 tid, int signo)
{
int ret;
@ -540,7 +788,11 @@ int OsPthreadKill(UINT32 tid, int signo)
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
///向信号集中加入signo信号
>>>>>>> remotes/origin/main
int OsSigAddSet(sigset_t *set, int signo)
{
/* Verify the signal */
@ -548,6 +800,15 @@ int OsSigAddSet(sigset_t *set, int signo)
return -EINVAL;
} else {
/* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
<<<<<<< HEAD
signo -= 1;
/* Add the signal to the set */
*set |= SIGNO2SET((unsigned int)signo);
return LOS_OK;
}
}
=======
signo -= 1;// 信号范围是 [1 ~ 64 ],而保存变量位的范围是[0 ~ 63]
/* Add the signal to the set */
*set |= SIGNO2SET((unsigned int)signo);//填充信号集
@ -555,6 +816,7 @@ int OsSigAddSet(sigset_t *set, int signo)
}
}
///获取阻塞当前任务的信号集
>>>>>>> remotes/origin/main
int OsSigPending(sigset_t *set)
{
LosTaskCB *tcb = NULL;
@ -566,7 +828,11 @@ int OsSigPending(sigset_t *set)
SCHEDULER_LOCK(intSave);
tcb = OsCurrTaskGet();
<<<<<<< HEAD
*set = tcb->sig.sigPendFlag;
=======
*set = tcb->sig.sigPendFlag;//被阻塞的信号集
>>>>>>> remotes/origin/main
SCHEDULER_UNLOCK(intSave);
return LOS_OK;
}
@ -581,7 +847,11 @@ STATIC int FindFirstSetedBit(UINT64 n)
for (count = 0; (count < UINT64_BIT_SIZE) && (n ^ 1ULL); n >>= 1, count++) {}
return (count < UINT64_BIT_SIZE) ? count : (-1);
}
<<<<<<< HEAD
=======
///等待信号时间
>>>>>>> remotes/origin/main
int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
{
LosTaskCB *task = NULL;
@ -592,19 +862,32 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
sigcb = &task->sig;
if (sigcb->waitList.pstNext == NULL) {
<<<<<<< HEAD
LOS_ListInit(&sigcb->waitList);
}
/* If pendingflag & set > 0, should clear pending flag */
=======
LOS_ListInit(&sigcb->waitList);//初始化信号等待链表
}
/* If pendingflag & set > 0, shound clear pending flag */
>>>>>>> remotes/origin/main
sigset_t clear = sigcb->sigPendFlag & *set;
if (clear) {
sigcb->sigPendFlag ^= clear;
ret = FindFirstSetedBit((UINT64)clear) + 1;
OsMoveTmpInfoToUnbInfo(sigcb, ret);
} else {
<<<<<<< HEAD
OsSigAddSet(set, SIGKILL);
OsSigAddSet(set, SIGSTOP);
sigcb->sigwaitmask |= *set;
=======
OsSigAddSet(set, SIGKILL);//kill 9 14 必须要处理
OsSigAddSet(set, SIGSTOP);//终止进程的信号也必须处理
sigcb->sigwaitmask |= *set;//按位加到等待集上,也就是说sigwaitmask的信号来了都是要处理的.
>>>>>>> remotes/origin/main
OsTaskWaitSetPendMask(OS_TASK_WAIT_SIGNAL, sigcb->sigwaitmask, timeout);
ret = task->ops->wait(task, &sigcb->waitList, timeout);
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
@ -617,7 +900,11 @@ int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
}
return ret;
}
<<<<<<< HEAD
=======
///让当前任务等待的信号
>>>>>>> remotes/origin/main
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout)
{
int ret;
@ -625,12 +912,20 @@ int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout)
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
ret = OsSigTimedWaitNoLock(set, info, timeout);
=======
ret = OsSigTimedWaitNoLock(set, info, timeout);//以不加锁的方式等待
>>>>>>> remotes/origin/main
SCHEDULER_UNLOCK(intSave);
return ret;
}
<<<<<<< HEAD
=======
///通过信号挂起当前任务
>>>>>>> remotes/origin/main
int OsPause(void)
{
LosTaskCB *spcb = NULL;
@ -640,7 +935,11 @@ int OsPause(void)
oldSigprocmask = spcb->sig.sigprocmask;
return OsSigSuspend(&oldSigprocmask);
}
<<<<<<< HEAD
=======
///用参数set代替进程的原有掩码并暂停进程执行直到收到信号再恢复原有掩码并继续执行进程。
>>>>>>> remotes/origin/main
int OsSigSuspend(const sigset_t *set)
{
unsigned int intSave;
@ -680,7 +979,10 @@ int OsSigSuspend(const sigset_t *set)
return -EINTR;
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
{
UINTPTR addr;
@ -689,6 +991,16 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
if (!GOOD_SIGNO(sig) || sig < 1 || act == NULL) {
return -EINVAL;
}
<<<<<<< HEAD
if (LOS_ArchCopyFromUser(&action, act, sizeof(sigaction_t)) != LOS_OK) {
return -EFAULT;
}
if (sig == SIGSYS) {
addr = OsGetSigHandler();
if (addr == 0) {
OsSetSigHandler((unsigned long)(UINTPTR)action.sa_handler);
=======
//将数据从用户空间拷贝到内核空间
if (LOS_ArchCopyFromUser(&action, act, sizeof(sigaction_t)) != LOS_OK) {
return -EFAULT;
@ -700,6 +1012,7 @@ int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
OsSetSigHandler((unsigned long)(UINTPTR)action.sa_handler);//设置进程信号处理函数
//void (*sa_handler)(int); //信号处理函数——普通版
//void (*sa_sigaction)(int, siginfo_t *, void *);//信号处理函数——高级版
>>>>>>> remotes/origin/main
return LOS_OK;
}
return -EINVAL;
@ -724,11 +1037,18 @@ VOID OsSigIntUnlock(VOID)
(VOID)LOS_AtomicSub((Atomic *)&sigcb->sigIntLock, 1);
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
VOID *OsSaveSignalContext(VOID *sp, VOID *newSp)
{
UINTPTR sigHandler;
UINT32 intSave;
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
LosTaskCB *task = OsCurrTaskGet();
LosProcessCB *process = OsCurrProcessGet();
sig_cb *sigcb = &task->sig;
@ -761,7 +1081,11 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp)
OsProcessExitCodeSignalSet(process, signo);
sigcb->sigContext = sp;
<<<<<<< HEAD
OsInitSignalContext(sp, newSp, sigHandler, signo, sigVal);
=======
OsInitSignalContext(sp, newSp, sigHandler, signo, sigVal);//初始化信号上下文
>>>>>>> remotes/origin/main
/* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
sigcb->sigFlag ^= 1ULL << (signo - 1);
@ -774,7 +1098,10 @@ VOID *OsSaveSignalContext(VOID *sp, VOID *newSp)
return sp;
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
VOID *OsRestorSignalContext(VOID *sp)
{
UINT32 intSave;
@ -793,8 +1120,13 @@ VOID *OsRestorSignalContext(VOID *sp)
VOID *saveContext = sigcb->sigContext;
sigcb->sigContext = NULL;
sigcb->count--;
<<<<<<< HEAD
process->sigShare = 0;
OsProcessExitCodeSignalClear(process);
=======
process->sigShare = 0; //回到用户态,信号共享清0
OsProcessExitCodeSignalClear(process);//清空进程退出码
>>>>>>> remotes/origin/main
SCHEDULER_UNLOCK(intSave);
return saveContext;
}

@ -32,9 +32,15 @@
#include "los_memstat_pri.h"
#include "los_task_pri.h"
<<<<<<< HEAD
LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT];
=======
/// 记录每个任务对内存的使用情况
LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT];
/// 计算指定任务对内存使用增加量
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID)
{
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
@ -43,9 +49,15 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID)
if (OS_INT_ACTIVE) {
return;
}
<<<<<<< HEAD
g_tskMemUsedInfo[taskID].memUsed += usedSize;
}
=======
g_tskMemUsedInfo[taskID].memUsed += usedSize; ///< 叠加
}
/// 计算指定任务对内存使用减少量
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID)
{
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
@ -59,9 +71,15 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID)
OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize);
return;
}
<<<<<<< HEAD
g_tskMemUsedInfo[taskID].memUsed -= usedSize;
}
=======
g_tskMemUsedInfo[taskID].memUsed -= usedSize; ///< 递减
}
/// 获取指定任务对内存的使用情况
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID)
{
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
@ -70,7 +88,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID)
return g_tskMemUsedInfo[taskID].memUsed;
}
<<<<<<< HEAD
=======
/// 清空任务内存使用记录
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID)
{
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
@ -82,8 +104,13 @@ LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID)
}
g_tskMemUsedInfo[taskID].memUsed = 0;
}
<<<<<<< HEAD
#ifdef LOS_MEM_SLAB
=======
// Slab是一种内存分配器通过将内存划分不同大小的空间分配给对象使用来进行缓存管理应用于内核对象的缓存。
#ifdef LOS_MEM_SLAB //
>>>>>>> remotes/origin/main
LITE_OS_SEC_BSS_MINOR STATIC TskSlabUsedInfo g_tskSlabUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT];
LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID)

@ -16,6 +16,8 @@
* to endorse or promote products derived from this software without specific prior written
* permission.
*
<<<<<<< HEAD
=======
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CON/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -34,6 +36,7 @@
* to endorse or promote products derived from this software without specific prior written
* permission.
*
>>>>>>> remotes/origin/main
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
* THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
@ -51,6 +54,8 @@
#include "los_hwi.h"
#include "los_spinlock.h"
<<<<<<< HEAD
=======
#ifdef LOSCFG_AARCH64
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5
#else
@ -256,6 +261,7 @@ TRIBUTORS
#include "los_hwi.h"
#include "los_spinlock.h"
>>>>>>> remotes/origin/main
#ifdef LOSCFG_AARCH64
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5

File diff suppressed because it is too large Load Diff

@ -48,6 +48,8 @@
#include "shell.h"
#endif
<<<<<<< HEAD
=======
/*********************************************
@ -65,6 +67,7 @@ pid 进程ID [1,MAX_INT]
pid256[1-256]
*********************************************/
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID)
{
PRINTK("\nkill: usage: kill [sigspec] [pid]\n");

@ -31,10 +31,14 @@
#include "los_task_pri.h"
<<<<<<< HEAD
=======
// 这个函数接受两个参数一个是地址addr另一个是对齐边界boundary。它返回一个对齐后的地址。
// 这个函数首先检查地址加上边界再减去1是否大于地址如果是
// 就返回地址加上边界再减去1然后与~((UINTPTR)(boundary - 1))进行位与运算的结果,
// 否则就返回地址与~((UINTPTR)(boundary - 1))进行位与运算的结果。这实际上是在对地址进行对齐。
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
{
if ((addr + boundary - 1) > addr) {
@ -44,6 +48,15 @@ LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
}
}
<<<<<<< HEAD
LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs)
{
UINT32 interval;
if (msecs == 0) {
interval = 0;
} else {
=======
LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs)
{
@ -52,6 +65,7 @@ LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs)
if (msecs == 0) {
interval = 0;
// } else { 否则它将毫秒数转换为tick数可能是操作系统的时间单位如果转换后的间隔为0就将间隔设置为1。然后它调用LOS_TaskDelay函数来延迟指定的间隔。
>>>>>>> remotes/origin/main
interval = LOS_MS2Tick(msecs);
if (interval == 0) {
interval = 1;

@ -37,6 +37,12 @@
#include "shcmd.h"
#include "shell.h"
#endif
<<<<<<< HEAD
const StackInfo *g_stackInfo = NULL;
UINT32 g_stackNum;
=======
/**
* @file los_stackinfo.c
* @brief
@ -66,10 +72,27 @@
const StackInfo *g_stackInfo = NULL; ///< CPU所有工作模式的栈信息
UINT32 g_stackNum; ///< CPU所有工作模式的栈数量
///获取栈的吃水线
>>>>>>> remotes/origin/main
UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed)
{
UINT32 size;
const UINTPTR *tmp = NULL;
<<<<<<< HEAD
if (*stackTop == OS_STACK_MAGIC_WORD) {
tmp = stackTop + 1;
while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) {
tmp++;
}
size = (UINT32)((UINTPTR)stackBottom - (UINTPTR)tmp);
*peakUsed = (size == 0) ? size : (size + sizeof(CHAR *));
return LOS_OK;
} else {
*peakUsed = OS_INVALID_WATERLINE;
return LOS_NOK;
}
}
=======
if (*stackTop == OS_STACK_MAGIC_WORD) {//栈顶值是否等于 magic 0xCCCCCCCC
tmp = stackTop + 1;
while ((tmp < stackBottom) && (*tmp == OS_STACK_INIT)) {//记录从栈顶到栈低有多少个连续的 0xCACACACA
@ -84,6 +107,7 @@ UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop,
}
}
///异常情况下的栈检查,主要就是检查栈顶值有没有被改写
>>>>>>> remotes/origin/main
VOID OsExcStackCheck(VOID)
{
UINT32 index;
@ -96,7 +120,11 @@ VOID OsExcStackCheck(VOID)
for (index = 0; index < g_stackNum; index++) {
for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize);
<<<<<<< HEAD
if (*stackTop != OS_STACK_MAGIC_WORD) {
=======
if (*stackTop != OS_STACK_MAGIC_WORD) {// 只要栈顶内容不是 0xCCCCCCCCC 就是溢出了.
>>>>>>> remotes/origin/main
PRINT_ERR("cpu:%u %s overflow , magic word changed to 0x%x\n",
LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, g_stackInfo[index].stackName, *stackTop);
}
@ -104,7 +132,10 @@ VOID OsExcStackCheck(VOID)
}
}
<<<<<<< HEAD
=======
///打印栈的信息 把每个CPU的栈信息打印出来
>>>>>>> remotes/origin/main
VOID OsExcStackInfo(VOID)
{
UINT32 index;
@ -119,17 +150,43 @@ VOID OsExcStackInfo(VOID)
PrintExcInfo("\n stack name cpu id stack addr total size used size\n"
" ---------- ------ --------- -------- --------\n");
<<<<<<< HEAD
for (index = 0; index < g_stackNum; index++) {
for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize);
stack = (UINTPTR *)((UINTPTR)stackTop + g_stackInfo[index].stackSize);
(VOID)OsStackWaterLineGet(stack, stackTop, &size);
=======
for (index = 0; index < g_stackNum; index++) {
for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {//可以看出 各个CPU的栈是紧挨的的
stackTop = (UINTPTR *)((UINTPTR)g_stackInfo[index].stackTop + cpuid * g_stackInfo[index].stackSize);
stack = (UINTPTR *)((UINTPTR)stackTop + g_stackInfo[index].stackSize);
(VOID)OsStackWaterLineGet(stack, stackTop, &size);//获取吃水线, 鸿蒙用WaterLine 这个词用的很妙
>>>>>>> remotes/origin/main
PrintExcInfo("%11s %-5d %-10p 0x%-8x 0x%-4x\n", g_stackInfo[index].stackName,
LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, stackTop, g_stackInfo[index].stackSize, size);
}
}
<<<<<<< HEAD
OsExcStackCheck();
}
VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum)
{
g_stackInfo = stackInfo;
g_stackNum = stackNum;
}
VOID OsStackInit(VOID *stacktop, UINT32 stacksize)
{
/* initialize the task stack, write magic num to stack top */
errno_t ret = memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize);
if (ret == EOK) {
*((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD;
=======
OsExcStackCheck();//发生异常时栈检查
}
@ -147,9 +204,14 @@ VOID OsStackInit(VOID *stacktop, UINT32 stacksize)
errno_t ret = memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize);//清一色填 0xCACACACA
if (ret == EOK) {
*((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD;//0xCCCCCCCCC 中文就是"烫烫烫烫" 这几个字懂点计算机的人都不会陌生了.
>>>>>>> remotes/origin/main
}
}
#ifdef LOSCFG_SHELL_CMD_DEBUG
<<<<<<< HEAD
SHELLCMD_ENTRY(stack_shellcmd, CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsExcStackInfo);
=======
SHELLCMD_ENTRY(stack_shellcmd, CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsExcStackInfo);//采用shell命令静态注册方式
>>>>>>> remotes/origin/main
#endif

@ -193,7 +193,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[])
if (argc == 1) {
if (strcmp(argv[0], "-a") == 0) {
<<<<<<< HEAD
PRINTK("%s %d.%d.%d.%d %s %s\n", KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE, \
=======
PRINTK("%s %d.%d.%d.%d %s %s\n", KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE,\
>>>>>>> remotes/origin/main
__DATE__, __TIME__);
return 0;
} else if (strcmp(argv[0], "-s") == 0) {

@ -58,6 +58,15 @@ STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr)
(VOID)LOS_SwtmrTimeGet(swtmr->usTimerID, &ticks);
PRINTK("%7u%10s%8s%12u%7u%#12x%#12x\n",
<<<<<<< HEAD
swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT,
g_shellSwtmrStatus[swtmr->ucState],
g_shellSwtmrMode[swtmr->ucMode],
swtmr->uwInterval,
ticks,
swtmr->uwArg,
swtmr->pfnHandler);
=======
swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT, //软件定时器ID。
g_shellSwtmrStatus[swtmr->ucState], //软件定时器状态,状态可能为:"UnUsed", "Created", "Ticking"。
g_shellSwtmrMode[swtmr->ucMode], //软件定时器模式。模式可能为:"Once", "Period", "NSD单次定时器定时结束后不会自动删除"
@ -65,14 +74,19 @@ STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr)
ticks,
swtmr->uwArg, //传入的参数。
swtmr->pfnHandler); //回调函数的地址。
>>>>>>> remotes/origin/main
}
STATIC INLINE VOID OsPrintSwtmrMsgHead(VOID)
{
PRINTK("\r\nSwTmrID State Mode Interval Count Arg handlerAddr\n");
}
<<<<<<< HEAD
=======
///shell命令之swtmr 命令用于查询系统软件定时器相关信息。
//参数缺省时,默认显示所有软件定时器的相关信息。
>>>>>>> remotes/origin/main
STATIC UINT32 SwtmrBaseInfoGet(UINT32 timerID)
{
SWTMR_CTRL_S *swtmr = g_swtmrCBArray;
@ -174,6 +188,11 @@ SWTMR_HELP:
PRINTK(" swtmr ID --- Specifies information about a software timer.\n");
return LOS_OK;
}
<<<<<<< HEAD
SHELLCMD_ENTRY(swtmr_shellcmd, CMD_TYPE_EX, "swtmr", 1, (CmdCallBackFunc)OsShellCmdSwtmrInfoGet);
=======
SHELLCMD_ENTRY(swtmr_shellcmd, CMD_TYPE_EX, "swtmr", 1, (CmdCallBackFunc)OsShellCmdSwtmrInfoGet);//采用shell命令静态注册方式
>>>>>>> remotes/origin/main
#endif /* LOSCFG_SHELL */

@ -118,7 +118,11 @@ UINT32 OsShellCmdSwtmrCntGet(VOID)
LOS_IntRestore(intSave);
return swtmrCnt;
}
<<<<<<< HEAD
=======
///查看系统资源使用情况
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID)
{
UINT8 isTaskEnable = TRUE;
@ -137,6 +141,29 @@ LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID)
#else
UINT8 isSwtmrEnable = FALSE;
#endif
<<<<<<< HEAD
PRINTK("\n Module Used Total Enabled\n");
PRINTK("--------------------------------------------\n");
PRINTK(" Task %-10u%-10d%s\n",
OsShellCmdTaskCntGet(),
LOSCFG_BASE_CORE_TSK_LIMIT,
SYSINFO_ENABLED(isTaskEnable));
PRINTK(" Sem %-10u%-10d%s\n",
OsShellCmdSemCntGet(),
LOSCFG_BASE_IPC_SEM_LIMIT,
SYSINFO_ENABLED(isSemEnable));
PRINTK(" Queue %-10u%-10d%s\n",
OsShellCmdQueueCntGet(),
LOSCFG_BASE_IPC_QUEUE_LIMIT,
SYSINFO_ENABLED(isQueueEnable));
PRINTK(" SwTmr %-10u%-10d%s\n",
OsShellCmdSwtmrCntGet(),
LOSCFG_BASE_CORE_SWTMR_LIMIT,
SYSINFO_ENABLED(isSwtmrEnable));
}
=======
//模块名称 当前使用量 最大可用量 模块是否开启
PRINTK("\n Module Used Total Enabled\n");
PRINTK("--------------------------------------------\n");
@ -158,6 +185,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID)
SYSINFO_ENABLED(isSwtmrEnable)); //定时器是否失效 YES or NO
}
///systeminfo命令用于显示当前操作系统内资源使用情况包括任务、信号量、互斥量、队列、定时器等。
>>>>>>> remotes/origin/main
INT32 OsShellCmdSystemInfo(INT32 argc, const CHAR **argv)
{
if (argc == 0) {

@ -54,7 +54,11 @@
#define VMM_CMD "vmm"
#define OOM_CMD "oom"
#define VMM_PMM_CMD "v2p"
<<<<<<< HEAD
=======
//dump内核空间
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OsDumpKernelAspace(VOID)
{
LosVmSpace *kAspace = LOS_GetKVmSpace();
@ -104,6 +108,28 @@ LITE_OS_SEC_TEXT_MINOR VOID OsDoDumpVm(pid_t pid)
PRINTK("\tThe process [%d] not active\n", pid);
}
}
<<<<<<< HEAD
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpVm(INT32 argc, const CHAR *argv[])
{
if (argc == 0) {
OsDumpAllAspace();
} else if (argc == 1) {
pid_t pid = OsPid(argv[0]);
if (strcmp(argv[0], "-a") == 0) {
OsDumpAllAspace();
} else if (strcmp(argv[0], "-k") == 0) {
OsDumpKernelAspace();
} else if (pid >= 0) {
OsDoDumpVm(pid);
} else if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) {
OsPrintUsage();
} else {
PRINTK("%s: invalid option: %s\n", VMM_CMD, argv[0]);
OsPrintUsage();
}
} else {
=======
///查看进程的虚拟内存使用情况。vmm [-a / -h / --help] vmm [pid]
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpVm(INT32 argc, const CHAR *argv[])
{
@ -124,6 +150,7 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpVm(INT32 argc, const CHAR *argv[])
OsPrintUsage();
}
} else { //多于一个参数 例如 # vmm 3 9
>>>>>>> remotes/origin/main
OsPrintUsage();
}
@ -135,7 +162,11 @@ LITE_OS_SEC_TEXT_MINOR VOID V2PPrintUsage(VOID)
PRINTK("pid vaddr(0x1000000~0x3e000000), print physical address of virtual address\n"
"-h | --help, print v2p command usage\n");
}
<<<<<<< HEAD
=======
///v2p 虚拟内存对应的物理内存
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdV2P(INT32 argc, const CHAR *argv[])
{
UINT32 vaddr;
@ -180,7 +211,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdV2P(INT32 argc, const CHAR *argv[])
return LOS_OK;
}
<<<<<<< HEAD
=======
///查看系统内存物理页及pagecache物理页使用情况 , Debug版本才具备的命令 # pmm
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpPmm(VOID)
{
OsVmPhysDump();
@ -192,6 +227,14 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpPmm(VOID)
LITE_OS_SEC_TEXT_MINOR VOID OomPrintUsage(VOID)
{
<<<<<<< HEAD
PRINTK("\t-i [interval], set oom check interval (ms)\n"
"\t-m [mem byte], set oom low memory threshold (Byte)\n"
"\t-r [mem byte], set page cache reclaim memory threshold (Byte)\n"
"\t-h | --help, print vmm command usage\n");
}
=======
PRINTK("\t-i [interval], set oom check interval (ms)\n" //设置oom线程任务检查的时间间隔。
"\t-m [mem byte], set oom low memory threshold (Byte)\n" //设置低内存阈值。
"\t-r [mem byte], set page cache reclaim memory threshold (Byte)\n" //设置pagecache内存回收阈值。
@ -199,6 +242,7 @@ LITE_OS_SEC_TEXT_MINOR VOID OomPrintUsage(VOID)
}
///查看和设置低内存阈值以及pagecache内存回收阈值。参数缺省时显示oom功能当前配置信息。
//当系统内存不足时,会打印出内存不足的提示信息。
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[])
{
UINT32 lowMemThreshold;
@ -220,7 +264,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[])
PRINTK("[oom] low mem threshold %s(byte) invalid.\n", argv[1]);
return OS_ERROR;
} else {
<<<<<<< HEAD
OomSetLowMemThreashold(lowMemThreshold);
=======
OomSetLowMemThreashold(lowMemThreshold);//设置低内存阈值
>>>>>>> remotes/origin/main
}
} else if (strcmp(argv[0], "-i") == 0) {
checkInterval = strtoul((CHAR *)argv[1], &endPtr, 0);
@ -228,7 +276,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[])
PRINTK("[oom] check interval %s(us) invalid.\n", argv[1]);
return OS_ERROR;
} else {
<<<<<<< HEAD
OomSetCheckInterval(checkInterval);
=======
OomSetCheckInterval(checkInterval);//设置oom线程任务检查的时间间隔
>>>>>>> remotes/origin/main
}
} else if (strcmp(argv[0], "-r") == 0) {
reclaimMemThreshold = strtoul((CHAR *)argv[1], &endPtr, 0);
@ -236,7 +288,11 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[])
PRINTK("[oom] reclaim mem threshold %s(byte) invalid.\n", argv[1]);
return OS_ERROR;
} else {
<<<<<<< HEAD
OomSetReclaimMemThreashold(reclaimMemThreshold);
=======
OomSetReclaimMemThreashold(reclaimMemThreshold);//设置pagecache内存回收阈值
>>>>>>> remotes/origin/main
}
} else {
PRINTK("%s: invalid option: %s %s\n", OOM_CMD, argv[0], argv[1]);
@ -251,6 +307,15 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[])
}
#ifdef LOSCFG_SHELL_CMD_DEBUG
<<<<<<< HEAD
SHELLCMD_ENTRY(oom_shellcmd, CMD_TYPE_SHOW, OOM_CMD, 2, (CmdCallBackFunc)OsShellCmdOom);
SHELLCMD_ENTRY(vm_shellcmd, CMD_TYPE_SHOW, VMM_CMD, 1, (CmdCallBackFunc)OsShellCmdDumpVm);
SHELLCMD_ENTRY(v2p_shellcmd, CMD_TYPE_SHOW, VMM_PMM_CMD, 1, (CmdCallBackFunc)OsShellCmdV2P);
#endif
#ifdef LOSCFG_SHELL
SHELLCMD_ENTRY(pmm_shellcmd, CMD_TYPE_SHOW, "pmm", 0, (CmdCallBackFunc)OsShellCmdDumpPmm);
=======
SHELLCMD_ENTRY(oom_shellcmd, CMD_TYPE_SHOW, OOM_CMD, 2, (CmdCallBackFunc)OsShellCmdOom);//采用shell命令静态注册方式
SHELLCMD_ENTRY(vm_shellcmd, CMD_TYPE_SHOW, VMM_CMD, 1, (CmdCallBackFunc)OsShellCmdDumpVm);//采用shell命令静态注册方式 vmm
SHELLCMD_ENTRY(v2p_shellcmd, CMD_TYPE_SHOW, VMM_PMM_CMD, 1, (CmdCallBackFunc)OsShellCmdV2P);//采用shell命令静态注册方式 v2p
@ -258,6 +323,7 @@ SHELLCMD_ENTRY(v2p_shellcmd, CMD_TYPE_SHOW, VMM_PMM_CMD, 1, (CmdCallBackFunc)OsS
#ifdef LOSCFG_SHELL
SHELLCMD_ENTRY(pmm_shellcmd, CMD_TYPE_SHOW, "pmm", 0, (CmdCallBackFunc)OsShellCmdDumpPmm);//采用shell命令静态注册方式
>>>>>>> remotes/origin/main
#endif
#endif

@ -36,14 +36,29 @@
#include "los_swtmr.h"
#include "los_task_pri.h"
<<<<<<< HEAD
#ifdef LOSCFG_KERNEL_SMP
=======
#ifdef LOSCFG_KERNEL_SMP
//给参数CPU发送调度信号
>>>>>>> remotes/origin/main
#ifdef LOSCFG_KERNEL_SMP_CALL
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_mpCallSpin);
#define MP_CALL_LOCK(state) LOS_SpinLockSave(&g_mpCallSpin, &(state))
#define MP_CALL_UNLOCK(state) LOS_SpinUnlockRestore(&g_mpCallSpin, (state))
#endif
<<<<<<< HEAD
VOID LOS_MpSchedule(UINT32 target)
{
UINT32 cpuid = ArchCurrCpuid();
target &= ~(1U << cpuid);
HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);
}
=======
VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core
{
UINT32 cpuid = ArchCurrCpuid();
@ -51,19 +66,37 @@ VOID LOS_MpSchedule(UINT32 target)//target每位对应CPU core
HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);//向目标CPU发送调度信号,核间中断(Inter-Processor Interrupts),IPI
}
///硬中断唤醒处理函数
>>>>>>> remotes/origin/main
VOID OsMpWakeHandler(VOID)
{
/* generic wakeup ipi, do nothing */
}
<<<<<<< HEAD
VOID OsMpScheduleHandler(VOID)
{
=======
///硬中断调度处理函数
VOID OsMpScheduleHandler(VOID)
{//将调度标志设置为与唤醒功能不同,这样就可以在硬中断结束时触发调度程序。
>>>>>>> remotes/origin/main
/*
* set schedule flag to differ from wake function,
* so that the scheduler can be triggered at the end of irq.
*/
OsSchedRunqueuePendingSet();
}
<<<<<<< HEAD
VOID OsMpHaltHandler(VOID)
{
(VOID)LOS_IntLock();
OsPercpuGet()->excFlag = CPU_HALT;
while (1) {}
}
=======
///硬中断暂停处理函数
VOID OsMpHaltHandler(VOID)
{
@ -73,6 +106,7 @@ VOID OsMpHaltHandler(VOID)
while (1) {}//陷入空循环,也就是空闲状态
}
///MP定时器处理函数, 递归检查所有可用任务
>>>>>>> remotes/origin/main
VOID OsMpCollectTasks(VOID)
{
LosTaskCB *taskCB = NULL;
@ -80,19 +114,32 @@ VOID OsMpCollectTasks(VOID)
UINT32 ret;
/* recursive checking all the available task */
<<<<<<< HEAD
for (; taskID <= g_taskMaxNum; taskID++) {
=======
for (; taskID <= g_taskMaxNum; taskID++) { //递归检查所有可用任务
>>>>>>> remotes/origin/main
taskCB = &g_taskCBArray[taskID];
if (OsTaskIsUnused(taskCB) || OsTaskIsRunning(taskCB)) {
continue;
}
<<<<<<< HEAD
/*
* though task status is not atomic, this check may success but not accomplish
* the deletion; this deletion will be handled until the next run.
*/
if (taskCB->signal & SIGNAL_KILL) {
ret = LOS_TaskDelete(taskID);
=======
/* 虽然任务状态不是原子的,但此检查可能成功,但无法完成删除,此删除将在下次运行之前处理
* though task status is not atomic, this check may success but not accomplish
* the deletion; this deletion will be handled until the next run.
*/
if (taskCB->signal & SIGNAL_KILL) {//任务收到被干掉信号
ret = LOS_TaskDelete(taskID);//干掉任务,回归任务池
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
PRINT_WARN("GC collect task failed err:0x%x\n", ret);
}
@ -101,7 +148,10 @@ VOID OsMpCollectTasks(VOID)
}
#ifdef LOSCFG_KERNEL_SMP_CALL
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
{
UINT32 index;
@ -111,6 +161,15 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
return;
}
<<<<<<< HEAD
if (!(target & OS_MP_CPU_ALL)) {
return;
}
for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {
if (CPUID_TO_AFFI_MASK(index) & target) {
MpCallFunc *mpCallFunc = (MpCallFunc *)LOS_MemAlloc(m_aucSysMem0, sizeof(MpCallFunc));
=======
if (!(target & OS_MP_CPU_ALL)) {//检查目标CPU是否正确
return;
}
@ -118,6 +177,7 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {//遍历所有核
if (CPUID_TO_AFFI_MASK(index) & target) {
MpCallFunc *mpCallFunc = (MpCallFunc *)LOS_MemAlloc(m_aucSysMem0, sizeof(MpCallFunc));//从内核空间 分配回调结构体
>>>>>>> remotes/origin/main
if (mpCallFunc == NULL) {
PRINT_ERR("smp func call malloc failed\n");
return;
@ -126,6 +186,19 @@ VOID OsMpFuncCall(UINT32 target, SMP_FUNC_CALL func, VOID *args)
mpCallFunc->args = args;
MP_CALL_LOCK(intSave);
<<<<<<< HEAD
LOS_ListAdd(&g_percpu[index].funcLink, &(mpCallFunc->node));
MP_CALL_UNLOCK(intSave);
}
}
HalIrqSendIpi(target, LOS_MP_IPI_FUNC_CALL);
}
VOID OsMpFuncCallHandler(VOID)
{
UINT32 intSave;
UINT32 cpuid = ArchCurrCpuid();
=======
LOS_ListAdd(&g_percpu[index].funcLink, &(mpCallFunc->node));//将回调结构体挂入链表尾部
MP_CALL_UNLOCK(intSave);
}
@ -144,10 +217,21 @@ VOID OsMpFuncCallHandler(VOID)
{
UINT32 intSave;
UINT32 cpuid = ArchCurrCpuid();//获取当前CPU
>>>>>>> remotes/origin/main
LOS_DL_LIST *list = NULL;
MpCallFunc *mpCallFunc = NULL;
MP_CALL_LOCK(intSave);
<<<<<<< HEAD
while (!LOS_ListEmpty(&g_percpu[cpuid].funcLink)) {
list = LOS_DL_LIST_FIRST(&g_percpu[cpuid].funcLink);
LOS_ListDelete(list);
MP_CALL_UNLOCK(intSave);
mpCallFunc = LOS_DL_LIST_ENTRY(list, MpCallFunc, node);
mpCallFunc->func(mpCallFunc->args);
(VOID)LOS_MemFree(m_aucSysMem0, mpCallFunc);
=======
while (!LOS_ListEmpty(&g_percpu[cpuid].funcLink)) {//遍历回调函数链表,知道为空
list = LOS_DL_LIST_FIRST(&g_percpu[cpuid].funcLink);//获取链表第一个数据
LOS_ListDelete(list);//将自己从链表上摘除
@ -156,11 +240,25 @@ VOID OsMpFuncCallHandler(VOID)
mpCallFunc = LOS_DL_LIST_ENTRY(list, MpCallFunc, node);//获取回调函数
mpCallFunc->func(mpCallFunc->args);//获取参数并回调该函数
(VOID)LOS_MemFree(m_aucSysMem0, mpCallFunc);//释放回调函数内存
>>>>>>> remotes/origin/main
MP_CALL_LOCK(intSave);
}
MP_CALL_UNLOCK(intSave);
}
<<<<<<< HEAD
VOID OsMpFuncCallInit(VOID)
{
UINT32 index;
/* init funclink for each core */
for (index = 0; index < LOSCFG_KERNEL_CORE_NUM; index++) {
LOS_ListInit(&g_percpu[index].funcLink);
}
}
#endif /* LOSCFG_KERNEL_SMP_CALL */
=======
/// CPU层级的回调模块初始化
VOID OsMpFuncCallInit(VOID)
{
@ -172,20 +270,31 @@ VOID OsMpFuncCallInit(VOID)
}
#endif /* LOSCFG_KERNEL_SMP_CALL */
//MP(multiprocessing) 多核处理器初始化
>>>>>>> remotes/origin/main
UINT32 OsMpInit(VOID)
{
UINT16 swtmrId;
<<<<<<< HEAD
(VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD,
(SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0);
(VOID)LOS_SwtmrStart(swtmrId);
=======
(VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD, //创建一个周期性,持续时间为 100个tick的定时器
(SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0);//OsMpCollectTasks为超时回调函数
(VOID)LOS_SwtmrStart(swtmrId);//开始定时任务
>>>>>>> remotes/origin/main
#ifdef LOSCFG_KERNEL_SMP_CALL
OsMpFuncCallInit();
#endif
return LOS_OK;
}
<<<<<<< HEAD
LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK);
=======
LOS_MODULE_INIT(OsMpInit, LOS_INIT_LEVEL_KMOD_TASK);//多处理器模块初始化
>>>>>>> remotes/origin/main
#endif

@ -33,7 +33,11 @@
#include "los_printf.h"
#ifdef LOSCFG_KERNEL_SMP
<<<<<<< HEAD
Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];
=======
Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM]; ///< CPU池,池大小由CPU核数决定
>>>>>>> remotes/origin/main
VOID OsAllCpuStatusOutput(VOID)
{

@ -31,6 +31,11 @@
#include "los_err.h"
<<<<<<< HEAD
LITE_OS_SEC_BSS STATIC LOS_ERRORHANDLE_FUNC g_errHandleHook = NULL;
=======
/**
@ -54,6 +59,7 @@ LITE_OS_SEC_BSS STATIC LOS_ERRORHANDLE_FUNC g_errHandleHook = NULL;///< 错误
* @param para NULL
* @return LITE_OS_SEC_TEXT_INIT
*/
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo,
UINT32 paraLen, VOID *para)
{
@ -63,7 +69,11 @@ LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32
return LOS_OK;
}
<<<<<<< HEAD
=======
///设置钩子函数,处理错误
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_INIT VOID LOS_SetErrHandleHook(LOS_ERRORHANDLE_FUNC fun)
{
g_errHandleHook = fun;

@ -44,7 +44,11 @@ STATIC VOID IdleTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 cur
STATIC INT32 IdleParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2);
STATIC VOID IdlePriorityInheritance(LosTaskCB *owner, const SchedParam *param);
STATIC VOID IdlePriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);
<<<<<<< HEAD
=======
//空闲调度
>>>>>>> remotes/origin/main
const STATIC SchedOps g_idleOps = {
.dequeue = IdleDequeue,
.enqueue = IdleEnqueue,

@ -1,5 +1,9 @@
/*
<<<<<<< HEAD
* Copyright (c) 2022-2023 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -43,8 +47,11 @@
#define OS_SCHED_READY_MAX 30
#define OS_TIME_SLICE_MIN (INT32)((50 * OS_SYS_NS_PER_US) / OS_NS_PER_CYCLE) /* 50us */
<<<<<<< HEAD
=======
//基于优先数调度算法 Highest-Priority-First (HPF)
>>>>>>> remotes/origin/main
STATIC HPFRunqueue g_schedHPF;
STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB);
@ -65,7 +72,11 @@ STATIC VOID HPFTimeSliceUpdate(SchedRunqueue *rq, LosTaskCB *taskCB, UINT64 curr
STATIC INT32 HPFParamCompare(const SchedPolicy *sp1, const SchedPolicy *sp2);
STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param);
STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param);
<<<<<<< HEAD
=======
//优先级调度算法操作
>>>>>>> remotes/origin/main
const STATIC SchedOps g_priorityOps = {
.dequeue = HPFDequeue,
.enqueue = HPFEnqueue,
@ -245,7 +256,11 @@ STATIC INLINE VOID PriQueInsert(HPFRunqueue *rq, LosTaskCB *taskCB)
taskCB->taskStatus &= ~OS_TASK_STATUS_BLOCKED;
taskCB->taskStatus |= OS_TASK_STATUS_READY;
}
<<<<<<< HEAD
=======
//入就绪队列
>>>>>>> remotes/origin/main
STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB)
{
#ifdef LOSCFG_SCHED_HPF_DEBUG
@ -255,14 +270,24 @@ STATIC VOID HPFEnqueue(SchedRunqueue *rq, LosTaskCB *taskCB)
#endif
PriQueInsert(rq->hpfRunqueue, taskCB);
}
<<<<<<< HEAD
=======
//出就绪队列
>>>>>>> remotes/origin/main
STATIC VOID HPFDequeue(SchedRunqueue *rq, LosTaskCB *taskCB)
{
SchedHPF *sched = (SchedHPF *)&taskCB->sp;
<<<<<<< HEAD
if (taskCB->taskStatus & OS_TASK_STATUS_READY) {
PriQueDelete(rq->hpfRunqueue, sched->basePrio, &taskCB->pendList, sched->priority);
taskCB->taskStatus &= ~OS_TASK_STATUS_READY;
=======
if (taskCB->taskStatus & OS_TASK_STATUS_READY) {//是否有就绪状态
PriQueDelete(rq->hpfRunqueue, sched->basePrio, &taskCB->pendList, sched->priority);
taskCB->taskStatus &= ~OS_TASK_STATUS_READY;//更新成非就绪状态
>>>>>>> remotes/origin/main
}
}
@ -477,7 +502,11 @@ STATIC VOID HPFPriorityInheritance(LosTaskCB *owner, const SchedParam *param)
LOS_BitmapSet(&sp->priBitmap, sp->priority);
sp->priority = param->priority;
}
<<<<<<< HEAD
=======
/// 恢复任务优先级
>>>>>>> remotes/origin/main
STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const SchedParam *param)
{
UINT16 priority;
@ -500,8 +529,13 @@ STATIC VOID HPFPriorityRestore(LosTaskCB *owner, const LOS_DL_LIST *list, const
}
if ((list != NULL) && !LOS_ListEmpty((LOS_DL_LIST *)list)) {
<<<<<<< HEAD
priority = LOS_HighBitGet(sp->priBitmap);
LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) {
=======
priority = LOS_HighBitGet(sp->priBitmap);//获取在历史调度中最高优先级
LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, list, LosTaskCB, pendList) {//遍历链表
>>>>>>> remotes/origin/main
SchedHPF *pendSp = (SchedHPF *)&pendedTask->sp;
if ((pendedTask->ops == owner->ops) && (priority != pendSp->priority)) {
LOS_BitmapClr(&sp->priBitmap, pendSp->priority);
@ -539,7 +573,11 @@ VOID HPFProcessDefaultSchedParamGet(SchedParam *param)
{
param->basePrio = OS_USER_PROCESS_PRIORITY_HIGHEST;
}
<<<<<<< HEAD
=======
//HPF 调度策略初始化
>>>>>>> remotes/origin/main
VOID HPFSchedPolicyInit(SchedRunqueue *rq)
{
if (ArchCurrCpuid() > 0) {

@ -1,6 +1,10 @@
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
<<<<<<< HEAD
* Copyright (c) 2020-2022 Huawei Device Co., Ltd. All rights reserved.
=======
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
>>>>>>> remotes/origin/main
*
* Redistribution and use in source and binary forms, with or without modification,
* are permitted provided that the following conditions are met:
@ -30,7 +34,11 @@
*/
#include "los_sortlink_pri.h"
<<<<<<< HEAD
=======
/// 排序链表初始化
>>>>>>> remotes/origin/main
VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
{
LOS_ListInit(&sortLinkHeader->sortLink);
@ -38,6 +46,33 @@ VOID OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
sortLinkHeader->nodeNum = 0;
}
<<<<<<< HEAD
STATIC INLINE VOID AddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
{
LOS_DL_LIST *head = (LOS_DL_LIST *)&sortLinkHeader->sortLink;
if (LOS_ListEmpty(head)) {
LOS_ListHeadInsert(head, &sortList->sortLinkNode);
sortLinkHeader->nodeNum++;
return;
}
SortLinkList *listSorted = LOS_DL_LIST_ENTRY(head->pstNext, SortLinkList, sortLinkNode);
if (listSorted->responseTime > sortList->responseTime) {
LOS_ListAdd(head, &sortList->sortLinkNode);
sortLinkHeader->nodeNum++;
return;
} else if (listSorted->responseTime == sortList->responseTime) {
LOS_ListAdd(head->pstNext, &sortList->sortLinkNode);
sortLinkHeader->nodeNum++;
return;
}
LOS_DL_LIST *prevNode = head->pstPrev;
do {
listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode);
if (listSorted->responseTime <= sortList->responseTime) {
=======
/*!
* @brief OsAddNode2SortLink ,
*
@ -72,13 +107,19 @@ STATIC INLINE VOID AddNode2SortLink(SortLinkAttribute *sortLinkHeader, SortLinkL
do { // @note_good 这里写的有点妙,也是双向链表的魅力所在
listSorted = LOS_DL_LIST_ENTRY(prevNode, SortLinkList, sortLinkNode);//一个个遍历,先比大的再比小的
if (listSorted->responseTime <= sortList->responseTime) {//如果时间比你小,就插到后面
>>>>>>> remotes/origin/main
LOS_ListAdd(prevNode, &sortList->sortLinkNode);
sortLinkHeader->nodeNum++;
break;
}
<<<<<<< HEAD
prevNode = prevNode->pstPrev;
} while (1);
=======
prevNode = prevNode->pstPrev;//再拿上一个更小的responseTime进行比较
} while (1);//死循环
>>>>>>> remotes/origin/main
}
VOID OsAdd2SortLink(SortLinkAttribute *head, SortLinkList *node, UINT64 responseTime, UINT16 idleCpu)

@ -159,26 +159,44 @@ UINT32 OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm)
/* Kernel resident memory, include default heap memory */
memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT);
<<<<<<< HEAD
spaceList = LOS_GetVmSpaceList();
LosMux *vmSpaceListMux = OsGVmSpaceMuxGet();
(VOID)LOS_MuxAcquire(vmSpaceListMux);
LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) {
if (space == LOS_GetKVmSpace()) {
=======
spaceList = LOS_GetVmSpaceList();//获取虚拟空间链表,上面挂了所有虚拟空间
LosMux *vmSpaceListMux = OsGVmSpaceMuxGet();
(VOID)LOS_MuxAcquire(vmSpaceListMux);
LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) {//遍历链表
if (space == LOS_GetKVmSpace()) {//内核空间不统计
>>>>>>> remotes/origin/main
continue;
}
UProcessUsed += OsUProcessPmUsage(space, NULL, NULL);
}
(VOID)LOS_MuxRelease(vmSpaceListMux);
<<<<<<< HEAD
/* Kernel dynamic memory, include extended heap memory */
memUsed += ((usedCount << PAGE_SHIFT) - UProcessUsed);
/* Remaining heap memory */
=======
/* Kernel dynamic memory, include extended heap memory */ //内核动态内存,包括扩展堆内存
memUsed += ((usedCount << PAGE_SHIFT) - UProcessUsed);
/* Remaining heap memory */ //剩余堆内存
>>>>>>> remotes/origin/main
memUsed -= freeMem;
*actualPm = memUsed;
return memUsed;
}
<<<<<<< HEAD
=======
///shell task 物理内存的使用情况
>>>>>>> remotes/origin/main
UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
{
if (space == NULL) {
@ -194,7 +212,11 @@ UINT32 OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actu
}
return OsUProcessPmUsage(space, sharePm, actualPm);
}
<<<<<<< HEAD
=======
///虚拟空间物理内存的使用情况参数同时带走共享物理内存sharePm和actualPm单位是字节
>>>>>>> remotes/origin/main
UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
{
LosVmMapRegion *region = NULL;
@ -230,10 +252,17 @@ UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
continue;
}
<<<<<<< HEAD
shareRef = LOS_AtomicRead(&page->refCounts);
if (shareRef > 1) {
if (sharePm != NULL) {
*sharePm += PAGE_SIZE;
=======
shareRef = LOS_AtomicRead(&page->refCounts);//ref 大于1 说明page被其他空间也引用了
if (shareRef > 1) {
if (sharePm != NULL) {
*sharePm += PAGE_SIZE;//一页4K字节
>>>>>>> remotes/origin/main
}
pmSize += PAGE_SIZE / shareRef;
} else {
@ -250,9 +279,13 @@ UINT32 OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
return pmSize;
}
<<<<<<< HEAD
=======
/// @brief 通过虚拟空间获取进程实体
/// @param space
/// @return
>>>>>>> remotes/origin/main
LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
{
UINT32 pid;
@ -260,6 +293,15 @@ LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
LosProcessCB *processCB = NULL;
SCHEDULER_LOCK(intSave);
<<<<<<< HEAD
for (pid = 0; pid < g_processMaxNum; ++pid) {
processCB = g_processCBArray + pid;
if (OsProcessIsUnused(processCB)) {
continue;
}
if (processCB->vmSpace == space) {
=======
for (pid = 0; pid < g_processMaxNum; ++pid) {//循环进程池,进程池本质是个数组
processCB = g_processCBArray + pid;
if (OsProcessIsUnused(processCB)) {//进程还没被分配使用
@ -267,6 +309,7 @@ LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
}
if (processCB->vmSpace == space) {//找到了
>>>>>>> remotes/origin/main
SCHEDULER_UNLOCK(intSave);
return processCB;
}
@ -274,11 +317,15 @@ LosProcessCB *OsGetPIDByAspace(const LosVmSpace *space)
SCHEDULER_UNLOCK(intSave);
return NULL;
}
<<<<<<< HEAD
=======
/// @brief 统计虚拟空间中某个线性区的页数
/// @param space
/// @param region
/// @param pssPages
/// @return
>>>>>>> remotes/origin/main
UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages)
{
UINT32 regionPages = 0;
@ -312,7 +359,11 @@ UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pss
return regionPages;
}
<<<<<<< HEAD
=======
///统计虚拟空间的总页数
>>>>>>> remotes/origin/main
UINT32 OsCountAspacePages(LosVmSpace *space)
{
UINT32 spacePages = 0;
@ -396,30 +447,49 @@ VOID OsDumpRegion2(LosVmSpace *space, LosVmMapRegion *region)
region->range.size, flagsStr, regionPages, pssPages);
(VOID)LOS_MemFree(m_aucSysMem0, flagsStr);
}
<<<<<<< HEAD
=======
///dump 指定虚拟空间的信息
>>>>>>> remotes/origin/main
VOID OsDumpAspace(LosVmSpace *space)
{
LosVmMapRegion *region = NULL;
LosRbNode *pstRbNode = NULL;
LosRbNode *pstRbNodeNext = NULL;
UINT32 spacePages;
<<<<<<< HEAD
LosProcessCB *pcb = OsGetPIDByAspace(space);
=======
LosProcessCB *pcb = OsGetPIDByAspace(space);//通过虚拟空间找到进程实体
>>>>>>> remotes/origin/main
if (pcb == NULL) {
return;
}
<<<<<<< HEAD
spacePages = OsCountAspacePages(space);
=======
//进程ID | 进程虚拟内存控制块地址信息 | 虚拟内存起始地址 | 虚拟内存大小 | 已使用的物理页数量
spacePages = OsCountAspacePages(space);//获取空间的页数
>>>>>>> remotes/origin/main
PRINTK("\r\n PID aspace name base size pages \n");
PRINTK(" ---- ------ ---- ---- ----- ----\n");
PRINTK(" %-4d %#010x %-10.10s %#010x %#010x %d\n", pcb->processID, space, pcb->processName,
space->base, space->size, spacePages);
<<<<<<< HEAD
PRINTK("\r\n\t region name base size mmu_flags pages pg/ref\n");
PRINTK("\t ------ ---- ---- ---- --------- ----- -----\n");
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
=======
//虚拟区间控制块地址信息 | 虚拟区间类型 | 虚拟区间起始地址 | 虚拟区间大小 | 虚拟区间mmu映射属性 | 已使用的物理页数量(包括共享内存部分 | 已使用的物理页数量
PRINTK("\r\n\t region name base size mmu_flags pages pg/ref\n");
PRINTK("\t ------ ---- ---- ---- --------- ----- -----\n");
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)//按region 轮询统计
>>>>>>> remotes/origin/main
region = (LosVmMapRegion *)pstRbNode;
if (region != NULL) {
OsDumpRegion2(space, region);
@ -430,6 +500,16 @@ VOID OsDumpAspace(LosVmSpace *space)
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
return;
}
<<<<<<< HEAD
VOID OsDumpAllAspace(VOID)
{
LosVmSpace *space = NULL;
LOS_DL_LIST *aspaceList = LOS_GetVmSpaceList();
LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) {
(VOID)LOS_MuxAcquire(&space->regionMux);
OsDumpAspace(space);
=======
///查看所有进程使用虚拟内存的情况
VOID OsDumpAllAspace(VOID)
{
@ -438,6 +518,7 @@ VOID OsDumpAllAspace(VOID)
LOS_DL_LIST_FOR_EACH_ENTRY(space, aspaceList, LosVmSpace, node) {//循环取出进程虚拟
(VOID)LOS_MuxAcquire(&space->regionMux);
OsDumpAspace(space);//dump 空间
>>>>>>> remotes/origin/main
(VOID)LOS_MuxRelease(&space->regionMux);
}
return;
@ -456,11 +537,19 @@ STATUS_T OsRegionOverlapCheck(LosVmSpace *space, LosVmMapRegion *region)
(VOID)LOS_MuxRelease(&space->regionMux);
return ret;
}
<<<<<<< HEAD
VOID OsDumpPte(VADDR_T vaddr)
{
UINT32 l1Index = vaddr >> MMU_DESCRIPTOR_L1_SMALL_SHIFT;
LosVmSpace *space = LOS_SpaceGet(vaddr);
=======
///dump 页表项
VOID OsDumpPte(VADDR_T vaddr)
{
UINT32 l1Index = vaddr >> MMU_DESCRIPTOR_L1_SMALL_SHIFT;
LosVmSpace *space = LOS_SpaceGet(vaddr);//通过虚拟地址获取空间,内核分三个空间 内核进程空间,内核堆空间,用户进程空间
>>>>>>> remotes/origin/main
UINT32 ttEntry;
LosVmPage *page = NULL;
PTE_T *l2Table = NULL;
@ -470,6 +559,16 @@ VOID OsDumpPte(VADDR_T vaddr)
return;
}
<<<<<<< HEAD
ttEntry = space->archMmu.virtTtb[l1Index];
if (ttEntry) {
l2Table = LOS_PaddrToKVaddr(MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(ttEntry));
l2Index = (vaddr % MMU_DESCRIPTOR_L1_SMALL_SIZE) >> PAGE_SHIFT;
if (l2Table == NULL) {
goto ERR;
}
page = LOS_VmPageGet(l2Table[l2Index] & ~(PAGE_SIZE - 1));
=======
ttEntry = space->archMmu.virtTtb[l1Index];//找到 L1 页面项
if (ttEntry) {
l2Table = LOS_PaddrToKVaddr(MMU_DESCRIPTOR_L1_PAGE_TABLE_ADDR(ttEntry));//找到L1页面项对应的 L2表
@ -478,19 +577,29 @@ VOID OsDumpPte(VADDR_T vaddr)
goto ERR;
}
page = LOS_VmPageGet(l2Table[l2Index] & ~(PAGE_SIZE - 1));//获取物理页框
>>>>>>> remotes/origin/main
if (page == NULL) {
goto ERR;
}
PRINTK("vaddr %p, l1Index %d, ttEntry %p, l2Table %p, l2Index %d, pfn %p count %d\n",
<<<<<<< HEAD
vaddr, l1Index, ttEntry, l2Table, l2Index, l2Table[l2Index], LOS_AtomicRead(&page->refCounts));
} else {
=======
vaddr, l1Index, ttEntry, l2Table, l2Index, l2Table[l2Index], LOS_AtomicRead(&page->refCounts));//打印L1 L2 页表项
} else {//不在L1表
>>>>>>> remotes/origin/main
PRINTK("vaddr %p, l1Index %d, ttEntry %p\n", vaddr, l1Index, ttEntry);
}
return;
ERR:
PRINTK("%s, error vaddr: %#x, l2Table: %#x, l2Index: %#x\n", __FUNCTION__, vaddr, l2Table, l2Index);
}
<<<<<<< HEAD
=======
///获取段剩余页框数
>>>>>>> remotes/origin/main
UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg)
{
UINT32 intSave;
@ -498,6 +607,16 @@ UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg)
UINT32 segFreePages = 0;
LOS_SpinLockSave(&seg->freeListLock, &intSave);
<<<<<<< HEAD
for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) {
segFreePages += ((1 << flindex) * seg->freeList[flindex].listCnt);
}
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
return segFreePages;
}
=======
for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) {//遍历块组
segFreePages += ((1 << flindex) * seg->freeList[flindex].listCnt);//1 << flindex等于页数, * 节点数 得到组块的总页数.
}
@ -517,6 +636,7 @@ UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg)
* inactive file: pagecache
* pmm pages totalused使free
************************************************************/
>>>>>>> remotes/origin/main
VOID OsVmPhysDump(VOID)
{
LosVmPhysSeg *seg = NULL;
@ -528,7 +648,11 @@ VOID OsVmPhysDump(VOID)
UINT32 flindex;
UINT32 listCount[VM_LIST_ORDER_MAX] = {0};
<<<<<<< HEAD
for (segIndex = 0; segIndex < g_vmPhysSegNum; segIndex++) {
=======
for (segIndex = 0; segIndex < g_vmPhysSegNum; segIndex++) {//循环取段
>>>>>>> remotes/origin/main
seg = &g_vmPhysSeg[segIndex];
if (seg->size > 0) {
segFreePages = OsVmPhySegPagesGet(seg);
@ -558,7 +682,11 @@ VOID OsVmPhysDump(VOID)
PRINTK("\n\rpmm pages: total = %u, used = %u, free = %u\n",
totalPages, (totalPages - totalFreePages), totalFreePages);
}
<<<<<<< HEAD
=======
///获取物理内存的使用信息,两个参数接走数据
>>>>>>> remotes/origin/main
VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount)
{
UINT32 index;
@ -571,12 +699,21 @@ VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount)
*usedCount = 0;
*totalCount = 0;
<<<<<<< HEAD
for (index = 0; index < g_vmPhysSegNum; index++) {
physSeg = &g_vmPhysSeg[index];
if (physSeg->size > 0) {
*totalCount += physSeg->size >> PAGE_SHIFT;
segFreePages = OsVmPhySegPagesGet(physSeg);
*usedCount += (*totalCount - segFreePages);
=======
for (index = 0; index < g_vmPhysSegNum; index++) {//循环取段
physSeg = &g_vmPhysSeg[index];
if (physSeg->size > 0) {
*totalCount += physSeg->size >> PAGE_SHIFT;//叠加段的总页数
segFreePages = OsVmPhySegPagesGet(physSeg);//获取段的剩余页数
*usedCount += (*totalCount - segFreePages);//叠加段的使用页数
>>>>>>> remotes/origin/main
}
}
}

@ -54,7 +54,11 @@
extern char __exc_table_start[];
extern char __exc_table_end[];
<<<<<<< HEAD
=======
//线性正确性检查
>>>>>>> remotes/origin/main
STATIC STATUS_T OsVmRegionPermissionCheck(LosVmMapRegion *region, UINT32 flags)
{
if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_READ) != VM_MAP_REGION_FLAG_PERM_READ) {
@ -62,14 +66,22 @@ STATIC STATUS_T OsVmRegionPermissionCheck(LosVmMapRegion *region, UINT32 flags)
return LOS_NOK;
}
<<<<<<< HEAD
if ((flags & VM_MAP_PF_FLAG_WRITE) == VM_MAP_PF_FLAG_WRITE) {
=======
if ((flags & VM_MAP_PF_FLAG_WRITE) == VM_MAP_PF_FLAG_WRITE) {//写入许可
>>>>>>> remotes/origin/main
if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_WRITE) != VM_MAP_REGION_FLAG_PERM_WRITE) {
VM_ERR("write permission check failed operation flags %x, region flags %x", flags, region->regionFlags);
return LOS_NOK;
}
}
<<<<<<< HEAD
if ((flags & VM_MAP_PF_FLAG_INSTRUCTION) == VM_MAP_PF_FLAG_INSTRUCTION) {
=======
if ((flags & VM_MAP_PF_FLAG_INSTRUCTION) == VM_MAP_PF_FLAG_INSTRUCTION) {//指令
>>>>>>> remotes/origin/main
if ((region->regionFlags & VM_MAP_REGION_FLAG_PERM_EXECUTE) != VM_MAP_REGION_FLAG_PERM_EXECUTE) {
VM_ERR("exec permission check failed operation flags %x, region flags %x", flags, region->regionFlags);
return LOS_NOK;
@ -97,8 +109,12 @@ STATIC VOID OsFaultTryFixup(ExcContext *frame, VADDR_T excVaddr, STATUS_T *statu
}
#ifdef LOSCFG_FS_VFS
<<<<<<< HEAD
STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
=======
//读页时发生缺页的处理
STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)//读缺页
>>>>>>> remotes/origin/main
{
status_t ret;
PADDR_T paddr;
@ -106,16 +122,36 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)//
VADDR_T vaddr = (VADDR_T)vmPgFault->vaddr;
LosVmSpace *space = region->space;
<<<<<<< HEAD
ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, NULL, NULL);
if (ret == LOS_OK) {
return LOS_OK;
}
if (region->unTypeData.rf.vmFOps == NULL || region->unTypeData.rf.vmFOps->fault == NULL) {
=======
ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, NULL, NULL);//查询是否缺页
if (ret == LOS_OK) {//注意这里时LOS_OK却返回,都OK了说明查到了物理地址,有页了。
return LOS_OK;//查到了就说明不缺页的,缺页就是因为虚拟地址没有映射到物理地址嘛
}
if (region->unTypeData.rf.vmFOps == NULL || region->unTypeData.rf.vmFOps->fault == NULL) {//线性区必须有实现了缺页接口
>>>>>>> remotes/origin/main
VM_ERR("region args invalid, file path: %s", region->unTypeData.rf.vnode->filePath);
return LOS_ERRNO_VM_INVALID_ARGS;
}
(VOID)LOS_MuxAcquire(&region->unTypeData.rf.vnode->mapping.mux_lock);
<<<<<<< HEAD
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
if (ret == LOS_OK) {
paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr);
page = LOS_VmPageGet(paddr);
if (page != NULL) { /* just incase of page null */
LOS_AtomicInc(&page->refCounts);
OsCleanPageLocked(page);
}
ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1,
region->regionFlags & (~VM_MAP_REGION_FLAG_PERM_WRITE));
=======
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);// 函数指针执行的是g_commVmOps.OsVmmFileFault
if (ret == LOS_OK) {
paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr);//查询物理地址
@ -126,6 +162,7 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)//
}
ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1,
region->regionFlags & (~VM_MAP_REGION_FLAG_PERM_WRITE));//重新映射为非可写
>>>>>>> remotes/origin/main
if (ret < 0) {
VM_ERR("LOS_ArchMmuMap failed");
OsDelMapInfo(region, vmPgFault, false);
@ -141,7 +178,11 @@ STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)//
return LOS_ERRNO_VM_NO_MEMORY;
}
<<<<<<< HEAD
/* unmap a page when cow happened only */
=======
/* unmap a page when cow happened only *///仅当写时拷贝发生时取消页面映射
>>>>>>> remotes/origin/main
STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, LosVmPgFault *vmf)
{
UINT32 intSave;
@ -169,7 +210,11 @@ STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, Los
return oldPage;
}
#endif
<<<<<<< HEAD
=======
//在私有线性区写入文件时发生缺页的处理
>>>>>>> remotes/origin/main
status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
{
STATUS_T ret;
@ -187,23 +232,40 @@ status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
}
space = region->space;
<<<<<<< HEAD
ret = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vmPgFault->vaddr, &oldPaddr, NULL);
if (ret == LOS_OK) {
oldPage = OsCowUnmapOrg(&space->archMmu, region, vmPgFault);
}
newPage = LOS_PhysPageAlloc();
=======
ret = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vmPgFault->vaddr, &oldPaddr, NULL);//查询出老物理地址
if (ret == LOS_OK) {
oldPage = OsCowUnmapOrg(&space->archMmu, region, vmPgFault);//取消页面映射
}
newPage = LOS_PhysPageAlloc();//分配一个新页面
>>>>>>> remotes/origin/main
if (newPage == NULL) {
VM_ERR("LOS_PhysPageAlloc failed");
ret = LOS_ERRNO_VM_NO_MEMORY;
goto ERR_OUT;
}
<<<<<<< HEAD
newPaddr = VM_PAGE_TO_PHYS(newPage);
kvaddr = OsVmPageToVaddr(newPage);
(VOID)LOS_MuxAcquire(&region->unTypeData.rf.vnode->mapping.mux_lock);
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
=======
newPaddr = VM_PAGE_TO_PHYS(newPage);//拿到新的物理地址
kvaddr = OsVmPageToVaddr(newPage);//拿到新的虚拟地址
(VOID)LOS_MuxAcquire(&region->unTypeData.rf.vnode->mapping.mux_lock);
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);// 函数指针 g_commVmOps.OsVmmFileFault
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
VM_ERR("call region->vm_ops->fault fail");
(VOID)LOS_MuxRelease(&region->unTypeData.rf.vnode->mapping.mux_lock);
@ -215,6 +277,17 @@ status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
* we can take it as a normal file cow map. 2.this page has done file cow map,
* we can take it as a anonymous cow map.
*/
<<<<<<< HEAD
if ((oldPaddr == 0) || (LOS_PaddrToKVaddr(oldPaddr) == vmPgFault->pageKVaddr)) {
(VOID)memcpy_s(kvaddr, PAGE_SIZE, vmPgFault->pageKVaddr, PAGE_SIZE);
LOS_AtomicInc(&newPage->refCounts);
OsCleanPageLocked(LOS_VmPageGet(LOS_PaddrQuery(vmPgFault->pageKVaddr)));
} else {
OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage);
/* use old page free the new one */
if (newPaddr == oldPaddr) {
LOS_PhysPageFree(newPage);
=======
if ((oldPaddr == 0) || (LOS_PaddrToKVaddr(oldPaddr) == vmPgFault->pageKVaddr)) {//没有映射或者 已在pagecache有映射
(VOID)memcpy_s(kvaddr, PAGE_SIZE, vmPgFault->pageKVaddr, PAGE_SIZE);//直接copy到新页
LOS_AtomicInc(&newPage->refCounts);//引用ref++
@ -224,11 +297,16 @@ status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
/* use old page free the new one */
if (newPaddr == oldPaddr) {//注意这里newPaddr可能已经被改变了,参数传入的是 &newPaddr
LOS_PhysPageFree(newPage);//释放新页,别浪费的内存,内核使用内存是一分钱当十块用.
>>>>>>> remotes/origin/main
newPage = NULL;
}
}
<<<<<<< HEAD
ret = LOS_ArchMmuMap(&space->archMmu, (VADDR_T)vmPgFault->vaddr, newPaddr, 1, region->regionFlags);
=======
ret = LOS_ArchMmuMap(&space->archMmu, (VADDR_T)vmPgFault->vaddr, newPaddr, 1, region->regionFlags);//把新物理地址映射给缺页的虚拟地址,这样就不会缺页啦
>>>>>>> remotes/origin/main
if (ret < 0) {
VM_ERR("LOS_ArchMmuMap failed");
ret = LOS_ERRNO_VM_NO_MEMORY;
@ -253,7 +331,11 @@ ERR_OUT:
return ret;
}
<<<<<<< HEAD
=======
///在共享线性区写文件操作发生缺页的情况处理,因为线性区是共享的
>>>>>>> remotes/origin/main
status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
{
STATUS_T ret;
@ -269,10 +351,17 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
return LOS_ERRNO_VM_INVALID_ARGS;
}
<<<<<<< HEAD
ret = LOS_ArchMmuQuery(&space->archMmu, vmPgFault->vaddr, &paddr, NULL);
if (ret == LOS_OK) {
LOS_ArchMmuUnmap(&space->archMmu, vmPgFault->vaddr, 1);
ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags);
=======
ret = LOS_ArchMmuQuery(&space->archMmu, vmPgFault->vaddr, &paddr, NULL);//查询物理地址
if (ret == LOS_OK) {
LOS_ArchMmuUnmap(&space->archMmu, vmPgFault->vaddr, 1);//先取消映射
ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags);//再重新映射,为啥这么干,是因为regionFlags变了,
>>>>>>> remotes/origin/main
if (ret < 0) {
VM_ERR("LOS_ArchMmuMap failed. ret=%d", ret);
return LOS_ERRNO_VM_NO_MEMORY;
@ -280,16 +369,27 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
LOS_SpinLockSave(&region->unTypeData.rf.vnode->mapping.list_lock, &intSave);
fpage = OsFindGetEntry(&region->unTypeData.rf.vnode->mapping, vmPgFault->pgoff);
<<<<<<< HEAD
if (fpage) {
OsMarkPageDirty(fpage, region, 0, 0);
=======
if (fpage) {//在页高速缓存(page cache)中找到了
OsMarkPageDirty(fpage, region, 0, 0);//标记为脏页
>>>>>>> remotes/origin/main
}
LOS_SpinUnlockRestore(&region->unTypeData.rf.vnode->mapping.list_lock, intSave);
return LOS_OK;
}
<<<<<<< HEAD
(VOID)LOS_MuxAcquire(&region->unTypeData.rf.vnode->mapping.mux_lock);
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
=======
//以下是没有映射到物理地址的处理
(VOID)LOS_MuxAcquire(&region->unTypeData.rf.vnode->mapping.mux_lock);
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);//函数指针执行的是g_commVmOps.OsVmmFileFault
>>>>>>> remotes/origin/main
if (ret == LOS_OK) {
paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr);
page = LOS_VmPageGet(paddr);
@ -320,11 +420,29 @@ status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
* For COW fault, pagecache is copied to private anonyous pages and the changes on this page
* won't write through to the underlying file. For SHARED fault, pagecache is mapping with
* region->arch_mmu_flags and the changes on this page will write through to the underlying file
<<<<<<< HEAD
*/
=======
*/ //操作文件时产生缺页中断
>>>>>>> remotes/origin/main
STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, UINT32 flags)
{
STATUS_T ret;
<<<<<<< HEAD
if (flags & VM_MAP_PF_FLAG_WRITE) {
if (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) {
ret = OsDoSharedFault(region, vmPgFault);
} else {
ret = OsDoCowFault(region, vmPgFault);
}
} else {
ret = OsDoReadFault(region, vmPgFault);
}
return ret;
}
=======
if (flags & VM_MAP_PF_FLAG_WRITE) {//写页的时候产生缺页
if (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) {//共享线性区
ret = OsDoSharedFault(region, vmPgFault);//写操作时的共享缺页,最复杂,此页上的更改将写入磁盘文件
@ -350,6 +468,7 @@ STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, U
* @param frame
* @return STATUS_T
*/
>>>>>>> remotes/origin/main
STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
{
LosVmSpace *space = LOS_SpaceGet(vaddr);
@ -368,9 +487,15 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
return status;
}
<<<<<<< HEAD
if (((flags & VM_MAP_PF_FLAG_USER) != 0) && (!LOS_IsUserAddress(vaddr))) {
VM_ERR("user space not allowed to access invalid address: %#x", vaddr);
return LOS_ERRNO_VM_ACCESS_DENIED;
=======
if (((flags & VM_MAP_PF_FLAG_USER) != 0) && (!LOS_IsUserAddress(vaddr))) {//地址保护,用户空间不允许跨界访问
VM_ERR("user space not allowed to access invalid address: %#x", vaddr);
return LOS_ERRNO_VM_ACCESS_DENIED;//拒绝访问
>>>>>>> remotes/origin/main
}
#ifdef LOSCFG_KERNEL_PLIMITS
@ -380,7 +505,11 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
#endif
(VOID)LOS_MuxAcquire(&space->regionMux);
<<<<<<< HEAD
region = LOS_RegionFind(space, vaddr);
=======
region = LOS_RegionFind(space, vaddr);//通过虚拟地址找到所在线性区
>>>>>>> remotes/origin/main
if (region == NULL) {
VM_ERR("region not exists, vaddr: %#x", vaddr);
status = LOS_ERRNO_VM_NOT_FOUND;
@ -389,11 +518,19 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
status = OsVmRegionPermissionCheck(region, flags);
if (status != LOS_OK) {
<<<<<<< HEAD
status = LOS_ERRNO_VM_ACCESS_DENIED;
goto CHECK_FAILED;
}
if (OomCheckProcess()) {
=======
status = LOS_ERRNO_VM_ACCESS_DENIED;//拒绝访问
goto CHECK_FAILED;
}
if (OomCheckProcess()) {//低内存检查
>>>>>>> remotes/origin/main
/*
* under low memory, when user process request memory allocation
* it will fail, and result is LOS_NOK and current user process
@ -403,6 +540,20 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
goto CHECK_FAILED;
}
<<<<<<< HEAD
vaddr = ROUNDDOWN(vaddr, PAGE_SIZE);
#ifdef LOSCFG_FS_VFS
if (LOS_IsRegionFileValid(region)) {
if (region->unTypeData.rf.vnode == NULL) {
goto CHECK_FAILED;
}
vmPgFault.vaddr = vaddr;
vmPgFault.pgoff = ((vaddr - region->range.base) >> PAGE_SHIFT) + region->pgOff;
vmPgFault.flags = flags;
vmPgFault.pageKVaddr = NULL;
status = OsDoFileFault(region, &vmPgFault, flags);
=======
vaddr = ROUNDDOWN(vaddr, PAGE_SIZE);//为啥要向下圆整,因为这一页要重新使用,需找到页面基地址
#ifdef LOSCFG_FS_VFS
if (LOS_IsRegionFileValid(region)) {//是否为文件线性区
@ -415,6 +566,7 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
vmPgFault.pageKVaddr = NULL;//缺失页初始化没有物理地址
status = OsDoFileFault(region, &vmPgFault, flags);//缺页处理
>>>>>>> remotes/origin/main
if (status) {
VM_ERR("vm fault error, status=%d", status);
goto CHECK_FAILED;
@ -422,13 +574,29 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
goto DONE;
}
#endif
<<<<<<< HEAD
newPage = LOS_PhysPageAlloc();
=======
//请求调页:推迟到不能再推迟为止
newPage = LOS_PhysPageAlloc();//分配一个新的物理页
>>>>>>> remotes/origin/main
if (newPage == NULL) {
status = LOS_ERRNO_VM_NO_MEMORY;
goto CHECK_FAILED;
}
<<<<<<< HEAD
newPaddr = VM_PAGE_TO_PHYS(newPage);
(VOID)memset_s(OsVmPageToVaddr(newPage), PAGE_SIZE, 0, PAGE_SIZE);
status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &oldPaddr, NULL);
if (status >= 0) {
LOS_ArchMmuUnmap(&space->archMmu, vaddr, 1);
OsPhysSharePageCopy(oldPaddr, &newPaddr, newPage);
/* use old page free the new one */
if (newPaddr == oldPaddr) {
LOS_PhysPageFree(newPage);
=======
newPaddr = VM_PAGE_TO_PHYS(newPage);//获取物理地址
(VOID)memset_s(OsVmPageToVaddr(newPage), PAGE_SIZE, 0, PAGE_SIZE);//获取虚拟地址 清0
status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &oldPaddr, NULL);//通过虚拟地址查询老物理地址
@ -438,11 +606,16 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
/* use old page free the new one */
if (newPaddr == oldPaddr) {//新老物理地址一致
LOS_PhysPageFree(newPage);//继续使用旧页释放新页
>>>>>>> remotes/origin/main
newPage = NULL;
}
/* map all of the pages */
<<<<<<< HEAD
status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);
=======
status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);//重新映射新物理地址
>>>>>>> remotes/origin/main
if (status < 0) {
VM_ERR("failed to map replacement page, status:%d", status);
status = LOS_ERRNO_VM_MAP_FAILED;
@ -453,8 +626,13 @@ STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
goto DONE;
} else {
/* map all of the pages */
<<<<<<< HEAD
LOS_AtomicInc(&newPage->refCounts);
status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);
=======
LOS_AtomicInc(&newPage->refCounts);//引用数自增
status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);//映射新物理地址,如此下次就不会缺页了
>>>>>>> remotes/origin/main
if (status < 0) {
VM_ERR("failed to map page, status:%d", status);
status = LOS_ERRNO_VM_MAP_FAILED;

@ -66,6 +66,11 @@ VOID ResetPageCacheHitInfo(int *try, int *hit)
#define TRACE_TRY_CACHE()
#define TRACE_HIT_CACHE()
#endif
<<<<<<< HEAD
#ifdef LOSCFG_KERNEL_VM
=======
#ifdef LOSCFG_KERNEL_VM
/**
@ -80,28 +85,63 @@ VOID ResetPageCacheHitInfo(int *try, int *hit)
* @param pgoff
* @return STATIC
*/
>>>>>>> remotes/origin/main
STATIC VOID OsPageCacheAdd(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff)
{
LosFilePage *fpage = NULL;
<<<<<<< HEAD
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
if (fpage->pgoff > pgoff) {
LOS_ListTailInsert(&fpage->node, &page->node);
=======
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {//遍历page_list链表
if (fpage->pgoff > pgoff) {//插入的条件,这样插入保证了按pgoff 从小到大排序
LOS_ListTailInsert(&fpage->node, &page->node);//等于挂到fpage节点的前面了
>>>>>>> remotes/origin/main
goto done_add;
}
}
<<<<<<< HEAD
LOS_ListTailInsert(&mapping->page_list, &page->node);
done_add:
mapping->nrpages++;
}
=======
LOS_ListTailInsert(&mapping->page_list, &page->node);//将页挂到文件映射的链表上,相当于挂到了最后
done_add:
mapping->nrpages++; //文件在缓存中多了一个 文件页
}
///将页面加到活动文件页LRU链表上
>>>>>>> remotes/origin/main
VOID OsAddToPageacheLru(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff)
{
OsPageCacheAdd(page, mapping, pgoff);
OsLruCacheAdd(page, VM_LRU_ACTIVE_FILE);
}
<<<<<<< HEAD
VOID OsPageCacheDel(LosFilePage *fpage)
{
/* delete from file cache list */
LOS_ListDelete(&fpage->node);
fpage->mapping->nrpages--;
/* unmap and remove map info */
if (OsIsPageMapped(fpage)) {
OsUnmapAllLocked(fpage);
}
LOS_PhysPageFree(fpage->vmPage);
LOS_MemFree(m_aucSysMem0, fpage);
}
=======
///从页高速缓存上删除页
VOID OsPageCacheDel(LosFilePage *fpage)
{
@ -124,15 +164,52 @@ VOID OsPageCacheDel(LosFilePage *fpage)
1. 2.
**************************************************************************************************/
>>>>>>> remotes/origin/main
VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr)
{
LosMapInfo *info = NULL;
<<<<<<< HEAD
info = (LosMapInfo *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosMapInfo));
=======
info = (LosMapInfo *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosMapInfo));//分配一个映射信息
>>>>>>> remotes/origin/main
if (info == NULL) {
VM_ERR("OsAddMapInfo alloc memory failed!");
return;
}
<<<<<<< HEAD
info->page = page;
info->archMmu = archMmu;
info->vaddr = vaddr;
LOS_ListAdd(&page->i_mmap, &info->node);
page->n_maps++;
}
LosMapInfo *OsGetMapInfo(const LosFilePage *page, const LosArchMmu *archMmu, VADDR_T vaddr)
{
LosMapInfo *info = NULL;
const LOS_DL_LIST *immap = &page->i_mmap;
LOS_DL_LIST_FOR_EACH_ENTRY(info, immap, LosMapInfo, node) {
if ((info->archMmu == archMmu) && (info->vaddr == vaddr) && (info->page == page)) {
return info;
}
}
return NULL;
}
VOID OsDeletePageCacheLru(LosFilePage *page)
{
/* delete from lru list */
OsLruCacheDel(page);
/* delete from cache list and free pmm if needed */
OsPageCacheDel(page);
}
=======
info->page = page; //文件页
info->archMmu = archMmu;//进程MMU,完成虚实地址转换
info->vaddr = vaddr; //虚拟地址
@ -163,17 +240,26 @@ VOID OsDeletePageCacheLru(LosFilePage *page)
}
//解除文件页和进程的映射关系
>>>>>>> remotes/origin/main
STATIC VOID OsPageCacheUnmap(LosFilePage *fpage, LosArchMmu *archMmu, VADDR_T vaddr)
{
UINT32 intSave;
LosMapInfo *info = NULL;
LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave);
<<<<<<< HEAD
info = OsGetMapInfo(fpage, archMmu, vaddr);
if (info == NULL) {
VM_ERR("OsPageCacheUnmap get map info failed!");
} else {
OsUnmapPageLocked(fpage, info);
=======
info = OsGetMapInfo(fpage, archMmu, vaddr);//获取文件页在进程的映射信息
if (info == NULL) {
VM_ERR("OsPageCacheUnmap get map info failed!");
} else {
OsUnmapPageLocked(fpage, info);//解除进程和文件页映射关系
>>>>>>> remotes/origin/main
}
if (!(OsIsPageMapped(fpage) && ((fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE) ||
OsIsPageDirty(fpage->vmPage)))) {
@ -182,7 +268,11 @@ STATIC VOID OsPageCacheUnmap(LosFilePage *fpage, LosArchMmu *archMmu, VADDR_T va
LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave);
}
<<<<<<< HEAD
=======
///删除文件
>>>>>>> remotes/origin/main
VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pgoff)
{
UINT32 intSave;
@ -195,6 +285,15 @@ VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pg
LosVmPage *mapPage = NULL;
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL)) {
<<<<<<< HEAD
return;
}
vnode = region->unTypeData.rf.vnode;
mapping = &vnode->mapping;
vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT);
status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL);
=======
return;//判断是否为文件映射是否已map
}
vnode = region->unTypeData.rf.vnode;
@ -202,10 +301,27 @@ VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pg
vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT);//得到虚拟地址
status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL);//获取物理地址
>>>>>>> remotes/origin/main
if (status != LOS_OK) {
return;
}
<<<<<<< HEAD
mapPage = LOS_VmPageGet(paddr);
/* is page is in cache list */
LOS_SpinLockSave(&mapping->list_lock, &intSave);
fpage = OsFindGetEntry(mapping, pgoff);
/* no cache or have cache but not map(cow), free it direct */
if ((fpage == NULL) || (fpage->vmPage != mapPage)) {
LOS_PhysPageFree(mapPage);
LOS_ArchMmuUnmap(archMmu, vaddr, 1);
/* this is a page cache map! */
} else {
OsPageCacheUnmap(fpage, archMmu, vaddr);
if (OsIsPageDirty(fpage->vmPage)) {
tmpPage = OsDumpDirtyPage(fpage);
=======
mapPage = LOS_VmPageGet(paddr);//获取物理页框
/* is page is in cache list */
@ -220,6 +336,7 @@ VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pg
OsPageCacheUnmap(fpage, archMmu, vaddr);////取消缓存中的映射
if (OsIsPageDirty(fpage->vmPage)) {//脏页处理
tmpPage = OsDumpDirtyPage(fpage);//dump 脏页
>>>>>>> remotes/origin/main
}
}
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
@ -229,6 +346,17 @@ VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pg
}
return;
}
<<<<<<< HEAD
VOID OsMarkPageDirty(LosFilePage *fpage, const LosVmMapRegion *region, INT32 off, INT32 len)
{
if (region != NULL) {
OsSetPageDirty(fpage->vmPage);
fpage->dirtyOff = off;
fpage->dirtyEnd = len;
} else {
OsSetPageDirty(fpage->vmPage);
=======
///标记page为脏页 进程修改了高速缓存里的数据时,该页就被内核标记为脏页
VOID OsMarkPageDirty(LosFilePage *fpage, const LosVmMapRegion *region, INT32 off, INT32 len)
{
@ -238,6 +366,7 @@ VOID OsMarkPageDirty(LosFilePage *fpage, const LosVmMapRegion *region, INT32 off
fpage->dirtyEnd = len;//脏页结束位置
} else {
OsSetPageDirty(fpage->vmPage);//设置为脏页
>>>>>>> remotes/origin/main
if ((off + len) > fpage->dirtyEnd) {
fpage->dirtyEnd = off + len;
}
@ -274,22 +403,37 @@ STATIC UINT32 GetDirtySize(LosFilePage *fpage, struct Vnode *vnode)
return PAGE_SIZE;
}
<<<<<<< HEAD
=======
///冲洗脏页,回写磁盘
>>>>>>> remotes/origin/main
STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage)
{
UINT32 ret;
size_t len;
char *buff = NULL;
<<<<<<< HEAD
struct Vnode *vnode = fpage->mapping->host;
=======
struct Vnode *vnode = fpage->mapping->host;/* owner of this mapping */ //此映射属于哪个文件,注意<file,page_mapping>是1:1的关系.
>>>>>>> remotes/origin/main
if (vnode == NULL) {
VM_ERR("page cache vnode error");
return LOS_NOK;
}
<<<<<<< HEAD
len = fpage->dirtyEnd - fpage->dirtyOff;
len = (len == 0) ? GetDirtySize(fpage, vnode) : len;
if (len == 0) {
OsCleanPageDirty(fpage->vmPage);
=======
len = fpage->dirtyEnd - fpage->dirtyOff;//计算出脏数据长度
len = (len == 0) ? GetDirtySize(fpage, vnode) : len;
if (len == 0) {//没有脏数据
OsCleanPageDirty(fpage->vmPage);//页面取消脏标签
>>>>>>> remotes/origin/main
return LOS_OK;
}
@ -306,7 +450,11 @@ STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage)
return ret;
}
<<<<<<< HEAD
=======
///备份脏页,老脏页撕掉脏页标签
>>>>>>> remotes/origin/main
LosFilePage *OsDumpDirtyPage(LosFilePage *oldFPage)
{
LosFilePage *newFPage = NULL;
@ -318,11 +466,19 @@ LosFilePage *OsDumpDirtyPage(LosFilePage *oldFPage)
}
OsCleanPageDirty(oldFPage->vmPage);
<<<<<<< HEAD
(VOID)memcpy_s(newFPage, sizeof(LosFilePage), oldFPage, sizeof(LosFilePage));
return newFPage;
}
=======
(VOID)memcpy_s(newFPage, sizeof(LosFilePage), oldFPage, sizeof(LosFilePage));//直接内存拷贝
return newFPage;
}
///冲洗脏页数据,将脏页数据回写磁盘
>>>>>>> remotes/origin/main
VOID OsDoFlushDirtyPage(LosFilePage *fpage)
{
if (fpage == NULL) {
@ -344,7 +500,11 @@ STATIC VOID OsReleaseFpage(struct page_mapping *mapping, LosFilePage *fpage)
LOS_SpinUnlockRestore(lruLock, lruSave);
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
}
<<<<<<< HEAD
=======
///删除映射信息
>>>>>>> remotes/origin/main
VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty)
{
UINT32 intSave;
@ -365,9 +525,15 @@ VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty)
}
if (cleanDirty) {
<<<<<<< HEAD
OsCleanPageDirty(fpage->vmPage);
}
info = OsGetMapInfo(fpage, &region->space->archMmu, (vaddr_t)vmf->vaddr);
=======
OsCleanPageDirty(fpage->vmPage);//恢复干净页
}
info = OsGetMapInfo(fpage, &region->space->archMmu, (vaddr_t)vmf->vaddr);//通过虚拟地址获取映射信息
>>>>>>> remotes/origin/main
if (info != NULL) {
fpage->n_maps--;
LOS_ListDelete(&info->node);
@ -378,10 +544,14 @@ VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty)
}
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
}
<<<<<<< HEAD
=======
/*!
,
OsDoReadFault(...),OsDoCowFault(...),OsDoSharedFault(...)
*/
>>>>>>> remotes/origin/main
INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
{
INT32 ret;
@ -393,7 +563,11 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
struct page_mapping *mapping = NULL;
LosFilePage *fpage = NULL;
<<<<<<< HEAD
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) {
=======
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.vnode == NULL) || (vmf == NULL)) {//文件是否映射到了内存
>>>>>>> remotes/origin/main
VM_ERR("Input param is NULL");
return LOS_NOK;
}
@ -402,6 +576,15 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
/* get or create a new cache node */
LOS_SpinLockSave(&mapping->list_lock, &intSave);
<<<<<<< HEAD
fpage = OsFindGetEntry(mapping, vmf->pgoff);
TRACE_TRY_CACHE();
if (fpage != NULL) {
TRACE_HIT_CACHE();
OsPageRefIncLocked(fpage);
} else {
fpage = OsPageCacheAlloc(mapping, vmf->pgoff);
=======
fpage = OsFindGetEntry(mapping, vmf->pgoff);//获取文件页
TRACE_TRY_CACHE();
if (fpage != NULL) {//找到了,说明该页已经在页高速缓存中
@ -409,11 +592,22 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
OsPageRefIncLocked(fpage);
} else {//真的缺页了,页高速缓存中没找到
fpage = OsPageCacheAlloc(mapping, vmf->pgoff);//分配一个文件页将数据初始化好包括vmpage(物理页框)
>>>>>>> remotes/origin/main
if (fpage == NULL) {
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
VM_ERR("Failed to alloc a page frame");
return LOS_NOK;
}
<<<<<<< HEAD
newCache = true;
}
OsSetPageLocked(fpage->vmPage);
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
kvaddr = OsVmPageToVaddr(fpage->vmPage);
/* read file to new page cache */
if (newCache) {
=======
newCache = true;//分配了新文件页
}
OsSetPageLocked(fpage->vmPage);//对vmpage上锁
@ -422,6 +616,7 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
/* read file to new page cache */
if (newCache) {//新cache
>>>>>>> remotes/origin/main
ret = vnode->vop->ReadPage(vnode, kvaddr, fpage->pgoff << PAGE_SHIFT);
if (ret == 0) {
VM_ERR("Failed to read from file!");
@ -429,18 +624,37 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
return LOS_NOK;
}
LOS_SpinLockSave(&mapping->list_lock, &intSave);
<<<<<<< HEAD
OsAddToPageacheLru(fpage, mapping, vmf->pgoff);
=======
OsAddToPageacheLru(fpage, mapping, vmf->pgoff);//将fpage挂入pageCache 和 LruCache
>>>>>>> remotes/origin/main
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
}
LOS_SpinLockSave(&mapping->list_lock, &intSave);
/* cow fault case no need to save mapinfo */
if (!((vmf->flags & VM_MAP_PF_FLAG_WRITE) && !(region->regionFlags & VM_MAP_REGION_FLAG_SHARED))) {
<<<<<<< HEAD
OsAddMapInfo(fpage, &region->space->archMmu, (vaddr_t)vmf->vaddr);
=======
OsAddMapInfo(fpage, &region->space->archMmu, (vaddr_t)vmf->vaddr);//添加<虚拟地址,文件页>的映射关系,如此进程以后就能通过虚拟地址操作文件页了.
>>>>>>> remotes/origin/main
fpage->flags = region->regionFlags;
}
/* share page fault, mark the page dirty */
<<<<<<< HEAD
if ((vmf->flags & VM_MAP_PF_FLAG_WRITE) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) {
OsMarkPageDirty(fpage, region, 0, 0);
}
vmf->pageKVaddr = kvaddr;
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
return LOS_OK;
}
=======
if ((vmf->flags & VM_MAP_PF_FLAG_WRITE) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) {//有过写操作或者为共享线性区
OsMarkPageDirty(fpage, region, 0, 0);//标记为脏页,要回写磁盘,内核会在适当的时候回写磁盘
}
@ -450,11 +664,16 @@ INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
return LOS_OK;
}
///文件缓存冲洗,把所有fpage冲洗一边把脏页洗到dirtyList中,配合OsFileCacheRemove理解
>>>>>>> remotes/origin/main
VOID OsFileCacheFlush(struct page_mapping *mapping)
{
UINT32 intSave;
UINT32 lruLock;
<<<<<<< HEAD
LOS_DL_LIST_HEAD(dirtyList);
=======
LOS_DL_LIST_HEAD(dirtyList);//LOS_DL_LIST list = { &(list), &(list) };
>>>>>>> remotes/origin/main
LosFilePage *ftemp = NULL;
LosFilePage *fpage = NULL;
@ -462,18 +681,34 @@ VOID OsFileCacheFlush(struct page_mapping *mapping)
return;
}
LOS_SpinLockSave(&mapping->list_lock, &intSave);
<<<<<<< HEAD
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
LOS_SpinLockSave(&fpage->physSeg->lruLock, &lruLock);
if (OsIsPageDirty(fpage->vmPage)) {
ftemp = OsDumpDirtyPage(fpage);
if (ftemp != NULL) {
LOS_ListTailInsert(&dirtyList, &ftemp->node);
=======
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {//循环从page_list中取node给fpage
LOS_SpinLockSave(&fpage->physSeg->lruLock, &lruLock);
if (OsIsPageDirty(fpage->vmPage)) {//是否为脏页
ftemp = OsDumpDirtyPage(fpage);//这里挺妙的copy出一份新页老页变成了非脏页继续用
if (ftemp != NULL) {
LOS_ListTailInsert(&dirtyList, &ftemp->node);//将新页插入脏页List,等待回写磁盘
>>>>>>> remotes/origin/main
}
}
LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, lruLock);
}
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
<<<<<<< HEAD
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, ftemp, &dirtyList, LosFilePage, node) {
OsDoFlushDirtyPage(fpage);
}
}
=======
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, ftemp, &dirtyList, LosFilePage, node) {//仔细看这个宏,关键在 &(item)->member != (list);
OsDoFlushDirtyPage(fpage);//立马洗掉所以dirtyList可以不是全局变量
}
@ -483,16 +718,54 @@ VOID OsFileCacheFlush(struct page_mapping *mapping)
,page cache
mapping
******************************************************************************/
>>>>>>> remotes/origin/main
VOID OsFileCacheRemove(struct page_mapping *mapping)
{
UINT32 intSave;
UINT32 lruSave;
SPIN_LOCK_S *lruLock = NULL;
<<<<<<< HEAD
LOS_DL_LIST_HEAD(dirtyList);
=======
LOS_DL_LIST_HEAD(dirtyList);//定义一个叫dirtyList的双循环链表并初始化,用于挂脏页
>>>>>>> remotes/origin/main
LosFilePage *ftemp = NULL;
LosFilePage *fpage = NULL;
LosFilePage *fnext = NULL;
<<<<<<< HEAD
LOS_SpinLockSave(&mapping->list_lock, &intSave);
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &mapping->page_list, LosFilePage, node) {
lruLock = &fpage->physSeg->lruLock;
LOS_SpinLockSave(lruLock, &lruSave);
if (OsIsPageDirty(fpage->vmPage)) {
ftemp = OsDumpDirtyPage(fpage);
if (ftemp != NULL) {
LOS_ListTailInsert(&dirtyList, &ftemp->node);
}
}
OsDeletePageCacheLru(fpage);
LOS_SpinUnlockRestore(lruLock, lruSave);
}
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) {
OsDoFlushDirtyPage(fpage);
}
}
LosVmFileOps g_commVmOps = {
.open = NULL,
.close = NULL,
.fault = OsVmmFileFault,
.remove = OsVmmFileRemove,
};
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
{
region->unTypeData.rf.vmFOps = &g_commVmOps;
=======
LOS_SpinLockSave(&mapping->list_lock, &intSave);//多进程操作,必须上锁.
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &mapping->page_list, LosFilePage, node) {//遍历文件在内存中产生的所有文件页(例如1,4,8页)不一定连续,取决于用户的读取顺序
lruLock = &fpage->physSeg->lruLock;
@ -524,15 +797,20 @@ LosVmFileOps g_commVmOps = {//
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
{
region->unTypeData.rf.vmFOps = &g_commVmOps;//文件操作
>>>>>>> remotes/origin/main
region->unTypeData.rf.vnode = filep->f_vnode;
region->unTypeData.rf.f_oflags = filep->f_oflags;
return ENOERR;
}
<<<<<<< HEAD
=======
/*!
,,
filep广,鸿,//////
*/
>>>>>>> remotes/origin/main
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
{
struct Vnode *vnode = NULL;
@ -545,10 +823,17 @@ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
vnode->useCount++;
VnodeDrop();
if (filep->ops != NULL && filep->ops->mmap != NULL) {
<<<<<<< HEAD
if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) {
LOS_SetRegionTypeDev(region);
} else {
LOS_SetRegionTypeFile(region);
=======
if (vnode->type == VNODE_TYPE_CHR || vnode->type == VNODE_TYPE_BLK) {//块设备或者字符设备 /dev/..
LOS_SetRegionTypeDev(region);//设置为设备类型
} else {
LOS_SetRegionTypeFile(region);//设置为文件类型
>>>>>>> remotes/origin/main
}
int ret = filep->ops->mmap(filep, region);
if (ret != LOS_OK) {
@ -564,14 +849,26 @@ STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
return LOS_OK;
}
<<<<<<< HEAD
=======
/**************************************************************************************************
:mapping->page_list 1,3,4,6 ,5
**************************************************************************************************/
>>>>>>> remotes/origin/main
LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
{
LosFilePage *fpage = NULL;
<<<<<<< HEAD
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
if (fpage->pgoff == pgoff) {
return fpage;
}
if (fpage->pgoff > pgoff) {
break;
=======
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {//遍历文件页
if (fpage->pgoff == pgoff) {//找到指定的页,
return fpage;
@ -579,6 +876,7 @@ LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
if (fpage->pgoff > pgoff) {//大于之前还没有找到,说明不在链表中,往后的也不用找了,
break;//因为 mapping->page_list节点上的数据都是按 fpage->pgoff 从小到大的顺序排列的.
>>>>>>> remotes/origin/main
}
}
@ -586,11 +884,14 @@ LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
}
/* need mutex & change memory to dma zone. */
<<<<<<< HEAD
=======
/*!
LosFilePage
Direct Memory Access访
"DMA控制器"CPU
*/
>>>>>>> remotes/origin/main
LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff)
{
VOID *kvaddr = NULL;
@ -598,26 +899,58 @@ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff)
LosVmPage *vmPage = NULL;
LosFilePage *fpage = NULL;
<<<<<<< HEAD
vmPage = LOS_PhysPageAlloc();
=======
vmPage = LOS_PhysPageAlloc(); //先分配一个物理页
>>>>>>> remotes/origin/main
if (vmPage == NULL) {
VM_ERR("alloc vm page failed");
return NULL;
}
<<<<<<< HEAD
physSeg = OsVmPhysSegGet(vmPage);
kvaddr = OsVmPageToVaddr(vmPage);
if ((physSeg == NULL) || (kvaddr == NULL)) {
LOS_PhysPageFree(vmPage);
=======
physSeg = OsVmPhysSegGet(vmPage);//通过页获取所在seg
kvaddr = OsVmPageToVaddr(vmPage);//获取内核空间的虚拟地址,具体点进去看函数说明,这里一定要理解透彻!
if ((physSeg == NULL) || (kvaddr == NULL)) {
LOS_PhysPageFree(vmPage); //异常情况要释放vmPage
>>>>>>> remotes/origin/main
VM_ERR("alloc vm page failed!");
return NULL;
}
<<<<<<< HEAD
fpage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage));
if (fpage == NULL) {
LOS_PhysPageFree(vmPage);
=======
fpage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage));//从内存池中分配一个filePage
if (fpage == NULL) {
LOS_PhysPageFree(vmPage); //异常情况要释放vmPage
>>>>>>> remotes/origin/main
VM_ERR("Failed to allocate for page!");
return NULL;
}
<<<<<<< HEAD
(VOID)memset_s((VOID *)fpage, sizeof(LosFilePage), 0, sizeof(LosFilePage));
LOS_ListInit(&fpage->i_mmap);
LOS_ListInit(&fpage->node);
LOS_ListInit(&fpage->lru);
fpage->n_maps = 0;
fpage->dirtyOff = PAGE_SIZE;
fpage->dirtyEnd = 0;
fpage->physSeg = physSeg;
fpage->vmPage = vmPage;
fpage->mapping = mapping;
fpage->pgoff = pgoff;
(VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE);
=======
(VOID)memset_s((VOID *)fpage, sizeof(LosFilePage), 0, sizeof(LosFilePage));//调标准库函数 置0
LOS_ListInit(&fpage->i_mmap); //初始化映射,链表上挂 MapInfo
@ -631,6 +964,7 @@ LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff)
fpage->mapping = mapping; //记录所有文件页映射
fpage->pgoff = pgoff; //将文件切成一页页,页标
(VOID)memset_s(kvaddr, PAGE_SIZE, 0, PAGE_SIZE);//页内数据清0
>>>>>>> remotes/origin/main
return fpage;
}
@ -644,4 +978,8 @@ INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region)
}
#endif
#endif
<<<<<<< HEAD
#endif
=======
#endif
>>>>>>> remotes/origin/main

@ -1,4 +1,6 @@
/*
<<<<<<< HEAD
=======
访
访Direct Memory AccessDMA访
CPU
@ -38,6 +40,7 @@
/*
>>>>>>> remotes/origin/main
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
*
@ -75,7 +78,11 @@
#include "los_vm_map.h"
#include "los_memory.h"
<<<<<<< HEAD
=======
///分配DMA空间
>>>>>>> remotes/origin/main
VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMemType type)
{
VOID *kVaddr = NULL;
@ -92,24 +99,42 @@ VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMe
#ifdef LOSCFG_KERNEL_VM
kVaddr = LOS_KernelMallocAlign(size, align);
#else
<<<<<<< HEAD
kVaddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, align);
#endif
if (kVaddr == NULL) {
VM_ERR("failed, size = %u, align = %u", size, align);
=======
kVaddr = LOS_MemAllocAlign(OS_SYS_MEM_ADDR, size, align);//不走内存池方式, 直接申请物理页
#endif
if (kVaddr == NULL) {
VM_ERR("failed, size = %u, align = %u", size, align);//从内存池中申请
>>>>>>> remotes/origin/main
return NULL;
}
if (dmaAddr != NULL) {
<<<<<<< HEAD
*dmaAddr = (DMA_ADDR_T)LOS_PaddrQuery(kVaddr);
}
if (type == DMA_NOCACHE) {
=======
*dmaAddr = (DMA_ADDR_T)LOS_PaddrQuery(kVaddr);//查询物理地址, DMA直接将数据灌到物理地址
}
if (type == DMA_NOCACHE) {//无缓存模式 , 计算新的虚拟地址
>>>>>>> remotes/origin/main
kVaddr = (VOID *)VMM_TO_UNCACHED_ADDR((UINTPTR)kVaddr);
}
return kVaddr;
}
<<<<<<< HEAD
=======
///释放DMA指针
>>>>>>> remotes/origin/main
VOID LOS_DmaMemFree(VOID *vaddr)
{
UINTPTR addr;
@ -118,6 +143,15 @@ VOID LOS_DmaMemFree(VOID *vaddr)
return;
}
addr = (UINTPTR)vaddr;
<<<<<<< HEAD
if ((addr >= UNCACHED_VMM_BASE) && (addr < UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)) {
addr = UNCACHED_TO_VMM_ADDR(addr);
#ifdef LOSCFG_KERNEL_VM
LOS_KernelFree((VOID *)addr);
#else
LOS_MemFree(OS_SYS_MEM_ADDR, (VOID *)addr);
=======
// 未缓存区
if ((addr >= UNCACHED_VMM_BASE) && (addr < UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)) {
addr = UNCACHED_TO_VMM_ADDR(addr);//转换成未缓存区地址
@ -125,6 +159,7 @@ VOID LOS_DmaMemFree(VOID *vaddr)
LOS_KernelFree((VOID *)addr);
#else
LOS_MemFree(OS_SYS_MEM_ADDR, (VOID *)addr);//内存池方式释放
>>>>>>> remotes/origin/main
#endif
} else if ((addr >= KERNEL_VMM_BASE) && (addr < KERNEL_VMM_BASE + KERNEL_VMM_SIZE)) {
#ifdef LOSCFG_KERNEL_VM

File diff suppressed because it is too large Load Diff

@ -40,6 +40,19 @@
#ifdef LOSCFG_KERNEL_VM
<<<<<<< HEAD
LosVmPage *g_vmPageArray = NULL;
size_t g_vmPageArraySize;
STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID)
{
LOS_ListInit(&page->node);
page->flags = FILE_PAGE_FREE;
LOS_AtomicSet(&page->refCounts, 0);
page->physAddr = pa;
page->segID = segID;
page->order = VM_LIST_ORDER_MAX;
=======
LosVmPage *g_vmPageArray = NULL;//物理页框数组
size_t g_vmPageArraySize;//物理页框大小
//页框初始化
@ -51,15 +64,23 @@ STATIC VOID OsVmPageInit(LosVmPage *page, paddr_t pa, UINT8 segID)
page->physAddr = pa;//物理地址
page->segID = segID;//物理地址使用段管理段ID
page->order = VM_LIST_ORDER_MAX;//初始化值,不属于任何块组
>>>>>>> remotes/origin/main
page->nPages = 0;
#ifdef LOSCFG_PAGE_TABLE_FINE_LOCK
LOS_SpinInit(&page->lock);
#endif
}
<<<<<<< HEAD
STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
{
OsVmPhysPagesFreeContiguous(page, nPages);
=======
///伙伴算法初始化
STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
{//@note_why 此时所有页面 page->order = VM_LIST_ORDER_MAX,能挂入伙伴算法的链表吗?
OsVmPhysPagesFreeContiguous(page, nPages);//释放连续的物理页框
>>>>>>> remotes/origin/main
}
#define VMPAGEINIT(page, pa, segID) do { \
@ -68,10 +89,13 @@ STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
(pa) += PAGE_SIZE; \
} while (0)
<<<<<<< HEAD
=======
/*!
,
1.g_vmPageArrayLosVmPage,4K.
*/
>>>>>>> remotes/origin/main
VOID OsVmPageStartup(VOID)
{
struct VmPhysSeg *seg = NULL;
@ -80,7 +104,11 @@ VOID OsVmPageStartup(VOID)
UINT32 nPage;
INT32 segID;
<<<<<<< HEAD
OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE));
=======
OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE));//校正 g_physArea size
>>>>>>> remotes/origin/main
/*
* Pages getting from OsVmPhysPageNumGet() interface here contain the memory
@ -89,6 +117,15 @@ VOID OsVmPageStartup(VOID)
*/
UINT32 pageNum = OsVmPhysPageNumGet();
nPage = pageNum * PAGE_SIZE / (sizeof(LosVmPage) + PAGE_SIZE);
<<<<<<< HEAD
g_vmPageArraySize = nPage * sizeof(LosVmPage);
g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);
OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE));
OsVmPhysSegAdd();
OsVmPhysInit();
=======
g_vmPageArraySize = nPage * sizeof(LosVmPage);//页表总大小
g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);//实模式下申请内存,此时还没有初始化MMU
@ -96,13 +133,20 @@ VOID OsVmPageStartup(VOID)
OsVmPhysSegAdd();// 完成对段的初始化
OsVmPhysInit();// 加入空闲链表和设置置换算法,LRU(最近最久未使用)算法
>>>>>>> remotes/origin/main
#ifdef LOSCFG_KERNEL_PLIMITS
OsMemLimitSetLimit(pageNum * PAGE_SIZE);
#endif
<<<<<<< HEAD
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
seg = &g_vmPhysSeg[segID];
nPage = seg->size >> PAGE_SHIFT;
=======
for (segID = 0; segID < g_vmPhysSegNum; segID++) {//遍历物理段,将段切成一页一页
seg = &g_vmPhysSeg[segID];
nPage = seg->size >> PAGE_SHIFT;//本段总页数
>>>>>>> remotes/origin/main
UINT32 count = nPage >> 3; /* 3: 2 ^ 3, nPage / 8, cycle count */
UINT32 left = nPage & 0x7; /* 0x7: nPage % 8, left page */
@ -120,17 +164,29 @@ VOID OsVmPageStartup(VOID)
for (; left > 0; left--) {
VMPAGEINIT(page, pa, segID);
}
<<<<<<< HEAD
OsVmPageOrderListInit(seg->pageBase, nPage);
}
}
=======
OsVmPageOrderListInit(seg->pageBase, nPage);//伙伴算法初始化,将所有页加入空闲链表供分配
}
}
///通过物理地址获取页框
>>>>>>> remotes/origin/main
LosVmPage *LOS_VmPageGet(PADDR_T paddr)
{
INT32 segID;
LosVmPage *page = NULL;
<<<<<<< HEAD
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
page = OsVmPhysToPage(paddr, segID);
=======
for (segID = 0; segID < g_vmPhysSegNum; segID++) {//物理内存采用段页管理
page = OsVmPhysToPage(paddr, segID);//通过物理地址和段ID找出物理页框
>>>>>>> remotes/origin/main
if (page != NULL) {
break;
}

@ -1,3 +1,5 @@
<<<<<<< HEAD
=======
/*!
CPU线
@ -24,6 +26,7 @@
1
*/
>>>>>>> remotes/origin/main
/*
* Copyright (c) 2013-2019 Huawei Technologies Co., Ltd. All rights reserved.
* Copyright (c) 2020-2021 Huawei Device Co., Ltd. All rights reserved.
@ -67,6 +70,19 @@
#define ONE_PAGE 1
<<<<<<< HEAD
/* Physical memory area array */
STATIC struct VmPhysArea g_physArea[] = {
{
.start = SYS_MEM_BASE,
.size = SYS_MEM_SIZE_DEFAULT,
},
};
struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX];
INT32 g_vmPhysSegNum = 0;
=======
/* Physical memory area array | 物理内存区数组 */
STATIC struct VmPhysArea g_physArea[] = {///< 这里只有一个区域,即只生成一个段
{
@ -78,15 +94,32 @@ STATIC struct VmPhysArea g_physArea[] = {///< 这里只有一个区域,即只生
struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX]; ///< 最大32段
INT32 g_vmPhysSegNum = 0; ///< 段数
/// 获取段数组,全局变量,变量放在 .bbs 区
>>>>>>> remotes/origin/main
LosVmPhysSeg *OsGVmPhysSegGet(void)
{
return g_vmPhysSeg;
}
<<<<<<< HEAD
=======
/// 初始化Lru置换链表
>>>>>>> remotes/origin/main
STATIC VOID OsVmPhysLruInit(struct VmPhysSeg *seg)
{
INT32 i;
UINT32 intSave;
<<<<<<< HEAD
LOS_SpinInit(&seg->lruLock);
LOS_SpinLockSave(&seg->lruLock, &intSave);
for (i = 0; i < VM_NR_LRU_LISTS; i++) {
seg->lruSize[i] = 0;
LOS_ListInit(&seg->lruList[i]);
}
LOS_SpinUnlockRestore(&seg->lruLock, intSave);
}
=======
LOS_SpinInit(&seg->lruLock);//初始化自旋锁,自旋锁用于CPU多核同步
LOS_SpinLockSave(&seg->lruLock, &intSave);
@ -97,6 +130,7 @@ STATIC VOID OsVmPhysLruInit(struct VmPhysSeg *seg)
LOS_SpinUnlockRestore(&seg->lruLock, intSave);
}
/// 创建物理段,由区划分转成段管理
>>>>>>> remotes/origin/main
STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size)
{
struct VmPhysSeg *seg = NULL;
@ -105,8 +139,13 @@ STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size)
return -1;
}
<<<<<<< HEAD
seg = &g_vmPhysSeg[g_vmPhysSegNum++];
for (; (seg > g_vmPhysSeg) && ((seg - 1)->start > (start + size)); seg--) {
=======
seg = &g_vmPhysSeg[g_vmPhysSegNum++];//拿到一段数据
for (; (seg > g_vmPhysSeg) && ((seg - 1)->start > (start + size)); seg--) {//定位到合适的段
>>>>>>> remotes/origin/main
*seg = *(seg - 1);
}
seg->start = start;
@ -114,21 +153,35 @@ STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size)
return 0;
}
<<<<<<< HEAD
=======
/// 添加物理段
>>>>>>> remotes/origin/main
VOID OsVmPhysSegAdd(VOID)
{
INT32 i, ret;
LOS_ASSERT(g_vmPhysSegNum < VM_PHYS_SEG_MAX);
<<<<<<< HEAD
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size);
=======
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {//遍历g_physArea数组
ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size);//由区划分转成段管理
>>>>>>> remotes/origin/main
if (ret != 0) {
VM_ERR("create phys seg failed");
}
}
}
<<<<<<< HEAD
=======
/// 段区域大小调整
>>>>>>> remotes/origin/main
VOID OsVmPhysAreaSizeAdjust(size_t size)
{
/*
@ -139,25 +192,50 @@ VOID OsVmPhysAreaSizeAdjust(size_t size)
g_physArea[0].size -= size;
}
<<<<<<< HEAD
=======
/// 获得物理内存的总页数
>>>>>>> remotes/origin/main
UINT32 OsVmPhysPageNumGet(VOID)
{
UINT32 nPages = 0;
INT32 i;
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
<<<<<<< HEAD
nPages += g_physArea[i].size >> PAGE_SHIFT;
}
return nPages;
}
=======
nPages += g_physArea[i].size >> PAGE_SHIFT;//右移12位相当于除以4K, 计算出总页数
}
return nPages;//返回所有物理内存总页数
}
/// 初始化空闲链表,分配物理页框使用伙伴算法
>>>>>>> remotes/origin/main
STATIC INLINE VOID OsVmPhysFreeListInit(struct VmPhysSeg *seg)
{
int i;
UINT32 intSave;
struct VmFreeList *list = NULL;
<<<<<<< HEAD
LOS_SpinInit(&seg->freeListLock);
LOS_SpinLockSave(&seg->freeListLock, &intSave);
for (i = 0; i < VM_LIST_ORDER_MAX; i++) {
list = &seg->freeList[i];
LOS_ListInit(&list->node);
list->listCnt = 0;
}
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
}
=======
LOS_SpinInit(&seg->freeListLock);//初始化用于分配的自旋锁
LOS_SpinLockSave(&seg->freeListLock, &intSave);
@ -169,6 +247,7 @@ STATIC INLINE VOID OsVmPhysFreeListInit(struct VmPhysSeg *seg)
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
}
/// 物理段初始化
>>>>>>> remotes/origin/main
VOID OsVmPhysInit(VOID)
{
struct VmPhysSeg *seg = NULL;
@ -177,6 +256,15 @@ VOID OsVmPhysInit(VOID)
for (i = 0; i < g_vmPhysSegNum; i++) {
seg = &g_vmPhysSeg[i];
<<<<<<< HEAD
seg->pageBase = &g_vmPageArray[nPages];
nPages += seg->size >> PAGE_SHIFT;
OsVmPhysFreeListInit(seg);
OsVmPhysLruInit(seg);
}
}
=======
seg->pageBase = &g_vmPageArray[nPages];//记录本段首页物理页框地址
nPages += seg->size >> PAGE_SHIFT;//偏移12位,按4K一页,算出本段总页数
OsVmPhysFreeListInit(seg); //初始化空闲链表,分配页框使用伙伴算法
@ -184,6 +272,7 @@ VOID OsVmPhysInit(VOID)
}
}
/// 将页框挂入空闲链表,分配物理页框从空闲链表里拿
>>>>>>> remotes/origin/main
STATIC VOID OsVmPhysFreeListAddUnsafe(LosVmPage *page, UINT8 order)
{
struct VmPhysSeg *seg = NULL;
@ -200,12 +289,29 @@ STATIC VOID OsVmPhysFreeListAddUnsafe(LosVmPage *page, UINT8 order)
LOS_ListTailInsert(&list->node, &page->node);
list->listCnt++;
}
<<<<<<< HEAD
=======
///将物理页框从空闲链表上摘除,见于物理页框被分配的情况
>>>>>>> remotes/origin/main
STATIC VOID OsVmPhysFreeListDelUnsafe(LosVmPage *page)
{
struct VmPhysSeg *seg = NULL;
struct VmFreeList *list = NULL;
<<<<<<< HEAD
if ((page->segID >= VM_PHYS_SEG_MAX) || (page->order >= VM_LIST_ORDER_MAX)) {
LOS_Panic("The page segment id(%u) or order(%u) is invalid\n", page->segID, page->order);
}
seg = &g_vmPhysSeg[page->segID];
list = &seg->freeList[page->order];
list->listCnt--;
LOS_ListDelete(&page->node);
page->order = VM_LIST_ORDER_MAX;
}
=======
if ((page->segID >= VM_PHYS_SEG_MAX) || (page->order >= VM_LIST_ORDER_MAX)) {//等于VM_LIST_ORDER_MAX也不行,说明伙伴算法最大支持 2^8的分配
LOS_Panic("The page segment id(%u) or order(%u) is invalid\n", page->segID, page->order);
}
@ -225,11 +331,22 @@ STATIC VOID OsVmPhysFreeListDelUnsafe(LosVmPage *page)
* @param newOrder 2^8
* @return STATIC
*/
>>>>>>> remotes/origin/main
STATIC VOID OsVmPhysPagesSpiltUnsafe(LosVmPage *page, UINT8 oldOrder, UINT8 newOrder)
{
UINT32 order;
LosVmPage *buddyPage = NULL;
<<<<<<< HEAD
for (order = newOrder; order > oldOrder;) {
order--;
buddyPage = &page[VM_ORDER_TO_PAGES(order)];
LOS_ASSERT(buddyPage->order == VM_LIST_ORDER_MAX);
OsVmPhysFreeListAddUnsafe(buddyPage, order);
}
}
=======
for (order = newOrder; order > oldOrder;) {//把肉剁碎的过程,把多余的肉块切成2^7,2^6...标准块,
order--;//越切越小,逐一挂到对应的空闲链表上
buddyPage = &page[VM_ORDER_TO_PAGES(order)];//@note_good 先把多余的肉割出来,这句代码很赞!因为LosVmPage本身是在一个大数组上,page[nPages]可直接定位
@ -238,6 +355,7 @@ STATIC VOID OsVmPhysPagesSpiltUnsafe(LosVmPage *page, UINT8 oldOrder, UINT8 newO
}
}
///通过物理地址获取所属参数段的物理页框
>>>>>>> remotes/origin/main
LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID)
{
struct VmPhysSeg *seg = NULL;
@ -251,8 +369,13 @@ LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID)
return NULL;
}
<<<<<<< HEAD
offset = pa - seg->start;
return (seg->pageBase + (offset >> PAGE_SHIFT));
=======
offset = pa - seg->start;//得到物理地址的偏移量
return (seg->pageBase + (offset >> PAGE_SHIFT));//得到对应的物理页框
>>>>>>> remotes/origin/main
}
LosVmPage *OsVmPaddrToPage(paddr_t paddr)
@ -268,6 +391,27 @@ LosVmPage *OsVmPaddrToPage(paddr_t paddr)
}
return NULL;
}
<<<<<<< HEAD
VOID *OsVmPageToVaddr(LosVmPage *page)
{
VADDR_T vaddr;
vaddr = KERNEL_ASPACE_BASE + page->physAddr - SYS_MEM_BASE;
return (VOID *)(UINTPTR)vaddr;
}
LosVmPage *OsVmVaddrToPage(VOID *ptr)
{
struct VmPhysSeg *seg = NULL;
PADDR_T pa = LOS_PaddrQuery(ptr);
UINT32 segID;
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
seg = &g_vmPhysSeg[segID];
if ((pa >= seg->start) && (pa < (seg->start + seg->size))) {
return seg->pageBase + ((pa - seg->start) >> PAGE_SHIFT);
=======
/*!
* @brief page OsArchMmuInit
\n #define SYS_MEM_BASE DDR_MEM_ADDR /* physical memory base 物理地址的起始地址 * /
@ -293,12 +437,17 @@ LosVmPage *OsVmVaddrToPage(VOID *ptr)
seg = &g_vmPhysSeg[segID];
if ((pa >= seg->start) && (pa < (seg->start + seg->size))) {//找到物理地址所在的段
return seg->pageBase + ((pa - seg->start) >> PAGE_SHIFT);//段基地址+页偏移索引 得到虚拟地址经映射所在物理页框
>>>>>>> remotes/origin/main
}
}
return NULL;
}
<<<<<<< HEAD
=======
/// 回收一定范围内的页框
>>>>>>> remotes/origin/main
STATIC INLINE VOID OsVmRecycleExtraPages(LosVmPage *page, size_t startPage, size_t endPage)
{
if (startPage >= endPage) {
@ -307,7 +456,11 @@ STATIC INLINE VOID OsVmRecycleExtraPages(LosVmPage *page, size_t startPage, size
OsVmPhysPagesFreeContiguous(page, endPage - startPage);
}
<<<<<<< HEAD
=======
/// 大块的物理内存分配
>>>>>>> remotes/origin/main
STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages)
{
struct VmFreeList *list = NULL;
@ -317,11 +470,19 @@ STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages)
PADDR_T paEnd;
size_t size = nPages << PAGE_SHIFT;
<<<<<<< HEAD
list = &seg->freeList[VM_LIST_ORDER_MAX - 1];
LOS_DL_LIST_FOR_EACH_ENTRY(page, &list->node, LosVmPage, node) {
paStart = page->physAddr;
paEnd = paStart + size;
if (paEnd > (seg->start + seg->size)) {
=======
list = &seg->freeList[VM_LIST_ORDER_MAX - 1];//先找伙伴算法中内存块最大的开撸
LOS_DL_LIST_FOR_EACH_ENTRY(page, &list->node, LosVmPage, node) {//遍历链表
paStart = page->physAddr;
paEnd = paStart + size;
if (paEnd > (seg->start + seg->size)) {//匹配物理地址范围
>>>>>>> remotes/origin/main
continue;
}
@ -343,7 +504,11 @@ STATIC LosVmPage *OsVmPhysLargeAlloc(struct VmPhysSeg *seg, size_t nPages)
return NULL;
}
<<<<<<< HEAD
=======
/// 申请物理页并挂在对应的链表上
>>>>>>> remotes/origin/main
STATIC LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages)
{
struct VmFreeList *list = NULL;
@ -353,6 +518,15 @@ STATIC LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages)
UINT32 newOrder;
order = OsVmPagesToOrder(nPages);
<<<<<<< HEAD
if (order < VM_LIST_ORDER_MAX) {
for (newOrder = order; newOrder < VM_LIST_ORDER_MAX; newOrder++) {
list = &seg->freeList[newOrder];
if (LOS_ListEmpty(&list->node)) {
continue;
}
page = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&list->node), LosVmPage, node);
=======
if (order < VM_LIST_ORDER_MAX) {//按正常的伙伴算法分配
for (newOrder = order; newOrder < VM_LIST_ORDER_MAX; newOrder++) {//从小往大了撸
list = &seg->freeList[newOrder];
@ -360,6 +534,7 @@ STATIC LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages)
continue;//继续往大的找
}
page = LOS_DL_LIST_ENTRY(LOS_DL_LIST_FIRST(&list->node), LosVmPage, node);//找到了直接返回第一个节点
>>>>>>> remotes/origin/main
goto DONE;
}
} else {
@ -380,7 +555,11 @@ DONE:
return page;
}
<<<<<<< HEAD
=======
/// 释放物理页框,所谓释放物理页就是把页挂到空闲链表中
>>>>>>> remotes/origin/main
VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order)
{
paddr_t pa;
@ -390,6 +569,17 @@ VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order)
return;
}
<<<<<<< HEAD
if (order < VM_LIST_ORDER_MAX - 1) {
pa = VM_PAGE_TO_PHYS(page);
do {
pa ^= VM_ORDER_TO_PHYS(order);
buddyPage = OsVmPhysToPage(pa, page->segID);
if ((buddyPage == NULL) || (buddyPage->order != order)) {
break;
}
OsVmPhysFreeListDelUnsafe(buddyPage);
=======
if (order < VM_LIST_ORDER_MAX - 1) {//order[0,7]
pa = VM_PAGE_TO_PHYS(page);//获取物理地址
do {//按位异或
@ -399,21 +589,51 @@ VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order)
break;
}
OsVmPhysFreeListDelUnsafe(buddyPage);//注意buddypage是连续的物理页框 例如order=2时,2^2=4页就是一个块组 |_|_|_|_|
>>>>>>> remotes/origin/main
order++;
pa &= ~(VM_ORDER_TO_PHYS(order) - 1);
page = OsVmPhysToPage(pa, page->segID);
} while (order < VM_LIST_ORDER_MAX - 1);
}
<<<<<<< HEAD
OsVmPhysFreeListAddUnsafe(page, order);
}
=======
OsVmPhysFreeListAddUnsafe(page, order);//伙伴算法 空闲节点增加
}
///连续的释放物理页框, 如果8页连在一块是一起释放的
>>>>>>> remotes/origin/main
VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages)
{
paddr_t pa;
UINT32 order;
size_t n;
<<<<<<< HEAD
while (TRUE) {
pa = VM_PAGE_TO_PHYS(page);
order = VM_PHYS_TO_ORDER(pa);
n = VM_ORDER_TO_PAGES(order);
if (n > nPages) {
break;
}
OsVmPhysPagesFree(page, order);
nPages -= n;
page += n;
}
while (nPages > 0) {
order = LOS_HighBitGet(nPages);
n = VM_ORDER_TO_PAGES(order);
OsVmPhysPagesFree(page, order);
nPages -= n;
page += n;
}
}
=======
while (TRUE) {//死循环
pa = VM_PAGE_TO_PHYS(page);//获取页面物理地址
order = VM_PHYS_TO_ORDER(pa);//通过物理地址找到伙伴算法的级别
@ -443,6 +663,7 @@ VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages)
*
* @see
*/
>>>>>>> remotes/origin/main
STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages)
{
UINT32 intSave;
@ -453,11 +674,19 @@ STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages)
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
seg = &g_vmPhysSeg[segID];
LOS_SpinLockSave(&seg->freeListLock, &intSave);
<<<<<<< HEAD
page = OsVmPhysPagesAlloc(seg, nPages);
if (page != NULL) {
/* the first page of continuous physical addresses holds refCounts */
LOS_AtomicSet(&page->refCounts, 0);
page->nPages = nPages;
=======
page = OsVmPhysPagesAlloc(seg, nPages);//分配指定页数的物理页,nPages需小于伙伴算法一次能分配的最大页数
if (page != NULL) {//分配成功
/* */
LOS_AtomicSet(&page->refCounts, 0);//设置引用次数为0
page->nPages = nPages;//页数
>>>>>>> remotes/origin/main
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
return page;
}
@ -465,7 +694,11 @@ STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages)
}
return NULL;
}
<<<<<<< HEAD
=======
///分配连续的物理页
>>>>>>> remotes/origin/main
VOID *LOS_PhysPagesAllocContiguous(size_t nPages)
{
LosVmPage *page = NULL;
@ -473,15 +706,26 @@ VOID *LOS_PhysPagesAllocContiguous(size_t nPages)
if (nPages == 0) {
return NULL;
}
<<<<<<< HEAD
page = OsVmPhysPagesGet(nPages);
=======
//鸿蒙 nPages 不能大于 2^8 次方,即256个页,1M内存,仅限于内核态,用户态不限制分配大小.
page = OsVmPhysPagesGet(nPages);//通过伙伴算法获取物理上连续的页
>>>>>>> remotes/origin/main
if (page == NULL) {
return NULL;
}
<<<<<<< HEAD
return OsVmPageToVaddr(page);
}
=======
return OsVmPageToVaddr(page);//通过物理页找虚拟地址
}
/// 释放指定页数地址连续的物理内存
>>>>>>> remotes/origin/main
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
{
UINT32 intSave;
@ -492,17 +736,29 @@ VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
return;
}
<<<<<<< HEAD
page = OsVmVaddrToPage(ptr);
=======
page = OsVmVaddrToPage(ptr);//通过虚拟地址找到页框
>>>>>>> remotes/origin/main
if (page == NULL) {
VM_ERR("vm page of ptr(%#x) is null", ptr);
return;
}
<<<<<<< HEAD
page->nPages = 0;
=======
page->nPages = 0;//被分配的页数置为0,表示不被分配
>>>>>>> remotes/origin/main
seg = &g_vmPhysSeg[page->segID];
LOS_SpinLockSave(&seg->freeListLock, &intSave);
<<<<<<< HEAD
OsVmPhysPagesFreeContiguous(page, nPages);
=======
OsVmPhysPagesFreeContiguous(page, nPages);//具体释放实现
>>>>>>> remotes/origin/main
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
#ifdef LOSCFG_KERNEL_PLIMITS
@ -517,7 +773,11 @@ PADDR_T OsKVaddrToPaddr(VADDR_T kvaddr)
}
return (kvaddr - KERNEL_ASPACE_BASE + SYS_MEM_BASE);
}
<<<<<<< HEAD
=======
/// 通过物理地址获取内核虚拟地址
>>>>>>> remotes/origin/main
VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
{
struct VmPhysSeg *seg = NULL;
@ -533,10 +793,17 @@ VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);
}
}
<<<<<<< HEAD
return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);
}
=======
//内核
return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);//
}
///释放一个物理页框
>>>>>>> remotes/origin/main
VOID LOS_PhysPageFree(LosVmPage *page)
{
UINT32 intSave;
@ -546,12 +813,21 @@ VOID LOS_PhysPageFree(LosVmPage *page)
return;
}
<<<<<<< HEAD
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);
=======
if (LOS_AtomicDecRet(&page->refCounts) <= 0) {//减少引用数后不能小于0
seg = &g_vmPhysSeg[page->segID];
LOS_SpinLockSave(&seg->freeListLock, &intSave);
OsVmPhysPagesFreeContiguous(page, ONE_PAGE);//释放一页
LOS_AtomicSet(&page->refCounts, 0);//只要物理内存被释放了,引用数就必须得重置为 0
>>>>>>> remotes/origin/main
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
}
@ -559,6 +835,14 @@ VOID LOS_PhysPageFree(LosVmPage *page)
OsMemLimitMemFree(PAGE_SIZE);
#endif
}
<<<<<<< HEAD
LosVmPage *LOS_PhysPageAlloc(VOID)
{
return OsVmPhysPagesGet(ONE_PAGE);
}
=======
/// 申请一个物理页
LosVmPage *LOS_PhysPageAlloc(VOID)
{
@ -575,6 +859,7 @@ LosVmPage *LOS_PhysPageAlloc(VOID)
*
* @see
*/
>>>>>>> remotes/origin/main
size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list)
{
LosVmPage *page = NULL;
@ -585,17 +870,29 @@ size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list)
}
while (nPages--) {
<<<<<<< HEAD
page = OsVmPhysPagesGet(ONE_PAGE);
if (page == NULL) {
break;
}
LOS_ListTailInsert(list, &page->node);
=======
page = OsVmPhysPagesGet(ONE_PAGE);//一页一页分配,由伙伴算法分配
if (page == NULL) {
break;
}
LOS_ListTailInsert(list, &page->node);//从参数链表list尾部挂入新页面结点
>>>>>>> remotes/origin/main
count++;
}
return count;
}
<<<<<<< HEAD
=======
///拷贝共享页面
>>>>>>> remotes/origin/main
VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage)
{
UINT32 intSave;
@ -609,12 +906,35 @@ VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage
return;
}
<<<<<<< HEAD
oldPage = LOS_VmPageGet(oldPaddr);
=======
oldPage = LOS_VmPageGet(oldPaddr);//由物理地址得到页框
>>>>>>> remotes/origin/main
if (oldPage == NULL) {
VM_ERR("invalid oldPaddr %p", oldPaddr);
return;
}
<<<<<<< HEAD
seg = &g_vmPhysSeg[oldPage->segID];
LOS_SpinLockSave(&seg->freeListLock, &intSave);
if (LOS_AtomicRead(&oldPage->refCounts) == 1) {
*newPaddr = oldPaddr;
} else {
newMem = LOS_PaddrToKVaddr(*newPaddr);
oldMem = LOS_PaddrToKVaddr(oldPaddr);
if ((newMem == NULL) || (oldMem == NULL)) {
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
return;
}
if (memcpy_s(newMem, PAGE_SIZE, oldMem, PAGE_SIZE) != EOK) {
VM_ERR("memcpy_s failed");
}
LOS_AtomicInc(&newPage->refCounts);
LOS_AtomicDec(&oldPage->refCounts);
=======
seg = &g_vmPhysSeg[oldPage->segID];//拿到物理段
LOS_SpinLockSave(&seg->freeListLock, &intSave);
if (LOS_AtomicRead(&oldPage->refCounts) == 1) {//页面引用次数仅一次,说明只有一个进程在操作
@ -632,20 +952,31 @@ VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage
LOS_AtomicInc(&newPage->refCounts);//新页引用次数以原子方式自动减量
LOS_AtomicDec(&oldPage->refCounts);//老页引用次数以原子方式自动减量
>>>>>>> remotes/origin/main
}
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
return;
}
<<<<<<< HEAD
=======
///获取物理页框所在段
>>>>>>> remotes/origin/main
struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page)
{
if ((page == NULL) || (page->segID >= VM_PHYS_SEG_MAX)) {
return NULL;
}
<<<<<<< HEAD
return (OsGVmPhysSegGet() + page->segID);
}
=======
return (OsGVmPhysSegGet() + page->segID);//等用于OsGVmPhysSegGet()[page->segID]
}
///获取参数nPages对应的块组,例如 7 -> 2^3 返回 3
>>>>>>> remotes/origin/main
UINT32 OsVmPagesToOrder(size_t nPages)
{
UINT32 order;
@ -654,7 +985,11 @@ UINT32 OsVmPagesToOrder(size_t nPages)
return order;
}
<<<<<<< HEAD
=======
///释放双链表中的所有节点内存,本质是回归到伙伴orderlist中
>>>>>>> remotes/origin/main
size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
{
UINT32 intSave;
@ -667,6 +1002,18 @@ size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
return 0;
}
<<<<<<< HEAD
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);
}
count++;
=======
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(page, nPage, list, LosVmPage, node) {//宏循环
LOS_ListDelete(&page->node);//先把自己摘出去
if (LOS_AtomicDecRet(&page->refCounts) <= 0) {//无引用
@ -677,6 +1024,7 @@ size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);//恢复锁
}
count++;//继续取下一个node
>>>>>>> remotes/origin/main
}
return count;
@ -691,3 +1039,7 @@ VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
return (VADDR_T *)DMA_TO_VMM_ADDR(paddr);
}
#endif
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main

@ -37,10 +37,13 @@
#ifdef LOSCFG_KERNEL_VM
/* unmap a lru page by map record info caller need lru lock */
<<<<<<< HEAD
=======
/**************************************************************************************************
(mmu)
infoMMU
**************************************************************************************************/
>>>>>>> remotes/origin/main
VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info)
{
if (page == NULL || info == NULL) {
@ -51,21 +54,101 @@ VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info)
LOS_ListDelete(&info->node);
LOS_AtomicDec(&page->vmPage->refCounts);
LOS_ArchMmuUnmap(info->archMmu, info->vaddr, 1);
<<<<<<< HEAD
LOS_MemFree(m_aucSysMem0, info);
}
=======
LOS_MemFree(m_aucSysMem0, info);//释放虚拟
}
///解除文件页在所有进程的映射
>>>>>>> remotes/origin/main
VOID OsUnmapAllLocked(LosFilePage *page)
{
LosMapInfo *info = NULL;
LosMapInfo *next = NULL;
LOS_DL_LIST *immap = &page->i_mmap;
<<<<<<< HEAD
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(info, next, immap, LosMapInfo, node) {
=======
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(info, next, immap, LosMapInfo, node) {//遍历 immap->info 链表
>>>>>>> remotes/origin/main
OsUnmapPageLocked(page, info);
}
}
/* add a new lru node to lru list, lruType can be file or anon */
<<<<<<< HEAD
VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType)
{
UINT32 intSave;
LosVmPhysSeg *physSeg = fpage->physSeg;
LosVmPage *page = fpage->vmPage;
LOS_SpinLockSave(&physSeg->lruLock, &intSave);
OsSetPageActive(page);
OsCleanPageReferenced(page);
physSeg->lruSize[lruType]++;
LOS_ListTailInsert(&physSeg->lruList[lruType], &fpage->lru);
LOS_SpinUnlockRestore(&physSeg->lruLock, intSave);
}
/* delete a lru node, caller need hold lru_lock */
VOID OsLruCacheDel(LosFilePage *fpage)
{
LosVmPhysSeg *physSeg = fpage->physSeg;
int type = OsIsPageActive(fpage->vmPage) ? VM_LRU_ACTIVE_FILE : VM_LRU_INACTIVE_FILE;
physSeg->lruSize[type]--;
LOS_ListDelete(&fpage->lru);
}
BOOL OsInactiveListIsLow(LosVmPhysSeg *physSeg)
{
return (physSeg->lruSize[VM_LRU_ACTIVE_FILE] >
physSeg->lruSize[VM_LRU_INACTIVE_FILE]) ? TRUE : FALSE;
}
/* move a page from inactive list to active list head */
STATIC INLINE VOID OsMoveToActiveList(LosFilePage *fpage)
{
LosVmPhysSeg *physSeg = fpage->physSeg;
physSeg->lruSize[VM_LRU_ACTIVE_FILE]++;
physSeg->lruSize[VM_LRU_INACTIVE_FILE]--;
LOS_ListDelete(&fpage->lru);
LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru);
}
/* move a page from active list to inactive list head */
STATIC INLINE VOID OsMoveToInactiveList(LosFilePage *fpage)
{
LosVmPhysSeg *physSeg = fpage->physSeg;
physSeg->lruSize[VM_LRU_ACTIVE_FILE]--;
physSeg->lruSize[VM_LRU_INACTIVE_FILE]++;
LOS_ListDelete(&fpage->lru);
LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru);
}
/* move a page to the most active pos in lru list(active head) */
STATIC INLINE VOID OsMoveToActiveHead(LosFilePage *fpage)
{
LosVmPhysSeg *physSeg = fpage->physSeg;
LOS_ListDelete(&fpage->lru);
LOS_ListTailInsert(&physSeg->lruList[VM_LRU_ACTIVE_FILE], &fpage->lru);
}
/* move a page to the most active pos in lru list(inactive head) */
STATIC INLINE VOID OsMoveToInactiveHead(LosFilePage *fpage)
{
LosVmPhysSeg *physSeg = fpage->physSeg;
LOS_ListDelete(&fpage->lru);
LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru);
=======
VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType)//在lru列表中添加一个新的lru节点lruType可以是文件或匿名
{
UINT32 intSave;
@ -133,6 +216,7 @@ STATIC INLINE VOID OsMoveToInactiveHead(LosFilePage *fpage)//鸿蒙会从inactiv
LosVmPhysSeg *physSeg = fpage->physSeg; //得到页面对应段
LOS_ListDelete(&fpage->lru); //将自己从lru链表中摘出来
LOS_ListTailInsert(&physSeg->lruList[VM_LRU_INACTIVE_FILE], &fpage->lru);//加入不活动页双循环链表中
>>>>>>> remotes/origin/main
}
/* page referced add: (call by page cache get)
@ -142,7 +226,11 @@ ref:0, act:0 --> ref:1, act:0
ref:1, act:0 --> ref:0, act:1
ref:0, act:1 --> ref:1, act:1
*/
<<<<<<< HEAD
VOID OsPageRefIncLocked(LosFilePage *fpage)
=======
VOID OsPageRefIncLocked(LosFilePage *fpage)// ref ,act 标签转换功能
>>>>>>> remotes/origin/main
{
BOOL isOrgActive;
UINT32 intSave;
@ -152,6 +240,18 @@ VOID OsPageRefIncLocked(LosFilePage *fpage)// ref ,act 标签转换功能
return;
}
<<<<<<< HEAD
LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave);
page = fpage->vmPage;
isOrgActive = OsIsPageActive(page);
if (OsIsPageReferenced(page) && !OsIsPageActive(page)) {
OsCleanPageReferenced(page);
OsSetPageActive(page);
} else if (!OsIsPageReferenced(page)) {
OsSetPageReferenced(page);
=======
LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave);//要处理lruList,先拿锁
page = fpage->vmPage;//拿到物理页框
@ -162,6 +262,7 @@ VOID OsPageRefIncLocked(LosFilePage *fpage)// ref ,act 标签转换功能
OsSetPageActive(page); //贴上活动标签
} else if (!OsIsPageReferenced(page)) {
OsSetPageReferenced(page);//ref:0, act:0 --> ref:1, act:0
>>>>>>> remotes/origin/main
}
if (!isOrgActive && OsIsPageActive(page)) {
@ -179,14 +280,22 @@ VOID OsPageRefIncLocked(LosFilePage *fpage)// ref ,act 标签转换功能
LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave);
}
<<<<<<< HEAD
/* page referced dec: (call by shrinker)
=======
/* page referced dec: (call by thrinker)
>>>>>>> remotes/origin/main
----------inactive----------|----------active------------
[ref:0,act:0], [ref:1,act:0]|[ref:0,act:1], [ref:1,act:1]
ref:1, act:1 --> ref:0, act:1
ref:0, act:1 --> ref:1, act:0
ref:1, act:0 --> ref:0, act:0
*/
<<<<<<< HEAD
VOID OsPageRefDecNoLock(LosFilePage *fpage)
=======
VOID OsPageRefDecNoLock(LosFilePage *fpage) // ref ,act 标签转换功能
>>>>>>> remotes/origin/main
{
BOOL isOrgActive;
LosVmPage *page = NULL;
@ -198,7 +307,11 @@ VOID OsPageRefDecNoLock(LosFilePage *fpage) // ref ,act 标签转换功能
page = fpage->vmPage;
isOrgActive = OsIsPageActive(page);
<<<<<<< HEAD
if (!OsIsPageReferenced(page) && OsIsPageActive(page)) {
=======
if (!OsIsPageReferenced(page) && OsIsPageActive(page)) {//[ref:0,act:1]的情况
>>>>>>> remotes/origin/main
OsCleanPageActive(page);
OsSetPageReferenced(page);
} else if (OsIsPageReferenced(page)) {
@ -209,13 +322,38 @@ VOID OsPageRefDecNoLock(LosFilePage *fpage) // ref ,act 标签转换功能
OsMoveToInactiveList(fpage);
}
}
<<<<<<< HEAD
=======
///缩小活动页链表
>>>>>>> remotes/origin/main
VOID OsShrinkActiveList(LosVmPhysSeg *physSeg, int nScan)
{
LosFilePage *fpage = NULL;
LosFilePage *fnext = NULL;
LOS_DL_LIST *activeFile = &physSeg->lruList[VM_LRU_ACTIVE_FILE];
<<<<<<< HEAD
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, activeFile, LosFilePage, lru) {
if (LOS_SpinTrylock(&fpage->mapping->list_lock) != LOS_OK) {
continue;
}
/* happened when caller hold cache lock and try reclaim this page */
if (OsIsPageLocked(fpage->vmPage)) {
LOS_SpinUnlock(&fpage->mapping->list_lock);
continue;
}
if (OsIsPageMapped(fpage) && (fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE)) {
LOS_SpinUnlock(&fpage->mapping->list_lock);
continue;
}
OsPageRefDecNoLock(fpage);
LOS_SpinUnlock(&fpage->mapping->list_lock);
=======
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, activeFile, LosFilePage, lru) {//一页一页处理
if (LOS_SpinTrylock(&fpage->mapping->list_lock) != LOS_OK) {//尝试获取文件页所在的page_mapping锁
continue;//接着处理下一文件页
@ -235,13 +373,18 @@ VOID OsShrinkActiveList(LosVmPhysSeg *physSeg, int nScan)
OsPageRefDecNoLock(fpage); //将页面移到未活动文件链表
LOS_SpinUnlock(&fpage->mapping->list_lock); //释放page_mapping锁.
>>>>>>> remotes/origin/main
if (--nScan <= 0) {
break;
}
}
}
<<<<<<< HEAD
=======
///缩小未活动页链表
>>>>>>> remotes/origin/main
int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list)
{
UINT32 nrReclaimed = 0;
@ -252,6 +395,38 @@ int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list)
LosFilePage *ftemp = NULL;
LOS_DL_LIST *inactive_file = &physSeg->lruList[VM_LRU_INACTIVE_FILE];
<<<<<<< HEAD
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, inactive_file, LosFilePage, lru) {
flock = &fpage->mapping->list_lock;
if (LOS_SpinTrylock(flock) != LOS_OK) {
continue;
}
page = fpage->vmPage;
if (OsIsPageLocked(page)) {
LOS_SpinUnlock(flock);
continue;
}
if (OsIsPageMapped(fpage) && (OsIsPageDirty(page) || (fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE))) {
LOS_SpinUnlock(flock);
continue;
}
if (OsIsPageDirty(page)) {
ftemp = OsDumpDirtyPage(fpage);
if (ftemp != NULL) {
LOS_ListTailInsert(list, &ftemp->node);
}
}
OsDeletePageCacheLru(fpage);
LOS_SpinUnlock(flock);
nrReclaimed++;
if (--nScan <= 0) {
=======
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, inactive_file, LosFilePage, lru) {//遍历链表一页一页处理
flock = &fpage->mapping->list_lock;
@ -282,6 +457,7 @@ int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list)
nrReclaimed++;//成功回收了一页
if (--nScan <= 0) {//继续回收
>>>>>>> remotes/origin/main
break;
}
}
@ -290,25 +466,62 @@ int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list)
}
#ifdef LOSCFG_FS_VFS
<<<<<<< HEAD
int OsTryShrinkMemory(size_t nPage)
=======
int OsTryShrinkMemory(size_t nPage)//尝试收缩文件页
>>>>>>> remotes/origin/main
{
UINT32 intSave;
size_t totalPages;
size_t nReclaimed = 0;
LosVmPhysSeg *physSeg = NULL;
UINT32 index;
<<<<<<< HEAD
LOS_DL_LIST_HEAD(dirtyList);
=======
LOS_DL_LIST_HEAD(dirtyList);//初始化脏页链表,上面将挂所有脏页用于同步到磁盘后回收
>>>>>>> remotes/origin/main
LosFilePage *fpage = NULL;
LosFilePage *fnext = NULL;
if (nPage == 0) {
<<<<<<< HEAD
nPage = VM_FILEMAP_MIN_SCAN;
=======
nPage = VM_FILEMAP_MIN_SCAN;//
>>>>>>> remotes/origin/main
}
if (nPage > VM_FILEMAP_MAX_SCAN) {
nPage = VM_FILEMAP_MAX_SCAN;
}
<<<<<<< HEAD
for (index = 0; index < g_vmPhysSegNum; index++) {
physSeg = &g_vmPhysSeg[index];
LOS_SpinLockSave(&physSeg->lruLock, &intSave);
totalPages = physSeg->lruSize[VM_LRU_ACTIVE_FILE] + physSeg->lruSize[VM_LRU_INACTIVE_FILE];
if (totalPages < VM_FILEMAP_MIN_SCAN) {
LOS_SpinUnlockRestore(&physSeg->lruLock, intSave);
continue;
}
if (OsInactiveListIsLow(physSeg)) {
OsShrinkActiveList(physSeg, (nPage < VM_FILEMAP_MIN_SCAN) ? VM_FILEMAP_MIN_SCAN : nPage);
}
nReclaimed += OsShrinkInactiveList(physSeg, nPage, &dirtyList);
LOS_SpinUnlockRestore(&physSeg->lruLock, intSave);
if (nReclaimed >= nPage) {
break;
}
}
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) {
OsDoFlushDirtyPage(fpage);
=======
for (index = 0; index < g_vmPhysSegNum; index++) {//遍历整个物理段组
physSeg = &g_vmPhysSeg[index];//一段段来
LOS_SpinLockSave(&physSeg->lruLock, &intSave);
@ -332,6 +545,7 @@ int OsTryShrinkMemory(size_t nPage)//尝试收缩文件页
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, &dirtyList, LosFilePage, node) {//遍历处理脏页数据
OsDoFlushDirtyPage(fpage);//冲洗脏页数据,将脏页数据回写磁盘
>>>>>>> remotes/origin/main
}
return nReclaimed;
@ -344,4 +558,8 @@ int OsTryShrinkMemory(size_t nPage)
#endif
#endif
#endif
<<<<<<< HEAD
#endif
=======
#endif
>>>>>>> remotes/origin/main

@ -65,7 +65,11 @@ STATUS_T OsCheckMMapParams(VADDR_T *vaddr, unsigned long flags, size_t len, unsi
return -EINVAL;
}
<<<<<<< HEAD
if ((flags & MAP_SUPPORT_MASK) == 0) {
=======
if ((flags & MAP_SUPPORT_MASK) == 0) {//映射权限限制
>>>>>>> remotes/origin/main
return -EINVAL;
}
if (((flags & MAP_SHARED_PRIVATE) == 0) || ((flags & MAP_SHARED_PRIVATE) == MAP_SHARED_PRIVATE)) {
@ -95,13 +99,19 @@ STATUS_T OsNamedMmapingPermCheck(struct file *filep, unsigned long flags, unsign
return LOS_OK;
}
<<<<<<< HEAD
=======
///匿名映射
>>>>>>> remotes/origin/main
STATUS_T OsAnonMMap(LosVmMapRegion *region)
{
LOS_SetRegionTypeAnon(region);
return LOS_OK;
}
<<<<<<< HEAD
=======
/**
mmap:
.
@ -136,13 +146,19 @@ STATUS_T OsAnonMMap(LosVmMapRegion *region)
(void *)-1
*/
>>>>>>> remotes/origin/main
VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff)
{
STATUS_T status;
VADDR_T resultVaddr;
UINT32 regionFlags;
<<<<<<< HEAD
LosVmMapRegion *newRegion = NULL;
struct file *filep = NULL;
=======
LosVmMapRegion *newRegion = NULL;//应用的内存分配对应到内核就是分配一个线性区
struct file *filep = NULL;// inode : file = 1:N ,一对多关系,一个inode可以被多个进程打开,返回不同的file但都指向同一个inode
>>>>>>> remotes/origin/main
LosVmSpace *vmSpace = OsCurrProcessGet()->vmSpace;
len = ROUNDUP(len, PAGE_SIZE);
@ -150,9 +166,15 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags,
if (checkRst != LOS_OK) {
return checkRst;
}
<<<<<<< HEAD
if (LOS_IsNamedMapping(flags)) {
status = fs_getfilep(fd, &filep);
=======
if (LOS_IsNamedMapping(flags)) {//是否文件映射
status = fs_getfilep(fd, &filep);//获取文件描述符和状态
>>>>>>> remotes/origin/main
if (status < 0) {
return -EBADF;
}
@ -165,6 +187,32 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags,
(VOID)LOS_MuxAcquire(&vmSpace->regionMux);
/* user mode calls mmap to release heap physical memory without releasing heap virtual space */
<<<<<<< HEAD
status = OsUserHeapFree(vmSpace, vaddr, len);
if (status == LOS_OK) {
resultVaddr = vaddr;
goto MMAP_DONE;
}
regionFlags = OsCvtProtFlagsToRegionFlags(prot, flags);
newRegion = LOS_RegionAlloc(vmSpace, vaddr, len, regionFlags, pgoff);
if (newRegion == NULL) {
resultVaddr = (VADDR_T)-ENOMEM;
goto MMAP_DONE;
}
newRegion->regionFlags |= VM_MAP_REGION_FLAG_MMAP;
resultVaddr = newRegion->range.base;
if (LOS_IsNamedMapping(flags)) {
status = OsNamedMMap(filep, newRegion);
} else {
status = OsAnonMMap(newRegion);
}
if (status != LOS_OK) {
LOS_RbDelNode(&vmSpace->regionRbTree, &newRegion->rbNode);
LOS_RegionFree(vmSpace, newRegion);
=======
status = OsUserHeapFree(vmSpace, vaddr, len);//用户模式释放堆物理内存而不释放堆虚拟空间
if (status == LOS_OK) {//OsUserHeapFree 干两件事 1.解除映射关系 2.释放物理页
resultVaddr = vaddr;
@ -189,6 +237,7 @@ VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags,
if (status != LOS_OK) {
LOS_RbDelNode(&vmSpace->regionRbTree, &newRegion->rbNode);//从红黑树和双循环链表中删除
LOS_RegionFree(vmSpace, newRegion);//释放
>>>>>>> remotes/origin/main
resultVaddr = (VADDR_T)-ENOMEM;
goto MMAP_DONE;
}
@ -197,7 +246,11 @@ MMAP_DONE:
(VOID)LOS_MuxRelease(&vmSpace->regionMux);
return resultVaddr;
}
<<<<<<< HEAD
=======
///解除映射关系
>>>>>>> remotes/origin/main
STATUS_T LOS_UnMMap(VADDR_T addr, size_t size)
{
if ((addr <= 0) || (size == 0)) {
@ -206,6 +259,10 @@ STATUS_T LOS_UnMMap(VADDR_T addr, size_t size)
return OsUnMMap(OsCurrProcessGet()->vmSpace, addr, size);
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
STATIC INLINE BOOL OsProtMprotectPermCheck(unsigned long prot, LosVmMapRegion *region)
{
UINT32 protFlags = 0;
@ -219,11 +276,26 @@ STATIC INLINE BOOL OsProtMprotectPermCheck(unsigned long prot, LosVmMapRegion *r
return ((protFlags & permFlags) == protFlags);
}
<<<<<<< HEAD
=======
/// 收缩堆区
>>>>>>> remotes/origin/main
VOID *OsShrinkHeap(VOID *addr, LosVmSpace *space)
{
VADDR_T newBrk, oldBrk;
<<<<<<< HEAD
newBrk = LOS_Align((VADDR_T)(UINTPTR)addr, PAGE_SIZE);
oldBrk = LOS_Align(space->heapNow, PAGE_SIZE);
if (LOS_UnMMap(newBrk, (oldBrk - newBrk)) < 0) {
return (void *)(UINTPTR)space->heapNow;
}
space->heapNow = (VADDR_T)(UINTPTR)addr;
return addr;
}
=======
newBrk = LOS_Align((VADDR_T)(UINTPTR)addr, PAGE_SIZE);//新堆顶
oldBrk = LOS_Align(space->heapNow, PAGE_SIZE);//旧堆顶
if (LOS_UnMMap(newBrk, (oldBrk - newBrk)) < 0) {//解除相差区的映射
@ -241,6 +313,7 @@ VOID *OsShrinkHeap(VOID *addr, LosVmSpace *space)
线线线
线
*/
>>>>>>> remotes/origin/main
VOID *LOS_DoBrk(VOID *addr)
{
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
@ -250,6 +323,24 @@ VOID *LOS_DoBrk(VOID *addr)
VOID *alignAddr = NULL;
VOID *shrinkAddr = NULL;
<<<<<<< HEAD
if (addr == NULL) {
return (void *)(UINTPTR)space->heapNow;
}
if ((UINTPTR)addr < (UINTPTR)space->heapBase) {
return (VOID *)-ENOMEM;
}
size = (UINTPTR)addr - (UINTPTR)space->heapBase;
size = ROUNDUP(size, PAGE_SIZE);
alignAddr = (CHAR *)(UINTPTR)(space->heapBase) + size;
PRINT_INFO("brk addr %p , size 0x%x, alignAddr %p, align %d\n", addr, size, alignAddr, PAGE_SIZE);
(VOID)LOS_MuxAcquire(&space->regionMux);
if (addr < (VOID *)(UINTPTR)space->heapNow) {
shrinkAddr = OsShrinkHeap(addr, space);
=======
if (addr == NULL) {//参数地址未传情况
return (void *)(UINTPTR)space->heapNow;//以现有指向地址为基础进行扩展
}
@ -266,25 +357,46 @@ VOID *LOS_DoBrk(VOID *addr)
(VOID)LOS_MuxAcquire(&space->regionMux);
if (addr < (VOID *)(UINTPTR)space->heapNow) {//如果地址小于堆区现地址
shrinkAddr = OsShrinkHeap(addr, space);//收缩堆区
>>>>>>> remotes/origin/main
(VOID)LOS_MuxRelease(&space->regionMux);
return shrinkAddr;
}
<<<<<<< HEAD
if ((UINTPTR)alignAddr >= space->mapBase) {
VM_ERR("Process heap memory space is insufficient");
=======
if ((UINTPTR)alignAddr >= space->mapBase) {//参数地址 大于映射区地址
VM_ERR("Process heap memory space is insufficient");//进程堆空间不足
>>>>>>> remotes/origin/main
ret = (VOID *)-ENOMEM;
goto REGION_ALLOC_FAILED;
}
<<<<<<< HEAD
if (space->heapBase == space->heapNow) {
region = LOS_RegionAlloc(space, space->heapBase, size,
VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE |
=======
if (space->heapBase == space->heapNow) {//往往是第一次调用本函数才会出现,因为初始化时 heapBase = heapNow
region = LOS_RegionAlloc(space, space->heapBase, size,//分配一个可读/可写/可使用的线性区,只需分配一次
VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE |//线性区的大小由range.size决定
>>>>>>> remotes/origin/main
VM_MAP_REGION_FLAG_FIXED | VM_MAP_REGION_FLAG_PERM_USER, 0);
if (region == NULL) {
ret = (VOID *)-ENOMEM;
VM_ERR("LOS_RegionAlloc failed");
goto REGION_ALLOC_FAILED;
}
<<<<<<< HEAD
region->regionFlags |= VM_MAP_REGION_FLAG_HEAP;
space->heap = region;
}
space->heapNow = (VADDR_T)(UINTPTR)alignAddr;
space->heap->range.size = size;
ret = (VOID *)(UINTPTR)space->heapNow;
=======
region->regionFlags |= VM_MAP_REGION_FLAG_HEAP;//贴上线性区类型为堆区的标签,注意一个线性区可以有多种标签
space->heap = region;//指定线性区为堆区
}
@ -292,18 +404,28 @@ VOID *LOS_DoBrk(VOID *addr)
space->heapNow = (VADDR_T)(UINTPTR)alignAddr;//更新堆区顶部位置
space->heap->range.size = size; //更新堆区大小,经此操作线性区变大或缩小了
ret = (VOID *)(UINTPTR)space->heapNow;//返回堆顶
>>>>>>> remotes/origin/main
REGION_ALLOC_FAILED:
(VOID)LOS_MuxRelease(&space->regionMux);
return ret;
}
<<<<<<< HEAD
=======
/// 继承老线性区的标签
>>>>>>> remotes/origin/main
STATIC UINT32 OsInheritOldRegionName(UINT32 oldRegionFlags)
{
UINT32 vmFlags = 0;
<<<<<<< HEAD
if (oldRegionFlags & VM_MAP_REGION_FLAG_HEAP) {
vmFlags |= VM_MAP_REGION_FLAG_HEAP;
=======
if (oldRegionFlags & VM_MAP_REGION_FLAG_HEAP) { //如果是从大堆区中申请的
vmFlags |= VM_MAP_REGION_FLAG_HEAP; //线性区则贴上堆区标签
>>>>>>> remotes/origin/main
} else if (oldRegionFlags & VM_MAP_REGION_FLAG_STACK) {
vmFlags |= VM_MAP_REGION_FLAG_STACK;
} else if (oldRegionFlags & VM_MAP_REGION_FLAG_TEXT) {
@ -318,7 +440,11 @@ STATIC UINT32 OsInheritOldRegionName(UINT32 oldRegionFlags)
return vmFlags;
}
<<<<<<< HEAD
=======
///修改内存段的访问权限
>>>>>>> remotes/origin/main
INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot)
{
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
@ -328,7 +454,11 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot)
int ret;
(VOID)LOS_MuxAcquire(&space->regionMux);
<<<<<<< HEAD
region = LOS_RegionFind(space, vaddr);
=======
region = LOS_RegionFind(space, vaddr);//通过虚拟地址找到线性区
>>>>>>> remotes/origin/main
if (!IS_ALIGNED(vaddr, PAGE_SIZE) || (region == NULL) || (vaddr > vaddr + len)) {
ret = -EINVAL;
goto OUT_MPROTECT;
@ -338,18 +468,30 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot)
ret = -EINVAL;
goto OUT_MPROTECT;
}
<<<<<<< HEAD
=======
//如果是堆区或VDSO区,说明区内容是不能修改的
>>>>>>> remotes/origin/main
if ((region->regionFlags & VM_MAP_REGION_FLAG_VDSO) || (region->regionFlags & VM_MAP_REGION_FLAG_HEAP)) {
ret = -EPERM;
goto OUT_MPROTECT;
}
<<<<<<< HEAD
=======
//如果是共享文件,说明内容也不能修改
>>>>>>> remotes/origin/main
if (LOS_IsRegionTypeFile(region) && (region->regionFlags & VM_MAP_REGION_FLAG_SHARED)) {
if (!OsProtMprotectPermCheck(prot, region)) {
ret = -EACCES;
goto OUT_MPROTECT;
}
}
<<<<<<< HEAD
=======
>>>>>>> remotes/origin/main
len = LOS_Align(len, PAGE_SIZE);
/* can't operation cross region */
if ((region->range.base + region->range.size) < (vaddr + len)) {
@ -358,11 +500,19 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot)
}
/* if only move some part of region, we need to split first */
<<<<<<< HEAD
if (region->range.size > len) {
OsVmRegionAdjust(space, vaddr, len);
}
vmFlags = OsCvtProtFlagsToRegionFlags(prot, 0);
=======
if (region->range.size > len) {//如果只修改部分区域,我们需要先拆分区
OsVmRegionAdjust(space, vaddr, len);//调整下线性区范围
}
vmFlags = OsCvtProtFlagsToRegionFlags(prot, 0);//转换FLAGS
>>>>>>> remotes/origin/main
vmFlags |= (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0;
vmFlags |= OsInheritOldRegionName(region->regionFlags);
region = LOS_RegionFind(space, vaddr);
@ -372,7 +522,11 @@ INT32 LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot)
}
region->regionFlags = vmFlags;
count = len >> PAGE_SHIFT;
<<<<<<< HEAD
ret = LOS_ArchMmuChangeProt(&space->archMmu, vaddr, count, region->regionFlags);
=======
ret = LOS_ArchMmuChangeProt(&space->archMmu, vaddr, count, region->regionFlags);//修改访问权限实体函数
>>>>>>> remotes/origin/main
if (ret) {
ret = -ENOMEM;
goto OUT_MPROTECT;
@ -427,7 +581,11 @@ STATUS_T OsMremapCheck(VADDR_T addr, size_t oldLen, VADDR_T newAddr, size_t newL
}
}
<<<<<<< HEAD
/* avoid new region overlapping with the old one */
=======
/* avoid new region overlaping with the old one */
>>>>>>> remotes/origin/main
if (flags & MREMAP_FIXED) {
if (((region->range.base + region->range.size) > newAddr) &&
(region->range.base < (newAddr + newLen))) {
@ -441,7 +599,11 @@ STATUS_T OsMremapCheck(VADDR_T addr, size_t oldLen, VADDR_T newAddr, size_t newL
return LOS_OK;
}
<<<<<<< HEAD
=======
///重新映射虚拟内存地址。
>>>>>>> remotes/origin/main
VADDR_T LOS_DoMremap(VADDR_T oldAddress, size_t oldSize, size_t newSize, int flags, VADDR_T newAddr)
{
LosVmMapRegion *regionOld = NULL;
@ -536,7 +698,11 @@ OUT_MREMAP:
(VOID)LOS_MuxRelease(&space->regionMux);
return ret;
}
<<<<<<< HEAD
=======
///输出内存线性区
>>>>>>> remotes/origin/main
VOID LOS_DumpMemRegion(VADDR_T vaddr)
{
LosVmSpace *space = NULL;
@ -546,6 +712,17 @@ VOID LOS_DumpMemRegion(VADDR_T vaddr)
return;
}
<<<<<<< HEAD
if (LOS_IsRangeInSpace(space, ROUNDDOWN(vaddr, MB), MB) == FALSE) {
return;
}
OsDumpPte(vaddr);
OsDumpAspace(space);
}
#endif
=======
if (LOS_IsRangeInSpace(space, ROUNDDOWN(vaddr, MB), MB) == FALSE) {//是否在空间范围内
return;
}
@ -553,4 +730,5 @@ VOID LOS_DumpMemRegion(VADDR_T vaddr)
OsDumpPte(vaddr);//dump L1 L2
OsDumpAspace(space);//dump 空间
}
#endif
#endif
>>>>>>> remotes/origin/main

@ -47,8 +47,13 @@
#ifdef LOSCFG_KERNEL_VM
<<<<<<< HEAD
LITE_OS_SEC_BSS OomCB *g_oomCB = NULL;
static SPIN_LOCK_INIT(g_oomSpinLock);
=======
LITE_OS_SEC_BSS OomCB *g_oomCB = NULL; //全局内存溢出控制块
static SPIN_LOCK_INIT(g_oomSpinLock);//内存溢出自旋锁
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomScoreProcess(LosProcessCB *candidateProcess)
{
@ -57,20 +62,32 @@ LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomScoreProcess(LosProcessCB *candidateProc
#ifndef LOSCFG_KERNEL_SMP
(VOID)LOS_MuxAcquire(&candidateProcess->vmSpace->regionMux);
#endif
<<<<<<< HEAD
/* we only consider actual physical memory here. */
=======
/* we only consider actual physical memory here. */ //只考虑实际的物理内存
>>>>>>> remotes/origin/main
OsUProcessPmUsage(candidateProcess->vmSpace, NULL, &actualPm);
#ifndef LOSCFG_KERNEL_SMP
(VOID)LOS_MuxRelease(&candidateProcess->vmSpace->regionMux);
#endif
return actualPm;
}
<<<<<<< HEAD
=======
///用于设置 g_oomCB->processVictimCB 回调函数
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomKillProcess(UINTPTR param)
{
/* we will not kill process, and do nothing here */
return LOS_OK;
}
<<<<<<< HEAD
=======
///强制收缩内存
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomForceShrinkMemory(VOID)
{
UINT32 i;
@ -80,14 +97,21 @@ LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomForceShrinkMemory(VOID)
* TryShrinkMemory maybe reclaim 0 pages in the first time from active list
* to inactive list, and in the second time reclaim memory from inactive list.
*/
<<<<<<< HEAD
=======
//TryShrinkMemory可能会在第一时间从活动列表中回收0页到非活动列表并在第二次从非活动列表中回收内存。
>>>>>>> remotes/origin/main
for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) {
reclaimMemPages += OsTryShrinkMemory(0);
}
return reclaimMemPages;
}
<<<<<<< HEAD
=======
///内存不足时回收页高速缓存
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR STATIC BOOL OomReclaimPageCache(VOID)
{
UINT32 totalPm = 0;
@ -97,14 +121,38 @@ LITE_OS_SEC_TEXT_MINOR STATIC BOOL OomReclaimPageCache(VOID)
UINT32 i;
for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) {
<<<<<<< HEAD
OsVmPhysUsedInfoGet(&usedPm, &totalPm);
isReclaimMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->reclaimMemThreshold;
if (isReclaimMemory) {
=======
OsVmPhysUsedInfoGet(&usedPm, &totalPm);//获取总的和已经使用的物理内存数量
isReclaimMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->reclaimMemThreshold;//检查是否过了回收门槛
if (isReclaimMemory) {//要回收了
>>>>>>> remotes/origin/main
/*
* we do force memory reclaim from page cache here.
* if we get memory, we will reclaim pagecache memory again.
* if there is no memory to reclaim, we will return.
*/
<<<<<<< HEAD
reclaimMemPages = OomForceShrinkMemory();
if (reclaimMemPages > 0) {
continue;
}
}
break;
}
return isReclaimMemory;
}
/*
* check is low memory or not, if low memory, try to kill process.
* return is kill process or not.
*/
LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID)
=======
//在这里强制从页缓存中回收内存,
reclaimMemPages = OomForceShrinkMemory();//强制回收内存
if (reclaimMemPages > 0) {//如果得到内存将再次回收pagecache内存
@ -122,19 +170,29 @@ LITE_OS_SEC_TEXT_MINOR STATIC BOOL OomReclaimPageCache(VOID)
* return is kill process or not.
*/
LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID)//检查内存是否不足,如果内存不足,请尝试终止进程,返回是否kill进程
>>>>>>> remotes/origin/main
{
UINT32 totalPm;
UINT32 usedPm;
BOOL isLowMemory = FALSE;
/*
<<<<<<< HEAD
* spinlock the current core schedule, make sure oom process atomic
* spinlock other place entering OomCheckProcess, make sure oom process mutex
=======
* spinlock the current core schedule, make sure oom process atomic //旋转锁定当前核心计划确保oom进程原子化
* spinlock other place entering OomCheckProcess, make sure oom process mutex //旋转锁定其他进入OomCheckProcess的地方确保oom进程互斥
>>>>>>> remotes/origin/main
*/
LOS_SpinLock(&g_oomSpinLock);
/* first we will check if we need to reclaim pagecache memory */
<<<<<<< HEAD
if (OomReclaimPageCache() == FALSE) {
=======
if (OomReclaimPageCache() == FALSE) {//
>>>>>>> remotes/origin/main
LOS_SpinUnlock(&g_oomSpinLock);
goto NO_VICTIM_PROCESS;
}
@ -142,7 +200,13 @@ LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID)//检查内存是否不足,
/* get free bytes */
OsVmPhysUsedInfoGet(&usedPm, &totalPm);
isLowMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->lowMemThreshold;
<<<<<<< HEAD
LOS_SpinUnlock(&g_oomSpinLock);
=======
LOS_SpinUnlock(&g_oomSpinLock);
>>>>>>> remotes/origin/main
if (isLowMemory) {
PRINTK("[oom] OS is in low memory state\n"
"total physical memory: %#x(byte), used: %#x(byte),"
@ -155,6 +219,16 @@ NO_VICTIM_PROCESS:
return isLowMemory;
}
<<<<<<< HEAD
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK
STATIC VOID OomWriteEvent(VOID)
{
OsWriteResourceEvent(OS_RESOURCE_EVENT_OOM);
}
#endif
LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID)
=======
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK //内存溢出监测任务开关
STATIC VOID OomWriteEvent(VOID) // OomTaskInit中创建的定时器回调
{
@ -163,6 +237,7 @@ STATIC VOID OomWriteEvent(VOID) // OomTaskInit中创建的定时器回调
#endif
//打印内存不足时的信息
LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID) //打印内存溢出信息
>>>>>>> remotes/origin/main
{
PRINTK("[oom] oom loop task status: %s\n"
" oom low memory threshold: %#x(byte)\n"
@ -172,7 +247,11 @@ LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID) //打印内存溢出信息
g_oomCB->lowMemThreshold, g_oomCB->reclaimMemThreshold,
g_oomCB->checkInterval);
}
<<<<<<< HEAD
=======
///设置低内存门槛
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold)
{
if ((lowMemThreshold > OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX)) {
@ -186,7 +265,11 @@ LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold)
g_oomCB->lowMemThreshold);
}
}
<<<<<<< HEAD
=======
///设置回收内存的门槛
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshold)
{
UINT32 totalPm = 0;
@ -204,7 +287,11 @@ LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshol
g_oomCB->reclaimMemThreshold);
}
}
<<<<<<< HEAD
=======
///设置监控间隔
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval)
{
if ((checkInterval >= OOM_CHECK_MIN) && (checkInterval <= OOM_CHECK_MAX)) {
@ -216,7 +303,11 @@ LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval)
g_oomCB->checkInterval, OOM_CHECK_MIN, OOM_CHECK_MAX);
}
}
<<<<<<< HEAD
=======
///内存不足监控任务初始化, OOM 通过开一个软件定时器来检查内存的使用情况
>>>>>>> remotes/origin/main
LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID)
{
g_oomCB = (OomCB *)LOS_MemAlloc(m_aucSysMem0, sizeof(OomCB));
@ -225,6 +316,19 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID)
return LOS_NOK;
}
<<<<<<< HEAD
g_oomCB->lowMemThreshold = OOM_DEFAULT_LOW_MEM_THRESHOLD;
g_oomCB->reclaimMemThreshold = OOM_DEFAULT_RECLAIM_MEM_THRESHOLD;
g_oomCB->checkInterval = OOM_DEFAULT_CHECK_INTERVAL;
g_oomCB->processVictimCB = (OomFn)OomKillProcess;
g_oomCB->scoreCB = (OomFn)OomScoreProcess;
g_oomCB->enabled = FALSE;
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK
g_oomCB->enabled = TRUE;
UINT32 ret = LOS_SwtmrCreate(g_oomCB->checkInterval, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)OomWriteEvent,
&g_oomCB->swtmrID, (UINTPTR)g_oomCB);
=======
g_oomCB->lowMemThreshold = OOM_DEFAULT_LOW_MEM_THRESHOLD; //运行任务的门槛
g_oomCB->reclaimMemThreshold = OOM_DEFAULT_RECLAIM_MEM_THRESHOLD; //回收内存的门槛
g_oomCB->checkInterval = OOM_DEFAULT_CHECK_INTERVAL; //检测时间间隔 1S
@ -236,16 +340,28 @@ LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID)
g_oomCB->enabled = TRUE;
UINT32 ret = LOS_SwtmrCreate(g_oomCB->checkInterval, LOS_SWTMR_MODE_PERIOD, (SWTMR_PROC_FUNC)OomWriteEvent,
&g_oomCB->swtmrID, (UINTPTR)g_oomCB);//创建检测定时器
>>>>>>> remotes/origin/main
if (ret != LOS_OK) {
return ret;
}
<<<<<<< HEAD
return LOS_SwtmrStart(g_oomCB->swtmrID);
=======
return LOS_SwtmrStart(g_oomCB->swtmrID);//启动定时器
>>>>>>> remotes/origin/main
#else
return LOS_OK;
#endif
}
<<<<<<< HEAD
LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK);
#endif
=======
LOS_MODULE_INIT(OomTaskInit, LOS_INIT_LEVEL_KMOD_TASK);//初始化内存监控模块
#endif
#endif
>>>>>>> remotes/origin/main

@ -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_dsshm_nattch1
@ -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, &region->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, &region->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

Loading…
Cancel
Save