add OpenHarmony 1.0 baseline
This commit is contained in:
82
kernel/base/BUILD.gn
Executable file
82
kernel/base/BUILD.gn
Executable file
@@ -0,0 +1,82 @@
|
||||
# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
# Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# 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
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
static_library("base") {
|
||||
|
||||
sources = [
|
||||
"ipc/los_mux.c",
|
||||
"ipc/los_sem_debug.c",
|
||||
"ipc/los_queue_debug.c",
|
||||
"ipc/los_ipcdebug.c",
|
||||
"ipc/los_mux_debug.c",
|
||||
"ipc/los_sem.c",
|
||||
"ipc/los_event.c",
|
||||
"ipc/los_queue.c",
|
||||
"core/los_swtmr.c",
|
||||
"core/los_task.c",
|
||||
"core/los_timeslice.c",
|
||||
"core/los_sortlink.c",
|
||||
"core/los_bitmap.c",
|
||||
"core/los_process.c",
|
||||
"core/los_sys.c",
|
||||
"core/los_tick.c",
|
||||
"mem/bestfit/los_memory.c",
|
||||
"mem/bestfit/los_multipledlinkhead.c",
|
||||
"mem/membox/los_membox.c",
|
||||
"mem/common/los_memstat.c",
|
||||
"om/los_err.c",
|
||||
"misc/task_shellcmd.c",
|
||||
"misc/los_stackinfo.c",
|
||||
"misc/sysinfo_shellcmd.c",
|
||||
"misc/los_misc.c",
|
||||
"misc/swtmr_shellcmd.c",
|
||||
"misc/mempt_shellcmd.c",
|
||||
"misc/vm_shellcmd.c",
|
||||
"mp/los_stat.c",
|
||||
"mp/los_lockdep.c",
|
||||
"mp/los_mp.c",
|
||||
"mp/los_percpu.c",
|
||||
"sched/sched_sq/los_priqueue.c",
|
||||
"sched/sched_sq/los_sched.c",
|
||||
"vm/filemap.c",
|
||||
"vm/pmm.c",
|
||||
"vm/vm.c",
|
||||
"vm/vmm.c",
|
||||
]
|
||||
|
||||
include_dirs = [
|
||||
"include",
|
||||
"../extended/include",
|
||||
"../extended/vdso/include",
|
||||
"../extended/dynload/include",
|
||||
"../include",
|
||||
"mem",
|
||||
]
|
||||
|
||||
}
|
||||
54
kernel/base/Makefile
Executable file
54
kernel/base/Makefile
Executable file
@@ -0,0 +1,54 @@
|
||||
# Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
# Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
#
|
||||
# Redistribution and use in source and binary forms, with or without modification,
|
||||
# are permitted provided that the following conditions are met:
|
||||
#
|
||||
# 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
# conditions and the following disclaimer.
|
||||
#
|
||||
# 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
# of conditions and the following disclaimer in the documentation and/or other materials
|
||||
# provided with the distribution.
|
||||
#
|
||||
# 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
# to endorse or promote products derived from this software without specific prior written
|
||||
# permission.
|
||||
#
|
||||
# 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
|
||||
# PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
# CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
# EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
# PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
# OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
# WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
# OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
# ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
|
||||
include $(LITEOSTOPDIR)/config.mk
|
||||
|
||||
MODULE_NAME := $(notdir $(shell pwd))
|
||||
|
||||
LOCAL_SRCS := $(wildcard ipc/*.c) $(wildcard core/*.c) $(wildcard mem/membox/*.c) $(wildcard mem/common/*.c) \
|
||||
$(wildcard om/*.c)\
|
||||
$(wildcard misc/*.c)\
|
||||
$(wildcard mem/bestfit/*.c) \
|
||||
$(wildcard mp/*.c) \
|
||||
$(wildcard sched/sched_sq/*.c) \
|
||||
$(wildcard vm/*.c)
|
||||
|
||||
ifeq ($(LOSCFG_MEM_RECORDINFO), y)
|
||||
LOCAL_SRCS += $(wildcard mem/common/memrecord/*.c)
|
||||
endif
|
||||
|
||||
LOCAL_INCLUDE := \
|
||||
-I $(LITEOSTOPDIR)/kernel/base/include \
|
||||
-I $(LITEOSTOPDIR)/kernel/extended/include \
|
||||
-I $(LITEOSTOPDIR)/kernel/base/mem \
|
||||
-I $(LITEOSTOPDIR)/kernel/base/vm
|
||||
|
||||
LOCAL_FLAGS := $(LITEOS_CFLAGS_INTERWORK) $(LOCAL_INCLUDE) $(LITEOS_GCOV_OPTS)
|
||||
|
||||
include $(MODULE)
|
||||
148
kernel/base/core/los_bitmap.c
Executable file
148
kernel/base/core/los_bitmap.c
Executable file
@@ -0,0 +1,148 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_bitmap.h"
|
||||
#include "los_printf.h"
|
||||
#include "los_toolchain.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#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;
|
||||
}
|
||||
|
||||
VOID LOS_BitmapSet(UINT32 *bitmap, UINT16 pos)
|
||||
{
|
||||
if (bitmap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
*bitmap |= 1U << (pos & OS_BITMAP_MASK);
|
||||
}
|
||||
|
||||
VOID LOS_BitmapClr(UINT32 *bitmap, UINT16 pos)
|
||||
{
|
||||
if (bitmap == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
*bitmap &= ~(1U << (pos & OS_BITMAP_MASK));
|
||||
}
|
||||
|
||||
UINT16 LOS_HighBitGet(UINT32 bitmap)
|
||||
{
|
||||
if (bitmap == 0) {
|
||||
return LOS_INVALID_BIT_INDEX;
|
||||
}
|
||||
|
||||
return (OS_BITMAP_MASK - CLZ(bitmap));
|
||||
}
|
||||
|
||||
UINT16 LOS_LowBitGet(UINT32 bitmap)
|
||||
{
|
||||
if (bitmap == 0) {
|
||||
return LOS_INVALID_BIT_INDEX;
|
||||
}
|
||||
|
||||
return CTZ(bitmap);
|
||||
}
|
||||
|
||||
VOID LOS_BitmapSetNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsSet)
|
||||
{
|
||||
UINTPTR *p = bitmap + BITMAP_WORD(start);
|
||||
const UINT32 size = start + numsSet;
|
||||
UINT16 bitsToSet = BITMAP_BITS_PER_WORD - (start % BITMAP_BITS_PER_WORD);
|
||||
UINTPTR maskToSet = BITMAP_FIRST_WORD_MASK(start);
|
||||
|
||||
while (numsSet > bitsToSet) {
|
||||
*p |= bitsToSet;
|
||||
numsSet -= bitsToSet;
|
||||
bitsToSet = BITMAP_BITS_PER_WORD;
|
||||
maskToSet = OS_BITMAP_WORD_MASK;
|
||||
p++;
|
||||
}
|
||||
if (numsSet) {
|
||||
maskToSet &= BITMAP_LAST_WORD_MASK(size);
|
||||
*p |= maskToSet;
|
||||
}
|
||||
}
|
||||
|
||||
VOID LOS_BitmapClrNBits(UINTPTR *bitmap, UINT32 start, UINT32 numsClear)
|
||||
{
|
||||
UINTPTR *p = bitmap + BITMAP_WORD(start);
|
||||
const UINT32 size = start + numsClear;
|
||||
UINT16 bitsToClear = BITMAP_BITS_PER_WORD - (start % BITMAP_BITS_PER_WORD);
|
||||
UINTPTR maskToClear = BITMAP_FIRST_WORD_MASK(start);
|
||||
|
||||
while (numsClear >= bitsToClear) {
|
||||
*p &= ~maskToClear;
|
||||
numsClear -= bitsToClear;
|
||||
bitsToClear = BITMAP_BITS_PER_WORD;
|
||||
maskToClear = OS_BITMAP_WORD_MASK;
|
||||
p++;
|
||||
}
|
||||
if (numsClear) {
|
||||
maskToClear &= BITMAP_LAST_WORD_MASK(size);
|
||||
*p &= ~maskToClear;
|
||||
}
|
||||
}
|
||||
|
||||
INT32 LOS_BitmapFfz(UINTPTR *bitmap, UINT32 numBits)
|
||||
{
|
||||
INT32 bit, i;
|
||||
|
||||
for (i = 0; i < BITMAP_NUM_WORDS(numBits); i++) {
|
||||
if (bitmap[i] == OS_BITMAP_WORD_MASK) {
|
||||
continue;
|
||||
}
|
||||
bit = i * BITMAP_BITS_PER_WORD + Ffz(bitmap[i]);
|
||||
if (bit < numBits) {
|
||||
return bit;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
2004
kernel/base/core/los_process.c
Executable file
2004
kernel/base/core/los_process.c
Executable file
File diff suppressed because it is too large
Load Diff
244
kernel/base/core/los_sortlink.c
Executable file
244
kernel/base/core/los_sortlink.c
Executable file
@@ -0,0 +1,244 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_sortlink_pri.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_exc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader)
|
||||
{
|
||||
UINT32 size;
|
||||
LOS_DL_LIST *listObject = NULL;
|
||||
UINT32 index;
|
||||
|
||||
size = sizeof(LOS_DL_LIST) << OS_TSK_SORTLINK_LOGLEN;
|
||||
listObject = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */
|
||||
if (listObject == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
(VOID)memset_s(listObject, size, 0, size);
|
||||
sortLinkHeader->sortLink = listObject;
|
||||
sortLinkHeader->cursor = 0;
|
||||
for (index = 0; index < OS_TSK_SORTLINK_LEN; index++, listObject++) {
|
||||
LOS_ListInit(listObject);
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
|
||||
{
|
||||
SortLinkList *listSorted = NULL;
|
||||
LOS_DL_LIST *listObject = NULL;
|
||||
UINT32 sortIndex;
|
||||
UINT32 rollNum;
|
||||
UINT32 timeout;
|
||||
|
||||
/*
|
||||
* huge rollnum could cause carry to invalid high bit
|
||||
* and eventually affect the calculation of sort index.
|
||||
*/
|
||||
if (sortList->idxRollNum > OS_TSK_MAX_ROLLNUM) {
|
||||
SET_SORTLIST_VALUE(sortList, OS_TSK_MAX_ROLLNUM);
|
||||
}
|
||||
timeout = sortList->idxRollNum;
|
||||
sortIndex = timeout & OS_TSK_SORTLINK_MASK;
|
||||
rollNum = (timeout >> OS_TSK_SORTLINK_LOGLEN) + 1;
|
||||
if (sortIndex == 0) {
|
||||
rollNum--;
|
||||
}
|
||||
EVALUATE_L(sortList->idxRollNum, rollNum);
|
||||
sortIndex = sortIndex + sortLinkHeader->cursor;
|
||||
sortIndex = sortIndex & OS_TSK_SORTLINK_MASK;
|
||||
EVALUATE_H(sortList->idxRollNum, sortIndex);
|
||||
|
||||
listObject = sortLinkHeader->sortLink + sortIndex;
|
||||
if (listObject->pstNext == listObject) {
|
||||
LOS_ListTailInsert(listObject, &sortList->sortLinkNode);
|
||||
} else {
|
||||
listSorted = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
|
||||
do {
|
||||
if (ROLLNUM(listSorted->idxRollNum) <= ROLLNUM(sortList->idxRollNum)) {
|
||||
ROLLNUM_SUB(sortList->idxRollNum, listSorted->idxRollNum);
|
||||
} else {
|
||||
ROLLNUM_SUB(listSorted->idxRollNum, sortList->idxRollNum);
|
||||
break;
|
||||
}
|
||||
|
||||
listSorted = LOS_DL_LIST_ENTRY(listSorted->sortLinkNode.pstNext, SortLinkList, sortLinkNode);
|
||||
} while (&listSorted->sortLinkNode != listObject);
|
||||
|
||||
LOS_ListTailInsert(&listSorted->sortLinkNode, &sortList->sortLinkNode);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC VOID OsCheckSortLink(const LOS_DL_LIST *listHead, const LOS_DL_LIST *listNode)
|
||||
{
|
||||
LOS_DL_LIST *tmp = listNode->pstPrev;
|
||||
|
||||
/* recursive check until double link round to itself */
|
||||
while (tmp != listNode) {
|
||||
if (tmp == listHead) {
|
||||
goto FOUND;
|
||||
}
|
||||
tmp = tmp->pstPrev;
|
||||
}
|
||||
|
||||
/* delete invalid sortlink node */
|
||||
PRINT_ERR("the node is not on this sortlink!\n");
|
||||
OsBackTrace();
|
||||
|
||||
FOUND:
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList)
|
||||
{
|
||||
LOS_DL_LIST *listObject = NULL;
|
||||
SortLinkList *nextSortList = NULL;
|
||||
UINT32 sortIndex;
|
||||
|
||||
sortIndex = SORT_INDEX(sortList->idxRollNum);
|
||||
listObject = sortLinkHeader->sortLink + sortIndex;
|
||||
|
||||
/* check if pstSortList node is on the right sortlink */
|
||||
OsCheckSortLink(listObject, &sortList->sortLinkNode);
|
||||
|
||||
if (listObject != sortList->sortLinkNode.pstNext) {
|
||||
nextSortList = LOS_DL_LIST_ENTRY(sortList->sortLinkNode.pstNext, SortLinkList, sortLinkNode);
|
||||
ROLLNUM_ADD(nextSortList->idxRollNum, sortList->idxRollNum);
|
||||
}
|
||||
LOS_ListDelete(&sortList->sortLinkNode);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC UINT32 OsCalcExpierTime(UINT32 rollNum, UINT32 sortIndex, UINT16 curSortIndex)
|
||||
{
|
||||
UINT32 expireTime;
|
||||
|
||||
if (sortIndex > curSortIndex) {
|
||||
sortIndex = sortIndex - curSortIndex;
|
||||
} else {
|
||||
sortIndex = OS_TSK_SORTLINK_LEN - curSortIndex + sortIndex;
|
||||
}
|
||||
expireTime = ((rollNum - 1) << OS_TSK_SORTLINK_LOGLEN) + sortIndex;
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader)
|
||||
{
|
||||
UINT16 cursor;
|
||||
UINT32 minSortIndex = OS_INVALID_VALUE;
|
||||
UINT32 minRollNum = OS_TSK_LOW_BITS_MASK;
|
||||
UINT32 expireTime = OS_INVALID_VALUE;
|
||||
LOS_DL_LIST *listObject = NULL;
|
||||
SortLinkList *listSorted = NULL;
|
||||
UINT32 i;
|
||||
|
||||
cursor = (sortLinkHeader->cursor + 1) & OS_TSK_SORTLINK_MASK;
|
||||
|
||||
for (i = 0; i < OS_TSK_SORTLINK_LEN; i++) {
|
||||
listObject = sortLinkHeader->sortLink + ((cursor + i) & OS_TSK_SORTLINK_MASK);
|
||||
if (!LOS_ListEmpty(listObject)) {
|
||||
listSorted = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
|
||||
if (minRollNum > ROLLNUM(listSorted->idxRollNum)) {
|
||||
minRollNum = ROLLNUM(listSorted->idxRollNum);
|
||||
minSortIndex = (cursor + i) & OS_TSK_SORTLINK_MASK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (minRollNum != OS_TSK_LOW_BITS_MASK) {
|
||||
expireTime = OsCalcExpierTime(minRollNum, minSortIndex, sortLinkHeader->cursor);
|
||||
}
|
||||
|
||||
return expireTime;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader)
|
||||
{
|
||||
SortLinkList *sortList = NULL;
|
||||
LOS_DL_LIST *listObject = NULL;
|
||||
UINT32 i;
|
||||
UINT32 sortIndex;
|
||||
UINT32 rollNum;
|
||||
|
||||
if (sleepTicks == 0) {
|
||||
return;
|
||||
}
|
||||
sortIndex = sleepTicks & OS_TSK_SORTLINK_MASK;
|
||||
rollNum = (sleepTicks >> OS_TSK_SORTLINK_LOGLEN) + 1;
|
||||
if (sortIndex == 0) {
|
||||
rollNum--;
|
||||
sortIndex = OS_TSK_SORTLINK_LEN;
|
||||
}
|
||||
|
||||
for (i = 0; i < OS_TSK_SORTLINK_LEN; i++) {
|
||||
listObject = sortLinkHeader->sortLink + ((sortLinkHeader->cursor + i) & OS_TSK_SORTLINK_MASK);
|
||||
if (listObject->pstNext != listObject) {
|
||||
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
|
||||
ROLLNUM_SUB(sortList->idxRollNum, rollNum - 1);
|
||||
if ((i > 0) && (i < sortIndex)) {
|
||||
ROLLNUM_DEC(sortList->idxRollNum);
|
||||
}
|
||||
}
|
||||
}
|
||||
sortLinkHeader->cursor = (sortLinkHeader->cursor + sleepTicks - 1) % OS_TSK_SORTLINK_LEN;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader,
|
||||
const SortLinkList *targetSortList)
|
||||
{
|
||||
SortLinkList *listSorted = NULL;
|
||||
LOS_DL_LIST *listObject = NULL;
|
||||
UINT32 sortIndex = SORT_INDEX(targetSortList->idxRollNum);
|
||||
UINT32 rollNum = ROLLNUM(targetSortList->idxRollNum);
|
||||
|
||||
listObject = sortLinkHeader->sortLink + sortIndex;
|
||||
|
||||
listSorted = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
|
||||
while (listSorted != targetSortList) {
|
||||
rollNum += ROLLNUM(listSorted->idxRollNum);
|
||||
listSorted = LOS_DL_LIST_ENTRY((listSorted->sortLinkNode).pstNext, SortLinkList, sortLinkNode);
|
||||
}
|
||||
return OsCalcExpierTime(rollNum, sortIndex, sortLinkHeader->cursor);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
543
kernel/base/core/los_swtmr.c
Executable file
543
kernel/base/core/los_swtmr.c
Executable file
@@ -0,0 +1,543 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_swtmr_pri.h"
|
||||
#include "los_sortlink_pri.h"
|
||||
#include "los_queue_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_BASE_CORE_SWTMR == YES)
|
||||
#if (LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0)
|
||||
#error "swtmr maxnum cannot be zero"
|
||||
#endif /* LOSCFG_BASE_CORE_SWTMR_LIMIT <= 0 */
|
||||
|
||||
LITE_OS_SEC_BSS SWTMR_CTRL_S *g_swtmrCBArray = NULL; /* First address in Timer memory space */
|
||||
LITE_OS_SEC_BSS UINT8 *g_swtmrHandlerPool = NULL; /* Pool of Swtmr Handler */
|
||||
LITE_OS_SEC_BSS LOS_DL_LIST g_swtmrFreeList; /* Free list of Software Timer */
|
||||
|
||||
/* spinlock for swtmr module, only available on SMP mode */
|
||||
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))
|
||||
|
||||
LITE_OS_SEC_TEXT VOID OsSwtmrTask(VOID)
|
||||
{
|
||||
SwtmrHandlerItemPtr swtmrHandlePtr = NULL;
|
||||
SwtmrHandlerItem swtmrHandle;
|
||||
UINT32 ret, swtmrHandlerQueue;
|
||||
|
||||
swtmrHandlerQueue = OsPercpuGet()->swtmrHandlerQueue;
|
||||
for (;;) {
|
||||
ret = LOS_QueueRead(swtmrHandlerQueue, &swtmrHandlePtr, sizeof(CHAR *), LOS_WAIT_FOREVER);
|
||||
if ((ret == LOS_OK) && (swtmrHandlePtr != NULL)) {
|
||||
swtmrHandle.handler = swtmrHandlePtr->handler;
|
||||
swtmrHandle.arg = swtmrHandlePtr->arg;
|
||||
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandlePtr);
|
||||
if (swtmrHandle.handler != NULL) {
|
||||
swtmrHandle.handler(swtmrHandle.arg);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrTaskCreate(VOID)
|
||||
{
|
||||
UINT32 ret, swtmrTaskID;
|
||||
TSK_INIT_PARAM_S swtmrTask;
|
||||
UINT32 cpuid = ArchCurrCpuid();
|
||||
|
||||
(VOID)memset_s(&swtmrTask, sizeof(TSK_INIT_PARAM_S), 0, sizeof(TSK_INIT_PARAM_S));
|
||||
swtmrTask.pfnTaskEntry = (TSK_ENTRY_FUNC)OsSwtmrTask;
|
||||
swtmrTask.uwStackSize = LOSCFG_BASE_CORE_TSK_DEFAULT_STACK_SIZE;
|
||||
swtmrTask.pcName = "Swt_Task";
|
||||
swtmrTask.usTaskPrio = 0;
|
||||
swtmrTask.uwResved = LOS_TASK_STATUS_DETACHED;
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
swtmrTask.usCpuAffiMask = CPUID_TO_AFFI_MASK(cpuid);
|
||||
#endif
|
||||
ret = LOS_TaskCreate(&swtmrTaskID, &swtmrTask);
|
||||
if (ret == LOS_OK) {
|
||||
g_percpu[cpuid].swtmrTaskID = swtmrTaskID;
|
||||
OS_TCB_FROM_TID(swtmrTaskID)->taskStatus |= OS_TASK_FLAG_SYSTEM_TASK;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID OsSwtmrRecycle(UINT32 processID)
|
||||
{
|
||||
for (UINT16 index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++) {
|
||||
if (g_swtmrCBArray[index].uwOwnerPid == processID) {
|
||||
LOS_SwtmrDelete(index);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 OsSwtmrInit(VOID)
|
||||
{
|
||||
UINT32 size;
|
||||
UINT16 index;
|
||||
UINT32 ret;
|
||||
SWTMR_CTRL_S *swtmr = NULL;
|
||||
UINT32 swtmrHandlePoolSize;
|
||||
UINT32 cpuid = ArchCurrCpuid();
|
||||
if (cpuid == 0) {
|
||||
size = sizeof(SWTMR_CTRL_S) * LOSCFG_BASE_CORE_SWTMR_LIMIT;
|
||||
swtmr = (SWTMR_CTRL_S *)LOS_MemAlloc(m_aucSysMem0, size); /* system resident resource */
|
||||
if (swtmr == NULL) {
|
||||
return LOS_ERRNO_SWTMR_NO_MEMORY;
|
||||
}
|
||||
|
||||
(VOID)memset_s(swtmr, size, 0, size);
|
||||
g_swtmrCBArray = swtmr;
|
||||
LOS_ListInit(&g_swtmrFreeList);
|
||||
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
|
||||
swtmr->usTimerID = index;
|
||||
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
|
||||
}
|
||||
|
||||
swtmrHandlePoolSize = LOS_MEMBOX_SIZE(sizeof(SwtmrHandlerItem), OS_SWTMR_HANDLE_QUEUE_SIZE);
|
||||
|
||||
g_swtmrHandlerPool = (UINT8 *)LOS_MemAlloc(m_aucSysMem1, swtmrHandlePoolSize); /* system resident resource */
|
||||
if (g_swtmrHandlerPool == NULL) {
|
||||
return LOS_ERRNO_SWTMR_NO_MEMORY;
|
||||
}
|
||||
|
||||
ret = LOS_MemboxInit(g_swtmrHandlerPool, swtmrHandlePoolSize, sizeof(SwtmrHandlerItem));
|
||||
if (ret != LOS_OK) {
|
||||
return LOS_ERRNO_SWTMR_HANDLER_POOL_NO_MEM;
|
||||
}
|
||||
}
|
||||
|
||||
ret = LOS_QueueCreate(NULL, OS_SWTMR_HANDLE_QUEUE_SIZE, &g_percpu[cpuid].swtmrHandlerQueue, 0, sizeof(CHAR *));
|
||||
if (ret != LOS_OK) {
|
||||
return LOS_ERRNO_SWTMR_QUEUE_CREATE_FAILED;
|
||||
}
|
||||
|
||||
ret = OsSwtmrTaskCreate();
|
||||
if (ret != LOS_OK) {
|
||||
return LOS_ERRNO_SWTMR_TASK_CREATE_FAILED;
|
||||
}
|
||||
|
||||
ret = OsSortLinkInit(&g_percpu[cpuid].swtmrSortLink);
|
||||
if (ret != LOS_OK) {
|
||||
return LOS_ERRNO_SWTMR_SORTLINK_CREATE_FAILED;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: Start Software Timer
|
||||
* Input : swtmr --- Need to start software timer
|
||||
*/
|
||||
LITE_OS_SEC_TEXT VOID OsSwtmrStart(SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
if ((swtmr->ucOverrun == 0) && ((swtmr->ucMode == LOS_SWTMR_MODE_ONCE) ||
|
||||
(swtmr->ucMode == LOS_SWTMR_MODE_OPP) ||
|
||||
(swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE))) {
|
||||
SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwExpiry);
|
||||
} else {
|
||||
SET_SORTLIST_VALUE(&(swtmr->stSortList), swtmr->uwInterval);
|
||||
}
|
||||
|
||||
OsAdd2SortLink(&OsPercpuGet()->swtmrSortLink, &swtmr->stSortList);
|
||||
|
||||
swtmr->ucState = OS_SWTMR_STATUS_TICKING;
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
swtmr->uwCpuid = ArchCurrCpuid();
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: Delete Software Timer
|
||||
* Input : swtmr --- Need to delete software timer, When using, Ensure that it can't be NULL.
|
||||
*/
|
||||
STATIC INLINE VOID OsSwtmrDelete(SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
/* insert to free list */
|
||||
LOS_ListTailInsert(&g_swtmrFreeList, &swtmr->stSortList.sortLinkNode);
|
||||
swtmr->ucState = OS_SWTMR_STATUS_UNUSED;
|
||||
swtmr->uwOwnerPid = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: Tick interrupt interface module of software timer
|
||||
* Return : LOS_OK on success or error code on failure
|
||||
*/
|
||||
LITE_OS_SEC_TEXT VOID OsSwtmrScan(VOID)
|
||||
{
|
||||
SortLinkList *sortList = NULL;
|
||||
SWTMR_CTRL_S *swtmr = NULL;
|
||||
SwtmrHandlerItemPtr swtmrHandler = NULL;
|
||||
LOS_DL_LIST *listObject = NULL;
|
||||
SortLinkAttribute* swtmrSortLink = &OsPercpuGet()->swtmrSortLink;
|
||||
|
||||
swtmrSortLink->cursor = (swtmrSortLink->cursor + 1) & OS_TSK_SORTLINK_MASK;
|
||||
listObject = swtmrSortLink->sortLink + swtmrSortLink->cursor;
|
||||
|
||||
/*
|
||||
* it needs to be carefully coped with, since the swtmr is in specific sortlink
|
||||
* while other cores still has the chance to process it, like stop the timer.
|
||||
*/
|
||||
LOS_SpinLock(&g_swtmrSpin);
|
||||
|
||||
if (LOS_ListEmpty(listObject)) {
|
||||
LOS_SpinUnlock(&g_swtmrSpin);
|
||||
return;
|
||||
}
|
||||
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
|
||||
ROLLNUM_DEC(sortList->idxRollNum);
|
||||
|
||||
while (ROLLNUM(sortList->idxRollNum) == 0) {
|
||||
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
|
||||
LOS_ListDelete(&sortList->sortLinkNode);
|
||||
swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
|
||||
|
||||
swtmrHandler = (SwtmrHandlerItemPtr)LOS_MemboxAlloc(g_swtmrHandlerPool);
|
||||
if (swtmrHandler != NULL) {
|
||||
swtmrHandler->handler = swtmr->pfnHandler;
|
||||
swtmrHandler->arg = swtmr->uwArg;
|
||||
|
||||
if (LOS_QueueWrite(OsPercpuGet()->swtmrHandlerQueue, swtmrHandler, sizeof(CHAR *), LOS_NO_WAIT)) {
|
||||
(VOID)LOS_MemboxFree(g_swtmrHandlerPool, swtmrHandler);
|
||||
}
|
||||
}
|
||||
|
||||
if (swtmr->ucMode == LOS_SWTMR_MODE_ONCE) {
|
||||
OsSwtmrDelete(swtmr);
|
||||
|
||||
if (swtmr->usTimerID < (OS_SWTMR_MAX_TIMERID - LOSCFG_BASE_CORE_SWTMR_LIMIT)) {
|
||||
swtmr->usTimerID += LOSCFG_BASE_CORE_SWTMR_LIMIT;
|
||||
} else {
|
||||
swtmr->usTimerID %= LOSCFG_BASE_CORE_SWTMR_LIMIT;
|
||||
}
|
||||
} else if (swtmr->ucMode == LOS_SWTMR_MODE_NO_SELFDELETE) {
|
||||
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
|
||||
} else {
|
||||
swtmr->ucOverrun++;
|
||||
OsSwtmrStart(swtmr);
|
||||
}
|
||||
|
||||
if (LOS_ListEmpty(listObject)) {
|
||||
break;
|
||||
}
|
||||
|
||||
sortList = LOS_DL_LIST_ENTRY(listObject->pstNext, SortLinkList, sortLinkNode);
|
||||
}
|
||||
|
||||
LOS_SpinUnlock(&g_swtmrSpin);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: Get next timeout
|
||||
* Return : Count of the Timer list
|
||||
*/
|
||||
LITE_OS_SEC_TEXT UINT32 OsSwtmrGetNextTimeout(VOID)
|
||||
{
|
||||
return OsSortLinkGetNextExpireTime(&OsPercpuGet()->swtmrSortLink);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: Stop of Software Timer interface
|
||||
* Input : swtmr --- the software timer contrl handler
|
||||
*/
|
||||
LITE_OS_SEC_TEXT STATIC VOID OsSwtmrStop(SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
SortLinkAttribute *sortLinkHeader = NULL;
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
/*
|
||||
* the timer is running on the specific processor,
|
||||
* we need delete the timer from that processor's sortlink.
|
||||
*/
|
||||
sortLinkHeader = &g_percpu[swtmr->uwCpuid].swtmrSortLink;
|
||||
#else
|
||||
sortLinkHeader = &g_percpu[0].swtmrSortLink;
|
||||
#endif
|
||||
OsDeleteSortLink(sortLinkHeader, &swtmr->stSortList);
|
||||
|
||||
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
|
||||
swtmr->ucOverrun = 0;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description: Get next software timer expiretime
|
||||
* Input : swtmr --- the software timer contrl handler
|
||||
*/
|
||||
LITE_OS_SEC_TEXT STATIC UINT32 OsSwtmrTimeGet(const SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
SortLinkAttribute *sortLinkHeader = NULL;
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
/*
|
||||
* the timer is running on the specific processor,
|
||||
* we need search the timer from that processor's sortlink.
|
||||
*/
|
||||
sortLinkHeader = &g_percpu[swtmr->uwCpuid].swtmrSortLink;
|
||||
#else
|
||||
sortLinkHeader = &g_percpu[0].swtmrSortLink;
|
||||
#endif
|
||||
|
||||
return OsSortLinkGetTargetExpireTime(sortLinkHeader, &swtmr->stSortList);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SwtmrCreate(UINT32 interval,
|
||||
UINT8 mode,
|
||||
SWTMR_PROC_FUNC handler,
|
||||
UINT16 *swtmrID,
|
||||
UINTPTR arg)
|
||||
{
|
||||
SWTMR_CTRL_S *swtmr = NULL;
|
||||
UINT32 intSave;
|
||||
SortLinkList *sortList = NULL;
|
||||
|
||||
if (interval == 0) {
|
||||
return LOS_ERRNO_SWTMR_INTERVAL_NOT_SUITED;
|
||||
}
|
||||
|
||||
if ((mode != LOS_SWTMR_MODE_ONCE) && (mode != LOS_SWTMR_MODE_PERIOD) &&
|
||||
(mode != LOS_SWTMR_MODE_NO_SELFDELETE)) {
|
||||
return LOS_ERRNO_SWTMR_MODE_INVALID;
|
||||
}
|
||||
|
||||
if (handler == NULL) {
|
||||
return LOS_ERRNO_SWTMR_PTR_NULL;
|
||||
}
|
||||
|
||||
if (swtmrID == NULL) {
|
||||
return LOS_ERRNO_SWTMR_RET_PTR_NULL;
|
||||
}
|
||||
|
||||
SWTMR_LOCK(intSave);
|
||||
if (LOS_ListEmpty(&g_swtmrFreeList)) {
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return LOS_ERRNO_SWTMR_MAXSIZE;
|
||||
}
|
||||
|
||||
sortList = LOS_DL_LIST_ENTRY(g_swtmrFreeList.pstNext, SortLinkList, sortLinkNode);
|
||||
swtmr = LOS_DL_LIST_ENTRY(sortList, SWTMR_CTRL_S, stSortList);
|
||||
LOS_ListDelete(LOS_DL_LIST_FIRST(&g_swtmrFreeList));
|
||||
SWTMR_UNLOCK(intSave);
|
||||
|
||||
swtmr->uwOwnerPid = OsCurrProcessGet()->processID;
|
||||
swtmr->pfnHandler = handler;
|
||||
swtmr->ucMode = mode;
|
||||
swtmr->ucOverrun = 0;
|
||||
swtmr->uwInterval = interval;
|
||||
swtmr->uwExpiry = interval;
|
||||
swtmr->uwArg = arg;
|
||||
swtmr->ucState = OS_SWTMR_STATUS_CREATED;
|
||||
SET_SORTLIST_VALUE(&(swtmr->stSortList), 0);
|
||||
*swtmrID = swtmr->usTimerID;
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStart(UINT16 swtmrID)
|
||||
{
|
||||
SWTMR_CTRL_S *swtmr = NULL;
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_OK;
|
||||
UINT16 swtmrCBID;
|
||||
|
||||
if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
|
||||
SWTMR_LOCK(intSave);
|
||||
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
|
||||
swtmr = g_swtmrCBArray + swtmrCBID;
|
||||
|
||||
if (swtmr->usTimerID != swtmrID) {
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
|
||||
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:
|
||||
OsSwtmrStop(swtmr);
|
||||
/* fall-through */
|
||||
case OS_SWTMR_STATUS_CREATED:
|
||||
OsSwtmrStart(swtmr);
|
||||
break;
|
||||
default:
|
||||
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrStop(UINT16 swtmrID)
|
||||
{
|
||||
SWTMR_CTRL_S *swtmr = NULL;
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_OK;
|
||||
UINT16 swtmrCBID;
|
||||
|
||||
if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
|
||||
SWTMR_LOCK(intSave);
|
||||
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
|
||||
swtmr = g_swtmrCBArray + swtmrCBID;
|
||||
|
||||
if (swtmr->usTimerID != swtmrID) {
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
|
||||
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:
|
||||
OsSwtmrStop(swtmr);
|
||||
break;
|
||||
default:
|
||||
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrTimeGet(UINT16 swtmrID, UINT32 *tick)
|
||||
{
|
||||
SWTMR_CTRL_S *swtmr = NULL;
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_OK;
|
||||
UINT16 swtmrCBID;
|
||||
|
||||
if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
|
||||
if (tick == NULL) {
|
||||
return LOS_ERRNO_SWTMR_TICK_PTR_NULL;
|
||||
}
|
||||
|
||||
SWTMR_LOCK(intSave);
|
||||
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
|
||||
swtmr = g_swtmrCBArray + swtmrCBID;
|
||||
|
||||
if (swtmr->usTimerID != swtmrID) {
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
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:
|
||||
*tick = OsSwtmrTimeGet(swtmr);
|
||||
break;
|
||||
default:
|
||||
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
|
||||
break;
|
||||
}
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_SwtmrDelete(UINT16 swtmrID)
|
||||
{
|
||||
SWTMR_CTRL_S *swtmr = NULL;
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_OK;
|
||||
UINT16 swtmrCBID;
|
||||
|
||||
if (swtmrID >= OS_SWTMR_MAX_TIMERID) {
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
|
||||
SWTMR_LOCK(intSave);
|
||||
swtmrCBID = swtmrID % LOSCFG_BASE_CORE_SWTMR_LIMIT;
|
||||
swtmr = g_swtmrCBArray + swtmrCBID;
|
||||
|
||||
if (swtmr->usTimerID != swtmrID) {
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return LOS_ERRNO_SWTMR_ID_INVALID;
|
||||
}
|
||||
|
||||
switch (swtmr->ucState) {
|
||||
case OS_SWTMR_STATUS_UNUSED:
|
||||
ret = LOS_ERRNO_SWTMR_NOT_CREATED;
|
||||
break;
|
||||
case OS_SWTMR_STATUS_TICKING:
|
||||
OsSwtmrStop(swtmr);
|
||||
/* fall-through */
|
||||
case OS_SWTMR_STATUS_CREATED:
|
||||
OsSwtmrDelete(swtmr);
|
||||
break;
|
||||
default:
|
||||
ret = LOS_ERRNO_SWTMR_STATUS_INVALID;
|
||||
break;
|
||||
}
|
||||
|
||||
SWTMR_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* (LOSCFG_BASE_CORE_SWTMR == YES) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
82
kernel/base/core/los_sys.c
Executable file
82
kernel/base/core/los_sys.c
Executable file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_sys_pri.h"
|
||||
#include "los_tick_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_MAX_VALUE 0xFFFFFFFF
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT64 LOS_TickCountGet(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT64 tick;
|
||||
|
||||
/*
|
||||
* use core0's tick as system's timeline,
|
||||
* the tick needs to be atomic.
|
||||
*/
|
||||
TICK_LOCK(intSave);
|
||||
tick = g_tickCount[0];
|
||||
TICK_UNLOCK(intSave);
|
||||
|
||||
return tick;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_CyclePerTickGet(VOID)
|
||||
{
|
||||
return g_sysClock / LOSCFG_BASE_CORE_TICK_PER_SECOND;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MS2Tick(UINT32 millisec)
|
||||
{
|
||||
if (millisec == OS_MAX_VALUE) {
|
||||
return OS_MAX_VALUE;
|
||||
}
|
||||
|
||||
return ((UINT64)millisec * LOSCFG_BASE_CORE_TICK_PER_SECOND) / OS_SYS_MS_PER_SECOND;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_Tick2MS(UINT32 tick)
|
||||
{
|
||||
return ((UINT64)tick * OS_SYS_MS_PER_SECOND) / LOSCFG_BASE_CORE_TICK_PER_SECOND;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
2015
kernel/base/core/los_task.c
Executable file
2015
kernel/base/core/los_task.c
Executable file
File diff suppressed because it is too large
Load Diff
93
kernel/base/core/los_tick.c
Executable file
93
kernel/base/core/los_tick.c
Executable file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_tick_pri.h"
|
||||
#include "los_swtmr_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_timeslice_pri.h"
|
||||
#ifdef LOSCFG_KERNEL_TICKLESS
|
||||
#include "los_tickless_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_VDSO
|
||||
#include "los_vdso.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_BSS volatile UINT64 g_tickCount[LOSCFG_KERNEL_CORE_NUM] = {0};
|
||||
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);
|
||||
|
||||
/*
|
||||
* Description : Tick interruption handler
|
||||
*/
|
||||
LITE_OS_SEC_TEXT VOID OsTickHandler(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
TICK_LOCK(intSave);
|
||||
g_tickCount[ArchCurrCpuid()]++;
|
||||
TICK_UNLOCK(intSave);
|
||||
|
||||
#ifdef LOSCFG_KERNEL_VDSO
|
||||
OsUpdateVdsoTimeval();
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_KERNEL_TICKLESS
|
||||
OsTickIrqFlagSet(OsTicklessFlagGet());
|
||||
#endif
|
||||
|
||||
#if (LOSCFG_BASE_CORE_TICK_HW_TIME == YES)
|
||||
HalClockIrqClear(); /* diff from every platform */
|
||||
#endif
|
||||
|
||||
OsTimesliceCheck();
|
||||
|
||||
OsTaskScan(); /* task timeout scan */
|
||||
|
||||
#if (LOSCFG_BASE_CORE_SWTMR == YES)
|
||||
OsSwtmrScan();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
75
kernel/base/core/los_timeslice.c
Executable file
75
kernel/base/core/los_timeslice.c
Executable file
@@ -0,0 +1,75 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_timeslice_pri.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_TEXT VOID OsTimesliceCheck(VOID)
|
||||
{
|
||||
LosTaskCB *runTask = NULL;
|
||||
LosProcessCB *runProcess = OsCurrProcessGet();
|
||||
if (runProcess->policy != LOS_SCHED_RR) {
|
||||
goto SCHED_TASK;
|
||||
}
|
||||
|
||||
if (runProcess->timeSlice != 0) {
|
||||
runProcess->timeSlice--;
|
||||
if (runProcess->timeSlice == 0) {
|
||||
LOS_Schedule();
|
||||
}
|
||||
}
|
||||
|
||||
SCHED_TASK:
|
||||
runTask = OsCurrTaskGet();
|
||||
if (runTask->policy != LOS_SCHED_RR) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (runTask->timeSlice != 0) {
|
||||
runTask->timeSlice--;
|
||||
if (runTask->timeSlice == 0) {
|
||||
LOS_Schedule();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
53
kernel/base/include/los_base_pri.h
Executable file
53
kernel/base/include/los_base_pri.h
Executable file
@@ -0,0 +1,53 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_BASE_PRI_H
|
||||
#define _LOS_BASE_PRI_H
|
||||
|
||||
#include "los_base.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_GOTO_ERREND() do { \
|
||||
goto LOS_ERREND; \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_BASE_PRI_H */
|
||||
110
kernel/base/include/los_binarytree_pri.h
Executable file
110
kernel/base/include/los_binarytree_pri.h
Executable file
@@ -0,0 +1,110 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_BINARYTREE_PRI_H
|
||||
#define _LOS_BINARYTREE_PRI_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct tagBinNode {
|
||||
struct tagBinNode *left;
|
||||
struct tagBinNode *right;
|
||||
UINT32 nodeID;
|
||||
CHAR keyValue[0];
|
||||
} BinNode;
|
||||
|
||||
typedef struct {
|
||||
BinNode leaf;
|
||||
UINTPTR linkReg1;
|
||||
UINTPTR linkReg2;
|
||||
UINTPTR linkReg3;
|
||||
} LinkRegNode;
|
||||
|
||||
#define LR_COUNT 4096
|
||||
extern LinkRegNode g_linkRegNode[LR_COUNT];
|
||||
extern UINT32 g_linkRegNodeIndex;
|
||||
extern LinkRegNode *g_linkRegRoot;
|
||||
|
||||
typedef struct {
|
||||
BinNode leaf;
|
||||
UINTPTR addr;
|
||||
} AddrNode;
|
||||
|
||||
#define ADDR_COUNT 40960
|
||||
extern AddrNode g_addrNode[ADDR_COUNT];
|
||||
extern UINT32 g_addrNodeIndex;
|
||||
extern AddrNode *g_addrRoot;
|
||||
|
||||
typedef struct {
|
||||
BinNode leaf;
|
||||
UINT32 reqSize;
|
||||
} ReqSizeNode;
|
||||
|
||||
#define REQ_SIZE_COUNT 4096
|
||||
extern ReqSizeNode g_reqSizeNode[REQ_SIZE_COUNT];
|
||||
extern UINT32 g_reqSizeNodeIndex;
|
||||
extern ReqSizeNode *g_reqSizeRoot;
|
||||
|
||||
typedef struct {
|
||||
BinNode leaf;
|
||||
UINT32 taskID;
|
||||
} TaskIDNode;
|
||||
|
||||
#define TASK_ID_COUNT 1024
|
||||
|
||||
extern UINT32 OsBinTreeInsert(const VOID *node, UINT32 nodeLen, BinNode **leaf,
|
||||
BinNode *(*GetMyBinNode)(UINT32 *nodeID),
|
||||
INT32 (*CompareNode)(const VOID *node1, const VOID *node2));
|
||||
|
||||
extern INT32 OsCompareLRNode(const VOID *node1, const VOID *node2);
|
||||
extern BinNode *OsGetLRBinNode(UINT32 *nodeID);
|
||||
|
||||
extern INT32 OsCompareAddrNode(const VOID *node1, const VOID *node2);
|
||||
extern BinNode *OsGetAddrBinNode(UINT32 *nodeID);
|
||||
|
||||
extern INT32 OsCompareReqSizeNode(const VOID *node1, const VOID *node2);
|
||||
extern BinNode *OsGetReqSizeBinNode(UINT32 *nodeID);
|
||||
|
||||
extern INT32 OsCompareTaskIDNode(const VOID *node1, const VOID *node2);
|
||||
extern BinNode *OsGetTaskIDBinNode(UINT32 *nodeID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_BINARYTREE_PRI_H */
|
||||
127
kernel/base/include/los_err_pri.h
Executable file
127
kernel/base/include/los_err_pri.h
Executable file
@@ -0,0 +1,127 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_ERR_PRI_H
|
||||
#define _LOS_ERR_PRI_H
|
||||
|
||||
#include "los_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @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_RETURN_ERROR(errNo) do { \
|
||||
(VOID)LOS_ErrHandle("os_unspecific_file", OS_ERR_MAGIC_WORD, errNo, 0, NULL); \
|
||||
return errNo; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
#define OS_RETURN_ERROR_P2(errLine, errNo) do { \
|
||||
(VOID)LOS_ErrHandle("os_unspecific_file", errLine, errNo, 0, NULL); \
|
||||
return errNo; \
|
||||
} while (0)
|
||||
|
||||
/**
|
||||
* @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.
|
||||
*/
|
||||
#define OS_GOTO_ERR_HANDLER(errorNo) do { \
|
||||
errNo = errorNo; \
|
||||
errLine = OS_ERR_MAGIC_WORD; \
|
||||
goto ERR_HANDLER; \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_ERR_PRI_H */
|
||||
64
kernel/base/include/los_event_pri.h
Executable file
64
kernel/base/include/los_event_pri.h
Executable file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_EVENT_PRI_H
|
||||
#define _LOS_EVENT_PRI_H
|
||||
|
||||
#include "los_event.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef LOSCFG_COMPAT_POSIX
|
||||
typedef struct {
|
||||
volatile INT32 *realValue;
|
||||
INT32 value;
|
||||
UINT32 clearEvent;
|
||||
} EventCond;
|
||||
|
||||
extern UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB,
|
||||
UINT32 eventMask, UINT32 mode, UINT32 timeout);
|
||||
#endif
|
||||
|
||||
extern VOID OsEventWriteUnsafe(PEVENT_CB_S eventCB, UINT32 events, BOOL once, UINT8 *exitFlag);
|
||||
extern UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout);
|
||||
extern UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_EVENT_PRI_H */
|
||||
63
kernel/base/include/los_futex_pri.h
Executable file
63
kernel/base/include/los_futex_pri.h
Executable file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_FUTEX_PRI_H
|
||||
#define _LOS_FUTEX_PRI_H
|
||||
#include "los_list.h"
|
||||
|
||||
#define FUTEX_WAIT 0
|
||||
#define FUTEX_WAKE 1
|
||||
#define FUTEX_REQUEUE 3
|
||||
#define FUTEX_WAKE_OP 5
|
||||
#define FUTEX_LOCK_PI 6
|
||||
#define FUTEX_UNLOCK_PI 7
|
||||
#define FUTEX_TRYLOCK_PI 8
|
||||
#define FUTEX_WAIT_BITSET 9
|
||||
|
||||
#define FUTEX_PRIVATE 128
|
||||
#define FUTEX_MASK 0x3U
|
||||
|
||||
typedef struct {
|
||||
UINTPTR key;
|
||||
UINT32 index;
|
||||
UINT32 pid;
|
||||
LOS_DL_LIST pendList;
|
||||
LOS_DL_LIST queueList;
|
||||
LOS_DL_LIST futexList;
|
||||
} FutexNode;
|
||||
|
||||
extern UINT32 OsFutexInit(VOID);
|
||||
extern VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags);
|
||||
extern INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber);
|
||||
extern INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime);
|
||||
extern INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber,
|
||||
INT32 count, const UINT32 *newUserVaddr);
|
||||
#endif
|
||||
253
kernel/base/include/los_heap_pri.h
Executable file
253
kernel/base/include/los_heap_pri.h
Executable file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/*
|
||||
* @defgroup los_heap Heap
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef _LOS_HEAP_PRI_H
|
||||
#define _LOS_HEAP_PRI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define ALIGNE(sz) (((sz) + HEAP_ALIGN - 1) & (~(HEAP_ALIGN - 1)))
|
||||
#define OS_MEM_ALIGN(value, align) (((UINT32)(UINTPTR)(value) + (UINT32)((align) - 1)) & \
|
||||
(~(UINT32)((align) - 1)))
|
||||
#define OS_MEM_ALIGN_FLAG 0x80000000
|
||||
#define OS_MEM_SET_ALIGN_FLAG(align) ((align) = ((align) | OS_MEM_ALIGN_FLAG))
|
||||
#define OS_MEM_GET_ALIGN_FLAG(align) ((align) & OS_MEM_ALIGN_FLAG)
|
||||
#define OS_MEM_GET_ALIGN_GAPSIZE(align) ((align) & (~OS_MEM_ALIGN_FLAG))
|
||||
|
||||
typedef struct tagLosHeapStatus {
|
||||
UINT32 totalUsedSize;
|
||||
UINT32 totalFreeSize;
|
||||
UINT32 maxFreeNodeSize;
|
||||
UINT32 usedNodeNum;
|
||||
UINT32 freeNodeNum;
|
||||
} LosHeapStatus;
|
||||
|
||||
struct LosHeapNode {
|
||||
struct LosHeapNode* prev;
|
||||
UINT32 size : 30;
|
||||
UINT32 used : 1;
|
||||
UINT32 align : 1;
|
||||
UINT8 data[0];
|
||||
};
|
||||
|
||||
struct LosHeapManager {
|
||||
struct LosHeapNode *head;
|
||||
struct LosHeapNode *tail;
|
||||
UINT32 size;
|
||||
#if (LOSCFG_MEM_MUL_POOL == YES)
|
||||
VOID *nextPool;
|
||||
#endif
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup los_heap
|
||||
* @brief Look up the next memory node according to one memory node in the memory block list.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to look up the next memory node according to one memory node in the memory block list.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param heapMan [IN] Type #LosHeapManager * Pointer to the manager,to distinguish heap.
|
||||
* @param node [IN] Type #LosHeapNode * Size of memory in bytes to allocate.
|
||||
*
|
||||
* @retval LosHeapNode * Pointer to next memory node.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern struct LosHeapNode* OsHeapPrvGetNext(struct LosHeapManager *heapMan, struct LosHeapNode* node);
|
||||
|
||||
/**
|
||||
* @ingroup los_heap
|
||||
* @brief Obtain the heap information.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the heap information.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool.
|
||||
*
|
||||
* @retval None.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID OsAlarmHeapInfo(VOID *pool);
|
||||
|
||||
/**
|
||||
* @ingroup los_heap
|
||||
* @brief Obtain the heap status.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the heap status.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool.
|
||||
* @param status [OUT] Type #LosHeapStatus * Heap status.
|
||||
*
|
||||
* @retval UINT32 Get status result.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status);
|
||||
|
||||
/**
|
||||
* @ingroup los_heap
|
||||
* @brief Get the max free block size.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to Get the max free block size.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool.
|
||||
*
|
||||
* @retval UINT32 Max free block size.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern UINT32 OsHeapGetMaxFreeBlkSize(VOID *pool);
|
||||
|
||||
/**
|
||||
* @ingroup OsHeapInit
|
||||
* @brief Initialize the heap memory pool.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to initialize the heap memory and get the begin address and
|
||||
* size of heap memory,then initialize LosHeapManager .
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param pool [IN] Type #VOID * A pointer pointed to the heap memory pool.
|
||||
* @param size [IN] Type #UINT32 Size of memory in bytes to initialized.
|
||||
*
|
||||
* @retval BOOL Get status return.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern BOOL OsHeapInit(VOID *pool, UINT32 size);
|
||||
|
||||
/**
|
||||
* @ingroup OsHeapAlloc
|
||||
* @brief Alloc memory block from the heap.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to alloc memory block from the heap memory pool.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param pool [IN] Type #VOID * Pointer to the manager,to distinguish heap
|
||||
* @param size [IN] Type #UINT32 Size of memory in bytes to alloc.
|
||||
*
|
||||
* @retval VOID * Get the address of the memory we alloced or NULL.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID* OsHeapAlloc(VOID *pool, UINT32 size);
|
||||
|
||||
/**
|
||||
* @ingroup OsHeapAllocAlign
|
||||
* @brief Alloc memory block from the heap with align.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to alloc memory block from the heap memory pool with align.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param pool [IN] Type #VOID * Pointer to the manager,to distinguish heap
|
||||
* @param size [IN] Type #UINT32 Size of memory in bytes to alloc.
|
||||
* @param boundary [IN] Type #UINT32 Boundary the heap needs align.
|
||||
*
|
||||
* @retval VOID * Get the address of the memory we alloced or NULL.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary);
|
||||
|
||||
/**
|
||||
* @ingroup OsHeapFree
|
||||
* @brief Free memory block from heap memory pool.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to To free the memory block from heap memory pool.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param pool [IN] Type #VOID * Pointer to the manager,to distinguish heap
|
||||
* @param ptr [IN] Type #VOID * Pinter of heap memory we want to free.
|
||||
*
|
||||
* @retval BOOL Get result return.
|
||||
*
|
||||
* @par Dependency:
|
||||
* <ul><li>los_heap_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern BOOL OsHeapFree(VOID *pool, VOID* ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_HEAP_PRI_H */
|
||||
67
kernel/base/include/los_ipcdebug_pri.h
Executable file
67
kernel/base/include/los_ipcdebug_pri.h
Executable file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_IPCDEBUG_PRI_H
|
||||
#define _LOS_IPCDEBUG_PRI_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
CHAR *buf; /**< Control block array total buffer */
|
||||
size_t ipcDebugCBSize; /**< Single control block size */
|
||||
size_t ipcDebugCBCnt; /**< Number of control blocks */
|
||||
UINT32 sortElemOff; /**< The offset of the member to be compared in the control block */
|
||||
} IpcSortParam;
|
||||
|
||||
/* Compare the size of the last access time */
|
||||
typedef BOOL (*OsCompareFunc)(const IpcSortParam *sortParam, UINT32 left, UINT32 right);
|
||||
|
||||
/* Get the address of the comparison member variable */
|
||||
#define SORT_ELEM_ADDR(sortParam, index) \
|
||||
((sortParam)->buf + ((index) * (sortParam)->ipcDebugCBSize) + (sortParam)->sortElemOff)
|
||||
|
||||
/* Sort this index array. */
|
||||
extern VOID OsArraySortByTime(UINT32 *sortArray, UINT32 start, UINT32 end, const IpcSortParam *sortParam,
|
||||
OsCompareFunc compareFunc);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_IPCDEBUG_PRI_H */
|
||||
49
kernel/base/include/los_membox_pri.h
Executable file
49
kernel/base/include/los_membox_pri.h
Executable file
@@ -0,0 +1,49 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_MEMBOX_PRI_H
|
||||
#define _LOS_MEMBOX_PRI_H
|
||||
|
||||
#include "los_membox.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_MEMBOX_PRI_H */
|
||||
72
kernel/base/include/los_memory_pri.h
Executable file
72
kernel/base/include/los_memory_pri.h
Executable file
@@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_MEMORY_PRI_H
|
||||
#define _LOS_MEMORY_PRI_H
|
||||
|
||||
#include "los_memory.h"
|
||||
#include "los_spinlock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern UINT32 OsMemSystemInit(UINTPTR memStart);
|
||||
extern STATUS_T OsKHeapInit(size_t size);
|
||||
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
extern UINT32 OsMemExcInteractionInit(UINTPTR memStart);
|
||||
#endif
|
||||
extern VOID OsDumpMemByte(size_t length, UINTPTR addr);
|
||||
|
||||
#ifdef LOSCFG_MEM_LEAKCHECK
|
||||
extern VOID OsMemUsedNodeShow(VOID *pool);
|
||||
#endif
|
||||
|
||||
extern VOID OsMemResetEndNode(VOID *pool, UINTPTR preAddr);
|
||||
extern UINT32 OsMemLargeNodeFree(const VOID *ptr);
|
||||
extern BOOL OsMemIsHeapNode(const VOID *ptr);
|
||||
extern UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[]);
|
||||
|
||||
/* spinlock for mem module, only available on SMP mode */
|
||||
extern SPIN_LOCK_S g_memSpin;
|
||||
#define MEM_LOCK(state) LOS_SpinLockSave(&g_memSpin, &(state))
|
||||
#define MEM_UNLOCK(state) LOS_SpinUnlockRestore(&g_memSpin, (state))
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_MEMORY_PRI_H */
|
||||
84
kernel/base/include/los_memrecord_pri.h
Executable file
84
kernel/base/include/los_memrecord_pri.h
Executable file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_MEMRECORD_PRI_H
|
||||
#define _LOS_MEMRECORD_PRI_H
|
||||
|
||||
#include "los_memory.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define RECORD_LEN 4000
|
||||
|
||||
typedef struct {
|
||||
UINT32 addrID;
|
||||
UINT32 taskID;
|
||||
UINT32 reqSizeID;
|
||||
UINT32 allocatedSizeID;
|
||||
UINT32 actType;
|
||||
UINT64 sysTick;
|
||||
UINT32 linkRegID;
|
||||
} MemRecordInfo;
|
||||
|
||||
#define MEM_RECORDSHOW_TIMEOUT 6000
|
||||
|
||||
extern VOID OsMemRecordShowSet(UINT32 value);
|
||||
extern VOID OsMemRecordMalloc(const VOID *ptr, UINT32 size);
|
||||
extern VOID OsMemRecordFree(const VOID *ptr, UINT32 size);
|
||||
extern VOID OsMemRecordShowTask(VOID);
|
||||
extern VOID OsDecTo64F(UINT32 num, CHAR *base64, INT32 base64Len);
|
||||
|
||||
|
||||
#ifndef LOSCFG_MEM_RECORDINFO
|
||||
INLINE VOID OsMemRecordFree(const VOID *ptr, UINT32 size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef LOSCFG_MEM_RECORDINFO
|
||||
INLINE VOID OsMemRecordMalloc(const VOID *ptr, UINT32 size)
|
||||
{
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_MEMRECORD_PRI_H */
|
||||
88
kernel/base/include/los_memstat_pri.h
Executable file
88
kernel/base/include/los_memstat_pri.h
Executable file
@@ -0,0 +1,88 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_MEMSTAT_PRI_H
|
||||
#define _LOS_MEMSTAT_PRI_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_memory.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
UINT32 memUsed;
|
||||
} TskMemUsedInfo;
|
||||
|
||||
extern VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID);
|
||||
extern VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID);
|
||||
extern UINT32 OsTaskMemUsage(UINT32 taskID);
|
||||
extern VOID OsTaskMemClear(UINT32 taskID);
|
||||
#define OS_MEM_ENABLE_MEM_STATISTICS
|
||||
|
||||
#ifdef LOS_MEM_SLAB
|
||||
typedef struct {
|
||||
UINT32 slabUsed;
|
||||
} TskSlabUsedInfo;
|
||||
|
||||
extern VOID OsTaskSlabUsedInc(UINT32 usedSize, UINT32 taskID);
|
||||
extern VOID OsTaskSlabUsedDec(UINT32 usedSize, UINT32 taskID);
|
||||
extern UINT32 OsTaskSlabUsage(UINT32 taskID);
|
||||
#endif
|
||||
|
||||
#ifdef OS_MEM_ENABLE_MEM_STATISTICS
|
||||
#define OS_MEM_ADD_USED(usedSize, taskID) OsTaskMemUsedInc(usedSize, taskID)
|
||||
#define OS_MEM_REDUCE_USED(usedSize, taskID) OsTaskMemUsedDec(usedSize, taskID)
|
||||
#define OS_MEM_CLEAR(taskID) OsTaskMemClear(taskID)
|
||||
#ifdef LOS_MEM_SLAB
|
||||
#define OS_SLAB_ADD_USED(usedSize, taskID) OsTaskSlabUsedInc(usedSize, taskID)
|
||||
#define OS_SLAB_REDUCE_USED(usedSize, taskID) OsTaskSlabUsedDec(usedSize, taskID)
|
||||
#endif
|
||||
#else
|
||||
#define OS_MEM_ADD_USED(usedSize, taskID)
|
||||
#define OS_MEM_REDUCE_USED(usedSize, taskID)
|
||||
#define OS_MEM_CLEAR(taskID)
|
||||
#ifdef LOS_MEM_SLAB
|
||||
#define OS_SLAB_ADD_USED(usedSize, taskID)
|
||||
#define OS_SLAB_REDUCE_USED(usedSize, taskID)
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_MEMSTAT_PRI_H */
|
||||
70
kernel/base/include/los_multipledlinkhead_pri.h
Executable file
70
kernel/base/include/los_multipledlinkhead_pri.h
Executable file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_MULTIPLE_DLINK_HEAD_PRI_H
|
||||
#define _LOS_MULTIPLE_DLINK_HEAD_PRI_H
|
||||
|
||||
#include "los_base.h"
|
||||
#include "los_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_MAX_MULTI_DLNK_LOG2 30
|
||||
#define OS_MIN_MULTI_DLNK_LOG2 4
|
||||
#define OS_MULTI_DLNK_NUM ((OS_MAX_MULTI_DLNK_LOG2 - OS_MIN_MULTI_DLNK_LOG2) + 1)
|
||||
#define OS_DLNK_HEAD_SIZE OS_MULTI_DLNK_HEAD_SIZE
|
||||
#define OS_MULTI_DLNK_HEAD_SIZE sizeof(LosMultipleDlinkHead)
|
||||
|
||||
typedef struct {
|
||||
LOS_DL_LIST listHead[OS_MULTI_DLNK_NUM];
|
||||
} LosMultipleDlinkHead;
|
||||
|
||||
STATIC INLINE LOS_DL_LIST *OsDLnkNextMultiHead(VOID *headAddr, LOS_DL_LIST *listNodeHead)
|
||||
{
|
||||
LosMultipleDlinkHead *head = (LosMultipleDlinkHead *)headAddr;
|
||||
|
||||
return (&head->listHead[OS_MULTI_DLNK_NUM - 1] == listNodeHead) ? NULL : (listNodeHead + 1);
|
||||
}
|
||||
|
||||
extern VOID OsDLnkInitMultiHead(VOID *headAddr);
|
||||
extern LOS_DL_LIST *OsDLnkMultiHead(VOID *headAddr, UINT32 size);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_MULTIPLE_DLINK_HEAD_PRI_H */
|
||||
57
kernel/base/include/los_mux_pri.h
Executable file
57
kernel/base/include/los_mux_pri.h
Executable file
@@ -0,0 +1,57 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_MUX_PRI_H
|
||||
#define _LOS_MUX_PRI_H
|
||||
|
||||
#include "los_mux.h"
|
||||
#include "los_task_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_MUX_MAGIC 0xEBCFDEA0
|
||||
|
||||
extern VOID OsMuxBitmapRestore(const LosMux *mutex, const LosTaskCB *taskCB, LosTaskCB *owner);
|
||||
extern UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout);
|
||||
extern UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout);
|
||||
extern UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_MUX_PRI_H */
|
||||
70
kernel/base/include/los_oom.h
Executable file
70
kernel/base/include/los_oom.h
Executable file
@@ -0,0 +1,70 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_OOM_H
|
||||
#define _LOS_OOM_H
|
||||
#include "los_typedef.h"
|
||||
|
||||
#define OOM_TASK_PRIORITY 9
|
||||
#define OOM_TASK_STACK_SIZE 0x1000
|
||||
|
||||
#define OOM_CHECK_MIN 10 /* 0.1s */
|
||||
#define OOM_DEFAULT_CHECK_INTERVAL 100 /* 1s */
|
||||
#define OOM_CHECK_MAX 1000 /* 10s */
|
||||
|
||||
#define OOM_DEFAULT_LOW_MEM_THRESHOLD 0x80000 /* 512KByte */
|
||||
#define OOM_DEFAULT_LOW_MEM_THRESHOLD_MIN 0 /* 0, means always no memory */
|
||||
#define OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX 0x100000 /* 1MByte */
|
||||
|
||||
#define OOM_DEFAULT_RECLAIM_MEM_THRESHOLD 0x500000 /* 5MByte */
|
||||
|
||||
typedef UINT32 (*OomFn)(UINTPTR param);
|
||||
|
||||
typedef struct {
|
||||
UINT32 lowMemThreshold; /* byte */
|
||||
UINT32 reclaimMemThreshold; /* byte */
|
||||
UINT32 checkInterval; /* microsecond */
|
||||
OomFn processVictimCB; /* process victim process cb function */
|
||||
OomFn scoreCB; /* out of memory, the process score function */
|
||||
UINT16 swtmrID;
|
||||
BOOL enabled; /* oom is enabled or not */
|
||||
} OomCB;
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID);
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID);
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomEnable(VOID);
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomDisable(VOID);
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold);
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshold);
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval);
|
||||
LITE_OS_SEC_TEXT_MINOR BOOL OomCheckProcess(VOID);
|
||||
#endif
|
||||
|
||||
87
kernel/base/include/los_percpu_pri.h
Executable file
87
kernel/base/include/los_percpu_pri.h
Executable file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_PERCPU_PRI_H
|
||||
#define _LOS_PERCPU_PRI_H
|
||||
|
||||
#include "los_base.h"
|
||||
#include "los_hw_cpu.h"
|
||||
#include "los_sortlink_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
typedef enum {
|
||||
CPU_RUNNING = 0, /* cpu is running */
|
||||
CPU_HALT, /* cpu in the halt */
|
||||
CPU_EXC /* cpu in the exc */
|
||||
} ExcFlag;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
SortLinkAttribute taskSortLink; /* task sort link */
|
||||
SortLinkAttribute swtmrSortLink; /* swtmr sort link */
|
||||
|
||||
UINT32 idleTaskID; /* idle task id */
|
||||
UINT32 taskLockCnt; /* task lock flag */
|
||||
UINT32 swtmrHandlerQueue; /* software timer timeout queue id */
|
||||
UINT32 swtmrTaskID; /* software timer task id */
|
||||
|
||||
UINT32 schedFlag; /* pending scheduler flag */
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
UINT32 excFlag; /* cpu halt or exc flag */
|
||||
#endif
|
||||
} Percpu;
|
||||
|
||||
/* the kernel per-cpu structure */
|
||||
extern Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];
|
||||
|
||||
STATIC INLINE Percpu *OsPercpuGet(VOID)
|
||||
{
|
||||
return &g_percpu[ArchCurrCpuid()];
|
||||
}
|
||||
|
||||
STATIC INLINE Percpu *OsPercpuGetByID(UINT32 cpuid)
|
||||
{
|
||||
return &g_percpu[cpuid];
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_PERCPU_PRI_H */
|
||||
56
kernel/base/include/los_pmm.h
Executable file
56
kernel/base/include/los_pmm.h
Executable file
@@ -0,0 +1,56 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_pmm physical memory management
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_PMM_H__
|
||||
#define __LOS_PMM_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
BOOL OsIsPaddrValid(paddr_t pa);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_PMM_H__ */
|
||||
58
kernel/base/include/los_printf_pri.h
Executable file
58
kernel/base/include/los_printf_pri.h
Executable file
@@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_PRINTF_PRI_H
|
||||
#define _LOS_PRINTF_PRI_H
|
||||
|
||||
#include "los_printf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern VOID UartVprintf(const CHAR *fmt, va_list ap);
|
||||
extern VOID PrintExcInfo(const CHAR *fmt, ...);
|
||||
|
||||
extern const CHAR *OsLogLvGet(INT32 level);
|
||||
extern VOID LkDprintf(const CHAR *fmt, va_list ap);
|
||||
#ifdef LOSCFG_SHELL_DMESG
|
||||
extern VOID DmesgPrintf(const CHAR *fmt, va_list ap);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_PRINTF_PRI_H */
|
||||
245
kernel/base/include/los_priqueue_pri.h
Executable file
245
kernel/base/include/los_priqueue_pri.h
Executable file
@@ -0,0 +1,245 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_PRIQUEUE_PRI_H
|
||||
#define _LOS_PRIQUEUE_PRI_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
extern LOS_DL_LIST *g_priQueueList;
|
||||
extern UINT32 g_priQueueBitmap;
|
||||
|
||||
#define OS_PRIORITY_QUEUE_NUM 32
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Initialize the priority queue.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to initialize the priority queue.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param none.
|
||||
*
|
||||
* @retval #LOS_NOK Insufficient memory for priority queue initialization.
|
||||
* @retval #LOS_OK The priority queue successfully initialized.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see none.
|
||||
*/
|
||||
extern UINT32 OsPriQueueInit(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Obtain the item with highest priority.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the item with highest priority in the priority queue.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param priQueueList [IN] The list of priority queue.
|
||||
* @param bitMap [IN] bit map of priority queue.
|
||||
*
|
||||
* @retval NULL The priority queue is empty.
|
||||
* @retval item node The node of the item with highest priority.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see none.
|
||||
*/
|
||||
extern LOS_DL_LIST *OsPriQueueTop(LOS_DL_LIST *priQueueList, UINT32 *bitMap);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Insert a item to the head of priority queue.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to insert a item to the head of priority queue according to the priority of this item.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Param priqueueItem must point to valid memory.</li>
|
||||
* <li>Param priority rang is [0, OS_PRIORITY_QUEUE_NUM),included 0 and not included OS_PRIORITY_QUEUE_NUM.</li>
|
||||
* </ul>
|
||||
* @param priQueueList [IN] The list of priority queue.
|
||||
* @param bitMap [IN] bit map of priority queue.
|
||||
* @param priqueueItem [IN] The node of item to be inserted.
|
||||
* @param priority [IN] Priority of the item be inserted.
|
||||
*
|
||||
* @retval none.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsPriQueueDequeue.
|
||||
*/
|
||||
extern VOID OsPriQueueEnqueueHead(
|
||||
LOS_DL_LIST *priQueueList, UINT32 *bitMap, LOS_DL_LIST *priqueueItem, UINT32 priority);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Insert a item to the priority queue.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to insert a item to the priority queue according to the priority of this item.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Param priqueueItem must point to valid memory.</li>
|
||||
* <li>Param priority rang is [0, OS_PRIORITY_QUEUE_NUM),included 0 and not included OS_PRIORITY_QUEUE_NUM.</li>
|
||||
* </ul>
|
||||
* @param priQueueList [IN] The list of priority queue.
|
||||
* @param bitMap [IN] bit map of priority queue.
|
||||
* @param priqueueItem [IN] The node of item to be inserted.
|
||||
* @param priority [IN] Priority of the item be inserted.
|
||||
*
|
||||
* @retval none.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsPriQueueDequeue.
|
||||
*/
|
||||
extern VOID OsPriQueueEnqueue(
|
||||
LOS_DL_LIST *priQueueList, UINT32 *bitMap, LOS_DL_LIST *priqueueItem, UINT32 priority);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Delete a item from the priority queue.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to delete a item from the priority queue.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Param priqueueItem must point to valid memory.</li>
|
||||
* </ul>
|
||||
* @param priQueueList [IN] The list of priority queue.
|
||||
* @param bitMap [IN] bit map of priority queue.
|
||||
* @param priqueueItem [IN] The node of item to be deleted.
|
||||
*
|
||||
* @retval none.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsPriQueueEnqueue.
|
||||
*/
|
||||
extern VOID OsPriQueueDequeue(LOS_DL_LIST *priQueueList, UINT32 *bitMap, LOS_DL_LIST *priqueueItem);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Delete a item from the priority queue.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to delete a item from the process priority queue.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Param priqueueItem must point to valid memory.</li>
|
||||
* </ul>
|
||||
* @param priQueueList [IN] The list of priority queue.
|
||||
* @param bitMap [IN] bit map of priority queue.
|
||||
* @param priqueueItem [IN] The node of item to be deleted.
|
||||
*
|
||||
* @retval none.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsPriQueueProcessDequeue.
|
||||
*/
|
||||
extern VOID OsPriQueueProcessDequeue(LOS_DL_LIST *priqueueItem);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Obtain the number of items with the specified priority.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the number of items with the specified priority.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Param priority rang is [0, OS_PRIORITY_QUEUE_NUM),included 0 and not included OS_PRIORITY_QUEUE_NUM.</li>
|
||||
* </ul>
|
||||
* @param priQueueList [IN] The list of priority queue.
|
||||
* @param priority [IN] Obtain the number of items with the specified priority.
|
||||
*
|
||||
* @retval The number of items The number of items with the specified priority.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see none.
|
||||
*/
|
||||
extern UINT32 OsPriQueueSize(LOS_DL_LIST *priQueueList, UINT32 priority);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Obtain the item with highest priority.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the item with highest priority in the priority queue.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
* @param none.
|
||||
*
|
||||
* @retval NULL The priority queue is empty.
|
||||
* @retval item node The node of the item with highest priority.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see none.
|
||||
*/
|
||||
extern LOS_DL_LIST *OsTaskPriQueueTop(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_priqueue
|
||||
* @brief Obtain the number of items with the specified priority.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the number of items with the specified process priority.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Param priority rang is [0, OS_PRIORITY_QUEUE_NUM),included 0 and not included OS_PRIORITY_QUEUE_NUM.</li>
|
||||
* </ul>
|
||||
* @param priQueueList [IN] The list of priority queue.
|
||||
* @param priority [IN] Obtain the number of items with the specified priority.
|
||||
*
|
||||
* @retval The number of items The number of items with the specified priority.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_priqueue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see none.
|
||||
*/
|
||||
extern UINT32 OsPriQueueProcessSize(LOS_DL_LIST *priQueueList, UINT32 priority);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_PRIQUEUE_PRI_H */
|
||||
498
kernel/base/include/los_process_pri.h
Executable file
498
kernel/base/include/los_process_pri.h
Executable file
@@ -0,0 +1,498 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_PROCESS_PRI_H
|
||||
#define _LOS_PROCESS_PRI_H
|
||||
|
||||
#include "los_sortlink_pri.h"
|
||||
#include "los_priqueue_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_sem_pri.h"
|
||||
#include "los_process.h"
|
||||
#include "los_vm_map.h"
|
||||
#if (LOSCFG_KERNEL_LITEIPC == YES)
|
||||
#include "hm_liteipc.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
#include "capability_type.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_SECURITY_VID
|
||||
#include "vid_type.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_PCB_NAME_LEN OS_TCB_NAME_LEN
|
||||
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
#define OS_GROUPS_NUMBER_MAX 256
|
||||
|
||||
typedef struct {
|
||||
UINT32 userID;
|
||||
UINT32 effUserID;
|
||||
UINT32 gid;
|
||||
UINT32 effGid;
|
||||
UINT32 groupNumber;
|
||||
UINT32 groups[1];
|
||||
} User;
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
UINT32 groupID; /**< Process group ID is the PID of 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 = leader thread ID */
|
||||
UINT16 processStatus; /**< [15:4] process Status; [3:0] The number of threads currently
|
||||
running in the process */
|
||||
UINT16 priority; /**< process priority */
|
||||
UINT16 policy; /**< process policy */
|
||||
UINT16 timeSlice; /**< Remaining time slice */
|
||||
UINT16 consoleID; /**< The console id of task belongs */
|
||||
UINT16 processMode; /**< Kernel Mode:0; User Mode:1; */
|
||||
UINT32 parentProcessID; /**< Parent process ID */
|
||||
UINT32 exitCode; /**< process exit status */
|
||||
LOS_DL_LIST pendList; /**< Block list to which the process belongs */
|
||||
LOS_DL_LIST childrenList; /**< my children process list */
|
||||
LOS_DL_LIST exitChildList; /**< my exit children process list */
|
||||
LOS_DL_LIST siblingList; /**< linkage in my parent's children list */
|
||||
ProcessGroup *group; /**< Process group to which a process belongs */
|
||||
LOS_DL_LIST subordinateGroupList; /**< linkage in my group list */
|
||||
UINT32 threadGroupID; /**< Which thread group , is the main thread ID of the process */
|
||||
UINT32 threadScheduleMap; /**< The scheduling bitmap table for the thread group of the
|
||||
process */
|
||||
LOS_DL_LIST threadSiblingList; /**< List of threads under this process */
|
||||
LOS_DL_LIST threadPriQueueList[OS_PRIORITY_QUEUE_NUM]; /**< The process's thread group schedules the
|
||||
priority hash table */
|
||||
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 */
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */
|
||||
#endif
|
||||
UINTPTR sigHandler; /**< signal handler */
|
||||
sigset_t sigShare; /**< signal share bit */
|
||||
#if (LOSCFG_KERNEL_LITEIPC == YES)
|
||||
ProcIpcInfo ipcInfo; /**< memory pool for lite ipc */
|
||||
#endif
|
||||
LosVmSpace *vmSpace; /**< VMM space for processes */
|
||||
#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 file *execFile; /**< Exec bin of the process */
|
||||
#endif
|
||||
mode_t umask;
|
||||
} LosProcessCB;
|
||||
|
||||
#define CLONE_VM 0x00000100
|
||||
#define CLONE_FS 0x00000200
|
||||
#define CLONE_FILES 0x00000400
|
||||
#define CLONE_SIGHAND 0x00000800
|
||||
#define CLONE_PTRACE 0x00002000
|
||||
#define CLONE_VFORK 0x00004000
|
||||
#define CLONE_PARENT 0x00008000
|
||||
#define CLONE_THREAD 0x00010000
|
||||
|
||||
#define OS_PCB_FROM_PID(processID) (((LosProcessCB *)g_processCBArray) + (processID))
|
||||
#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)
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process is created but does not participate in scheduling.
|
||||
*/
|
||||
#define OS_PROCESS_STATUS_INIT 0x0010U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process is ready.
|
||||
*/
|
||||
#define OS_PROCESS_STATUS_READY 0x0020U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process is running.
|
||||
*/
|
||||
#define OS_PROCESS_STATUS_RUNNING 0x0040U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process is pend
|
||||
*/
|
||||
#define OS_PROCESS_STATUS_PEND 0x0080U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process is run out but the resources occupied by the process are not recovered.
|
||||
*/
|
||||
#define OS_PROCESS_STATUS_ZOMBIES 0x100U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The number of task currently running under the process, it only works with multiple cores.
|
||||
*/
|
||||
#define OS_PROCESS_RUNTASK_COUNT_MASK 0x000FU
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process status mask.
|
||||
*/
|
||||
#define OS_PROCESS_STATUS_MASK 0xFFF0U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process status equal this is process control block unused,
|
||||
* coexisting with OS_PROCESS_STATUS_ZOMBIES means that the control block is not recovered.
|
||||
*/
|
||||
#define OS_PROCESS_FLAG_UNUSED 0x0200U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process has been call exit, it only works with multiple cores.
|
||||
*/
|
||||
#define OS_PROCESS_FLAG_EXIT 0x0400U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process is the leader of the process group.
|
||||
*/
|
||||
#define OS_PROCESS_FLAG_GROUP_LEADER 0x0800U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process has performed the exec operation.
|
||||
*/
|
||||
#define OS_PROCESS_FLAG_ALREADY_EXEC 0x1000U
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Flag that indicates the process or process control block status.
|
||||
*
|
||||
* The process is dying or already dying.
|
||||
*/
|
||||
#define OS_PROCESS_STATUS_INACTIVE (OS_PROCESS_FLAG_EXIT | OS_PROCESS_STATUS_ZOMBIES)
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Used to check if the process control block is unused.
|
||||
*/
|
||||
STATIC INLINE BOOL OsProcessIsUnused(const LosProcessCB *processCB)
|
||||
{
|
||||
return ((processCB->processStatus & OS_PROCESS_FLAG_UNUSED) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Used to check if the process is inactive.
|
||||
*/
|
||||
STATIC INLINE BOOL OsProcessIsInactive(const LosProcessCB *processCB)
|
||||
{
|
||||
return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_INACTIVE)) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Used to check if the process is dead.
|
||||
*/
|
||||
STATIC INLINE BOOL OsProcessIsDead(const LosProcessCB *processCB)
|
||||
{
|
||||
return ((processCB->processStatus & (OS_PROCESS_FLAG_UNUSED | OS_PROCESS_STATUS_ZOMBIES)) != 0);
|
||||
}
|
||||
|
||||
/**
|
||||
* @ingroup los_process
|
||||
* Hold the time slice process
|
||||
*/
|
||||
#define OS_PROCESS_SCHED_RR_INTERVAL LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT
|
||||
|
||||
/**
|
||||
* @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
|
||||
|
||||
#define OS_GET_PROCESS_STATUS(status) ((UINT16)((UINT16)(status) & OS_PROCESS_STATUS_MASK))
|
||||
#define OS_PROCESS_GET_RUNTASK_COUNT(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_RUNTASK_COUNT_MASK))
|
||||
#define OS_PROCESS_RUNTASK_COUNT_ADD(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_STATUS_MASK) | \
|
||||
((OS_PROCESS_GET_RUNTASK_COUNT(status) + 1) & OS_PROCESS_RUNTASK_COUNT_MASK))
|
||||
#define OS_PROCESS_RUNTASK_COUNT_DEC(status) ((UINT16)(((UINT16)(status)) & OS_PROCESS_STATUS_MASK) | \
|
||||
((OS_PROCESS_GET_RUNTASK_COUNT(status) - 1) & OS_PROCESS_RUNTASK_COUNT_MASK))
|
||||
|
||||
#define OS_TASK_DEFAULT_STACK_SIZE 0x2000
|
||||
#define OS_USER_TASK_SYSCALL_SATCK_SIZE 0x3000
|
||||
#define OS_USER_TASK_STACK_SIZE 0x100000
|
||||
|
||||
#define OS_KERNEL_MODE 0x0U
|
||||
#define OS_USER_MODE 0x1U
|
||||
STATIC INLINE BOOL OsProcessIsUserMode(const LosProcessCB *processCB)
|
||||
{
|
||||
return (processCB->processMode == OS_USER_MODE);
|
||||
}
|
||||
|
||||
#define LOS_SCHED_NORMAL 0U
|
||||
#define LOS_SCHED_FIFO 1U
|
||||
#define LOS_SCHED_RR 2U
|
||||
|
||||
#define LOS_PRIO_PROCESS 0U
|
||||
#define LOS_PRIO_PGRP 1U
|
||||
#define LOS_PRIO_USER 2U
|
||||
|
||||
#define OS_KERNEL_PROCESS_GROUP 2U
|
||||
#define OS_USER_PRIVILEGE_PROCESS_GROUP 1U
|
||||
|
||||
/*
|
||||
* Process exit code
|
||||
* 31 15 8 7 0
|
||||
* | | exit code | core dump | signal |
|
||||
*/
|
||||
#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);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsProcessExitCodeSignalIsSet(LosProcessCB *processCB)
|
||||
{
|
||||
return (processCB->exitCode) & 0x7FU;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsProcessExitCodeSet(LosProcessCB *processCB, UINT32 code)
|
||||
{
|
||||
processCB->exitCode |= ((code & 0x000000FFU) << 8U) & 0x0000FF00U; /* 8: Move 8 bits to the left, exitCode */
|
||||
}
|
||||
|
||||
extern LosProcessCB *g_processCBArray;
|
||||
extern LosProcessCB *g_runProcess[LOSCFG_KERNEL_CORE_NUM];
|
||||
extern UINT32 g_processMaxNum;
|
||||
|
||||
#define OS_PID_CHECK_INVALID(pid) (((UINT32)(pid)) >= g_processMaxNum)
|
||||
|
||||
STATIC INLINE BOOL OsProcessIDUserCheckInvalid(UINT32 pid)
|
||||
{
|
||||
return ((pid >= g_processMaxNum) || (pid == 0));
|
||||
}
|
||||
|
||||
STATIC INLINE LosProcessCB *OsCurrProcessGet(VOID)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosProcessCB *runProcess = NULL;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
runProcess = g_runProcess[ArchCurrCpuid()];
|
||||
LOS_IntRestore(intSave);
|
||||
return runProcess;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCurrProcessSet(const LosProcessCB *process)
|
||||
{
|
||||
g_runProcess[ArchCurrCpuid()] = (LosProcessCB *)process;
|
||||
}
|
||||
|
||||
STATIC INLINE UINT32 OsCpuProcessIDGetUnsafe(UINT16 cpuID)
|
||||
{
|
||||
LosProcessCB *runProcess = g_runProcess[cpuID];
|
||||
return runProcess->processID;
|
||||
}
|
||||
|
||||
STATIC INLINE UINT32 OsCpuProcessIDGet(UINT16 cpuID)
|
||||
{
|
||||
UINT32 pid;
|
||||
UINT32 intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
pid = OsCpuProcessIDGetUnsafe(cpuID);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
return pid;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
STATIC INLINE User *OsCurrUserGet(VOID)
|
||||
{
|
||||
User *user = NULL;
|
||||
UINT32 intSave;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
user = OsCurrProcessGet()->user;
|
||||
LOS_IntRestore(intSave);
|
||||
return user;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* return immediately if no child has exited.
|
||||
*/
|
||||
#define LOS_WAIT_WNOHANG (1 << 0U)
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
#define LOS_WAIT_WUNTRACED (1 << 1U)
|
||||
|
||||
/*
|
||||
* return if a stopped child has been resumed by delivery of SIGCONT.
|
||||
* (For Linux-only options, see below.)
|
||||
*/
|
||||
#define LOS_WAIT_WCONTINUED (1 << 3U)
|
||||
|
||||
/*
|
||||
* Indicates that you are already in a wait state
|
||||
*/
|
||||
#define OS_PROCESS_WAIT (1 << 15U)
|
||||
|
||||
/*
|
||||
* Wait for any child process to finish
|
||||
*/
|
||||
#define OS_PROCESS_WAIT_ANY (1 << 0U)
|
||||
|
||||
/*
|
||||
* Wait for the child process specified by the pid to finish
|
||||
*/
|
||||
#define OS_PROCESS_WAIT_PRO (1 << 1U)
|
||||
|
||||
/*
|
||||
* Waits for any child process in the specified process group to finish.
|
||||
*/
|
||||
#define OS_PROCESS_WAIT_GID (1 << 2U)
|
||||
|
||||
#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;
|
||||
extern UINT32 OsKernelInitProcess(VOID);
|
||||
extern VOID OsProcessCBRecyleToFree(VOID);
|
||||
extern VOID OsProcessResourcesToFree(LosProcessCB *processCB);
|
||||
extern VOID OsProcessExit(LosTaskCB *runTask, INT32 status);
|
||||
extern UINT32 OsUserInitProcess(VOID);
|
||||
extern VOID OsTaskSchedQueueDequeue(LosTaskCB *taskCB, UINT16 status);
|
||||
extern VOID OsTaskSchedQueueEnqueue(LosTaskCB *taskCB, UINT16 status);
|
||||
extern INT32 OsClone(UINT32 flags, UINTPTR sp, UINT32 size);
|
||||
extern VOID OsWaitSignalToWakeProcess(LosProcessCB *processCB);
|
||||
extern UINT32 OsExecRecycleAndInit(LosProcessCB *processCB, const CHAR *name,
|
||||
LosVmSpace *oldAspace, UINTPTR oldFiles);
|
||||
extern UINT32 OsExecStart(const TSK_ENTRY_FUNC entry, UINTPTR sp, UINTPTR mapBase, UINT32 mapSize);
|
||||
extern INT32 OsSetProcessScheduler(INT32 which, INT32 pid, UINT16 prio, UINT16 policy, BOOL policyFlag);
|
||||
extern INT32 OsGetProcessPriority(INT32 which, INT32 pid);
|
||||
extern VOID *OsUserStackAlloc(UINT32 processID, UINT32 *size);
|
||||
extern UINT32 OsGetUserInitProcessID(VOID);
|
||||
extern UINT32 OsGetIdleProcessID(VOID);
|
||||
extern INT32 OsSetProcessGroupID(UINT32 pid, UINT32 gid);
|
||||
extern INT32 OsSetCurrProcessGroupID(UINT32 gid);
|
||||
extern UINT32 OsGetKernelInitProcessID(VOID);
|
||||
extern VOID OsSetSigHandler(UINTPTR addr);
|
||||
extern UINTPTR OsGetSigHandler(VOID);
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
86
kernel/base/include/los_queue_debug_pri.h
Executable file
86
kernel/base/include/los_queue_debug_pri.h
Executable file
@@ -0,0 +1,86 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_QUEUE_DEBUG_PRI_H
|
||||
#define _LOS_QUEUE_DEBUG_PRI_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_task.h"
|
||||
#include "los_queue_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* queue debug initialization interface */
|
||||
extern UINT32 OsQueueDbgInit(VOID);
|
||||
STATIC INLINE UINT32 OsQueueDbgInitHook(VOID)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_QUEUE
|
||||
return OsQueueDbgInit();
|
||||
#else
|
||||
return LOS_OK;
|
||||
#endif
|
||||
}
|
||||
/* Update the last time the queue was executed */
|
||||
extern VOID OsQueueDbgTimeUpdate(UINT32 queueID);
|
||||
STATIC INLINE VOID OsQueueDbgTimeUpdateHook(UINT32 queueID)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_QUEUE
|
||||
OsQueueDbgTimeUpdate(queueID);
|
||||
#endif
|
||||
}
|
||||
/* Update the task entry of the queue debug info when created or deleted */
|
||||
extern VOID OsQueueDbgUpdate(UINT32 queueID, TSK_ENTRY_FUNC entry);
|
||||
STATIC INLINE VOID OsQueueDbgUpdateHook(UINT32 queueID, TSK_ENTRY_FUNC entry)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_QUEUE
|
||||
OsQueueDbgUpdate(queueID, entry);
|
||||
#endif
|
||||
}
|
||||
/* check the leak of queue */
|
||||
extern VOID OsQueueCheck(VOID);
|
||||
STATIC INLINE VOID OsQueueCheckHook(VOID)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_QUEUE
|
||||
OsQueueCheck();
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_QUEUE_DEBUG_PRI_H */
|
||||
207
kernel/base/include/los_queue_pri.h
Executable file
207
kernel/base/include/los_queue_pri.h
Executable file
@@ -0,0 +1,207 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_QUEUE_PRI_H
|
||||
#define _LOS_QUEUE_PRI_H
|
||||
|
||||
#include "los_queue.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef enum {
|
||||
OS_QUEUE_READ = 0,
|
||||
OS_QUEUE_WRITE = 1,
|
||||
OS_QUEUE_N_RW = 2
|
||||
} QueueReadWrite;
|
||||
|
||||
typedef enum {
|
||||
OS_QUEUE_HEAD = 0,
|
||||
OS_QUEUE_TAIL = 1
|
||||
} QueueHeadTail;
|
||||
|
||||
#define OS_QUEUE_OPERATE_TYPE(ReadOrWrite, HeadOrTail) (((UINT32)(HeadOrTail) << 1) | (ReadOrWrite))
|
||||
#define OS_QUEUE_READ_WRITE_GET(type) ((type) & 0x01U)
|
||||
#define OS_QUEUE_READ_HEAD (OS_QUEUE_READ | (OS_QUEUE_HEAD << 1))
|
||||
#define OS_QUEUE_READ_TAIL (OS_QUEUE_READ | (OS_QUEUE_TAIL << 1))
|
||||
#define OS_QUEUE_WRITE_HEAD (OS_QUEUE_WRITE | (OS_QUEUE_HEAD << 1))
|
||||
#define OS_QUEUE_WRITE_TAIL (OS_QUEUE_WRITE | (OS_QUEUE_TAIL << 1))
|
||||
#define OS_QUEUE_OPERATE_GET(type) ((type) & 0x03U)
|
||||
#define OS_QUEUE_IS_READ(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_READ)
|
||||
#define OS_QUEUE_IS_WRITE(type) (OS_QUEUE_READ_WRITE_GET(type) == OS_QUEUE_WRITE)
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Queue information block structure
|
||||
*/
|
||||
typedef struct {
|
||||
UINT8 *queueHandle; /**< Pointer to a queue handle */
|
||||
UINT16 queueState; /**< Queue state */
|
||||
UINT16 queueLen; /**< Queue length */
|
||||
UINT16 queueSize; /**< Node size */
|
||||
UINT32 queueID; /**< queueID */
|
||||
UINT16 queueHead; /**< Node head */
|
||||
UINT16 queueTail; /**< Node tail */
|
||||
UINT16 readWriteableCnt[OS_QUEUE_N_RW]; /**< Count of readable or writable resources, 0:readable, 1:writable */
|
||||
LOS_DL_LIST readWriteList[OS_QUEUE_N_RW]; /**< the linked list to be read or written, 0:readlist, 1:writelist */
|
||||
LOS_DL_LIST memList; /**< Pointer to the memory linked list */
|
||||
} LosQueueCB;
|
||||
|
||||
/* queue state */
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Message queue state: not in use.
|
||||
*/
|
||||
#define OS_QUEUE_UNUSED 0
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Message queue state: used.
|
||||
*/
|
||||
#define OS_QUEUE_INUSED 1
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Not in use.
|
||||
*/
|
||||
#define OS_QUEUE_WAIT_FOR_POOL 1
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Normal message queue.
|
||||
*/
|
||||
#define OS_QUEUE_NORMAL 0
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Queue information control block
|
||||
*/
|
||||
extern LosQueueCB *g_allQueue;
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* COUNT | INDEX split bit
|
||||
*/
|
||||
#define QUEUE_SPLIT_BIT 16
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Set the queue id
|
||||
*/
|
||||
#define SET_QUEUE_ID(count, queueID) (((count) << QUEUE_SPLIT_BIT) | (queueID))
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* get the queue index
|
||||
*/
|
||||
#define GET_QUEUE_INDEX(queueID) ((queueID) & ((1U << QUEUE_SPLIT_BIT) - 1))
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* get the queue count
|
||||
*/
|
||||
#define GET_QUEUE_COUNT(queueID) ((queueID) >> QUEUE_SPLIT_BIT)
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Obtain a handle of the queue that has a specified ID.
|
||||
*
|
||||
*/
|
||||
#define GET_QUEUE_HANDLE(queueID) (((LosQueueCB *)g_allQueue) + GET_QUEUE_INDEX(queueID))
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* Obtain the head node in a queue doubly linked list.
|
||||
*/
|
||||
#define GET_QUEUE_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosQueueCB, readWriteList[OS_QUEUE_WRITE])
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* @brief Alloc a stationary memory for a mail.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to alloc a stationary memory for a mail according to queueID.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>Do not alloc memory in unblocking modes such as interrupt.</li>
|
||||
* <li>This API cannot be called before the Huawei LiteOS is initialized.</li>
|
||||
* <li>The argument timeout is a relative time.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT].
|
||||
* @param mailPool [IN] The memory poll that stores the mail.
|
||||
* @param timeout [IN] Expiry time. The value range is [0,LOS_WAIT_FOREVER].
|
||||
*
|
||||
* @retval #NULL The memory allocation is failed.
|
||||
* @retval #pMem The address of alloc memory.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_queue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsQueueMailFree
|
||||
*/
|
||||
extern VOID *OsQueueMailAlloc(UINT32 queueID, VOID *mailPool, UINT32 timeout);
|
||||
|
||||
/**
|
||||
* @ingroup los_queue
|
||||
* @brief Free a stationary memory of a mail.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to free a stationary memory for a mail according to queueID.
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>This API cannot be called before the Huawei LiteOS is initialized.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param queueID [IN] Queue ID. The value range is [1,LOSCFG_BASE_IPC_QUEUE_LIMIT].
|
||||
* @param mailPool [IN] The mail memory poll address.
|
||||
* @param mailMem [IN] The mail memory block address.
|
||||
*
|
||||
* @retval #LOS_OK 0x00000000: The memory free successfully.
|
||||
* @retval #OS_ERRNO_QUEUE_MAIL_HANDLE_INVALID 0x02000619: The handle of the queue passed-in when the memory
|
||||
* for the queue is being freed is invalid.
|
||||
* @retval #OS_ERRNO_QUEUE_MAIL_PTR_INVALID 0x0200061a: The pointer to the memory to be freed is null.
|
||||
* @retval #OS_ERRNO_QUEUE_MAIL_FREE_ERROR 0x0200061b: The memory for the queue fails to be freed.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_queue_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsQueueMailAlloc
|
||||
*/
|
||||
extern UINT32 OsQueueMailFree(UINT32 queueID, VOID *mailPool, VOID *mailMem);
|
||||
|
||||
extern UINT32 OsQueueInit(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_QUEUE_PRI_H */
|
||||
144
kernel/base/include/los_sched_pri.h
Executable file
144
kernel/base/include/los_sched_pri.h
Executable file
@@ -0,0 +1,144 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SCHED_PRI_H
|
||||
#define _LOS_SCHED_PRI_H
|
||||
|
||||
#include "los_percpu_pri.h"
|
||||
#include "los_hwi.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern UINT32 g_taskScheduled;
|
||||
|
||||
/*
|
||||
* Schedule flag, one bit represents one core.
|
||||
* This flag is used to prevent kernel scheduling before OSStartToRun.
|
||||
*/
|
||||
#define OS_SCHEDULER_SET(cpuid) do { \
|
||||
g_taskScheduled |= (1U << (cpuid)); \
|
||||
} while (0);
|
||||
|
||||
#define OS_SCHEDULER_CLR(cpuid) do { \
|
||||
g_taskScheduled &= ~(1U << (cpuid)); \
|
||||
} while (0);
|
||||
|
||||
#define OS_SCHEDULER_ACTIVE (g_taskScheduled & (1U << ArchCurrCpuid()))
|
||||
|
||||
typedef enum {
|
||||
INT_NO_RESCH = 0, /* no needs to schedule */
|
||||
INT_PEND_RESCH, /* pending schedule flag */
|
||||
} SchedFlag;
|
||||
|
||||
/* Check if preemptable with counter flag */
|
||||
STATIC INLINE BOOL OsPreemptable(VOID)
|
||||
{
|
||||
/*
|
||||
* Unlike OsPreemptableInSched, the int may be not disabled when OsPreemptable
|
||||
* is called, needs mannually disable interrupt, to prevent current task from
|
||||
* being migrated to another core, and get the wrong preeptable status.
|
||||
*/
|
||||
UINT32 intSave = LOS_IntLock();
|
||||
BOOL preemptable = (OsPercpuGet()->taskLockCnt == 0);
|
||||
if (!preemptable) {
|
||||
/* Set schedule flag if preemption is disabled */
|
||||
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return preemptable;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsPreemptableInSched(VOID)
|
||||
{
|
||||
BOOL preemptable = FALSE;
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
/*
|
||||
* For smp systems, schedule must hold the task spinlock, and this counter
|
||||
* will increase by 1 in that case.
|
||||
*/
|
||||
preemptable = (OsPercpuGet()->taskLockCnt == 1);
|
||||
|
||||
#else
|
||||
preemptable = (OsPercpuGet()->taskLockCnt == 0);
|
||||
#endif
|
||||
if (!preemptable) {
|
||||
/* Set schedule flag if preemption is disabled */
|
||||
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
|
||||
}
|
||||
|
||||
return preemptable;
|
||||
}
|
||||
|
||||
/*
|
||||
* This function simply picks the next task and switches to it.
|
||||
* Current task needs to already be in the right state or the right
|
||||
* queues it needs to be in.
|
||||
*/
|
||||
extern VOID OsSchedResched(VOID);
|
||||
|
||||
/*
|
||||
* This function put the current task back to the ready queue and
|
||||
* try to do the schedule. However, the schedule won't be definitely
|
||||
* taken place while there're no other higher priority tasks or locked.
|
||||
*/
|
||||
extern VOID OsSchedPreempt(VOID);
|
||||
|
||||
/*
|
||||
* Just like OsSchedPreempt, except this function will do the OS_INT_ACTIVE
|
||||
* check, in case the schedule taken place in the middle of an interrupt.
|
||||
*/
|
||||
STATIC INLINE VOID LOS_Schedule(VOID)
|
||||
{
|
||||
if (OS_INT_ACTIVE) {
|
||||
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
|
||||
return;
|
||||
}
|
||||
|
||||
/*
|
||||
* trigger schedule in task will also do the slice check
|
||||
* if neccessary, it will give up the timeslice more in time.
|
||||
* otherwhise, there's no other side effects.
|
||||
*/
|
||||
OsSchedPreempt();
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SCHED_PRI_H */
|
||||
87
kernel/base/include/los_sem_debug_pri.h
Executable file
87
kernel/base/include/los_sem_debug_pri.h
Executable file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SEM_DEBUG_PRI_H
|
||||
#define _LOS_SEM_DEBUG_PRI_H
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_sem_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* semaphore debug initialization interface */
|
||||
extern UINT32 OsSemDbgInit(VOID);
|
||||
STATIC INLINE UINT32 OsSemDbgInitHook(VOID)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_SEMAPHORE
|
||||
return OsSemDbgInit();
|
||||
#else
|
||||
return LOS_OK;
|
||||
#endif
|
||||
}
|
||||
/* Update the last time the semaphore was executed */
|
||||
extern VOID OsSemDbgTimeUpdate(UINT32 semID);
|
||||
STATIC INLINE VOID OsSemDbgTimeUpdateHook(UINT32 semID)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_SEMAPHORE
|
||||
OsSemDbgTimeUpdate(semID);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
/* Update the SEM_DEBUG_CB of the semaphore when created or deleted */
|
||||
extern VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creater, UINT16 count);
|
||||
STATIC INLINE VOID OsSemDbgUpdateHook(UINT32 semID, TSK_ENTRY_FUNC creater, UINT16 count)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_SEMAPHORE
|
||||
OsSemDbgUpdate(semID, creater, count);
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
/* get the full data of SEM_DFX_CB */
|
||||
extern UINT32 OsSemInfoGetFullData(VOID);
|
||||
STATIC INLINE VOID OsSemInfoGetFullDataHook(VOID)
|
||||
{
|
||||
#ifdef LOSCFG_DEBUG_SEMAPHORE
|
||||
(VOID)OsSemInfoGetFullData();
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SEM_DEBUG_PRI_H */
|
||||
120
kernel/base/include/los_sem_pri.h
Executable file
120
kernel/base/include/los_sem_pri.h
Executable file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SEM_PRI_H
|
||||
#define _LOS_SEM_PRI_H
|
||||
|
||||
#include "los_sem.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* Semaphore control structure.
|
||||
*/
|
||||
typedef struct {
|
||||
UINT8 semStat; /**< Semaphore state */
|
||||
UINT16 semCount; /**< Number of available semaphores */
|
||||
UINT16 maxSemCount; /**< Max number of available semaphores */
|
||||
UINT32 semID; /**< Semaphore control structure ID */
|
||||
LOS_DL_LIST semList; /**< Queue of tasks that are waiting on a semaphore */
|
||||
} LosSemCB;
|
||||
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* The semaphore is not in use.
|
||||
*
|
||||
*/
|
||||
#define OS_SEM_UNUSED 0
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* The semaphore is used.
|
||||
*
|
||||
*/
|
||||
#define OS_SEM_USED 1
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* Obtain the head node in a semaphore doubly linked list.
|
||||
*
|
||||
*/
|
||||
#define GET_SEM_LIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosSemCB, semList)
|
||||
extern LosSemCB *g_allSem;
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* COUNT | INDEX split bit
|
||||
*/
|
||||
#define SEM_SPLIT_BIT 16
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* Set the semaphore id
|
||||
*/
|
||||
#define SET_SEM_ID(count, semID) (((count) << SEM_SPLIT_BIT) | (semID))
|
||||
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* get the semaphore index
|
||||
*/
|
||||
#define GET_SEM_INDEX(semID) ((semID) & ((1U << SEM_SPLIT_BIT) - 1))
|
||||
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* get the semaphore count
|
||||
*/
|
||||
#define GET_SEM_COUNT(semID) ((semID) >> SEM_SPLIT_BIT)
|
||||
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* Obtain a semaphore ID.
|
||||
*
|
||||
*/
|
||||
#define GET_SEM(semID) (((LosSemCB *)g_allSem) + GET_SEM_INDEX(semID))
|
||||
|
||||
/**
|
||||
* @ingroup los_sem
|
||||
* Maximum value of task information.
|
||||
*
|
||||
*/
|
||||
#define OS_MAX_PENDTASK_INFO 4
|
||||
|
||||
extern UINT32 OsSemInit(VOID);
|
||||
extern UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SEM_PRI_H */
|
||||
198
kernel/base/include/los_signal.h
Executable file
198
kernel/base/include/los_signal.h
Executable file
@@ -0,0 +1,198 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SIGNAL_H
|
||||
#define _LOS_SIGNAL_H
|
||||
|
||||
#include <stddef.h>
|
||||
#include <limits.h>
|
||||
#include <sys/types.h>
|
||||
#include <signal.h>
|
||||
#include "los_event.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define LOS_BIT_SET(val, bit) ((val) = (val) | (1ULL << (UINT32)(bit)))
|
||||
#define LOS_BIT_CLR(val, bit) ((val) = (val) & ~(1ULL << (UINT32)(bit)))
|
||||
#define LOS_IS_BIT_SET(val, bit) (bool)((((val) >> (UINT32)(bit)) & 1ULL))
|
||||
|
||||
#define OS_SYSCALL_SET_CPSR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs) - 4)) = (cpsr))
|
||||
#define OS_SYSCALL_SET_SR(regs, cpsr) (*((unsigned long *)((UINTPTR)(regs))) = (cpsr))
|
||||
#define OS_SYSCALL_GET_CPSR(regs) (*((unsigned long *)((UINTPTR)(regs) - 4)))
|
||||
#define SIG_STOP_VISIT 1
|
||||
|
||||
#define OS_KERNEL_KILL_PERMISSION 0U
|
||||
#define OS_USER_KILL_PERMISSION 3U
|
||||
|
||||
#define OS_RETURN_IF(expr, errcode) \
|
||||
if ((expr)) { \
|
||||
return errcode; \
|
||||
}
|
||||
|
||||
#define OS_RETURN_IF_VOID(expr) \
|
||||
if ((expr)) { \
|
||||
return; \
|
||||
}
|
||||
#define OS_GOTO_EXIT_IF(expr, errcode) \
|
||||
if (expr) { \
|
||||
ret = errcode; \
|
||||
goto EXIT; \
|
||||
}
|
||||
#define OS_GOTO_EXIT_IF_ONLY(expr) \
|
||||
if (expr) { \
|
||||
goto EXIT; \
|
||||
}
|
||||
|
||||
#define OS_RETURN_VOID_IF_NULL(pPara) \
|
||||
if (NULL == (pPara)) { \
|
||||
return; \
|
||||
}
|
||||
#define OS_RETURN_IF_NULL(pPara) \
|
||||
if (NULL == (pPara)) { \
|
||||
return (-EINVAL); \
|
||||
}
|
||||
|
||||
#define OS_GOTO_EXIT_IF_NULL(pPara) \
|
||||
if (NULL == (pPara)) { \
|
||||
ret = -EINVAL; \
|
||||
goto EXIT; \
|
||||
}
|
||||
|
||||
typedef void (*sa_sighandler_t)(int);
|
||||
typedef void (*sa_siginfoaction_t)(int, siginfo_t *, void *);
|
||||
|
||||
#define SIGNO2SET(s) ((sigset_t)1ULL << (s))
|
||||
#define NULL_SIGNAL_SET ((sigset_t)0ULL)
|
||||
#define FULL_SIGNAL_SET ((sigset_t)~0ULL)
|
||||
|
||||
static inline int GOOD_SIGNO(unsigned int sig)
|
||||
{
|
||||
return (sig < _NSIG) ? 1 : 0;
|
||||
}
|
||||
|
||||
#define MAX_SIG_ARRAY_IN_MUSL 128
|
||||
|
||||
typedef struct {
|
||||
unsigned long sig[MAX_SIG_ARRAY_IN_MUSL / sizeof(unsigned long)];
|
||||
} sigset_t_l;
|
||||
|
||||
typedef struct sigaction sigaction_t;
|
||||
|
||||
struct sigactq {
|
||||
struct sigactq *flink; /* Forward link */
|
||||
sigaction_t act; /* Sigaction data */
|
||||
uint8_t signo; /* Signal associated with action */
|
||||
};
|
||||
typedef struct sigactq sigactq_t;
|
||||
|
||||
struct sq_entry_s {
|
||||
struct sq_entry_s *flink;
|
||||
};
|
||||
typedef struct sq_entry_s sq_entry_t;
|
||||
|
||||
struct sigpendq {
|
||||
struct sigpendq *flink; /* Forward link */
|
||||
siginfo_t info; /* Signal information */
|
||||
uint8_t type; /* (Used to manage allocations) */
|
||||
};
|
||||
typedef struct sigpendq sigpendq_t;
|
||||
|
||||
struct sq_queue_s {
|
||||
sq_entry_t *head;
|
||||
sq_entry_t *tail;
|
||||
};
|
||||
typedef struct sq_queue_s sq_queue_t;
|
||||
|
||||
#define TASK_IRQ_CONTEXT \
|
||||
unsigned int R0; \
|
||||
unsigned int R1; \
|
||||
unsigned int R2; \
|
||||
unsigned int R3; \
|
||||
unsigned int R12; \
|
||||
unsigned int USP; \
|
||||
unsigned int ULR; \
|
||||
unsigned int CPSR; \
|
||||
unsigned int PC;
|
||||
|
||||
typedef struct {
|
||||
TASK_IRQ_CONTEXT
|
||||
} TaskIrqDataSize;
|
||||
|
||||
typedef struct {
|
||||
TASK_IRQ_CONTEXT
|
||||
unsigned int R7;
|
||||
unsigned int count;
|
||||
} sig_switch_context;
|
||||
|
||||
typedef struct {
|
||||
sigset_t sigFlag;
|
||||
sigset_t sigPendFlag;
|
||||
sigset_t sigprocmask; /* Signals that are blocked */
|
||||
sq_queue_t sigactionq;
|
||||
LOS_DL_LIST waitList;
|
||||
sigset_t sigwaitmask; /* Waiting for pending signals */
|
||||
siginfo_t sigunbinfo; /* Signal info when task unblocked */
|
||||
sig_switch_context context;
|
||||
} sig_cb;
|
||||
|
||||
#define SIGEV_THREAD_ID 4
|
||||
|
||||
int sys_sigqueue(pid_t, int, const union sigval);
|
||||
int sys_sigpending(sigset_t *);
|
||||
int sys_rt_sigtimedwait(const sigset_t *mask, siginfo_t *si, const struct timespec *ts, size_t sigsetsize);
|
||||
int sys_sigsuspend(const sigset_t *);
|
||||
int OsKillLock(pid_t pid, int sig);
|
||||
int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact);
|
||||
int OsSigprocMask(int how, const sigset_t_l *set, sigset_t_l *oldset);
|
||||
int OsPthreadKill(UINT32 tid, int signo);
|
||||
int OsSigEmptySet(sigset_t *);
|
||||
int OsSigAddSet(sigset_t *, int);
|
||||
int OsSigIsMember(const sigset_t *, int);
|
||||
void OsSaveSignalContext(unsigned int *sp);
|
||||
void OsRestorSignalContext(unsigned int *sp);
|
||||
int OsKill(pid_t pid, int sig, int permission);
|
||||
int OsDispatch(pid_t pid, siginfo_t *info, int permission);
|
||||
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout);
|
||||
int OsPause(void);
|
||||
int OsSigPending(sigset_t *set);
|
||||
int OsSigSuspend(const sigset_t *set);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SIGNAL_H */
|
||||
108
kernel/base/include/los_sortlink_pri.h
Executable file
108
kernel/base/include/los_sortlink_pri.h
Executable file
@@ -0,0 +1,108 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SORTLINK_PRI_H
|
||||
#define _LOS_SORTLINK_PRI_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_list.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/*
|
||||
* Sortlink Rollnum Structure:
|
||||
* ------------------------------------------
|
||||
* | 31 | 30 | 29 |.......| 4 | 3 | 2 | 1 | 0 |
|
||||
* ------------------------------------------
|
||||
* |<-High Bits->|<---------Low Bits--------->|
|
||||
*
|
||||
* Low Bits : circles
|
||||
* High Bits : sortlink index
|
||||
*/
|
||||
#define OS_TSK_HIGH_BITS 3U
|
||||
#define OS_TSK_LOW_BITS (32U - OS_TSK_HIGH_BITS)
|
||||
#define OS_TSK_SORTLINK_LOGLEN OS_TSK_HIGH_BITS
|
||||
#define OS_TSK_SORTLINK_LEN (1U << OS_TSK_SORTLINK_LOGLEN)
|
||||
#define OS_TSK_SORTLINK_MASK (OS_TSK_SORTLINK_LEN - 1U)
|
||||
#define OS_TSK_MAX_ROLLNUM (0xFFFFFFFFU - OS_TSK_SORTLINK_LEN)
|
||||
#define OS_TSK_HIGH_BITS_MASK (OS_TSK_SORTLINK_MASK << OS_TSK_LOW_BITS)
|
||||
#define OS_TSK_LOW_BITS_MASK (~OS_TSK_HIGH_BITS_MASK)
|
||||
|
||||
#define EVALUATE_L(NUM, VALUE) NUM = (((NUM) & OS_TSK_HIGH_BITS_MASK) | (VALUE))
|
||||
|
||||
#define EVALUATE_H(NUM, VALUE) NUM = (((NUM) & OS_TSK_LOW_BITS_MASK) | ((VALUE) << OS_TSK_LOW_BITS))
|
||||
|
||||
#define ROLLNUM_SUB(NUM1, NUM2) \
|
||||
NUM1 = (((NUM1) & OS_TSK_HIGH_BITS_MASK) | \
|
||||
(ROLLNUM(NUM1) - ROLLNUM(NUM2)))
|
||||
|
||||
#define ROLLNUM_ADD(NUM1, NUM2) \
|
||||
NUM1 = (((NUM1) & OS_TSK_HIGH_BITS_MASK) | \
|
||||
(ROLLNUM(NUM1) + ROLLNUM(NUM2)))
|
||||
|
||||
#define ROLLNUM_DEC(NUM) NUM = ((NUM) - 1)
|
||||
|
||||
#define ROLLNUM(NUM) ((NUM) & OS_TSK_LOW_BITS_MASK)
|
||||
|
||||
#define SORT_INDEX(NUM) ((NUM) >> OS_TSK_LOW_BITS)
|
||||
|
||||
#define SET_SORTLIST_VALUE(sortList, value) (((SortLinkList *)(sortList))->idxRollNum = (value))
|
||||
|
||||
typedef struct {
|
||||
LOS_DL_LIST sortLinkNode;
|
||||
UINT32 idxRollNum;
|
||||
} SortLinkList;
|
||||
|
||||
typedef struct {
|
||||
LOS_DL_LIST *sortLink;
|
||||
UINT16 cursor;
|
||||
UINT16 reserved;
|
||||
} SortLinkAttribute;
|
||||
|
||||
extern UINT32 OsSortLinkInit(SortLinkAttribute *sortLinkHeader);
|
||||
extern VOID OsAdd2SortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList);
|
||||
extern VOID OsDeleteSortLink(const SortLinkAttribute *sortLinkHeader, SortLinkList *sortList);
|
||||
extern UINT32 OsSortLinkGetNextExpireTime(const SortLinkAttribute *sortLinkHeader);
|
||||
extern UINT32 OsSortLinkGetTargetExpireTime(const SortLinkAttribute *sortLinkHeader,
|
||||
const SortLinkList *targetSortList);
|
||||
extern VOID OsSortLinkUpdateExpireTime(UINT32 sleepTicks, SortLinkAttribute *sortLinkHeader);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SORTLINK_PRI_H */
|
||||
84
kernel/base/include/los_stackinfo_pri.h
Executable file
84
kernel/base/include/los_stackinfo_pri.h
Executable file
@@ -0,0 +1,84 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_STACK_INFO_PRI_H
|
||||
#define _LOS_STACK_INFO_PRI_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "arch_config.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
VOID *stackTop;
|
||||
UINT32 stackSize;
|
||||
CHAR *stackName;
|
||||
} StackInfo;
|
||||
|
||||
#define OS_INVALID_WATERLINE 0xFFFFFFFF
|
||||
#define OS_STACK_MAGIC_CHECK(topstack) (*(UINTPTR *)(topstack) == OS_STACK_MAGIC_WORD) /* 1:magic valid 0:unvalid */
|
||||
|
||||
extern VOID OsExcStackInfo(VOID);
|
||||
extern VOID OsExcStackInfoReg(const StackInfo *stackInfo, UINT32 stackNum);
|
||||
extern VOID OsStackInit(VOID *stacktop, UINT32 stacksize);
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* @brief Get stack waterline.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to get stack waterline size and check stack whether overflow.
|
||||
*
|
||||
* @attention None
|
||||
*
|
||||
* @param stackBottom [IN] Type #const UINTPTR * pointer to stack bottom.
|
||||
* @param stackTop [IN] Type #const UINTPTR * pointer to stack top.
|
||||
* @param peakUsed [OUT] Type #UINT32 * stack waterline.
|
||||
*
|
||||
* @retval #LOS_NOK stack overflow
|
||||
* @retval #LOS_OK stack is normal, not overflow
|
||||
* @par Dependency:
|
||||
* <ul><li>los_stackinfo_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
extern UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_STACK_INFO_PRI_H */
|
||||
59
kernel/base/include/los_stat_pri.h
Executable file
59
kernel/base/include/los_stat_pri.h
Executable file
@@ -0,0 +1,59 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LOS_STAT_PRI_H
|
||||
#define __LOS_STAT_PRI_H
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
UINT64 runtime;
|
||||
UINT32 contexSwitch;
|
||||
} SchedPercpu;
|
||||
|
||||
typedef struct {
|
||||
UINT64 startRuntime;
|
||||
UINT64 allRuntime;
|
||||
UINT32 allContextSwitch;
|
||||
SchedPercpu schedPercpu[LOSCFG_KERNEL_SMP_CORE_NUM];
|
||||
} SchedStat;
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_STAT_PRI_H */
|
||||
114
kernel/base/include/los_swtmr_pri.h
Executable file
114
kernel/base/include/los_swtmr_pri.h
Executable file
@@ -0,0 +1,114 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SWTMR_PRI_H
|
||||
#define _LOS_SWTMR_PRI_H
|
||||
|
||||
#include "los_swtmr.h"
|
||||
#include "los_spinlock.h"
|
||||
|
||||
#ifdef LOSCFG_SECURITY_VID
|
||||
#include "vid_api.h"
|
||||
#else
|
||||
#define MAX_INVALID_TIMER_VID OS_SWTMR_MAX_TIMERID
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @ingroup los_swtmr_pri
|
||||
* Software timer state
|
||||
*/
|
||||
enum SwtmrState {
|
||||
OS_SWTMR_STATUS_UNUSED, /**< The software timer is not used. */
|
||||
OS_SWTMR_STATUS_CREATED, /**< The software timer is created. */
|
||||
OS_SWTMR_STATUS_TICKING /**< The software timer is timing. */
|
||||
};
|
||||
|
||||
/**
|
||||
* @ingroup los_swtmr_pri
|
||||
* Structure of the callback function that handles software timer timeout
|
||||
*/
|
||||
typedef struct {
|
||||
SWTMR_PROC_FUNC handler; /**< Callback function that handles software timer timeout */
|
||||
UINTPTR arg; /**< Parameter passed in when the callback function
|
||||
that handles software timer timeout is called */
|
||||
} SwtmrHandlerItem;
|
||||
|
||||
/**
|
||||
* @ingroup los_swtmr_pri
|
||||
* Type of the pointer to the structure of the callback function that handles software timer timeout
|
||||
*/
|
||||
typedef SwtmrHandlerItem *SwtmrHandlerItemPtr;
|
||||
|
||||
extern SWTMR_CTRL_S *g_swtmrCBArray;
|
||||
|
||||
extern SortLinkAttribute g_swtmrSortLink; /* The software timer count list */
|
||||
|
||||
#define OS_SWT_FROM_SID(swtmrID) ((SWTMR_CTRL_S *)g_swtmrCBArray + ((swtmrID) % LOSCFG_BASE_CORE_SWTMR_LIMIT))
|
||||
|
||||
/**
|
||||
* @ingroup los_swtmr_pri
|
||||
* @brief Scan a software timer.
|
||||
*
|
||||
* @par Description:
|
||||
* <ul>
|
||||
* <li>This API is used to scan a software timer when a Tick interrupt occurs and determine whether
|
||||
* the software timer expires.</li>
|
||||
* </ul>
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_swtmr_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see LOS_SwtmrStop
|
||||
*/
|
||||
extern VOID OsSwtmrScan(VOID);
|
||||
extern UINT32 OsSwtmrInit(VOID);
|
||||
extern VOID OsSwtmrTask(VOID);
|
||||
extern VOID OsSwtmrRecycle(UINT32 processID);
|
||||
extern SPIN_LOCK_S g_swtmrSpin;
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SWTMR_PRI_H */
|
||||
104
kernel/base/include/los_sys_pri.h
Executable file
104
kernel/base/include/los_sys_pri.h
Executable file
@@ -0,0 +1,104 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_SYS_PRI_H
|
||||
#define _LOS_SYS_PRI_H
|
||||
|
||||
#include "los_sys.h"
|
||||
#include "los_base_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* Number of milliseconds in one second.
|
||||
*/
|
||||
#define OS_SYS_MS_PER_SECOND 1000
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* Number of microseconds in one second.
|
||||
*/
|
||||
#define OS_SYS_US_PER_SECOND 1000000
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* Number of nanoseconds in one second.
|
||||
*/
|
||||
#define OS_SYS_NS_PER_SECOND 1000000000
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* Number of microseconds in one milliseconds.
|
||||
*/
|
||||
#define OS_SYS_US_PER_MS 1000
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* Number of nanoseconds in one milliseconds.
|
||||
*/
|
||||
#define OS_SYS_NS_PER_MS 1000000
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* Number of nanoseconds in one microsecond.
|
||||
*/
|
||||
#define OS_SYS_NS_PER_US 1000
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* The maximum length of name.
|
||||
*/
|
||||
#define OS_SYS_APPVER_NAME_MAX 64
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* The magic word.
|
||||
*/
|
||||
#define OS_SYS_MAGIC_WORD 0xAAAAAAAA
|
||||
|
||||
/**
|
||||
* @ingroup los_sys
|
||||
* The initialization value of stack space.
|
||||
*/
|
||||
#define OS_SYS_EMPTY_STACK 0xCACACACA
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_SYS_PRI_H */
|
||||
587
kernel/base/include/los_task_pri.h
Executable file
587
kernel/base/include/los_task_pri.h
Executable file
@@ -0,0 +1,587 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_TASK_PRI_H
|
||||
#define _LOS_TASK_PRI_H
|
||||
|
||||
#include "los_task.h"
|
||||
#include "los_sched_pri.h"
|
||||
#include "los_sortlink_pri.h"
|
||||
#include "los_spinlock.h"
|
||||
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES)
|
||||
#include "los_stat_pri.h"
|
||||
#endif
|
||||
#include "los_stackinfo_pri.h"
|
||||
#include "los_futex_pri.h"
|
||||
#include "los_signal.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Define task siginal types.
|
||||
*
|
||||
* Task siginal types.
|
||||
*/
|
||||
#define SIGNAL_NONE 0U
|
||||
#define SIGNAL_KILL (1U << 0)
|
||||
#define SIGNAL_SUSPEND (1U << 1)
|
||||
#define SIGNAL_AFFI (1U << 2)
|
||||
|
||||
/* scheduler lock */
|
||||
extern SPIN_LOCK_S g_taskSpin;
|
||||
#define SCHEDULER_LOCK(state) LOS_SpinLockSave(&g_taskSpin, &(state))
|
||||
#define SCHEDULER_UNLOCK(state) LOS_SpinUnlockRestore(&g_taskSpin, state)
|
||||
|
||||
/* default and non-running task's ownership id */
|
||||
#define OS_TASK_INVALID_CPUID 0xFFFF
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Null task ID
|
||||
*
|
||||
*/
|
||||
#define OS_TASK_ERRORID 0xFFFFFFFF
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Define a usable task priority.
|
||||
*
|
||||
* Highest task priority.
|
||||
*/
|
||||
#define OS_TASK_PRIORITY_HIGHEST 0
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Define a usable task priority.
|
||||
*
|
||||
* Lowest task priority.
|
||||
*/
|
||||
#define OS_TASK_PRIORITY_LOWEST 31
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is init.
|
||||
*/
|
||||
#define OS_TASK_STATUS_INIT 0x0001U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is ready.
|
||||
*/
|
||||
#define OS_TASK_STATUS_READY 0x0002U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is running.
|
||||
*/
|
||||
#define OS_TASK_STATUS_RUNNING 0x0004U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is suspended.
|
||||
*/
|
||||
#define OS_TASK_STATUS_SUSPEND 0x0008U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is blocked.
|
||||
*/
|
||||
#define OS_TASK_STATUS_PEND 0x0010U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is delayed.
|
||||
*/
|
||||
#define OS_TASK_STATUS_DELAY 0x0020U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The time for waiting for an event to occur expires.
|
||||
*/
|
||||
#define OS_TASK_STATUS_TIMEOUT 0x0040U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is pend for a period of time.
|
||||
*/
|
||||
#define OS_TASK_STATUS_PEND_TIME 0x0080U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is exit.
|
||||
*/
|
||||
#define OS_TASK_STATUS_EXIT 0x0100U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task control block is unused.
|
||||
*/
|
||||
#define OS_TASK_STATUS_UNUSED 0x0200U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is joinable.
|
||||
*/
|
||||
#define OS_TASK_FLAG_PTHREAD_JOIN 0x0400U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task or task control block status.
|
||||
*
|
||||
* The task is status detached.
|
||||
*/
|
||||
#define OS_TASK_FLAG_DETACHED 0x0800U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task property.
|
||||
*
|
||||
* The task is idle task, Belong to idle process.
|
||||
*/
|
||||
#define OS_TASK_FLAG_IDLEFLAG 0x1000U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task property.
|
||||
*
|
||||
* The task is system-level task, like idle, swtmr and etc.
|
||||
*/
|
||||
#define OS_TASK_FLAG_SYSTEM_TASK 0x2000U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Flag that indicates the task property.
|
||||
*
|
||||
* Specifies the process creation task.
|
||||
*/
|
||||
#define OS_TASK_FLAG_SPECIFIES_PROCESS 0x4000U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Boundary on which the stack size is aligned.
|
||||
*
|
||||
*/
|
||||
#define OS_TASK_STACK_SIZE_ALIGN 16U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Boundary on which the stack address is aligned.
|
||||
*
|
||||
*/
|
||||
#define OS_TASK_STACK_ADDR_ALIGN 8U
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Number of usable task priorities.
|
||||
*/
|
||||
#define OS_TSK_PRINUM (OS_TASK_PRIORITY_LOWEST - OS_TASK_PRIORITY_HIGHEST + 1)
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* @brief Check whether a task ID is valid.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to check whether a task ID, excluding the idle task ID, is valid.
|
||||
* @attention None.
|
||||
*
|
||||
* @param taskID [IN] Task ID.
|
||||
*
|
||||
* @retval 0 or 1. One indicates that the task ID is invalid, whereas zero indicates that the task ID is valid.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
#define OS_TSK_GET_INDEX(taskID) (taskID)
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* @brief Obtain the pointer to a task control block.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the pointer to a task control block using a corresponding parameter.
|
||||
* @attention None.
|
||||
*
|
||||
* @param ptr [IN] Parameter used for obtaining the task control block.
|
||||
*
|
||||
* @retval Pointer to the task control block.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
#define OS_TCB_FROM_PENDLIST(ptr) LOS_DL_LIST_ENTRY(ptr, LosTaskCB, pendList)
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* @brief Obtain the pointer to a task control block.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to obtain the pointer to a task control block that has a specified task ID.
|
||||
* @attention None.
|
||||
*
|
||||
* @param TaskID [IN] Task ID.
|
||||
*
|
||||
* @retval Pointer to the task control block.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
#define OS_TCB_FROM_TID(taskID) (((LosTaskCB *)g_taskCBArray) + (taskID))
|
||||
|
||||
#ifndef LOSCFG_STACK_POINT_ALIGN_SIZE
|
||||
#define LOSCFG_STACK_POINT_ALIGN_SIZE (sizeof(UINTPTR) * 2)
|
||||
#endif
|
||||
|
||||
#define OS_TASK_RESOURCE_STATCI_SIZE 0x1000
|
||||
#define OS_TASK_RESOURCE_FREE_PRIORITY 5
|
||||
#define OS_RESOURCE_EVENT_MASK 0xFF
|
||||
#define OS_RESOURCE_EVENT_OOM 0x02
|
||||
#define OS_RESOURCE_EVENT_FREE 0x04
|
||||
#define OS_TCB_NAME_LEN 32
|
||||
|
||||
typedef struct {
|
||||
VOID *stackPointer; /**< Task stack pointer */
|
||||
UINT16 taskStatus; /**< Task status */
|
||||
UINT16 priority; /**< Task priority */
|
||||
UINT16 policy;
|
||||
UINT16 timeSlice; /**< Remaining time slice */
|
||||
UINT32 stackSize; /**< Task stack size */
|
||||
UINTPTR topOfStack; /**< Task stack top */
|
||||
UINT32 taskID; /**< Task ID */
|
||||
TSK_ENTRY_FUNC taskEntry; /**< Task entrance function */
|
||||
VOID *joinRetval; /**< pthread adaption */
|
||||
VOID *taskSem; /**< Task-held semaphore */
|
||||
VOID *taskMux; /**< Task-held mutex */
|
||||
VOID *taskEvent; /**< Task-held event */
|
||||
UINTPTR args[4]; /**< Parameter, of which the maximum number is 4 */
|
||||
CHAR taskName[OS_TCB_NAME_LEN]; /**< Task name */
|
||||
LOS_DL_LIST pendList; /**< Task pend node */
|
||||
LOS_DL_LIST threadList; /**< thread list */
|
||||
SortLinkList sortList; /**< Task sortlink node */
|
||||
UINT32 eventMask; /**< Event mask */
|
||||
UINT32 eventMode; /**< Event mode */
|
||||
UINT32 priBitMap; /**< BitMap for recording the change of task priority,
|
||||
the priority can not be greater than 31 */
|
||||
INT32 errorNo; /**< Error Num */
|
||||
UINT32 signal; /**< Task signal */
|
||||
sig_cb sig;
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
UINT16 currCpu; /**< CPU core number of this task is running on */
|
||||
UINT16 lastCpu; /**< CPU core number of this task is running on last time */
|
||||
UINT16 cpuAffiMask; /**< CPU affinity mask, support up to 16 cores */
|
||||
UINT32 timerCpu; /**< CPU core number of this task is delayed or pended */
|
||||
#if (LOSCFG_KERNEL_SMP_TASK_SYNC == YES)
|
||||
UINT32 syncSignal; /**< Synchronization for signal handling */
|
||||
#endif
|
||||
#if (LOSCFG_KERNEL_SMP_LOCKDEP == YES)
|
||||
LockDep lockDep;
|
||||
#endif
|
||||
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES)
|
||||
SchedStat schedStat; /**< Schedule statistics */
|
||||
#endif
|
||||
#endif
|
||||
UINTPTR userArea;
|
||||
UINTPTR userMapBase;
|
||||
UINT32 userMapSize; /**< user thread stack size ,real size : userMapSize + USER_STACK_MIN_SIZE */
|
||||
UINT32 processID; /**< Which belong process */
|
||||
FutexNode futex;
|
||||
LOS_DL_LIST joinList; /**< join list */
|
||||
LOS_DL_LIST lockList; /**< Hold the lock list */
|
||||
UINT32 waitID; /**< Wait for the PID or GID of the child process */
|
||||
UINT16 waitFlag; /**< The type of child process that is waiting, belonging to a group or parent,
|
||||
a specific child process, or any child process */
|
||||
#if (LOSCFG_KERNEL_LITEIPC == YES)
|
||||
UINT32 ipcStatus;
|
||||
LOS_DL_LIST msgListHead;
|
||||
BOOL accessMap[LOSCFG_BASE_CORE_TSK_LIMIT];
|
||||
#endif
|
||||
} LosTaskCB;
|
||||
|
||||
typedef struct {
|
||||
LosTaskCB *runTask;
|
||||
LosTaskCB *newTask;
|
||||
} LosTask;
|
||||
|
||||
struct ProcessSignalInfo {
|
||||
siginfo_t *sigInfo; /**< Signal to be dispatched */
|
||||
LosTaskCB *defaultTcb; /**< Default TCB */
|
||||
LosTaskCB *unblockedTcb; /**< The signal unblock on this TCB*/
|
||||
LosTaskCB *awakenedTcb; /**< This TCB was awakened */
|
||||
LosTaskCB *receivedTcb; /**< This TCB received the signal */
|
||||
};
|
||||
|
||||
typedef int (*ForEachTaskCB)(LosTaskCB *tcb, void *arg);
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Maximum number of tasks.
|
||||
*
|
||||
*/
|
||||
extern UINT32 g_taskMaxNum;
|
||||
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Starting address of a task.
|
||||
*
|
||||
*/
|
||||
extern LosTaskCB *g_taskCBArray;
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* Time slice structure.
|
||||
*/
|
||||
typedef struct {
|
||||
LosTaskCB *task; /**< Current running task */
|
||||
UINT16 time; /**< Expiration time point */
|
||||
UINT16 timeout; /**< Expiration duration */
|
||||
} OsTaskRobin;
|
||||
|
||||
STATIC INLINE LosTaskCB *OsCurrTaskGet(VOID)
|
||||
{
|
||||
return (LosTaskCB *)ArchCurrTaskGet();
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCurrTaskSet(LosTaskCB *task)
|
||||
{
|
||||
ArchCurrTaskSet(task);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCurrUserTaskSet(UINTPTR thread)
|
||||
{
|
||||
ArchCurrUserTaskSet(thread);
|
||||
}
|
||||
|
||||
STATIC INLINE LosTaskCB *OsGetTaskCB(UINT32 taskID)
|
||||
{
|
||||
return OS_TCB_FROM_TID(taskID);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsTaskIsUnused(const LosTaskCB *taskCB)
|
||||
{
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsTaskIsRunning(const LosTaskCB *taskCB)
|
||||
{
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsTaskIsInactive(const LosTaskCB *taskCB)
|
||||
{
|
||||
if (taskCB->taskStatus & (OS_TASK_STATUS_UNUSED | OS_TASK_STATUS_INIT | OS_TASK_STATUS_EXIT)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#define OS_TID_CHECK_INVALID(taskID) ((UINT32)(taskID) >= g_taskMaxNum)
|
||||
|
||||
/* get task info */
|
||||
#define OS_ALL_TASK_MASK 0xFFFFFFFF
|
||||
|
||||
#define OS_PROCESS_PRI_QUEUE_SIZE(processCB) OsPriQueueProcessSize(g_priQueueList, (processCB)->priority)
|
||||
|
||||
#define OS_TASK_PRI_QUEUE_ENQUEUE(processCB, taskCB) \
|
||||
OsPriQueueEnqueue((processCB)->threadPriQueueList, &((processCB)->threadScheduleMap), \
|
||||
&((taskCB)->pendList), (taskCB)->priority)
|
||||
|
||||
#define OS_TASK_PRI_QUEUE_ENQUEUE_HEAD(processCB, taskCB) \
|
||||
OsPriQueueEnqueueHead((processCB)->threadPriQueueList, &((processCB)->threadScheduleMap), \
|
||||
&((taskCB)->pendList), (taskCB)->priority)
|
||||
|
||||
#define OS_TASK_PRI_QUEUE_DEQUEUE(processCB, taskCB) \
|
||||
OsPriQueueDequeue((processCB)->threadPriQueueList, &((processCB)->threadScheduleMap), &((taskCB)->pendList))
|
||||
|
||||
|
||||
#define OS_TASK_SCHED_QUEUE_ENQUEUE(taskCB, status) OsTaskSchedQueueEnqueue(taskCB, status)
|
||||
#define OS_TASK_SCHED_QUEUE_DEQUEUE(taskCB, status) OsTaskSchedQueueDequeue(taskCB, status)
|
||||
|
||||
#define OS_PROCESS_PRI_QUEUE_ENQUEUE(processCB) \
|
||||
OsPriQueueEnqueue(g_priQueueList, &g_priQueueBitmap, &((processCB)->pendList), (processCB)->priority)
|
||||
#define OS_PROCESS_PRI_QUEUE_ENQUEUE_HEAD(processCB) \
|
||||
OsPriQueueEnqueueHead(g_priQueueList, &g_priQueueBitmap, &((processCB)->pendList), (processCB)->priority)
|
||||
#define OS_PROCESS_PRI_QUEUE_DEQUEUE(processCB) OsPriQueueProcessDequeue(&((processCB)->pendList))
|
||||
|
||||
#define OS_TASK_PRI_QUEUE_SIZE(processCB, taskCB) OsPriQueueSize((processCB)->threadPriQueueList, (taskCB)->priority)
|
||||
#define OS_TASK_GET_NEW(processCB) LOS_DL_LIST_ENTRY(OsPriQueueTop((processCB)->threadPriQueueList, \
|
||||
&((processCB)->threadScheduleMap)), \
|
||||
LosTaskCB, pendList)
|
||||
|
||||
#define OS_PROCESS_GET_NEW() \
|
||||
LOS_DL_LIST_ENTRY(OsPriQueueTop(g_priQueueList, &g_priQueueBitmap), LosProcessCB, pendList)
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* @brief Modify the priority of task.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to modify the priority of task.
|
||||
*
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>The taskCB should be a correct pointer to task control block structure.</li>
|
||||
* <li>the priority should be in [0, OS_TASK_PRIORITY_LOWEST].</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param taskCB [IN] Type #LosTaskCB * pointer to task control block structure.
|
||||
* @param priority [IN] Type #UINT16 the priority of task.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see
|
||||
*/
|
||||
extern VOID OsTaskPriModify(LosTaskCB *taskCB, UINT16 priority);
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* @brief pend running task to pendlist
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to pend task to pendlist and add to sorted delay list.
|
||||
*
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>The list should be a vaild pointer to pendlist.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param list [IN] Type #LOS_DL_LIST * pointer to list which running task will be pended.
|
||||
* @param timeout [IN] Type #UINT32 Expiry time. The value range is [0,LOS_WAIT_FOREVER].
|
||||
* @param needSched [IN] Type #bool need sched
|
||||
*
|
||||
* @retval LOS_OK wait success
|
||||
* @retval LOS_NOK pend out
|
||||
* @par Dependency:
|
||||
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsTaskWake
|
||||
*/
|
||||
extern UINT32 OsTaskWait(LOS_DL_LIST *list, UINT32 timeout, BOOL needSched);
|
||||
|
||||
/**
|
||||
* @ingroup los_task
|
||||
* @brief delete task from pendlist.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is used to delete task from pendlist and also add to the priqueue.
|
||||
*
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>The resumedTask should be the task which will be add to priqueue.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param resumedTask [IN] Type #LosTaskCB * pointer to the task which will be add to priqueue.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_task_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see OsTaskWait
|
||||
*/
|
||||
extern VOID OsTaskWake(LosTaskCB *resumedTask);
|
||||
|
||||
extern UINT32 OsTaskSetDeatchUnsafe(LosTaskCB *taskCB);
|
||||
extern VOID OsTaskJoinPostUnsafe(LosTaskCB *taskCB);
|
||||
extern UINT32 OsTaskJoinPendUnsafe(LosTaskCB *taskCB);
|
||||
extern VOID OsTaskSchedule(LosTaskCB *, LosTaskCB *);
|
||||
extern VOID OsStartToRun(LosTaskCB *);
|
||||
extern VOID OsTaskScan(VOID);
|
||||
extern VOID OsIdleTask(VOID);
|
||||
extern UINT32 OsIdleTaskCreate(VOID);
|
||||
extern UINT32 OsTaskInit(VOID);
|
||||
extern UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv);
|
||||
extern UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqfile, UINT16 flag);
|
||||
extern VOID* OsGetMainTask(VOID);
|
||||
extern VOID OsSetMainTask(VOID);
|
||||
extern LosTaskCB* OsGetTopTask(VOID);
|
||||
extern UINT32 OsGetIdleTaskId(VOID);
|
||||
extern VOID OsTaskEntry(UINT32 taskID);
|
||||
extern SortLinkAttribute *OsTaskSortLinkGet(VOID);
|
||||
extern UINT32 OsTaskSwitchCheck(LosTaskCB *oldTask, LosTaskCB *newTask);
|
||||
extern UINT32 OsTaskProcSignal(VOID);
|
||||
extern VOID OsSchedStatistics(LosTaskCB *runTask, LosTaskCB *newTask);
|
||||
extern UINT32 OsTaskDeleteUnsafe(LosTaskCB *taskCB, UINT32 status, UINT32 intSave);
|
||||
extern VOID OsTaskResourcesToFree(LosTaskCB *taskCB);
|
||||
extern VOID OsRunTaskToDelete(LosTaskCB *taskCB);
|
||||
extern UINT32 OsTaskSyncWait(const LosTaskCB *taskCB);
|
||||
extern INT32 OsCreateUserTask(UINT32 processID, TSK_INIT_PARAM_S *initParam);
|
||||
extern INT32 OsTaskSchedulerSetUnsafe(LosTaskCB *taskCB, UINT16 policy, UINT16 priority,
|
||||
BOOL policyFlag, UINT32 intSave);
|
||||
extern INT32 OsSetCurrTaskName(const CHAR *name);
|
||||
extern VOID OsTaskCBRecyleToFree(VOID);
|
||||
extern VOID OsTaskExitGroup(UINT32 status);
|
||||
extern VOID OsTaskToExit(LosTaskCB *taskCB, UINT32 status);
|
||||
extern VOID OsExecDestroyTaskGroup(VOID);
|
||||
extern VOID OsProcessSuspendAllTask(VOID);
|
||||
extern UINT32 OsUserTaskOperatePermissionsCheck(LosTaskCB *taskCB);
|
||||
extern VOID OsWriteResourceEvent(UINT32 events);
|
||||
extern UINT32 OsCreateResourceFreeTask(VOID);
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_TASK_PRI_H */
|
||||
101
kernel/base/include/los_tick_pri.h
Executable file
101
kernel/base/include/los_tick_pri.h
Executable file
@@ -0,0 +1,101 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_TICK_PRI_H
|
||||
#define _LOS_TICK_PRI_H
|
||||
|
||||
#include "los_base.h"
|
||||
#include "los_tick.h"
|
||||
#include "los_spinlock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
|
||||
/* spinlock for tick */
|
||||
extern SPIN_LOCK_S g_tickSpin;
|
||||
#define TICK_LOCK(state) LOS_SpinLockSave(&g_tickSpin, &(state))
|
||||
#define TICK_UNLOCK(state) LOS_SpinUnlockRestore(&g_tickSpin, (state))
|
||||
|
||||
/**
|
||||
* @ingroup los_tick
|
||||
* Count of Ticks
|
||||
*/
|
||||
extern volatile UINT64 g_tickCount[];
|
||||
|
||||
/**
|
||||
* @ingroup los_tick
|
||||
* Cycle to nanosecond scale
|
||||
*/
|
||||
extern DOUBLE g_cycle2NsScale;
|
||||
|
||||
/**
|
||||
* @ingroup los_tick
|
||||
* @brief Handle the system tick timeout.
|
||||
*
|
||||
* @par Description:
|
||||
* This API is called when the system tick timeout and triggers the interrupt.
|
||||
*
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param none.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_tick.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID OsTickHandler(VOID);
|
||||
|
||||
/**
|
||||
* @ingroup los_tick
|
||||
* Convert from the cycle count to nanosecond.
|
||||
*/
|
||||
#define CYCLE_TO_NS(cycles) ((cycles) * g_cycle2NsScale)
|
||||
|
||||
/**
|
||||
* Current system timer register is 32 bit, therefore TIMER_MAXLOAD define just in order to avoid ambiguity.
|
||||
*/
|
||||
#define TIMER_MAXLOAD 0xffffffff
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_TICK_PRI_H */
|
||||
77
kernel/base/include/los_timeslice_pri.h
Executable file
77
kernel/base/include/los_timeslice_pri.h
Executable file
@@ -0,0 +1,77 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_timeslice Timeslice
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef _LOS_TIMESLICE_PRI_H
|
||||
#define _LOS_TIMESLICE_PRI_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* @ingroup los_timeslice
|
||||
* @brief Check time slices.
|
||||
*
|
||||
* @par Description:
|
||||
* <ul>
|
||||
* <li>This API is used to check time slices. If the number of Ticks equals to the time for task switch,
|
||||
* tasks are switched. Otherwise, the Tick counting continues.</li>
|
||||
* </ul>
|
||||
* @attention
|
||||
* <ul>
|
||||
* <li>None.</li>
|
||||
* </ul>
|
||||
*
|
||||
* @param None.
|
||||
*
|
||||
* @retval None.
|
||||
* @par Dependency:
|
||||
* <ul><li>los_timeslice_pri.h: the header file that contains the API declaration.</li></ul>
|
||||
* @see None.
|
||||
*/
|
||||
extern VOID OsTimesliceCheck(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* _LOS_TIMESLICE_PRI_H */
|
||||
37
kernel/base/include/los_typedef_pri.h
Executable file
37
kernel/base/include/los_typedef_pri.h
Executable file
@@ -0,0 +1,37 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef _LOS_TYPEDEF_PRI_H
|
||||
#define _LOS_TYPEDEF_PRI_H
|
||||
|
||||
#include "los_typedef.h"
|
||||
|
||||
#endif /* _LOS_TYPEDEF_PRI_H */
|
||||
74
kernel/base/include/los_vm_boot.h
Executable file
74
kernel/base/include/los_vm_boot.h
Executable file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/* flags for initial mapping struct */
|
||||
#define MMU_INITIAL_MAPPING_TEMPORARY (0x1)
|
||||
#define MMU_INITIAL_MAPPING_FLAG_UNCACHED (0x2)
|
||||
#define MMU_INITIAL_MAPPING_FLAG_DEVICE (0x4)
|
||||
#define MMU_INITIAL_MAPPING_FLAG_DYNAMIC (0x8)
|
||||
#ifndef ASSEMBLY
|
||||
|
||||
#ifndef __LOS_VM_BOOT_H__
|
||||
#define __LOS_VM_BOOT_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_KHEAP_BLOCK_SIZE (512 * 1024UL)
|
||||
|
||||
typedef struct ArchMmuInitMapping {
|
||||
PADDR_T phys;
|
||||
VADDR_T virt;
|
||||
size_t size;
|
||||
unsigned int flags;
|
||||
const char *name;
|
||||
} LosArchMmuInitMapping;
|
||||
|
||||
extern UINTPTR g_vmBootMemBase;
|
||||
extern BOOL g_kHeapInited;
|
||||
|
||||
UINT32 OsVmAddrCheck(size_t tempAddr, size_t length);
|
||||
VOID *OsVmBootMemAlloc(size_t len);
|
||||
UINT32 OsSysMemInit(VOID);
|
||||
VOID OsInitMappingStartUp(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __LOS_VM_BOOT_H__ */
|
||||
#endif /* ASSEMBLY */
|
||||
140
kernel/base/include/los_vm_common.h
Executable file
140
kernel/base/include/los_vm_common.h
Executable file
@@ -0,0 +1,140 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_map vm common definition
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_COMMON_H__
|
||||
#define __LOS_VM_COMMON_H__
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* user address space, defaults to below kernel space with a 16MB guard gap on either side */
|
||||
#ifndef USER_ASPACE_BASE
|
||||
#define USER_ASPACE_BASE ((vaddr_t)0x01000000UL)
|
||||
#endif
|
||||
#ifndef USER_ASPACE_SIZE
|
||||
#define USER_ASPACE_SIZE ((vaddr_t)KERNEL_ASPACE_BASE - USER_ASPACE_BASE - 0x01000000UL)
|
||||
#endif
|
||||
|
||||
#define USER_ASPACE_TOP_MAX ((vaddr_t)(USER_ASPACE_BASE + USER_ASPACE_SIZE))
|
||||
#define USER_HEAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 2))
|
||||
#define USER_MAP_BASE ((vaddr_t)(USER_ASPACE_TOP_MAX >> 1))
|
||||
#define USER_MAP_SIZE ((vaddr_t)(USER_ASPACE_SIZE >> 3))
|
||||
|
||||
#ifndef PAGE_SIZE
|
||||
#define PAGE_SIZE (0x1000U)
|
||||
#endif
|
||||
#define PAGE_MASK (~(PAGE_SIZE - 1))
|
||||
#define PAGE_SHIFT (12)
|
||||
|
||||
#define KB (1024UL)
|
||||
#define MB (1024UL * 1024UL)
|
||||
#define GB (1024UL * 1024UL * 1024UL)
|
||||
|
||||
#define ROUNDUP(a, b) (((a) + ((b) - 1)) & ~((b) - 1))
|
||||
#define ROUNDDOWN(a, b) ((a) & ~((b) - 1))
|
||||
#define ROUNDOFFSET(a, b) ((a) & ((b) - 1))
|
||||
#define MIN2(a, b) (((a) < (b)) ? (a) : (b))
|
||||
|
||||
#define IS_ALIGNED(a, b) (!(((UINTPTR)(a)) & (((UINTPTR)(b)) - 1)))
|
||||
#define IS_PAGE_ALIGNED(x) IS_ALIGNED(x, PAGE_SIZE)
|
||||
#define IS_SECTION_ALIGNED(x) IS_ALIGNED(x, SECTION_SIZE)
|
||||
|
||||
#define LOS_ERRNO_VM_NO_ERROR (0)
|
||||
#define LOS_ERRNO_VM_GENERIC (-1)
|
||||
#define LOS_ERRNO_VM_NOT_FOUND (-2)
|
||||
#define LOS_ERRNO_VM_NOT_READY (-3)
|
||||
#define LOS_ERRNO_VM_NO_MSG (-4)
|
||||
#define LOS_ERRNO_VM_NO_MEMORY (-5)
|
||||
#define LOS_ERRNO_VM_ALREADY_STARTED (-6)
|
||||
#define LOS_ERRNO_VM_NOT_VALID (-7)
|
||||
#define LOS_ERRNO_VM_INVALID_ARGS (-8)
|
||||
#define LOS_ERRNO_VM_NOT_ENOUGH_BUFFER (-9)
|
||||
#define LOS_ERRNO_VM_NOT_SUSPENDED (-10)
|
||||
#define LOS_ERRNO_VM_OBJECT_DESTROYED (-11)
|
||||
#define LOS_ERRNO_VM_NOT_BLOCKED (-12)
|
||||
#define LOS_ERRNO_VM_TIMED_OUT (-13)
|
||||
#define LOS_ERRNO_VM_ALREADY_EXISTS (-14)
|
||||
#define LOS_ERRNO_VM_CHANNEL_CLOSED (-15)
|
||||
#define LOS_ERRNO_VM_OFFLINE (-16)
|
||||
#define LOS_ERRNO_VM_NOT_ALLOWED (-17)
|
||||
#define LOS_ERRNO_VM_BAD_PATH (-18)
|
||||
#define LOS_ERRNO_VM_ALREADY_MOUNTED (-19)
|
||||
#define LOS_ERRNO_VM_IO (-20)
|
||||
#define LOS_ERRNO_VM_NOT_DIR (-21)
|
||||
#define LOS_ERRNO_VM_NOT_FILE (-22)
|
||||
#define LOS_ERRNO_VM_RECURSE_TOO_DEEP (-23)
|
||||
#define LOS_ERRNO_VM_NOT_SUPPORTED (-24)
|
||||
#define LOS_ERRNO_VM_TOO_BIG (-25)
|
||||
#define LOS_ERRNO_VM_CANCELLED (-26)
|
||||
#define LOS_ERRNO_VM_NOT_IMPLEMENTED (-27)
|
||||
#define LOS_ERRNO_VM_CHECKSUM_FAIL (-28)
|
||||
#define LOS_ERRNO_VM_CRC_FAIL (-29)
|
||||
#define LOS_ERRNO_VM_CMD_UNKNOWN (-30)
|
||||
#define LOS_ERRNO_VM_BAD_STATE (-31)
|
||||
#define LOS_ERRNO_VM_BAD_LEN (-32)
|
||||
#define LOS_ERRNO_VM_BUSY (-33)
|
||||
#define LOS_ERRNO_VM_THREAD_DETACHED (-34)
|
||||
#define LOS_ERRNO_VM_I2C_NACK (-35)
|
||||
#define LOS_ERRNO_VM_ALREADY_EXPIRED (-36)
|
||||
#define LOS_ERRNO_VM_OUT_OF_RANGE (-37)
|
||||
#define LOS_ERRNO_VM_NOT_CONFIGURED (-38)
|
||||
#define LOS_ERRNO_VM_NOT_MOUNTED (-39)
|
||||
#define LOS_ERRNO_VM_FAULT (-40)
|
||||
#define LOS_ERRNO_VM_NO_RESOURCES (-41)
|
||||
#define LOS_ERRNO_VM_BAD_HANDLE (-42)
|
||||
#define LOS_ERRNO_VM_ACCESS_DENIED (-43)
|
||||
#define LOS_ERRNO_VM_PARTIAL_WRITE (-44)
|
||||
#define LOS_ERRNO_VM_LOCK (-45)
|
||||
#define LOS_ERRNO_VM_MAP_FAILED (-46)
|
||||
|
||||
#define VM_ERR(args...) do { \
|
||||
PRINT_ERR("%s %d ", __FUNCTION__, __LINE__); \
|
||||
if (PRINT_LEVEL == LOS_DEBUG_LEVEL) { \
|
||||
PRINTK(args); \
|
||||
} \
|
||||
PRINTK("\n"); \
|
||||
} while (0)
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_COMMON_H__ */
|
||||
82
kernel/base/include/los_vm_dump.h
Executable file
82
kernel/base/include/los_vm_dump.h
Executable file
@@ -0,0 +1,82 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_dump virtual memory dump operation
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_DUMP_H__
|
||||
#define __LOS_VM_DUMP_H__
|
||||
|
||||
#include "los_vm_map.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/**
|
||||
* These macros is used for process memory usage statistics.
|
||||
* Include virtual memory, shared memory and physical memory.
|
||||
*/
|
||||
#define PROCESS_VM_INDEX_MAX 3
|
||||
#define PROCESS_MEMINFO_LEN (sizeof(UINT32) * PROCESS_VM_INDEX_MAX)
|
||||
#define PROCESS_VM_INDEX 0
|
||||
#define PROCESS_SM_INDEX 1
|
||||
#define PROCESS_PM_INDEX 2
|
||||
|
||||
const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region);
|
||||
INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region);
|
||||
UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space);
|
||||
VOID OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm);
|
||||
VOID OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm);
|
||||
VOID OsKProcessPmUsage(LosVmSpace *kAspace, UINT32 *actualPm);
|
||||
VOID OsDumpAspace(LosVmSpace *space);
|
||||
UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages);
|
||||
UINT32 OsCountAspacePages(LosVmSpace *space);
|
||||
VOID OsDumpAllAspace(VOID);
|
||||
VOID OsVmPhysDump(VOID);
|
||||
VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount);
|
||||
INT32 OsRegionOverlapCheck(LosVmSpace *space, LosVmMapRegion *region);
|
||||
VOID OsDumpPte(VADDR_T vaddr);
|
||||
LosProcessCB *OsGetPIDByAspace(LosVmSpace *space);
|
||||
CHAR *OsArchFlagsToStr(const UINT32 archFlags);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_DUMP_H__ */
|
||||
67
kernel/base/include/los_vm_fault.h
Executable file
67
kernel/base/include/los_vm_fault.h
Executable file
@@ -0,0 +1,67 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_fault vm fault definition
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_FAULT_H__
|
||||
#define __LOS_VM_FAULT_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_exc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct {
|
||||
VADDR_T excAddr;
|
||||
VADDR_T fixAddr;
|
||||
} LosExcTable;
|
||||
|
||||
#define VM_MAP_PF_FLAG_WRITE (1U << 0)
|
||||
#define VM_MAP_PF_FLAG_USER (1U << 1)
|
||||
#define VM_MAP_PF_FLAG_INSTRUCTION (1U << 2)
|
||||
#define VM_MAP_PF_FLAG_NOT_PRESENT (1U << 3)
|
||||
|
||||
STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame);
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_FAULT_H__ */
|
||||
|
||||
214
kernel/base/include/los_vm_filemap.h
Executable file
214
kernel/base/include/los_vm_filemap.h
Executable file
@@ -0,0 +1,214 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_filemap vm filemap definition
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_FILEMAP_H__
|
||||
#define __LOS_VM_FILEMAP_H__
|
||||
|
||||
#include "fs/file.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_vm_page.h"
|
||||
#include "los_vm_common.h"
|
||||
#include "los_vm_phys.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct FilePage {
|
||||
LOS_DL_LIST node;
|
||||
LOS_DL_LIST lru;
|
||||
LOS_DL_LIST i_mmap; /* list of mappings */
|
||||
UINT32 n_maps; /* num of mapping */
|
||||
struct VmPhysSeg *physSeg; /* physical memory that file page belongs to */
|
||||
struct VmPage *vmPage;
|
||||
struct page_mapping *mapping;
|
||||
VM_OFFSET_T pgoff;
|
||||
UINT32 flags;
|
||||
UINT16 dirtyOff;
|
||||
UINT16 dirtyEnd;
|
||||
} LosFilePage;
|
||||
|
||||
typedef struct MapInfo {
|
||||
LOS_DL_LIST node;
|
||||
VADDR_T vaddr;
|
||||
LosFilePage *page;
|
||||
LosArchMmu *archMmu;
|
||||
} LosMapInfo;
|
||||
|
||||
enum OsPageFlags {
|
||||
FILE_PAGE_FREE,
|
||||
FILE_PAGE_LOCKED,
|
||||
FILE_PAGE_REFERENCED,
|
||||
FILE_PAGE_DIRTY,
|
||||
FILE_PAGE_LRU,
|
||||
FILE_PAGE_ACTIVE,
|
||||
FILE_PAGE_SHARED,
|
||||
};
|
||||
|
||||
#define PGOFF_MAX 2000
|
||||
#define MAX_SHRINK_PAGECACHE_TRY 2
|
||||
#define VM_FILEMAP_MAX_SCAN (SYS_MEM_SIZE_DEFAULT >> PAGE_SHIFT)
|
||||
#define VM_FILEMAP_MIN_SCAN 32
|
||||
|
||||
STATIC INLINE VOID OsSetPageLocked(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapSet(&page->flags, FILE_PAGE_LOCKED);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCleanPageLocked(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapClr(&page->flags, FILE_PAGE_LOCKED);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsSetPageDirty(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapSet(&page->flags, FILE_PAGE_DIRTY);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCleanPageDirty(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapClr(&page->flags, FILE_PAGE_DIRTY);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsSetPageActive(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapSet(&page->flags, FILE_PAGE_ACTIVE);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCleanPageActive(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapClr(&page->flags, FILE_PAGE_ACTIVE);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsSetPageLRU(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapSet(&page->flags, FILE_PAGE_LRU);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsSetPageFree(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapSet(&page->flags, FILE_PAGE_FREE);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCleanPageFree(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapClr(&page->flags, FILE_PAGE_FREE);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsSetPageReferenced(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapSet(&page->flags, FILE_PAGE_REFERENCED);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCleanPageReferenced(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapClr(&page->flags, FILE_PAGE_REFERENCED);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsIsPageActive(LosVmPage *page)
|
||||
{
|
||||
return BIT_GET(page->flags, FILE_PAGE_ACTIVE);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsIsPageLocked(LosVmPage *page)
|
||||
{
|
||||
return BIT_GET(page->flags, FILE_PAGE_LOCKED);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsIsPageReferenced(LosVmPage *page)
|
||||
{
|
||||
return BIT_GET(page->flags, FILE_PAGE_REFERENCED);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsIsPageDirty(LosVmPage *page)
|
||||
{
|
||||
return BIT_GET(page->flags, FILE_PAGE_DIRTY);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsIsPageMapped(LosFilePage *page)
|
||||
{
|
||||
return (page->n_maps != 0);
|
||||
}
|
||||
|
||||
/* The follow three functions is used to SHM module */
|
||||
STATIC INLINE VOID OsSetPageShared(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapSet(&page->flags, FILE_PAGE_SHARED);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsCleanPageShared(LosVmPage *page)
|
||||
{
|
||||
LOS_BitmapClr(&page->flags, FILE_PAGE_SHARED);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsIsPageShared(LosVmPage *page)
|
||||
{
|
||||
return BIT_GET(page->flags, FILE_PAGE_SHARED);
|
||||
}
|
||||
|
||||
INT32 OsVfsFileMmap(struct file *filep, LosVmMapRegion *region);
|
||||
LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff);
|
||||
LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff);
|
||||
LosMapInfo *OsGetMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr);
|
||||
VOID OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr);
|
||||
VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *pgFault, BOOL cleanDirty);
|
||||
VOID OsFileCacheFlush(struct page_mapping *mapping);
|
||||
VOID OsFileCacheRemove(struct page_mapping *mapping);
|
||||
VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info);
|
||||
VOID OsUnmapAllLocked(LosFilePage *page);
|
||||
VOID OsLruCacheAdd(LosFilePage *fpage, enum OsLruList lruType);
|
||||
VOID OsLruCacheDel(LosFilePage *fpage);
|
||||
LosFilePage *OsDumpDirtyPage(LosFilePage *oldPage);
|
||||
VOID OsDoFlushDirtyPage(LosFilePage *fpage);
|
||||
VOID OsDeletePageCacheLru(LosFilePage *page);
|
||||
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region);
|
||||
VOID OsPageRefDecNoLock(LosFilePage *page);
|
||||
VOID OsPageRefIncLocked(LosFilePage *page);
|
||||
int OsTryShrinkMemory(size_t nPage);
|
||||
VOID OsMarkPageDirty(LosFilePage *fpage, LosVmMapRegion *region, int off, int len);
|
||||
|
||||
typedef struct ProcessCB LosProcessCB;
|
||||
VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB);
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_FILEMAP_H__ */
|
||||
|
||||
63
kernel/base/include/los_vm_iomap.h
Executable file
63
kernel/base/include/los_vm_iomap.h
Executable file
@@ -0,0 +1,63 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_IOMAP_H__
|
||||
#define __LOS_VM_IOMAP_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_vm_zone.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
enum DmaMemType {
|
||||
DMA_CACHE,
|
||||
DMA_NOCACHE
|
||||
};
|
||||
|
||||
#define IS_PERIPH_ADDR(addr) ((addr >= PERIPH_PMM_BASE) && (addr <= PERIPH_PMM_BASE + PERIPH_PMM_SIZE))
|
||||
#define IS_MEMORY_ADDR(addr) ((addr >= DDR_MEM_ADDR) && (addr <= DDR_MEM_ADDR + DDR_MEM_SIZE))
|
||||
|
||||
/* thread safety */
|
||||
VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMemType type);
|
||||
VOID LOS_DmaMemFree(VOID *vaddr);
|
||||
DMA_ADDR_T LOS_DmaVaddrToPaddr(VOID *vaddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_IOMAP_H__ */
|
||||
64
kernel/base/include/los_vm_lock.h
Executable file
64
kernel/base/include/los_vm_lock.h
Executable file
@@ -0,0 +1,64 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_map vm lock operation
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_LOCK_H__
|
||||
#define __LOS_VM_LOCK_H__
|
||||
|
||||
#include "los_mux.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
STATIC INLINE STATUS_T LOS_MuxAcquire(LosMux *m)
|
||||
{
|
||||
return LOS_MuxLock(m, LOS_WAIT_FOREVER);
|
||||
}
|
||||
|
||||
STATIC INLINE STATUS_T LOS_MuxRelease(LosMux *m)
|
||||
{
|
||||
return LOS_MuxUnlock(m);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_LOCK_H__ */
|
||||
314
kernel/base/include/los_vm_map.h
Executable file
314
kernel/base/include/los_vm_map.h
Executable file
@@ -0,0 +1,314 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_map vm mapping management
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_MAP_H__
|
||||
#define __LOS_VM_MAP_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_arch_mmu.h"
|
||||
#include "los_rbtree.h"
|
||||
#include "los_vm_syscall.h"
|
||||
#include "los_vm_zone.h"
|
||||
#include "los_vm_common.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct VmMapRange {
|
||||
VADDR_T base; /**< vm region base addr */
|
||||
UINT32 size; /**< vm region size */
|
||||
} LosVmMapRange;
|
||||
|
||||
struct VmMapRegion;
|
||||
typedef struct VmMapRegion LosVmMapRegion;
|
||||
struct VmFileOps;
|
||||
typedef struct VmFileOps LosVmFileOps;
|
||||
struct VmSpace;
|
||||
typedef struct VmSpace LosVmSpace;
|
||||
|
||||
typedef struct VmFault {
|
||||
UINT32 flags; /* FAULT_FLAG_xxx flags */
|
||||
unsigned long pgoff; /* Logical page offset based on region */
|
||||
VADDR_T vaddr; /* Faulting virtual address */
|
||||
VADDR_T *pageKVaddr; /* KVaddr of pagefault's vm page's paddr */
|
||||
} LosVmPgFault;
|
||||
|
||||
struct VmFileOps {
|
||||
void (*open)(struct VmMapRegion *region);
|
||||
void (*close)(struct VmMapRegion *region);
|
||||
int (*fault)(struct VmMapRegion *region, LosVmPgFault *pageFault);
|
||||
void (*remove)(struct VmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T offset);
|
||||
};
|
||||
|
||||
struct VmMapRegion {
|
||||
LosRbNode rbNode; /**< region red-black tree node */
|
||||
LosVmSpace *space;
|
||||
LOS_DL_LIST node; /**< region dl list */
|
||||
LosVmMapRange range; /**< region address range */
|
||||
VM_OFFSET_T pgOff; /**< region page offset to file */
|
||||
UINT32 regionFlags; /**< region flags: cow, user_wired */
|
||||
UINT32 shmid; /**< shmid about shared region */
|
||||
UINT8 protectFlags; /**< vm region protect flags: PROT_READ, PROT_WRITE, */
|
||||
UINT8 forkFlags; /**< vm space fork flags: COPY, ZERO, */
|
||||
UINT8 regionType; /**< vm region type: ANON, FILE, DEV */
|
||||
union {
|
||||
struct VmRegionFile {
|
||||
unsigned int fileMagic;
|
||||
struct file *file;
|
||||
const LosVmFileOps *vmFOps;
|
||||
} rf;
|
||||
struct VmRegionAnon {
|
||||
LOS_DL_LIST node; /**< region LosVmPage list */
|
||||
} ra;
|
||||
struct VmRegionDev {
|
||||
LOS_DL_LIST node; /**< region LosVmPage list */
|
||||
const LosVmFileOps *vmFOps;
|
||||
} rd;
|
||||
} unTypeData;
|
||||
};
|
||||
|
||||
typedef struct VmSpace {
|
||||
LOS_DL_LIST node; /**< vm space dl list */
|
||||
LOS_DL_LIST regions; /**< region dl list */
|
||||
LosRbTree regionRbTree; /**< region red-black tree root */
|
||||
LosMux regionMux; /**< region list mutex lock */
|
||||
VADDR_T base; /**< vm space base addr */
|
||||
UINT32 size; /**< vm space size */
|
||||
VADDR_T heapBase; /**< vm space heap base address */
|
||||
VADDR_T heapNow; /**< vm space heap base now */
|
||||
LosVmMapRegion *heap; /**< heap region */
|
||||
VADDR_T mapBase; /**< vm space mapping area base */
|
||||
UINT32 mapSize; /**< vm space mapping area size */
|
||||
LosArchMmu archMmu; /**< vm mapping physical memory */
|
||||
#ifdef LOSCFG_DRIVERS_TZDRIVER
|
||||
VADDR_T codeStart; /**< user process code area start */
|
||||
VADDR_T codeEnd; /**< user process code area end */
|
||||
#endif
|
||||
} LosVmSpace;
|
||||
|
||||
#define VM_MAP_REGION_TYPE_NONE (0x0)
|
||||
#define VM_MAP_REGION_TYPE_ANON (0x1)
|
||||
#define VM_MAP_REGION_TYPE_FILE (0x2)
|
||||
#define VM_MAP_REGION_TYPE_DEV (0x4)
|
||||
#define VM_MAP_REGION_TYPE_MASK (0x7)
|
||||
|
||||
/* the high 8 bits(24~31) should reserved, shm will use it */
|
||||
#define VM_MAP_REGION_FLAG_CACHED (0<<0)
|
||||
#define VM_MAP_REGION_FLAG_UNCACHED (1<<0)
|
||||
#define VM_MAP_REGION_FLAG_UNCACHED_DEVICE (2<<0) /* only exists on some arches, otherwise UNCACHED */
|
||||
#define VM_MAP_REGION_FLAG_WRITE_COMBINING (3<<0) /* only exists on some arches, otherwise UNCACHED */
|
||||
#define VM_MAP_REGION_FLAG_CACHE_MASK (3<<0)
|
||||
#define VM_MAP_REGION_FLAG_PERM_USER (1<<2)
|
||||
#define VM_MAP_REGION_FLAG_PERM_READ (1<<3)
|
||||
#define VM_MAP_REGION_FLAG_PERM_WRITE (1<<4)
|
||||
#define VM_MAP_REGION_FLAG_PERM_EXECUTE (1<<5)
|
||||
#define VM_MAP_REGION_FLAG_PROT_MASK (0xF<<2)
|
||||
#define VM_MAP_REGION_FLAG_NS (1<<6) /* NON-SECURE */
|
||||
#define VM_MAP_REGION_FLAG_SHARED (1<<7)
|
||||
#define VM_MAP_REGION_FLAG_PRIVATE (1<<8)
|
||||
#define VM_MAP_REGION_FLAG_FLAG_MASK (3<<7)
|
||||
#define VM_MAP_REGION_FLAG_STACK (1<<9)
|
||||
#define VM_MAP_REGION_FLAG_HEAP (1<<10)
|
||||
#define VM_MAP_REGION_FLAG_DATA (1<<11)
|
||||
#define VM_MAP_REGION_FLAG_TEXT (1<<12)
|
||||
#define VM_MAP_REGION_FLAG_BSS (1<<13)
|
||||
#define VM_MAP_REGION_FLAG_VDSO (1<<14)
|
||||
#define VM_MAP_REGION_FLAG_MMAP (1<<15)
|
||||
#define VM_MAP_REGION_FLAG_SHM (1<<16)
|
||||
#define VM_MAP_REGION_FLAG_INVALID (1<<17) /* indicates that flags are not specified */
|
||||
|
||||
STATIC INLINE UINT32 OsCvtProtFlagsToRegionFlags(unsigned long prot, unsigned long flags)
|
||||
{
|
||||
UINT32 regionFlags = 0;
|
||||
|
||||
regionFlags |= VM_MAP_REGION_FLAG_PERM_USER;
|
||||
regionFlags |= (prot & PROT_READ) ? VM_MAP_REGION_FLAG_PERM_READ : 0;
|
||||
regionFlags |= (prot & PROT_WRITE) ? VM_MAP_REGION_FLAG_PERM_WRITE : 0;
|
||||
regionFlags |= (prot & PROT_EXEC) ? VM_MAP_REGION_FLAG_PERM_EXECUTE : 0;
|
||||
regionFlags |= (flags & MAP_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0;
|
||||
regionFlags |= (flags & MAP_PRIVATE) ? VM_MAP_REGION_FLAG_PRIVATE : 0;
|
||||
|
||||
return regionFlags;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsKernelAddress(VADDR_T vaddr)
|
||||
{
|
||||
return ((vaddr >= (VADDR_T)KERNEL_ASPACE_BASE) &&
|
||||
(vaddr <= ((VADDR_T)KERNEL_ASPACE_BASE + ((VADDR_T)KERNEL_ASPACE_SIZE - 1))));
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsKernelAddressRange(VADDR_T vaddr, size_t len)
|
||||
{
|
||||
return (vaddr + len > vaddr) && LOS_IsKernelAddress(vaddr) && (LOS_IsKernelAddress(vaddr + len - 1));
|
||||
}
|
||||
|
||||
STATIC INLINE VADDR_T LOS_RegionEndAddr(LosVmMapRegion *region)
|
||||
{
|
||||
return (region->range.base + region->range.size - 1);
|
||||
}
|
||||
|
||||
STATIC INLINE size_t LOS_RegionSize(VADDR_T start, VADDR_T end)
|
||||
{
|
||||
return (end - start + 1);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsRegionTypeFile(LosVmMapRegion* region)
|
||||
{
|
||||
return region->regionType == VM_MAP_REGION_TYPE_FILE;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsRegionPermUserReadOnly(LosVmMapRegion* region)
|
||||
{
|
||||
return ((region->regionFlags & VM_MAP_REGION_FLAG_PROT_MASK) ==
|
||||
(VM_MAP_REGION_FLAG_PERM_USER | VM_MAP_REGION_FLAG_PERM_READ));
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsRegionFlagPrivateOnly(LosVmMapRegion* region)
|
||||
{
|
||||
return ((region->regionFlags & VM_MAP_REGION_FLAG_FLAG_MASK) == VM_MAP_REGION_FLAG_PRIVATE);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID LOS_SetRegionTypeFile(LosVmMapRegion* region)
|
||||
{
|
||||
region->regionType = VM_MAP_REGION_TYPE_FILE;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsRegionTypeDev(LosVmMapRegion* region)
|
||||
{
|
||||
return region->regionType == VM_MAP_REGION_TYPE_DEV;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID LOS_SetRegionTypeDev(LosVmMapRegion* region)
|
||||
{
|
||||
region->regionType = VM_MAP_REGION_TYPE_DEV;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsRegionTypeAnon(LosVmMapRegion* region)
|
||||
{
|
||||
return region->regionType == VM_MAP_REGION_TYPE_ANON;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID LOS_SetRegionTypeAnon(LosVmMapRegion* region)
|
||||
{
|
||||
region->regionType = VM_MAP_REGION_TYPE_ANON;
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsUserAddress(VADDR_T vaddr)
|
||||
{
|
||||
return ((vaddr >= USER_ASPACE_BASE) &&
|
||||
(vaddr <= (USER_ASPACE_BASE + (USER_ASPACE_SIZE - 1))));
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsUserAddressRange(VADDR_T vaddr, size_t len)
|
||||
{
|
||||
return (vaddr + len > vaddr) && LOS_IsUserAddress(vaddr) && (LOS_IsUserAddress(vaddr + len - 1));
|
||||
}
|
||||
|
||||
|
||||
STATIC INLINE BOOL LOS_IsVmallocAddress(VADDR_T vaddr)
|
||||
{
|
||||
return ((vaddr >= VMALLOC_START) &&
|
||||
(vaddr <= (VMALLOC_START + (VMALLOC_SIZE - 1))));
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL OsIsVmRegionEmpty(LosVmSpace *vmSpace)
|
||||
{
|
||||
if (vmSpace->regionRbTree.ulNodes == 0) {
|
||||
return TRUE;
|
||||
}
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
LosVmSpace *LOS_GetKVmSpace(VOID);
|
||||
LOS_DL_LIST *LOS_GetVmSpaceList(VOID);
|
||||
LosVmSpace *LOS_GetVmallocSpace(VOID);
|
||||
VOID OsInitMappingStartUp(VOID);
|
||||
VOID OsKSpaceInit(VOID);
|
||||
BOOL LOS_IsRangeInSpace(const LosVmSpace *space, VADDR_T vaddr, size_t size);
|
||||
STATUS_T LOS_VmSpaceReserve(LosVmSpace *space, size_t size, VADDR_T vaddr);
|
||||
LosVmSpace *LOS_GetKVmSpace(VOID);
|
||||
INT32 OsUserHeapFree(LosVmSpace *vmSpace, VADDR_T addr, size_t len);
|
||||
VADDR_T OsAllocRange(LosVmSpace *vmSpace, size_t len);
|
||||
VADDR_T OsAllocSpecificRange(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len);
|
||||
LosVmMapRegion *OsCreateRegion(VADDR_T vaddr, size_t len, UINT32 regionFlags, unsigned long offset);
|
||||
BOOL OsInsertRegion(LosRbTree *regionRbTree, LosVmMapRegion *region);
|
||||
LosVmSpace *LOS_SpaceGet(VADDR_T vaddr);
|
||||
BOOL LOS_IsRegionFileValid(LosVmMapRegion *region);
|
||||
LosVmMapRegion *LOS_RegionRangeFind(LosVmSpace *vmSpace, VADDR_T addr, size_t len);
|
||||
LosVmMapRegion *LOS_RegionFind(LosVmSpace *vmSpace, VADDR_T addr);
|
||||
PADDR_T LOS_PaddrQuery(VOID *vaddr);
|
||||
LosVmMapRegion *LOS_RegionAlloc(LosVmSpace *vmSpace, VADDR_T vaddr, size_t len, UINT32 regionFlags, VM_OFFSET_T pgoff);
|
||||
STATUS_T OsRegionsRemove(LosVmSpace *space, VADDR_T vaddr, size_t size);
|
||||
STATUS_T OsVmRegionAdjust(LosVmSpace *space, VADDR_T vaddr, size_t size);
|
||||
LosVmMapRegion *OsVmRegionDup(LosVmSpace *space, LosVmMapRegion *oldRegion, VADDR_T vaddr, size_t size);
|
||||
STATUS_T OsIsRegionCanExpand(LosVmSpace *space, LosVmMapRegion *region, size_t size);
|
||||
STATUS_T LOS_RegionFree(LosVmSpace *space, LosVmMapRegion *region);
|
||||
STATUS_T LOS_VmSpaceFree(LosVmSpace *space);
|
||||
STATUS_T LOS_VaddrToPaddrMmap(LosVmSpace *space, VADDR_T vaddr, PADDR_T paddr, size_t len, UINT32 flags);
|
||||
BOOL OsUserVmSpaceInit(LosVmSpace *vmSpace, VADDR_T *virtTtb);
|
||||
STATUS_T LOS_VmSpaceClone(LosVmSpace *oldVmSpace, LosVmSpace *newVmSpace);
|
||||
STATUS_T LOS_UserSpaceVmAlloc(LosVmSpace *space, size_t size, VOID **ptr, UINT8 align_log2, UINT32 regionFlags);
|
||||
LosMux *OsGVmSpaceMuxGet(VOID);
|
||||
STATUS_T OsUnMMap(LosVmSpace *space, VADDR_T addr, size_t size);
|
||||
/**
|
||||
* thread safety
|
||||
* it is used to malloc continuous virtual memory, no sure for continuous physical memory.
|
||||
*/
|
||||
VOID *LOS_VMalloc(size_t size);
|
||||
VOID LOS_VFree(const VOID *addr);
|
||||
|
||||
/**
|
||||
* thread safety
|
||||
* these is used to malloc or free kernel memory.
|
||||
* when the size is large and close to multiples of pages,
|
||||
* will alloc pmm pages, otherwise alloc bestfit memory.
|
||||
*/
|
||||
VOID *LOS_KernelMalloc(UINT32 size);
|
||||
VOID *LOS_KernelMallocAlign(UINT32 size, UINT32 boundary);
|
||||
VOID *LOS_KernelRealloc(VOID *ptr, UINT32 size);
|
||||
VOID LOS_KernelFree(VOID *ptr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_MAP_H__ */
|
||||
|
||||
69
kernel/base/include/los_vm_page.h
Executable file
69
kernel/base/include/los_vm_page.h
Executable file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_PAGE_H__
|
||||
#define __LOS_VM_PAGE_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_bitmap.h"
|
||||
#include "los_list.h"
|
||||
#include "los_atomic.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
typedef struct VmPage {
|
||||
LOS_DL_LIST node; /**< vm object dl list */
|
||||
UINT32 index; /**< vm page index to vm object */
|
||||
PADDR_T physAddr; /**< vm page physical addr */
|
||||
Atomic refCounts; /**< vm page ref count */
|
||||
UINT32 flags; /**< vm page flags */
|
||||
UINT8 order; /**< vm page in which order list */
|
||||
UINT8 segID; /**< the segment id of vm page */
|
||||
UINT16 nPages; /**< the vm page is used for kernel heap */
|
||||
} LosVmPage;
|
||||
|
||||
extern LosVmPage *g_vmPageArray;
|
||||
extern size_t g_vmPageArraySize;
|
||||
|
||||
LosVmPage *LOS_VmPageGet(PADDR_T paddr);
|
||||
VOID OsVmPageStartup(VOID);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_PAGE_H__ */
|
||||
120
kernel/base/include/los_vm_phys.h
Executable file
120
kernel/base/include/los_vm_phys.h
Executable file
@@ -0,0 +1,120 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_PHYS_H__
|
||||
#define __LOS_VM_PHYS_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_list.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_vm_page.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define VM_LIST_ORDER_MAX 9
|
||||
#define VM_PHYS_SEG_MAX 32
|
||||
|
||||
#ifndef min
|
||||
#define min(x, y) ((x) < (y) ? (x) : (y))
|
||||
#endif
|
||||
|
||||
#define VM_PAGE_TO_PHYS(page) (page->physAddr)
|
||||
#define VM_ORDER_TO_PAGES(order) (1 << (order))
|
||||
#define VM_ORDER_TO_PHYS(order) (1 << (PAGE_SHIFT + (order)))
|
||||
#define VM_PHYS_TO_ORDER(phys) (min(LOS_LowBitGet((phys) >> PAGE_SHIFT), VM_LIST_ORDER_MAX - 1))
|
||||
|
||||
struct VmFreeList {
|
||||
LOS_DL_LIST node;
|
||||
UINT32 listCnt;
|
||||
};
|
||||
|
||||
enum OsLruList {
|
||||
VM_LRU_INACTIVE_ANON = 0,
|
||||
VM_LRU_ACTIVE_ANON,
|
||||
VM_LRU_INACTIVE_FILE,
|
||||
VM_LRU_ACTIVE_FILE,
|
||||
VM_LRU_UNEVICTABLE,
|
||||
VM_NR_LRU_LISTS
|
||||
};
|
||||
|
||||
typedef struct VmPhysSeg {
|
||||
PADDR_T start; /* The start of physical memory area */
|
||||
size_t size; /* The size of physical memory area */
|
||||
LosVmPage *pageBase; /* The first page address of this area */
|
||||
|
||||
SPIN_LOCK_S freeListLock; /* The buddy list spinlock */
|
||||
struct VmFreeList freeList[VM_LIST_ORDER_MAX]; /* The free pages in the buddy list */
|
||||
|
||||
SPIN_LOCK_S lruLock;
|
||||
size_t lruSize[VM_NR_LRU_LISTS];
|
||||
LOS_DL_LIST lruList[VM_NR_LRU_LISTS];
|
||||
} LosVmPhysSeg;
|
||||
|
||||
struct VmPhysArea {
|
||||
PADDR_T start;
|
||||
size_t size;
|
||||
};
|
||||
|
||||
extern struct VmPhysSeg g_vmPhysSeg[VM_PHYS_SEG_MAX];
|
||||
extern INT32 g_vmPhysSegNum;
|
||||
|
||||
UINT32 OsVmPagesToOrder(size_t nPages);
|
||||
struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page);
|
||||
LosVmPhysSeg *OsGVmPhysSegGet(VOID);
|
||||
VOID *OsVmPageToVaddr(LosVmPage *page);
|
||||
VOID OsVmPhysSegAdd(VOID);
|
||||
VOID OsVmPhysInit(VOID);
|
||||
VOID OsVmPhysAreaSizeAdjust(size_t size);
|
||||
UINT32 OsVmPhysPageNumGet(VOID);
|
||||
LosVmPage *OsVmVaddrToPage(VOID *ptr);
|
||||
VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage);
|
||||
VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages);
|
||||
LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID);
|
||||
|
||||
LosVmPage *LOS_PhysPageAlloc(VOID);
|
||||
VOID LOS_PhysPageFree(LosVmPage *page);
|
||||
size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list);
|
||||
size_t LOS_PhysPagesFree(LOS_DL_LIST *list);
|
||||
VOID *LOS_PhysPagesAllocContiguous(size_t nPages);
|
||||
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages);
|
||||
VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_PHYS_H__ */
|
||||
54
kernel/base/include/los_vm_shm_pri.h
Executable file
54
kernel/base/include/los_vm_shm_pri.h
Executable file
@@ -0,0 +1,54 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __LOS_SHM_PRI_H__
|
||||
#define __LOS_SHM_PRI_H__
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_vm_map.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
VOID OsShmFork(LosVmSpace *space, LosVmMapRegion *oldRegion, LosVmMapRegion *newRegion);
|
||||
VOID OsShmRegionFree(LosVmSpace *space, LosVmMapRegion *region);
|
||||
BOOL OsIsShmRegion(LosVmMapRegion *region);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_SHM_PRI_H__ */
|
||||
78
kernel/base/include/los_vm_syscall.h
Executable file
78
kernel/base/include/los_vm_syscall.h
Executable file
@@ -0,0 +1,78 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_syscall vm syscall definition
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#ifndef __LOS_VM_SYSCALL_H__
|
||||
#define __LOS_VM_SYSCALL_H__
|
||||
|
||||
#include "sys/shm.h"
|
||||
#include "sys/mman.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
STATIC INLINE BOOL LOS_IsNamedMapping(unsigned long flags)
|
||||
{
|
||||
return ((flags & MAP_ANONYMOUS) == 0);
|
||||
}
|
||||
|
||||
STATIC INLINE BOOL LOS_IsAnonymousMapping(unsigned long flags)
|
||||
{
|
||||
return ((flags & MAP_ANONYMOUS) == MAP_ANONYMOUS);
|
||||
}
|
||||
|
||||
VADDR_T LOS_MMap(VADDR_T vaddr, size_t len, unsigned prot, unsigned long flags, int fd, unsigned long pgoff);
|
||||
STATUS_T LOS_UnMMap(VADDR_T addr, size_t size);
|
||||
VOID *LOS_DoBrk(VOID *addr);
|
||||
int LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot);
|
||||
VADDR_T LOS_DoMremap(VADDR_T oldAddress, size_t oldSize, size_t newSize, int flags, VADDR_T newAddr);
|
||||
VOID LOS_DumpMemRegion(VADDR_T vaddr);
|
||||
INT32 ShmInit(VOID);
|
||||
INT32 ShmDeinit(VOID);
|
||||
INT32 ShmGet(key_t key, size_t size, INT32 shmflg);
|
||||
VOID *ShmAt(INT32 shmid, const VOID *shmaddr, INT32 shmflg);
|
||||
INT32 ShmCtl(INT32 shmid, INT32 cmd, struct shmid_ds *buf);
|
||||
INT32 ShmDt(const VOID *shmaddr);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif /* __LOS_VM_SYSCALL_H__ */
|
||||
89
kernel/base/include/los_vm_zone.h
Executable file
89
kernel/base/include/los_vm_zone.h
Executable file
@@ -0,0 +1,89 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifndef __VM_ZONE_H__
|
||||
#define __VM_ZONE_H__
|
||||
|
||||
#include "board.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define DEFINE_(X) X##U
|
||||
#define DEFINE(X) DEFINE_(X)
|
||||
|
||||
#define KERNEL_VMM_BASE DEFINE(KERNEL_VADDR_BASE)
|
||||
#define KERNEL_VMM_SIZE DEFINE(KERNEL_VADDR_SIZE)
|
||||
|
||||
#define KERNEL_ASPACE_BASE KERNEL_VMM_BASE
|
||||
#define KERNEL_ASPACE_SIZE KERNEL_VMM_SIZE
|
||||
|
||||
/* Uncached vmm aspace */
|
||||
#define UNCACHED_VMM_BASE (KERNEL_VMM_BASE + KERNEL_VMM_SIZE)
|
||||
#define UNCACHED_VMM_SIZE DDR_MEM_SIZE
|
||||
|
||||
#define VMALLOC_START (UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)
|
||||
#define VMALLOC_SIZE 0x08000000
|
||||
|
||||
#define PERIPH_DEVICE_BASE (VMALLOC_START + VMALLOC_SIZE)
|
||||
#define PERIPH_DEVICE_SIZE PERIPH_PMM_SIZE
|
||||
#define PERIPH_CACHED_BASE (PERIPH_DEVICE_BASE + PERIPH_DEVICE_SIZE)
|
||||
#define PERIPH_CACHED_SIZE PERIPH_PMM_SIZE
|
||||
#define PERIPH_UNCACHED_BASE (PERIPH_CACHED_BASE + PERIPH_CACHED_SIZE)
|
||||
#define PERIPH_UNCACHED_SIZE PERIPH_PMM_SIZE
|
||||
|
||||
#define IO_DEVICE_ADDR(paddr) (paddr - PERIPH_PMM_BASE + PERIPH_DEVICE_BASE)
|
||||
#define IO_CACHED_ADDR(paddr) (paddr - PERIPH_PMM_BASE + PERIPH_CACHED_BASE)
|
||||
#define IO_UNCACHED_ADDR(paddr) (paddr - PERIPH_PMM_BASE + PERIPH_UNCACHED_BASE)
|
||||
|
||||
#define MEM_CACHED_ADDR(paddr) (paddr - DDR_MEM_ADDR + KERNEL_VMM_BASE)
|
||||
#define MEM_UNCACHED_ADDR(paddr) (paddr - DDR_MEM_ADDR + UNCACHED_VMM_BASE)
|
||||
|
||||
#define VMM_TO_UNCACHED_ADDR(vaddr) (vaddr - KERNEL_VMM_BASE + UNCACHED_VMM_BASE)
|
||||
#define UNCACHED_TO_VMM_ADDR(vaddr) (vaddr - UNCACHED_VMM_BASE + KERNEL_VMM_BASE)
|
||||
|
||||
#define VMM_TO_DMA_ADDR(vaddr) (vaddr - KERNEL_VMM_BASE + SYS_MEM_BASE)
|
||||
#define DMA_TO_VMM_ADDR(vaddr) (vaddr - SYS_MEM_BASE + KERNEL_VMM_BASE)
|
||||
|
||||
#if (PERIPH_UNCACHED_BASE >= (0xFFFFFFFFU - PERIPH_UNCACHED_SIZE))
|
||||
#error "Kernel virtual memory space has overflowed!"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
349
kernel/base/ipc/los_event.c
Executable file
349
kernel/base/ipc/los_event.c
Executable file
@@ -0,0 +1,349 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_event_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_mp.h"
|
||||
#include "los_percpu_pri.h"
|
||||
|
||||
#if (LOSCFG_BASE_CORE_SWTMR == YES)
|
||||
#include "los_exc.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventInit(PEVENT_CB_S eventCB)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if (eventCB == NULL) {
|
||||
return LOS_ERRNO_EVENT_PTR_NULL;
|
||||
}
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
eventCB->uwEventID = 0;
|
||||
LOS_ListInit(&eventCB->stEventList);
|
||||
LOS_IntRestore(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC UINT32 OsEventParamCheck(const VOID *ptr, UINT32 eventMask, UINT32 mode)
|
||||
{
|
||||
if (ptr == NULL) {
|
||||
return LOS_ERRNO_EVENT_PTR_NULL;
|
||||
}
|
||||
|
||||
if (eventMask == 0) {
|
||||
return LOS_ERRNO_EVENT_EVENTMASK_INVALID;
|
||||
}
|
||||
|
||||
if (eventMask & LOS_ERRTYPE_ERROR) {
|
||||
return LOS_ERRNO_EVENT_SETBIT_INVALID;
|
||||
}
|
||||
|
||||
if (((mode & LOS_WAITMODE_OR) && (mode & LOS_WAITMODE_AND)) ||
|
||||
(mode & ~(LOS_WAITMODE_OR | LOS_WAITMODE_AND | LOS_WAITMODE_CLR)) ||
|
||||
!(mode & (LOS_WAITMODE_OR | LOS_WAITMODE_AND))) {
|
||||
return LOS_ERRNO_EVENT_FLAGS_INVALID;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 OsEventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode)
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
|
||||
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))) {
|
||||
ret = *eventID & eventMask;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret && (mode & LOS_WAITMODE_CLR)) {
|
||||
*eventID = *eventID & ~ret;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadCheck(const PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode)
|
||||
{
|
||||
UINT32 ret;
|
||||
LosTaskCB *runTask = NULL;
|
||||
|
||||
ret = OsEventParamCheck(eventCB, eventMask, mode);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC UINT32 OsEventReadImp(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode,
|
||||
UINT32 timeout, BOOL once)
|
||||
{
|
||||
UINT32 ret = 0;
|
||||
LosTaskCB *runTask = OsCurrTaskGet();
|
||||
|
||||
if (once == FALSE) {
|
||||
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;
|
||||
ret = OsTaskWait(&eventCB->stEventList, timeout, TRUE);
|
||||
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
|
||||
runTask->taskEvent = NULL;
|
||||
return LOS_ERRNO_EVENT_READ_TIMEOUT;
|
||||
}
|
||||
|
||||
ret = OsEventPoll(&eventCB->uwEventID, eventMask, mode);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC UINT32 OsEventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout,
|
||||
BOOL once)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 intSave;
|
||||
|
||||
ret = OsEventReadCheck(eventCB, eventMask, mode);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
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;
|
||||
|
||||
resumedTask->taskEvent = NULL;
|
||||
OsTaskWake(resumedTask);
|
||||
}
|
||||
|
||||
return exitFlag;
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT STATIC UINT32 OsEventWrite(PEVENT_CB_S eventCB, UINT32 events, BOOL once)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT8 exitFlag = 0;
|
||||
|
||||
if (eventCB == NULL) {
|
||||
return LOS_ERRNO_EVENT_PTR_NULL;
|
||||
}
|
||||
|
||||
if (events & LOS_ERRTYPE_ERROR) {
|
||||
return LOS_ERRNO_EVENT_SETBIT_INVALID;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_EventPoll(UINT32 *eventID, UINT32 eventMask, UINT32 mode)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 intSave;
|
||||
|
||||
ret = OsEventParamCheck((VOID *)eventID, eventMask, mode);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
ret = OsEventPoll(eventID, eventMask, mode);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_EventRead(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode, UINT32 timeout)
|
||||
{
|
||||
return OsEventRead(eventCB, eventMask, mode, timeout, FALSE);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_EventWrite(PEVENT_CB_S eventCB, UINT32 events)
|
||||
{
|
||||
return OsEventWrite(eventCB, events, FALSE);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsEventReadOnce(PEVENT_CB_S eventCB, UINT32 eventMask, UINT32 mode,
|
||||
UINT32 timeout)
|
||||
{
|
||||
return OsEventRead(eventCB, eventMask, mode, timeout, TRUE);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsEventWriteOnce(PEVENT_CB_S eventCB, UINT32 events)
|
||||
{
|
||||
return OsEventWrite(eventCB, events, TRUE);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_EventDestroy(PEVENT_CB_S eventCB)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if (eventCB == NULL) {
|
||||
return LOS_ERRNO_EVENT_PTR_NULL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (!LOS_ListEmpty(&eventCB->stEventList)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_ERRNO_EVENT_SHOULD_NOT_DESTORY;
|
||||
}
|
||||
|
||||
eventCB->uwEventID = 0;
|
||||
LOS_ListDelInit(&eventCB->stEventList);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_EventClear(PEVENT_CB_S eventCB, UINT32 events)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if (eventCB == NULL) {
|
||||
return LOS_ERRNO_EVENT_PTR_NULL;
|
||||
}
|
||||
SCHEDULER_LOCK(intSave);
|
||||
eventCB->uwEventID &= events;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_COMPAT_POSIX
|
||||
LITE_OS_SEC_TEXT UINT32 OsEventReadWithCond(const EventCond *cond, PEVENT_CB_S eventCB,
|
||||
UINT32 eventMask, UINT32 mode, UINT32 timeout)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 intSave;
|
||||
|
||||
ret = OsEventReadCheck(eventCB, eventMask, mode);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
if (*cond->realValue != cond->value) {
|
||||
eventCB->uwEventID &= cond->clearEvent;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
ret = OsEventReadImp(eventCB, eventMask, mode, timeout, FALSE);
|
||||
OUT:
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
944
kernel/base/ipc/los_futex.c
Executable file
944
kernel/base/ipc/los_futex.c
Executable file
@@ -0,0 +1,944 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_futex_pri.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "los_sys_pri.h"
|
||||
#include "los_sched_pri.h"
|
||||
#include "los_mp.h"
|
||||
#include "los_exc.h"
|
||||
#include "los_mux_pri.h"
|
||||
#include "user_copy.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#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)
|
||||
|
||||
typedef struct {
|
||||
LosMux listLock;
|
||||
LOS_DL_LIST lockList;
|
||||
} FutexHash;
|
||||
|
||||
#define FUTEX_INDEX_MAX 128
|
||||
FutexHash g_futexHash[FUTEX_INDEX_MAX];
|
||||
|
||||
STATIC INT32 OsFutexLock(LosMux *lock)
|
||||
{
|
||||
UINT32 ret = LOS_MuxLock(lock, LOS_WAIT_FOREVER);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Futex lock failed! ERROR: 0x%x!\n", ret);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexUnlock(LosMux *lock)
|
||||
{
|
||||
UINT32 ret = LOS_MuxUnlock(lock);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Futex unlock failed! ERROR: 0x%x!\n", ret);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsFutexInit(VOID)
|
||||
{
|
||||
INT32 count;
|
||||
UINT32 ret;
|
||||
|
||||
for (count = 0; count < FUTEX_INDEX_MAX; count++) {
|
||||
LOS_ListInit(&g_futexHash[count].lockList);
|
||||
ret = LOS_MuxInit(&(g_futexHash[count].listLock), NULL);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#ifdef LOS_FUTEX_DEBUG
|
||||
STATIC VOID OsFutexShowTaskNodeAttr(const LOS_DL_LIST *futexList)
|
||||
{
|
||||
FutexNode *tempNode = NULL;
|
||||
FutexNode *lastNode = NULL;
|
||||
LosTaskCB *taskCB = NULL;
|
||||
LOS_DL_LIST *queueList = NULL;
|
||||
|
||||
tempNode = OS_FUTEX_FROM_FUTEXLIST(futexList);
|
||||
PRINTK("key : 0x%x : ->", tempNode->key);
|
||||
|
||||
for (queueList = &tempNode->queueList; ;) {
|
||||
lastNode = OS_FUTEX_FROM_QUEUELIST(queueList);
|
||||
if (!LOS_ListEmpty(&(lastNode->pendList))) {
|
||||
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(lastNode->pendList)));
|
||||
PRINTK(" %d(%d) ->", taskCB->taskID, taskCB->priority);
|
||||
} else {
|
||||
taskCB = LOS_DL_LIST_ENTRY(lastNode, LosTaskCB, futex);
|
||||
PRINTK(" %d(%d) ->", taskCB->taskID, -1);
|
||||
}
|
||||
queueList = queueList->pstNext;
|
||||
if (queueList == &tempNode->queueList) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
PRINTK("\n");
|
||||
}
|
||||
|
||||
VOID OsFutexHashShow(VOID)
|
||||
{
|
||||
LOS_DL_LIST *futexList = NULL;
|
||||
INT32 count;
|
||||
/* The maximum number of barrels of a hash table */
|
||||
INT32 hashNodeMax = FUTEX_INDEX_MAX;
|
||||
PRINTK("################los_futex_pri.hash ######################\n");
|
||||
for (count = 0; count < hashNodeMax; count++) {
|
||||
futexList = &(g_futexHash[count].lockList);
|
||||
if (LOS_ListEmpty(futexList)) {
|
||||
continue;
|
||||
}
|
||||
PRINTK("hash -> index : %d\n", count);
|
||||
for (futexList = futexList->pstNext;
|
||||
futexList != &(g_futexHash[count].lockList);
|
||||
futexList = futexList->pstNext) {
|
||||
OsFutexShowTaskNodeAttr(futexList);
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC UINT32 OsFutexGetTick(UINT32 absTime)
|
||||
{
|
||||
UINT32 interval;
|
||||
|
||||
/* the values not less than per Millisecond */
|
||||
if (absTime < OS_SYS_MS_PER_SECOND) {
|
||||
interval = OS_SYS_MS_PER_SECOND / LOSCFG_BASE_CORE_TICK_PER_SECOND;
|
||||
} else {
|
||||
interval = absTime / OS_SYS_MS_PER_SECOND;
|
||||
}
|
||||
|
||||
interval = LOS_MS2Tick(interval);
|
||||
if (interval == 0) {
|
||||
interval = 1;
|
||||
}
|
||||
|
||||
return interval;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsFutexSetKey(UINTPTR futexKey, FutexNode *node)
|
||||
{
|
||||
node->key = futexKey;
|
||||
node->index = futexKey / OS_FUTEX_KEY_BASE;
|
||||
node->pid = LOS_GetCurrProcessID();
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsFutexDeinitFutexNode(FutexNode *node)
|
||||
{
|
||||
node->index = OS_INVALID_VALUE;
|
||||
node->pid = 0;
|
||||
LOS_ListDelete(&node->queueList);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsFutexReplaceQueueListHeadNode(FutexNode *oldHeadNode, FutexNode *newHeadNode)
|
||||
{
|
||||
LOS_DL_LIST *futexList = oldHeadNode->futexList.pstPrev;
|
||||
LOS_ListDelete(&oldHeadNode->futexList);
|
||||
LOS_ListHeadInsert(futexList, &newHeadNode->futexList);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsFutexDeleteKeyFromFutexList(FutexNode *node)
|
||||
{
|
||||
LOS_ListDelete(&node->futexList);
|
||||
}
|
||||
|
||||
STATIC VOID OsFutexDeleteKeyNodeFromHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags)
|
||||
{
|
||||
FutexNode *nextNode = NULL;
|
||||
|
||||
if (node->index >= FUTEX_INDEX_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOS_ListEmpty(&node->queueList)) {
|
||||
OsFutexDeleteKeyFromFutexList(node);
|
||||
if (queueFlags != NULL) {
|
||||
*queueFlags = TRUE;
|
||||
}
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
/* FutexList is not NULL, but the header node of queueList */
|
||||
if (node->futexList.pstNext != NULL) {
|
||||
if (isDeleteHead == TRUE) {
|
||||
nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&node->queueList));
|
||||
OsFutexReplaceQueueListHeadNode(node, nextNode);
|
||||
if (headNode != NULL) {
|
||||
*headNode = nextNode;
|
||||
}
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
EXIT:
|
||||
OsFutexDeinitFutexNode(node);
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsFutexNodeDeleteFromFutexHash(FutexNode *node, BOOL isDeleteHead, FutexNode **headNode, BOOL *queueFlags)
|
||||
{
|
||||
FutexHash *hashNode = NULL;
|
||||
UINT32 index = node->key / OS_FUTEX_KEY_BASE;
|
||||
|
||||
if (index >= FUTEX_INDEX_MAX) {
|
||||
return;
|
||||
}
|
||||
|
||||
hashNode = &g_futexHash[index];
|
||||
if (OsMuxLockUnsafe(&hashNode->listLock, LOS_WAIT_FOREVER)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (node->index != index) {
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
OsFutexDeleteKeyNodeFromHash(node, isDeleteHead, headNode, queueFlags);
|
||||
|
||||
EXIT:
|
||||
if (OsMuxUnlockUnsafe(OsCurrTaskGet(), &hashNode->listLock, NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC FutexNode *OsFutexDeleteAlreadyWakeTaskAndGetNext(const FutexNode *node, FutexNode **headNode, BOOL isDeleteHead)
|
||||
{
|
||||
FutexNode *tempNode = (FutexNode *)node;
|
||||
FutexNode *nextNode = NULL;
|
||||
BOOL queueFlag = FALSE;
|
||||
|
||||
while (LOS_ListEmpty(&(tempNode->pendList))) { /* already weak */
|
||||
if (!LOS_ListEmpty(&(tempNode->queueList))) { /* It's not a head node */
|
||||
nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&(tempNode->queueList)));
|
||||
}
|
||||
|
||||
OsFutexDeleteKeyNodeFromHash(tempNode, isDeleteHead, headNode, &queueFlag);
|
||||
if (queueFlag) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
tempNode = nextNode;
|
||||
}
|
||||
|
||||
return tempNode;
|
||||
}
|
||||
|
||||
STATIC VOID OsFutexInsertNewFutexKeyToHash(FutexNode *node)
|
||||
{
|
||||
FutexNode *headNode = NULL;
|
||||
FutexNode *tailNode = NULL;
|
||||
LOS_DL_LIST *futexList = NULL;
|
||||
FutexHash *hashNode = &g_futexHash[node->index];
|
||||
|
||||
if (LOS_ListEmpty(&hashNode->lockList)) {
|
||||
LOS_ListHeadInsert(&(hashNode->lockList), &(node->futexList));
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
headNode = OS_FUTEX_FROM_FUTEXLIST(LOS_DL_LIST_FIRST(&(hashNode->lockList)));
|
||||
/* The small key is at the front of the queue */
|
||||
if (node->key < headNode->key) {
|
||||
LOS_ListHeadInsert(&(hashNode->lockList), &(node->futexList));
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
tailNode = OS_FUTEX_FROM_FUTEXLIST(LOS_DL_LIST_LAST(&(hashNode->lockList)));
|
||||
if (node->key > tailNode->key) {
|
||||
LOS_ListTailInsert(&(hashNode->lockList), &(node->futexList));
|
||||
goto EXIT;
|
||||
}
|
||||
|
||||
for (futexList = hashNode->lockList.pstNext;
|
||||
futexList != &(hashNode->lockList);
|
||||
futexList = futexList->pstNext) {
|
||||
headNode = OS_FUTEX_FROM_FUTEXLIST(futexList);
|
||||
if (node->key > headNode->key) {
|
||||
continue;
|
||||
} else if (node->key < headNode->key) {
|
||||
LOS_ListTailInsert(&(headNode->futexList), &(node->futexList));
|
||||
break;
|
||||
}
|
||||
|
||||
LOS_ListTailInsert(&(headNode->futexList), &(node->futexList));
|
||||
break;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexInsertFindFormBackToFront(LOS_DL_LIST *queueList, const LosTaskCB *runTask, FutexNode *node)
|
||||
{
|
||||
LOS_DL_LIST *listHead = queueList;
|
||||
LOS_DL_LIST *listTail = queueList->pstPrev;
|
||||
FutexNode *tempNode = NULL;
|
||||
LosTaskCB *taskTail = NULL;
|
||||
|
||||
for (; listHead != listTail; listTail = listTail->pstPrev) {
|
||||
tempNode = OS_FUTEX_FROM_QUEUELIST(listTail);
|
||||
tempNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(tempNode, NULL, FALSE);
|
||||
taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList)));
|
||||
if (runTask->priority >= taskTail->priority) {
|
||||
LOS_ListHeadInsert(&(tempNode->queueList), &(node->queueList));
|
||||
return LOS_OK;
|
||||
} else if (runTask->priority < taskTail->priority) {
|
||||
if (listTail->pstPrev == listHead) {
|
||||
LOS_ListTailInsert(&(tempNode->queueList), &(node->queueList));
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexInsertFindFromFrontToBack(LOS_DL_LIST *queueList, const LosTaskCB *runTask, FutexNode *node)
|
||||
{
|
||||
LOS_DL_LIST *listHead = queueList;
|
||||
LOS_DL_LIST *listTail = queueList->pstPrev;
|
||||
FutexNode *tempNode = NULL;
|
||||
LosTaskCB *taskHead = NULL;
|
||||
|
||||
for (; listHead != listTail; listHead = listHead->pstNext) {
|
||||
tempNode = OS_FUTEX_FROM_QUEUELIST(listHead);
|
||||
tempNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(tempNode, NULL, FALSE);
|
||||
taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tempNode->pendList)));
|
||||
/* High priority comes before low priority,
|
||||
* in the case of the same priority, after the current node
|
||||
*/
|
||||
if (runTask->priority >= taskHead->priority) {
|
||||
if (listHead->pstNext == listTail) {
|
||||
LOS_ListHeadInsert(&(tempNode->queueList), &(node->queueList));
|
||||
return LOS_OK;
|
||||
}
|
||||
continue;
|
||||
} else if (runTask->priority < taskHead->priority) {
|
||||
LOS_ListTailInsert(&(tempNode->queueList), &(node->queueList));
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexRecycleAndFindHeadNode(FutexNode *headNode, FutexNode *node, FutexNode **firstNode)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
*firstNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(headNode, NULL, TRUE);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
/* The head node is removed and there was originally only one node under the key */
|
||||
if (*firstNode == NULL) {
|
||||
OsFutexInsertNewFutexKeyToHash(node);
|
||||
LOS_ListInit(&(node->queueList));
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexInsertTasktoPendList(FutexNode **firstNode, FutexNode *node, const LosTaskCB *run)
|
||||
{
|
||||
LosTaskCB *taskHead = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&((*firstNode)->pendList)));
|
||||
LOS_DL_LIST *queueList = &((*firstNode)->queueList);
|
||||
FutexNode *tailNode = NULL;
|
||||
LosTaskCB *taskTail = NULL;
|
||||
|
||||
if (run->priority < taskHead->priority) {
|
||||
/* The one with the highest priority is inserted at the top of the queue */
|
||||
LOS_ListTailInsert(queueList, &(node->queueList));
|
||||
OsFutexReplaceQueueListHeadNode(*firstNode, node);
|
||||
*firstNode = node;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
if (LOS_ListEmpty(queueList) && (run->priority >= taskHead->priority)) {
|
||||
/* Insert the next position in the queue with equal priority */
|
||||
LOS_ListHeadInsert(queueList, &(node->queueList));
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList));
|
||||
taskTail = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(tailNode->pendList)));
|
||||
if ((run->priority >= taskTail->priority) ||
|
||||
((run->priority - taskHead->priority) > (taskTail->priority - run->priority))) {
|
||||
return OsFutexInsertFindFormBackToFront(queueList, run, node);
|
||||
}
|
||||
|
||||
return OsFutexInsertFindFromFrontToBack(queueList, run, node);
|
||||
}
|
||||
|
||||
STATIC FutexNode *OsFindFutexNode(const FutexNode *node)
|
||||
{
|
||||
FutexHash *hashNode = &g_futexHash[node->index];
|
||||
LOS_DL_LIST *futexList = &(hashNode->lockList);
|
||||
FutexNode *headNode = NULL;
|
||||
|
||||
for (futexList = futexList->pstNext;
|
||||
futexList != &(hashNode->lockList);
|
||||
futexList = futexList->pstNext) {
|
||||
headNode = OS_FUTEX_FROM_FUTEXLIST(futexList);
|
||||
if ((headNode->key == node->key) && (headNode->pid == node->pid)) {
|
||||
return headNode;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFindAndInsertToHash(FutexNode *node)
|
||||
{
|
||||
FutexNode *headNode = NULL;
|
||||
FutexNode *firstNode = NULL;
|
||||
UINT32 intSave;
|
||||
INT32 ret;
|
||||
|
||||
headNode = OsFindFutexNode(node);
|
||||
if (headNode == NULL) {
|
||||
OsFutexInsertNewFutexKeyToHash(node);
|
||||
LOS_ListInit(&(node->queueList));
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
ret = OsFutexRecycleAndFindHeadNode(headNode, node, &firstNode);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
} else if (firstNode == NULL) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
ret = OsFutexInsertTasktoPendList(&firstNode, node, OsCurrTaskGet());
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexWaitParmaCheck(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime)
|
||||
{
|
||||
UINTPTR futexKey = (UINTPTR)userVaddr;
|
||||
UINT32 lockVal;
|
||||
INT32 ret;
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
return LOS_EINTR;
|
||||
}
|
||||
|
||||
if (flags) {
|
||||
PRINT_ERR("Futex wait parma check failed! error flags: 0x%x\n", flags);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if ((futexKey % sizeof(INT32)) || (futexKey < OS_FUTEX_KEY_BASE) || (futexKey >= OS_FUTEX_KEY_MAX)) {
|
||||
PRINT_ERR("Futex wait parma check failed! error futex key: 0x%x\n", futexKey);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (!absTime) {
|
||||
PRINT_ERR("Futex wait parma check failed! error absTime: %u\n", absTime);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
ret = LOS_ArchCopyFromUser(&lockVal, userVaddr, sizeof(UINT32));
|
||||
if (ret) {
|
||||
PRINT_ERR("Futex wait parma check failed! copy from user failed!\n");
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (lockVal != val) {
|
||||
return LOS_EBADF;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexDeleteTimeoutTaskNode(FutexHash *hashNode, FutexNode *node)
|
||||
{
|
||||
UINT32 intSave;
|
||||
if (OsFutexLock(&hashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (node->index < FUTEX_INDEX_MAX) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
(VOID)OsFutexDeleteAlreadyWakeTaskAndGetNext(node, NULL, TRUE);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
#ifdef LOS_FUTEX_DEBUG
|
||||
OsFutexHashShow();
|
||||
#endif
|
||||
|
||||
if (OsFutexUnlock(&hashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
return LOS_ETIMEDOUT;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexInserTaskToHash(LosTaskCB **taskCB, FutexNode **node, const UINTPTR futexKey)
|
||||
{
|
||||
INT32 ret;
|
||||
*taskCB = OsCurrTaskGet();
|
||||
*node = &((*taskCB)->futex);
|
||||
OsFutexSetKey(futexKey, *node);
|
||||
|
||||
ret = OsFindAndInsertToHash(*node);
|
||||
if (ret) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
LOS_ListInit(&((*node)->pendList));
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexWaitTask(const UINT32 timeOut, const UINT32 *userVaddr)
|
||||
{
|
||||
INT32 futexRet;
|
||||
UINT32 intSave;
|
||||
LosTaskCB *taskCB = NULL;
|
||||
FutexNode *node = NULL;
|
||||
UINTPTR futexKey = (UINTPTR)userVaddr;
|
||||
UINT32 index = futexKey / OS_FUTEX_KEY_BASE;
|
||||
FutexHash *hashNode = &g_futexHash[index];
|
||||
|
||||
if (OsFutexLock(&hashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (OsFutexInserTaskToHash(&taskCB, &node, futexKey)) {
|
||||
goto EXIT_ERR;
|
||||
}
|
||||
SCHEDULER_LOCK(intSave);
|
||||
OsTaskWait(&(node->pendList), timeOut, FALSE);
|
||||
OsPercpuGet()->taskLockCnt++;
|
||||
LOS_SpinUnlock(&g_taskSpin);
|
||||
|
||||
#ifdef LOS_FUTEX_DEBUG
|
||||
OsFutexHashShow();
|
||||
#endif
|
||||
|
||||
futexRet = OsFutexUnlock(&hashNode->listLock);
|
||||
if (futexRet) {
|
||||
OsPercpuGet()->taskLockCnt--;
|
||||
LOS_IntRestore(intSave);
|
||||
goto EXIT_UNLOCK_ERR;
|
||||
}
|
||||
|
||||
LOS_SpinLock(&g_taskSpin);
|
||||
OsPercpuGet()->taskLockCnt--;
|
||||
|
||||
/*
|
||||
* it will immediately do the scheduling, so there's no need to release the
|
||||
* task spinlock. when this task's been rescheduled, it will be holding the spinlock.
|
||||
*/
|
||||
OsSchedResched();
|
||||
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_TIMEOUT) {
|
||||
taskCB->taskStatus &= ~OS_TASK_STATUS_TIMEOUT;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return OsFutexDeleteTimeoutTaskNode(hashNode, node);
|
||||
}
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
|
||||
EXIT_ERR:
|
||||
futexRet = OsFutexUnlock(&hashNode->listLock);
|
||||
EXIT_UNLOCK_ERR:
|
||||
if (futexRet) {
|
||||
return futexRet;
|
||||
}
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
INT32 OsFutexWait(const UINT32 *userVaddr, UINT32 flags, UINT32 val, UINT32 absTime)
|
||||
{
|
||||
INT32 ret;
|
||||
UINT32 timeOut = LOS_WAIT_FOREVER;
|
||||
|
||||
ret = OsFutexWaitParmaCheck(userVaddr, flags, val, absTime);
|
||||
if (ret) {
|
||||
return ret;
|
||||
}
|
||||
if (absTime != LOS_WAIT_FOREVER) {
|
||||
timeOut = OsFutexGetTick(absTime);
|
||||
}
|
||||
|
||||
return OsFutexWaitTask(timeOut, userVaddr);
|
||||
}
|
||||
|
||||
/* Check to see if the task to be awakened has timed out
|
||||
* if time out, to weak next pend task.
|
||||
*/
|
||||
STATIC VOID OsFutexCheckAndWakePendTask(FutexNode *headNode, const INT32 wakeNumber,
|
||||
FutexHash *hashNode, FutexNode **nextNode, BOOL *wakeAny)
|
||||
{
|
||||
INT32 count;
|
||||
LosTaskCB *taskCB = NULL;
|
||||
FutexNode *node = headNode;
|
||||
for (count = 0; count < wakeNumber; count++) {
|
||||
/* Ensure the integrity of the head */
|
||||
*nextNode = OsFutexDeleteAlreadyWakeTaskAndGetNext(node, NULL, FALSE);
|
||||
if (*nextNode == NULL) {
|
||||
/* The last node in queuelist is invalid or the entire list is invalid */
|
||||
return;
|
||||
}
|
||||
node = *nextNode;
|
||||
taskCB = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(node->pendList)));
|
||||
OsTaskWake(taskCB);
|
||||
*wakeAny = TRUE;
|
||||
*nextNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_FIRST(&(node->queueList)));
|
||||
if (node != headNode) {
|
||||
OsFutexDeinitFutexNode(node);
|
||||
}
|
||||
|
||||
if (LOS_ListEmpty(&headNode->queueList)) {
|
||||
/* Wakes up the entire linked list node */
|
||||
*nextNode = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
node = *nextNode;
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexWakeTask(UINTPTR futexKey, INT32 wakeNumber, FutexNode **newHeadNode, BOOL *wakeAny)
|
||||
{
|
||||
UINT32 intSave;
|
||||
FutexNode *node = NULL;
|
||||
FutexNode *headNode = NULL;
|
||||
UINT32 index = futexKey / OS_FUTEX_KEY_BASE;
|
||||
FutexHash *hashNode = &g_futexHash[index];
|
||||
FutexNode tempNode = {
|
||||
.key = futexKey,
|
||||
.index = index,
|
||||
.pid = LOS_GetCurrProcessID(),
|
||||
};
|
||||
|
||||
node = OsFindFutexNode(&tempNode);
|
||||
if (node == NULL) {
|
||||
return LOS_EBADF;
|
||||
}
|
||||
|
||||
headNode = node;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
OsFutexCheckAndWakePendTask(headNode, wakeNumber, hashNode, newHeadNode, wakeAny);
|
||||
if ((*newHeadNode) != NULL) {
|
||||
OsFutexReplaceQueueListHeadNode(headNode, *newHeadNode);
|
||||
OsFutexDeinitFutexNode(headNode);
|
||||
} else if (headNode->index < FUTEX_INDEX_MAX) {
|
||||
OsFutexDeleteKeyFromFutexList(headNode);
|
||||
OsFutexDeinitFutexNode(headNode);
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
INT32 OsFutexWake(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber)
|
||||
{
|
||||
INT32 ret, futexRet;
|
||||
UINTPTR futexKey = (UINTPTR)userVaddr;
|
||||
FutexHash *hashNode = NULL;
|
||||
INT32 index = futexKey / OS_FUTEX_KEY_BASE;
|
||||
FutexNode *headNode = NULL;
|
||||
BOOL wakeAny = FALSE;
|
||||
|
||||
if (!(flags & FUTEX_WAKE)) {
|
||||
PRINT_ERR("Futex wake param check failed! error flags: 0x%x\n", flags);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if ((futexKey % sizeof(INT32)) || (futexKey < OS_FUTEX_KEY_BASE) || (futexKey >= OS_FUTEX_KEY_MAX)) {
|
||||
PRINT_ERR("Futex wake param check failed! error futex key: 0x%x\n", futexKey);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
hashNode = &g_futexHash[index];
|
||||
if (OsFutexLock(&hashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
ret = OsFutexWakeTask(futexKey, wakeNumber, &headNode, &wakeAny);
|
||||
if (ret) {
|
||||
goto EXIT_ERR;
|
||||
}
|
||||
|
||||
#ifdef LOS_FUTEX_DEBUG
|
||||
OsFutexHashShow();
|
||||
#endif
|
||||
|
||||
futexRet = OsFutexUnlock(&hashNode->listLock);
|
||||
if (futexRet) {
|
||||
goto EXIT_UNLOCK_ERR;
|
||||
}
|
||||
|
||||
if (wakeAny == TRUE) {
|
||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||
LOS_Schedule();
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
|
||||
EXIT_ERR:
|
||||
futexRet = OsFutexUnlock(&hashNode->listLock);
|
||||
EXIT_UNLOCK_ERR:
|
||||
if (futexRet) {
|
||||
return futexRet;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexRequeueInsertNewKey(UINTPTR newFutexKey, INT32 newIndex, FutexNode *oldHeadNode)
|
||||
{
|
||||
INT32 ret;
|
||||
UINT32 intSave;
|
||||
LosTaskCB *task = NULL;
|
||||
FutexNode *nextNode = NULL;
|
||||
FutexNode newTempNode = {
|
||||
.key = newFutexKey,
|
||||
.index = newIndex,
|
||||
.pid = LOS_GetCurrProcessID(),
|
||||
};
|
||||
LOS_DL_LIST *queueList = &oldHeadNode->queueList;
|
||||
FutexNode *newHeadNode = OsFindFutexNode(&newTempNode);
|
||||
if (newHeadNode == NULL) {
|
||||
OsFutexInsertNewFutexKeyToHash(oldHeadNode);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
do {
|
||||
nextNode = OS_FUTEX_FROM_QUEUELIST(queueList);
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (LOS_ListEmpty(&nextNode->pendList)) {
|
||||
queueList = queueList->pstNext;
|
||||
OsFutexDeinitFutexNode(nextNode);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if (queueList->pstNext != NULL) {
|
||||
continue;
|
||||
} else {
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
task = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(nextNode->pendList)));
|
||||
queueList = queueList->pstNext;
|
||||
LOS_ListDelete(&nextNode->queueList);
|
||||
ret = OsFutexInsertTasktoPendList(&newHeadNode, nextNode, task);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_ERR("Futex requeue insert new key failed!\n");
|
||||
}
|
||||
} while (queueList->pstNext != NULL);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID OsFutexRequeueSplitTwoLists(FutexHash *oldHashNode, FutexNode *oldHeadNode, UINTPTR futexKey, INT32 count)
|
||||
{
|
||||
LOS_DL_LIST *queueList = &oldHeadNode->queueList;
|
||||
FutexNode *tailNode = OS_FUTEX_FROM_QUEUELIST(LOS_DL_LIST_LAST(queueList));
|
||||
INT32 newIndex = futexKey / OS_FUTEX_KEY_BASE;
|
||||
FutexNode *nextNode = NULL;
|
||||
FutexNode *newHeadNode = NULL;
|
||||
LOS_DL_LIST *futexList = NULL;
|
||||
BOOL IsAll = FALSE;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < count; i++) {
|
||||
nextNode = OS_FUTEX_FROM_QUEUELIST(queueList);
|
||||
nextNode->key = futexKey;
|
||||
nextNode->index = newIndex;
|
||||
if (queueList->pstNext == &oldHeadNode->queueList) {
|
||||
IsAll = TRUE;
|
||||
break;
|
||||
}
|
||||
|
||||
queueList = queueList->pstNext;
|
||||
}
|
||||
|
||||
futexList = oldHeadNode->futexList.pstPrev;
|
||||
LOS_ListDelete(&oldHeadNode->futexList);
|
||||
if (IsAll == TRUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
newHeadNode = OS_FUTEX_FROM_QUEUELIST(queueList);
|
||||
LOS_ListHeadInsert(futexList, &newHeadNode->futexList);
|
||||
oldHeadNode->queueList.pstPrev = &nextNode->queueList;
|
||||
nextNode->queueList.pstNext = &oldHeadNode->queueList;
|
||||
newHeadNode->queueList.pstPrev = &tailNode->queueList;
|
||||
tailNode->queueList.pstNext = &newHeadNode->queueList;
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC FutexNode *OsFutexRequeueRemoveOldKeyAndGetHead(UINTPTR oldFutexKey, INT32 wakeNumber,
|
||||
UINTPTR newFutexKey, INT32 requeueCount, BOOL *wakeAny)
|
||||
{
|
||||
INT32 ret;
|
||||
FutexNode *oldHeadNode = NULL;
|
||||
INT32 oldIndex = oldFutexKey / OS_FUTEX_KEY_BASE;
|
||||
FutexHash *oldHashNode = &g_futexHash[oldIndex];
|
||||
FutexNode oldTempNode = {
|
||||
.key = oldFutexKey,
|
||||
.index = oldIndex,
|
||||
.pid = LOS_GetCurrProcessID(),
|
||||
};
|
||||
|
||||
if (wakeNumber > 0) {
|
||||
ret = OsFutexWakeTask(oldFutexKey, wakeNumber, &oldHeadNode, wakeAny);
|
||||
if ((ret != LOS_OK) || (oldHeadNode == NULL)) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
if (requeueCount <= 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (oldHeadNode == NULL) {
|
||||
oldHeadNode = OsFindFutexNode(&oldTempNode);
|
||||
if (oldHeadNode == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
OsFutexRequeueSplitTwoLists(oldHashNode, oldHeadNode, newFutexKey, requeueCount);
|
||||
|
||||
return oldHeadNode;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFutexRequeueParamCheck(UINTPTR oldFutexKey, UINTPTR newFutexKey)
|
||||
{
|
||||
if (oldFutexKey == newFutexKey) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if ((oldFutexKey % sizeof(INT32)) || (oldFutexKey < OS_FUTEX_KEY_BASE) || (oldFutexKey >= OS_FUTEX_KEY_MAX)) {
|
||||
PRINT_ERR("Futex requeue param check failed! error old futex key: 0x%x\n", oldFutexKey);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if ((newFutexKey % sizeof(INT32)) || (newFutexKey < OS_FUTEX_KEY_BASE) || (newFutexKey >= OS_FUTEX_KEY_MAX)) {
|
||||
PRINT_ERR("Futex requeue param check failed! error new futex key: 0x%x\n", newFutexKey);
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
INT32 OsFutexRequeue(const UINT32 *userVaddr, UINT32 flags, INT32 wakeNumber, INT32 count, const UINT32 *newUserVaddr)
|
||||
{
|
||||
INT32 ret;
|
||||
UINTPTR oldFutexKey = (UINTPTR)userVaddr;
|
||||
UINTPTR newFutexKey = (UINTPTR)newUserVaddr;
|
||||
INT32 oldIndex = oldFutexKey / OS_FUTEX_KEY_BASE;
|
||||
INT32 newIndex = newFutexKey / OS_FUTEX_KEY_BASE;
|
||||
FutexHash *oldHashNode = NULL;
|
||||
FutexHash *newHashNode = NULL;
|
||||
FutexNode *oldHeadNode = NULL;
|
||||
BOOL wakeAny = FALSE;
|
||||
|
||||
if (OsFutexRequeueParamCheck(oldFutexKey, newFutexKey)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
oldHashNode = &g_futexHash[oldIndex];
|
||||
if (OsFutexLock(&oldHashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
oldHeadNode = OsFutexRequeueRemoveOldKeyAndGetHead(oldFutexKey, wakeNumber, newFutexKey, count, &wakeAny);
|
||||
if (oldHeadNode == NULL) {
|
||||
(VOID)OsFutexUnlock(&oldHashNode->listLock);
|
||||
if (wakeAny == TRUE) {
|
||||
ret = LOS_OK;
|
||||
goto EXIT;
|
||||
}
|
||||
return LOS_EBADF;
|
||||
}
|
||||
|
||||
newHashNode = &g_futexHash[newIndex];
|
||||
if (oldIndex != newIndex) {
|
||||
if (OsFutexUnlock(&oldHashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (OsFutexLock(&newHashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = OsFutexRequeueInsertNewKey(newFutexKey, newIndex, oldHeadNode);
|
||||
|
||||
if (OsFutexUnlock(&newHashNode->listLock)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
EXIT:
|
||||
if (wakeAny == TRUE) {
|
||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||
LOS_Schedule();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
90
kernel/base/ipc/los_ipcdebug.c
Executable file
90
kernel/base/ipc/los_ipcdebug.c
Executable file
@@ -0,0 +1,90 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_ipcdebug_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_DEBUG_QUEUE)
|
||||
|
||||
VOID OsArraySortByTime(UINT32 *sortArray, UINT32 start, UINT32 end, const IpcSortParam *sortParam,
|
||||
OsCompareFunc compareFunc)
|
||||
{
|
||||
UINT32 left = start;
|
||||
UINT32 right = end;
|
||||
UINT32 idx = start;
|
||||
UINT32 pivot = sortArray[start];
|
||||
|
||||
while (left < right) {
|
||||
while ((left < right) && (sortArray[right] < sortParam->ipcDebugCBCnt) && (pivot < sortParam->ipcDebugCBCnt) &&
|
||||
compareFunc(sortParam, sortArray[right], pivot)) {
|
||||
right--;
|
||||
}
|
||||
|
||||
if (left < right) {
|
||||
sortArray[left] = sortArray[right];
|
||||
idx = right;
|
||||
left++;
|
||||
}
|
||||
|
||||
while ((left < right) && (sortArray[left] < sortParam->ipcDebugCBCnt) && (pivot < sortParam->ipcDebugCBCnt) &&
|
||||
compareFunc(sortParam, pivot, sortArray[left])) {
|
||||
left++;
|
||||
}
|
||||
|
||||
if (left < right) {
|
||||
sortArray[right] = sortArray[left];
|
||||
idx = left;
|
||||
right--;
|
||||
}
|
||||
}
|
||||
|
||||
sortArray[idx] = pivot;
|
||||
|
||||
if (start < idx) {
|
||||
OsArraySortByTime(sortArray, start, idx - 1, sortParam, compareFunc);
|
||||
}
|
||||
if (idx < end) {
|
||||
OsArraySortByTime(sortArray, idx + 1, end, sortParam, compareFunc);
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
612
kernel/base/ipc/los_mux.c
Executable file
612
kernel/base/ipc/los_mux.c
Executable file
@@ -0,0 +1,612 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_mux_pri.h"
|
||||
#include "los_bitmap.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_mp.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_exc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_BASE_IPC_MUX == YES)
|
||||
#define MUTEXATTR_TYPE_MASK 0x0FU
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrInit(LosMuxAttr *attr)
|
||||
{
|
||||
if (attr == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
attr->protocol = LOS_MUX_PRIO_INHERIT;
|
||||
attr->prioceiling = OS_TASK_PRIORITY_LOWEST;
|
||||
attr->type = LOS_MUX_DEFAULT;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrDestroy(LosMuxAttr *attr)
|
||||
{
|
||||
if (attr == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetType(const LosMuxAttr *attr, INT32 *outType)
|
||||
{
|
||||
INT32 type;
|
||||
|
||||
if ((attr == NULL) || (outType == NULL)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
type = (INT32)(attr->type & MUTEXATTR_TYPE_MASK);
|
||||
if ((type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
*outType = type;
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetType(LosMuxAttr *attr, INT32 type)
|
||||
{
|
||||
if ((attr == NULL) || (type < LOS_MUX_NORMAL) || (type > LOS_MUX_ERRORCHECK)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
attr->type = (UINT8)((attr->type & ~MUTEXATTR_TYPE_MASK) | (UINT32)type);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetProtocol(const LosMuxAttr *attr, INT32 *protocol)
|
||||
{
|
||||
if ((attr != NULL) && (protocol != NULL)) {
|
||||
*protocol = attr->protocol;
|
||||
} else {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetProtocol(LosMuxAttr *attr, INT32 protocol)
|
||||
{
|
||||
if (attr == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
switch (protocol) {
|
||||
case LOS_MUX_PRIO_NONE:
|
||||
case LOS_MUX_PRIO_INHERIT:
|
||||
case LOS_MUX_PRIO_PROTECT:
|
||||
attr->protocol = (UINT8)protocol;
|
||||
return LOS_OK;
|
||||
default:
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrGetPrioceiling(const LosMuxAttr *attr, INT32 *prioceiling)
|
||||
{
|
||||
if (attr == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (prioceiling != NULL) {
|
||||
*prioceiling = attr->prioceiling;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxAttrSetPrioceiling(LosMuxAttr *attr, INT32 prioceiling)
|
||||
{
|
||||
if ((attr == NULL) ||
|
||||
(prioceiling < OS_TASK_PRIORITY_HIGHEST) ||
|
||||
(prioceiling > OS_TASK_PRIORITY_LOWEST)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
attr->prioceiling = (UINT8)prioceiling;
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxSetPrioceiling(LosMux *mutex, INT32 prioceiling, INT32 *oldPrioceiling)
|
||||
{
|
||||
INT32 ret;
|
||||
INT32 retLock;
|
||||
if ((mutex == NULL) ||
|
||||
(prioceiling < OS_TASK_PRIORITY_HIGHEST) ||
|
||||
(prioceiling > OS_TASK_PRIORITY_LOWEST)) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
retLock = LOS_MuxLock(mutex, LOS_WAIT_FOREVER);
|
||||
if (retLock != LOS_OK) {
|
||||
return retLock;
|
||||
}
|
||||
|
||||
if (oldPrioceiling != NULL) {
|
||||
*oldPrioceiling = mutex->attr.prioceiling;
|
||||
}
|
||||
|
||||
ret = LOS_MuxAttrSetPrioceiling(&mutex->attr, prioceiling);
|
||||
|
||||
retLock = LOS_MuxUnlock(mutex);
|
||||
if ((ret == LOS_OK) && (retLock != LOS_OK)) {
|
||||
return retLock;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxGetPrioceiling(const LosMux *mutex, INT32 *prioceiling)
|
||||
{
|
||||
if ((mutex != NULL) && (prioceiling != NULL) && (mutex->magic == OS_MUX_MAGIC)) {
|
||||
*prioceiling = mutex->attr.prioceiling;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT BOOL LOS_MuxIsValid(const LosMux *mutex)
|
||||
{
|
||||
if ((mutex != NULL) && (mutex->magic == OS_MUX_MAGIC)) {
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsCheckMutexAttr(const LosMuxAttr *attr)
|
||||
{
|
||||
if (((INT8)(attr->type) < LOS_MUX_NORMAL) || (attr->type > LOS_MUX_ERRORCHECK)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
if (((INT8)(attr->prioceiling) < OS_TASK_PRIORITY_HIGHEST) || (attr->prioceiling > OS_TASK_PRIORITY_LOWEST)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
if (((INT8)(attr->protocol) < LOS_MUX_PRIO_NONE) || (attr->protocol > LOS_MUX_PRIO_PROTECT)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxInit(LosMux *mutex, const LosMuxAttr *attr)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (attr == NULL) {
|
||||
(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;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxDestroy(LosMux *mutex)
|
||||
{
|
||||
UINT32 intSave;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (mutex->magic != OS_MUX_MAGIC) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_EBADF;
|
||||
}
|
||||
|
||||
if (mutex->muxCount != 0) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_EBUSY;
|
||||
}
|
||||
|
||||
(VOID)memset_s(mutex, sizeof(LosMux), 0, sizeof(LosMux));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID OsMuxBitmapSet(const LosMux *mutex, const LosTaskCB *runTask, LosTaskCB *owner)
|
||||
{
|
||||
if ((owner->priority > runTask->priority) && (mutex->attr.protocol == LOS_MUX_PRIO_INHERIT)) {
|
||||
LOS_BitmapSet(&(owner->priBitMap), owner->priority);
|
||||
OsTaskPriModify(owner, runTask->priority);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsMuxBitmapRestore(const LosMux *mutex, const LosTaskCB *taskCB, LosTaskCB *owner)
|
||||
{
|
||||
UINT16 bitMapPri;
|
||||
|
||||
if (mutex->attr.protocol != LOS_MUX_PRIO_INHERIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (owner->priority >= taskCB->priority) {
|
||||
bitMapPri = LOS_LowBitGet(owner->priBitMap);
|
||||
if (bitMapPri != LOS_INVALID_BIT_INDEX) {
|
||||
LOS_BitmapClr(&(owner->priBitMap), bitMapPri);
|
||||
OsTaskPriModify(owner, bitMapPri);
|
||||
}
|
||||
} else {
|
||||
if (LOS_HighBitGet(owner->priBitMap) != taskCB->priority) {
|
||||
LOS_BitmapClr(&(owner->priBitMap), taskCB->priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC LOS_DL_LIST *OsMuxPendFindPosSub(const LosTaskCB *runTask, const LosMux *mutex)
|
||||
{
|
||||
LosTaskCB *pendedTask = NULL;
|
||||
LOS_DL_LIST *node = NULL;
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, &(mutex->muxList), LosTaskCB, pendList) {
|
||||
if (pendedTask->priority < runTask->priority) {
|
||||
continue;
|
||||
} else if (pendedTask->priority > runTask->priority) {
|
||||
node = &pendedTask->pendList;
|
||||
break;
|
||||
} else {
|
||||
node = pendedTask->pendList.pstNext;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
STATIC LOS_DL_LIST *OsMuxPendFindPos(const LosTaskCB *runTask, LosMux *mutex)
|
||||
{
|
||||
LosTaskCB *pendedTask1 = NULL;
|
||||
LosTaskCB *pendedTask2 = NULL;
|
||||
LOS_DL_LIST *node = NULL;
|
||||
|
||||
if (LOS_ListEmpty(&mutex->muxList)) {
|
||||
node = &mutex->muxList;
|
||||
} else {
|
||||
pendedTask1 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&mutex->muxList));
|
||||
pendedTask2 = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_LAST(&mutex->muxList));
|
||||
if ((pendedTask1 != NULL) && (pendedTask1->priority > runTask->priority)) {
|
||||
node = mutex->muxList.pstNext;
|
||||
} else if ((pendedTask2 != NULL) && (pendedTask2->priority <= runTask->priority)) {
|
||||
node = &mutex->muxList;
|
||||
} else {
|
||||
node = OsMuxPendFindPosSub(runTask, mutex);
|
||||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
}
|
||||
|
||||
STATIC UINT32 OsMuxPendOp(LosTaskCB *runTask, LosMux *mutex, UINT32 timeout)
|
||||
{
|
||||
UINT32 ret;
|
||||
LOS_DL_LIST *node = NULL;
|
||||
LosTaskCB *owner = NULL;
|
||||
|
||||
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;
|
||||
LOS_ListTailInsert(&runTask->lockList, &mutex->holdList);
|
||||
if ((runTask->priority > mutex->attr.prioceiling) && (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT)) {
|
||||
LOS_BitmapSet(&runTask->priBitMap, runTask->priority);
|
||||
OsTaskPriModify(runTask, mutex->attr.prioceiling);
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
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, (LosTaskCB *)mutex->owner);
|
||||
|
||||
owner = (LosTaskCB *)mutex->owner;
|
||||
runTask->taskMux = (VOID *)mutex;
|
||||
node = OsMuxPendFindPos(runTask, mutex);
|
||||
|
||||
ret = OsTaskWait(node, timeout, TRUE);
|
||||
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
|
||||
runTask->taskMux = NULL;
|
||||
ret = LOS_ETIMEDOUT;
|
||||
}
|
||||
|
||||
if (timeout != LOS_WAIT_FOREVER) {
|
||||
OsMuxBitmapRestore(mutex, runTask, owner);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
UINT32 OsMuxLockUnsafe(LosMux *mutex, UINT32 timeout)
|
||||
{
|
||||
LosTaskCB *runTask = OsCurrTaskGet();
|
||||
|
||||
if (mutex->magic != OS_MUX_MAGIC) {
|
||||
return LOS_EBADF;
|
||||
}
|
||||
|
||||
if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if ((mutex->attr.type == LOS_MUX_ERRORCHECK) && (mutex->muxCount != 0) && (mutex->owner == (VOID *)runTask)) {
|
||||
return LOS_EDEADLK;
|
||||
}
|
||||
|
||||
return OsMuxPendOp(runTask, mutex, timeout);
|
||||
}
|
||||
|
||||
UINT32 OsMuxTrylockUnsafe(LosMux *mutex, UINT32 timeout)
|
||||
{
|
||||
LosTaskCB *runTask = OsCurrTaskGet();
|
||||
|
||||
if (mutex->magic != OS_MUX_MAGIC) {
|
||||
return LOS_EBADF;
|
||||
}
|
||||
|
||||
if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if ((mutex->owner != NULL) && ((LosTaskCB *)mutex->owner != runTask)) {
|
||||
return LOS_EBUSY;
|
||||
}
|
||||
if ((mutex->attr.type != LOS_MUX_RECURSIVE) && (mutex->muxCount != 0)) {
|
||||
return LOS_EBUSY;
|
||||
}
|
||||
|
||||
return OsMuxPendOp(runTask, mutex, timeout);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxLock(LosMux *mutex, UINT32 timeout)
|
||||
{
|
||||
LosTaskCB *runTask = NULL;
|
||||
UINT32 intSave;
|
||||
UINT32 ret;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
return LOS_EINTR;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxTrylock(LosMux *mutex)
|
||||
{
|
||||
LosTaskCB *runTask = NULL;
|
||||
UINT32 intSave;
|
||||
UINT32 ret;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
return LOS_EINTR;
|
||||
}
|
||||
|
||||
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 = OsMuxTrylockUnsafe(mutex, 0);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC VOID OsMuxPostOpSub(LosTaskCB *taskCB, LosMux *mutex)
|
||||
{
|
||||
LosTaskCB *pendedTask = NULL;
|
||||
UINT16 bitMapPri;
|
||||
|
||||
if (!LOS_ListEmpty(&mutex->muxList)) {
|
||||
bitMapPri = LOS_HighBitGet(taskCB->priBitMap);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(pendedTask, (&mutex->muxList), LosTaskCB, pendList) {
|
||||
if (bitMapPri != pendedTask->priority) {
|
||||
LOS_BitmapClr(&taskCB->priBitMap, pendedTask->priority);
|
||||
}
|
||||
}
|
||||
}
|
||||
bitMapPri = LOS_LowBitGet(taskCB->priBitMap);
|
||||
LOS_BitmapClr(&taskCB->priBitMap, bitMapPri);
|
||||
OsTaskPriModify((LosTaskCB *)mutex->owner, bitMapPri);
|
||||
}
|
||||
|
||||
STATIC UINT32 OsMuxPostOp(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
|
||||
{
|
||||
LosTaskCB *resumedTask = NULL;
|
||||
|
||||
if (LOS_ListEmpty(&mutex->muxList)) {
|
||||
LOS_ListDelete(&mutex->holdList);
|
||||
mutex->owner = NULL;
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&(mutex->muxList)));
|
||||
if (mutex->attr.protocol == LOS_MUX_PRIO_INHERIT) {
|
||||
if (resumedTask->priority > taskCB->priority) {
|
||||
if (LOS_HighBitGet(taskCB->priBitMap) != resumedTask->priority) {
|
||||
LOS_BitmapClr(&taskCB->priBitMap, resumedTask->priority);
|
||||
}
|
||||
} else if (taskCB->priBitMap != 0) {
|
||||
OsMuxPostOpSub(taskCB, mutex);
|
||||
}
|
||||
}
|
||||
mutex->muxCount = 1;
|
||||
mutex->owner = (VOID *)resumedTask;
|
||||
resumedTask->taskMux = NULL;
|
||||
LOS_ListDelete(&mutex->holdList);
|
||||
LOS_ListTailInsert(&resumedTask->lockList, &mutex->holdList);
|
||||
OsTaskWake(resumedTask);
|
||||
if (needSched != NULL) {
|
||||
*needSched = TRUE;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsMuxUnlockUnsafe(LosTaskCB *taskCB, LosMux *mutex, BOOL *needSched)
|
||||
{
|
||||
UINT16 bitMapPri;
|
||||
|
||||
if (mutex->magic != OS_MUX_MAGIC) {
|
||||
return LOS_EBADF;
|
||||
}
|
||||
|
||||
if (OsCheckMutexAttr(&mutex->attr) != LOS_OK) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (mutex->muxCount == 0) {
|
||||
return LOS_EPERM;
|
||||
}
|
||||
|
||||
if ((LosTaskCB *)mutex->owner != taskCB) {
|
||||
return LOS_EPERM;
|
||||
}
|
||||
|
||||
if ((--mutex->muxCount != 0) && (mutex->attr.type == LOS_MUX_RECURSIVE)) {
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
if (mutex->attr.protocol == LOS_MUX_PRIO_PROTECT) {
|
||||
bitMapPri = LOS_HighBitGet(taskCB->priBitMap);
|
||||
if (bitMapPri != LOS_INVALID_BIT_INDEX) {
|
||||
LOS_BitmapClr(&taskCB->priBitMap, bitMapPri);
|
||||
OsTaskPriModify(taskCB, bitMapPri);
|
||||
}
|
||||
}
|
||||
|
||||
/* Whether a task block the mutex lock. */
|
||||
return OsMuxPostOp(taskCB, mutex, needSched);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MuxUnlock(LosMux *mutex)
|
||||
{
|
||||
LosTaskCB *runTask = NULL;
|
||||
BOOL needSched = FALSE;
|
||||
UINT32 intSave;
|
||||
UINT32 ret;
|
||||
|
||||
if (mutex == NULL) {
|
||||
return LOS_EINVAL;
|
||||
}
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
return LOS_EINTR;
|
||||
}
|
||||
|
||||
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 = OsMuxUnlockUnsafe(runTask, mutex, &needSched);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if (needSched == TRUE) {
|
||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||
LOS_Schedule();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* (LOSCFG_BASE_IPC_MUX == YES) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
504
kernel/base/ipc/los_queue.c
Executable file
504
kernel/base/ipc/los_queue.c
Executable file
@@ -0,0 +1,504 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_queue_pri.h"
|
||||
#include "los_queue_debug_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_mp.h"
|
||||
#include "los_percpu_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_BASE_IPC_QUEUE == YES)
|
||||
#if (LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0)
|
||||
#error "queue maxnum cannot be zero"
|
||||
#endif /* LOSCFG_BASE_IPC_QUEUE_LIMIT <= 0 */
|
||||
|
||||
LITE_OS_SEC_BSS LosQueueCB *g_allQueue = NULL;
|
||||
LITE_OS_SEC_BSS STATIC LOS_DL_LIST g_freeQueueList;
|
||||
|
||||
/*
|
||||
* Description : queue initial
|
||||
* Return : LOS_OK on success or error code on failure
|
||||
*/
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 OsQueueInit(VOID)
|
||||
{
|
||||
LosQueueCB *queueNode = NULL;
|
||||
UINT32 index;
|
||||
UINT32 size;
|
||||
|
||||
size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(LosQueueCB);
|
||||
/* system resident memory, don't free */
|
||||
g_allQueue = (LosQueueCB *)LOS_MemAlloc(m_aucSysMem0, size);
|
||||
if (g_allQueue == NULL) {
|
||||
return LOS_ERRNO_QUEUE_NO_MEMORY;
|
||||
}
|
||||
(VOID)memset_s(g_allQueue, size, 0, size);
|
||||
LOS_ListInit(&g_freeQueueList);
|
||||
for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) {
|
||||
queueNode = ((LosQueueCB *)g_allQueue) + index;
|
||||
queueNode->queueID = index;
|
||||
LOS_ListTailInsert(&g_freeQueueList, &queueNode->readWriteList[OS_QUEUE_WRITE]);
|
||||
}
|
||||
|
||||
if (OsQueueDbgInitHook() != LOS_OK) {
|
||||
return LOS_ERRNO_QUEUE_NO_MEMORY;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueCreate(CHAR *queueName, UINT16 len, UINT32 *queueID,
|
||||
UINT32 flags, UINT16 maxMsgSize)
|
||||
{
|
||||
LosQueueCB *queueCB = NULL;
|
||||
UINT32 intSave;
|
||||
LOS_DL_LIST *unusedQueue = NULL;
|
||||
UINT8 *queue = NULL;
|
||||
UINT16 msgSize;
|
||||
|
||||
(VOID)queueName;
|
||||
(VOID)flags;
|
||||
|
||||
if (queueID == NULL) {
|
||||
return LOS_ERRNO_QUEUE_CREAT_PTR_NULL;
|
||||
}
|
||||
|
||||
if (maxMsgSize > (OS_NULL_SHORT - sizeof(UINT32))) {
|
||||
return LOS_ERRNO_QUEUE_SIZE_TOO_BIG;
|
||||
}
|
||||
|
||||
if ((len == 0) || (maxMsgSize == 0)) {
|
||||
return LOS_ERRNO_QUEUE_PARA_ISZERO;
|
||||
}
|
||||
|
||||
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(&g_freeQueueList)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
OsQueueCheckHook();
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, queue);
|
||||
return LOS_ERRNO_QUEUE_CB_UNAVAILABLE;
|
||||
}
|
||||
|
||||
unusedQueue = LOS_DL_LIST_FIRST(&g_freeQueueList);
|
||||
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;
|
||||
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;
|
||||
}
|
||||
|
||||
OsQueueDbgTimeUpdateHook(queueID);
|
||||
|
||||
if (timeout != LOS_NO_WAIT) {
|
||||
if (OS_INT_ACTIVE) {
|
||||
return LOS_ERRNO_QUEUE_READ_IN_INTERRUPT;
|
||||
}
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
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) {
|
||||
return LOS_ERRNO_QUEUE_WRITESIZE_ISZERO;
|
||||
}
|
||||
|
||||
OsQueueDbgTimeUpdateHook(queueID);
|
||||
|
||||
if (timeout != LOS_NO_WAIT) {
|
||||
if (OS_INT_ACTIVE) {
|
||||
return LOS_ERRNO_QUEUE_WRITE_IN_INTERRUPT;
|
||||
}
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID OsQueueBufferOperate(LosQueueCB *queueCB, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize)
|
||||
{
|
||||
UINT8 *queueNode = NULL;
|
||||
UINT32 msgDataSize;
|
||||
UINT16 queuePosion;
|
||||
|
||||
/* get the queue position */
|
||||
switch (OS_QUEUE_OPERATE_GET(operateType)) {
|
||||
case OS_QUEUE_READ_HEAD:
|
||||
queuePosion = 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);
|
||||
queuePosion = queueCB->queueHead;
|
||||
break;
|
||||
case OS_QUEUE_WRITE_TAIL:
|
||||
queuePosion = queueCB->queueTail;
|
||||
((queueCB->queueTail + 1) == queueCB->queueLen) ? (queueCB->queueTail = 0) : (queueCB->queueTail++);
|
||||
break;
|
||||
default: /* read tail, reserved. */
|
||||
PRINT_ERR("invalid queue operate type!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
queueNode = &(queueCB->queueHandle[(queuePosion * (queueCB->queueSize))]);
|
||||
|
||||
if (OS_QUEUE_IS_READ(operateType)) {
|
||||
if (memcpy_s(&msgDataSize, sizeof(UINT32), queueNode + queueCB->queueSize - sizeof(UINT32),
|
||||
sizeof(UINT32)) != EOK) {
|
||||
PRINT_ERR("get msgdatasize failed\n");
|
||||
return;
|
||||
}
|
||||
if (memcpy_s(bufferAddr, *bufferSize, queueNode, msgDataSize) != EOK) {
|
||||
PRINT_ERR("copy message to buffer failed\n");
|
||||
return;
|
||||
}
|
||||
|
||||
*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) {
|
||||
PRINT_ERR("store message size failed\n");
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
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_READ(operateType) && (*bufferSize < (queueCB->queueSize - sizeof(UINT32)))) {
|
||||
return LOS_ERRNO_QUEUE_READ_SIZE_TOO_SMALL;
|
||||
} else if (OS_QUEUE_IS_WRITE(operateType) && (*bufferSize > (queueCB->queueSize - sizeof(UINT32)))) {
|
||||
return LOS_ERRNO_QUEUE_WRITE_SIZE_TOO_BIG;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
UINT32 OsQueueOperate(UINT32 queueID, UINT32 operateType, VOID *bufferAddr, UINT32 *bufferSize, UINT32 timeout)
|
||||
{
|
||||
LosQueueCB *queueCB = NULL;
|
||||
LosTaskCB *resumedTask = NULL;
|
||||
UINT32 ret;
|
||||
UINT32 readWrite = OS_QUEUE_READ_WRITE_GET(operateType);
|
||||
UINT32 intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
|
||||
ret = OsQueueOperateParamCheck(queueCB, queueID, operateType, bufferSize);
|
||||
if (ret != LOS_OK) {
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
if (queueCB->readWriteableCnt[readWrite] == 0) {
|
||||
if (timeout == LOS_NO_WAIT) {
|
||||
ret = OS_QUEUE_IS_READ(operateType) ? LOS_ERRNO_QUEUE_ISEMPTY : LOS_ERRNO_QUEUE_ISFULL;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
if (!OsPreemptableInSched()) {
|
||||
ret = LOS_ERRNO_QUEUE_PEND_IN_LOCK;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
ret = OsTaskWait(&queueCB->readWriteList[readWrite], timeout, TRUE);
|
||||
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])) {
|
||||
resumedTask = OS_TCB_FROM_PENDLIST(LOS_DL_LIST_FIRST(&queueCB->readWriteList[!readWrite]));
|
||||
OsTaskWake(resumedTask);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||
LOS_Schedule();
|
||||
return LOS_OK;
|
||||
} else {
|
||||
queueCB->readWriteableCnt[!readWrite]++;
|
||||
}
|
||||
|
||||
QUEUE_END:
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_QueueReadCopy(UINT32 queueID,
|
||||
VOID *bufferAddr,
|
||||
UINT32 *bufferSize,
|
||||
UINT32 timeout)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 operateType;
|
||||
|
||||
ret = OsQueueReadParameterCheck(queueID, bufferAddr, bufferSize, timeout);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_READ, OS_QUEUE_HEAD);
|
||||
return OsQueueOperate(queueID, operateType, bufferAddr, bufferSize, timeout);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHeadCopy(UINT32 queueID,
|
||||
VOID *bufferAddr,
|
||||
UINT32 bufferSize,
|
||||
UINT32 timeout)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 operateType;
|
||||
|
||||
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_HEAD);
|
||||
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteCopy(UINT32 queueID,
|
||||
VOID *bufferAddr,
|
||||
UINT32 bufferSize,
|
||||
UINT32 timeout)
|
||||
{
|
||||
UINT32 ret;
|
||||
UINT32 operateType;
|
||||
|
||||
ret = OsQueueWriteParameterCheck(queueID, bufferAddr, &bufferSize, timeout);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
operateType = OS_QUEUE_OPERATE_TYPE(OS_QUEUE_WRITE, OS_QUEUE_TAIL);
|
||||
return OsQueueOperate(queueID, operateType, bufferAddr, &bufferSize, timeout);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_QueueRead(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
|
||||
{
|
||||
return LOS_QueueReadCopy(queueID, bufferAddr, &bufferSize, timeout);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_QueueWrite(UINT32 queueID, VOID *bufferAddr, UINT32 bufferSize, UINT32 timeout)
|
||||
{
|
||||
if (bufferAddr == NULL) {
|
||||
return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
|
||||
}
|
||||
bufferSize = sizeof(CHAR *);
|
||||
return LOS_QueueWriteCopy(queueID, &bufferAddr, bufferSize, timeout);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_QueueWriteHead(UINT32 queueID,
|
||||
VOID *bufferAddr,
|
||||
UINT32 bufferSize,
|
||||
UINT32 timeout)
|
||||
{
|
||||
if (bufferAddr == NULL) {
|
||||
return LOS_ERRNO_QUEUE_WRITE_PTR_NULL;
|
||||
}
|
||||
bufferSize = sizeof(CHAR *);
|
||||
return LOS_QueueWriteHeadCopy(queueID, &bufferAddr, bufferSize, timeout);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_QueueDelete(UINT32 queueID)
|
||||
{
|
||||
LosQueueCB *queueCB = NULL;
|
||||
UINT8 *queue = NULL;
|
||||
UINT32 intSave;
|
||||
UINT32 ret;
|
||||
|
||||
if (GET_QUEUE_INDEX(queueID) >= LOSCFG_BASE_IPC_QUEUE_LIMIT) {
|
||||
return LOS_ERRNO_QUEUE_NOT_FOUND;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
queueCB = (LosQueueCB *)GET_QUEUE_HANDLE(queueID);
|
||||
if ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
|
||||
ret = LOS_ERRNO_QUEUE_NOT_CREATE;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_READ])) {
|
||||
ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
if (!LOS_ListEmpty(&queueCB->readWriteList[OS_QUEUE_WRITE])) {
|
||||
ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
if (!LOS_ListEmpty(&queueCB->memList)) {
|
||||
ret = LOS_ERRNO_QUEUE_IN_TSKUSE;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
if ((queueCB->readWriteableCnt[OS_QUEUE_WRITE] + queueCB->readWriteableCnt[OS_QUEUE_READ]) !=
|
||||
queueCB->queueLen) {
|
||||
ret = LOS_ERRNO_QUEUE_IN_TSKWRITE;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
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(&g_freeQueueList, &queueCB->readWriteList[OS_QUEUE_WRITE]);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
ret = LOS_MemFree(m_aucSysMem1, (VOID *)queue);
|
||||
return ret;
|
||||
|
||||
QUEUE_END:
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_QueueInfoGet(UINT32 queueID, QUEUE_INFO_S *queueInfo)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 ret = LOS_OK;
|
||||
LosQueueCB *queueCB = NULL;
|
||||
LosTaskCB *tskCB = NULL;
|
||||
|
||||
if (queueInfo == NULL) {
|
||||
return LOS_ERRNO_QUEUE_PTR_NULL;
|
||||
}
|
||||
|
||||
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 ((queueCB->queueID != queueID) || (queueCB->queueState == OS_QUEUE_UNUSED)) {
|
||||
ret = LOS_ERRNO_QUEUE_NOT_CREATE;
|
||||
goto QUEUE_END;
|
||||
}
|
||||
|
||||
queueInfo->uwQueueID = queueID;
|
||||
queueInfo->usQueueLen = queueCB->queueLen;
|
||||
queueInfo->usQueueSize = queueCB->queueSize;
|
||||
queueInfo->usQueueHead = queueCB->queueHead;
|
||||
queueInfo->usQueueTail = queueCB->queueTail;
|
||||
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;
|
||||
}
|
||||
|
||||
QUEUE_END:
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
#endif /* (LOSCFG_BASE_IPC_QUEUE == YES) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
208
kernel/base/ipc/los_queue_debug.c
Executable file
208
kernel/base/ipc/los_queue_debug.c
Executable file
@@ -0,0 +1,208 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_queue_debug_pri.h"
|
||||
#include "los_hw_pri.h"
|
||||
#include "los_ipcdebug_pri.h"
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#endif /* LOSCFG_SHELL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef LOSCFG_DEBUG_QUEUE
|
||||
|
||||
typedef struct {
|
||||
TSK_ENTRY_FUNC creater; /* The task entry who created this queue */
|
||||
UINT64 lastAccessTime; /* The last access time */
|
||||
} QueueDebugCB;
|
||||
STATIC QueueDebugCB *g_queueDebugArray = NULL;
|
||||
|
||||
STATIC BOOL QueueCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right)
|
||||
{
|
||||
return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) >
|
||||
*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right)));
|
||||
}
|
||||
|
||||
UINT32 OsQueueDbgInit(VOID)
|
||||
{
|
||||
UINT32 size = LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(QueueDebugCB);
|
||||
/* system resident memory, don't free */
|
||||
g_queueDebugArray = (QueueDebugCB *)LOS_MemAlloc(m_aucSysMem1, size);
|
||||
if (g_queueDebugArray == NULL) {
|
||||
PRINT_ERR("%s: malloc failed!\n", __FUNCTION__);
|
||||
return LOS_NOK;
|
||||
}
|
||||
(VOID)memset_s(g_queueDebugArray, size, 0, size);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID OsQueueDbgTimeUpdate(UINT32 queueID)
|
||||
{
|
||||
QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueID)];
|
||||
queueDebug->lastAccessTime = LOS_TickCountGet();
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsQueueDbgUpdate(UINT32 queueID, TSK_ENTRY_FUNC entry)
|
||||
{
|
||||
QueueDebugCB *queueDebug = &g_queueDebugArray[GET_QUEUE_INDEX(queueID)];
|
||||
queueDebug->creater = entry;
|
||||
queueDebug->lastAccessTime = LOS_TickCountGet();
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsQueueInfoOutPut(const LosQueueCB *node)
|
||||
{
|
||||
PRINTK("Queue ID <0x%x> may leak, queue len is 0x%x, "
|
||||
"readable cnt:0x%x, writeable cnt:0x%x, ",
|
||||
node->queueID,
|
||||
node->queueLen,
|
||||
node->readWriteableCnt[OS_QUEUE_READ],
|
||||
node->readWriteableCnt[OS_QUEUE_WRITE]);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsQueueOpsOutput(const QueueDebugCB *node)
|
||||
{
|
||||
PRINTK("TaskEntry of creater:0x%p, Latest operation time: 0x%llx\n",
|
||||
node->creater, node->lastAccessTime);
|
||||
}
|
||||
|
||||
STATIC VOID SortQueueIndexArray(UINT32 *indexArray, UINT32 count)
|
||||
{
|
||||
LosQueueCB queueNode = {0};
|
||||
QueueDebugCB queueDebugNode = {0};
|
||||
UINT32 index, intSave;
|
||||
IpcSortParam queueSortParam;
|
||||
queueSortParam.buf = (CHAR *)g_queueDebugArray;
|
||||
queueSortParam.ipcDebugCBSize = sizeof(QueueDebugCB);
|
||||
queueSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT;
|
||||
queueSortParam.sortElemOff = OFFSET_OF_FIELD(QueueDebugCB, lastAccessTime);
|
||||
|
||||
if (count > 0) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
OsArraySortByTime(indexArray, 0, count - 1, &queueSortParam, QueueCompareValue);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
for (index = 0; index < count; index++) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
(VOID)memcpy_s(&queueNode, sizeof(LosQueueCB),
|
||||
GET_QUEUE_HANDLE(indexArray[index]), sizeof(LosQueueCB));
|
||||
(VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB),
|
||||
&g_queueDebugArray[indexArray[index]], sizeof(QueueDebugCB));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if (queueNode.queueState == OS_QUEUE_UNUSED) {
|
||||
continue;
|
||||
}
|
||||
OsQueueInfoOutPut(&queueNode);
|
||||
OsQueueOpsOutput(&queueDebugNode);
|
||||
}
|
||||
}
|
||||
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray);
|
||||
}
|
||||
|
||||
VOID OsQueueCheck(VOID)
|
||||
{
|
||||
LosQueueCB queueNode = {0};
|
||||
QueueDebugCB queueDebugNode = {0};
|
||||
UINT32 index, intSave;
|
||||
UINT32 count = 0;
|
||||
|
||||
/*
|
||||
* This return value does not need to be judged immediately,
|
||||
* and the following code logic has already distinguished the return value from null and non-empty,
|
||||
* and there is no case of accessing the null pointer.
|
||||
*/
|
||||
UINT32 *indexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, LOSCFG_BASE_IPC_QUEUE_LIMIT * sizeof(UINT32));
|
||||
|
||||
for (index = 0; index < LOSCFG_BASE_IPC_QUEUE_LIMIT; index++) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
(VOID)memcpy_s(&queueNode, sizeof(LosQueueCB),
|
||||
GET_QUEUE_HANDLE(index), sizeof(LosQueueCB));
|
||||
(VOID)memcpy_s(&queueDebugNode, sizeof(QueueDebugCB),
|
||||
&g_queueDebugArray[index], sizeof(QueueDebugCB));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if ((queueNode.queueState == OS_QUEUE_UNUSED) ||
|
||||
((queueNode.queueState == OS_QUEUE_INUSED) && (queueDebugNode.creater == NULL))) {
|
||||
continue;
|
||||
}
|
||||
if ((queueNode.queueState == OS_QUEUE_INUSED) &&
|
||||
(queueNode.queueLen == queueNode.readWriteableCnt[OS_QUEUE_WRITE]) &&
|
||||
LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_READ]) &&
|
||||
LOS_ListEmpty(&queueNode.readWriteList[OS_QUEUE_WRITE]) &&
|
||||
LOS_ListEmpty(&queueNode.memList)) {
|
||||
PRINTK("Queue ID <0x%x> may leak, No task uses it, "
|
||||
"QueueLen is 0x%x, ",
|
||||
queueNode.queueID,
|
||||
queueNode.queueLen);
|
||||
OsQueueOpsOutput(&queueDebugNode);
|
||||
} else {
|
||||
if (indexArray != NULL) {
|
||||
*(indexArray + count) = index;
|
||||
count++;
|
||||
} else {
|
||||
OsQueueInfoOutPut(&queueNode);
|
||||
OsQueueOpsOutput(&queueDebugNode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (indexArray != NULL) {
|
||||
SortQueueIndexArray(indexArray, count);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdQueueInfoGet(UINT32 argc, const CHAR **argv)
|
||||
{
|
||||
if (argc > 0) {
|
||||
PRINTK("\nUsage: queue\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
PRINTK("used queues information: \n");
|
||||
OsQueueCheck();
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
SHELLCMD_ENTRY(queue_shellcmd, CMD_TYPE_EX, "queue", 0, (CmdCallBackFunc)OsShellCmdQueueInfoGet);
|
||||
#endif /* LOSCFG_SHELL */
|
||||
#endif /* LOSCFG_DEBUG_QUEUE */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
298
kernel/base/ipc/los_sem.c
Executable file
298
kernel/base/ipc/los_sem.c
Executable file
@@ -0,0 +1,298 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_sem_pri.h"
|
||||
#include "los_sem_debug_pri.h"
|
||||
#include "los_err_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_exc.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_mp.h"
|
||||
#include "los_percpu_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_BASE_IPC_SEM == YES)
|
||||
|
||||
#if (LOSCFG_BASE_IPC_SEM_LIMIT <= 0)
|
||||
#error "sem maxnum cannot be zero"
|
||||
#endif /* LOSCFG_BASE_IPC_SEM_LIMIT <= 0 */
|
||||
|
||||
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
|
||||
* Return : LOS_OK on success, or error code on failure
|
||||
*/
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 OsSemInit(VOID)
|
||||
{
|
||||
LosSemCB *semNode = NULL;
|
||||
UINT32 index;
|
||||
|
||||
LOS_ListInit(&g_unusedSemList);
|
||||
/* system resident memory, don't free */
|
||||
g_allSem = (LosSemCB *)LOS_MemAlloc(m_aucSysMem0, (LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(LosSemCB)));
|
||||
if (g_allSem == NULL) {
|
||||
return LOS_ERRNO_SEM_NO_MEMORY;
|
||||
}
|
||||
|
||||
for (index = 0; index < LOSCFG_BASE_IPC_SEM_LIMIT; index++) {
|
||||
semNode = ((LosSemCB *)g_allSem) + index;
|
||||
semNode->semID = SET_SEM_ID(0, index);
|
||||
semNode->semStat = OS_SEM_UNUSED;
|
||||
LOS_ListTailInsert(&g_unusedSemList, &semNode->semList);
|
||||
}
|
||||
|
||||
if (OsSemDbgInitHook() != LOS_OK) {
|
||||
return LOS_ERRNO_SEM_NO_MEMORY;
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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
|
||||
*/
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 OsSemCreate(UINT16 count, UINT16 maxCount, UINT32 *semHandle)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosSemCB *semCreated = NULL;
|
||||
LOS_DL_LIST *unusedSem = NULL;
|
||||
UINT32 errNo;
|
||||
UINT32 errLine;
|
||||
|
||||
if (semHandle == NULL) {
|
||||
return LOS_ERRNO_SEM_PTR_NULL;
|
||||
}
|
||||
|
||||
if (count > maxCount) {
|
||||
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_OVERFLOW);
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
if (LOS_ListEmpty(&g_unusedSemList)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
OsSemInfoGetFullDataHook();
|
||||
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_ALL_BUSY);
|
||||
}
|
||||
|
||||
unusedSem = LOS_DL_LIST_FIRST(&g_unusedSemList);
|
||||
LOS_ListDelete(unusedSem);
|
||||
semCreated = GET_SEM_LIST(unusedSem);
|
||||
semCreated->semCount = count;
|
||||
semCreated->semStat = OS_SEM_USED;
|
||||
semCreated->maxSemCount = maxCount;
|
||||
LOS_ListInit(&semCreated->semList);
|
||||
*semHandle = semCreated->semID;
|
||||
|
||||
OsSemDbgUpdateHook(semCreated->semID, OsCurrTaskGet()->taskEntry, count);
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
|
||||
ERR_HANDLER:
|
||||
OS_RETURN_ERROR_P2(errLine, errNo);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemCreate(UINT16 count, UINT32 *semHandle)
|
||||
{
|
||||
return OsSemCreate(count, OS_SEM_COUNT_MAX, semHandle);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_BinarySemCreate(UINT16 count, UINT32 *semHandle)
|
||||
{
|
||||
return OsSemCreate(count, OS_SEM_BINARY_COUNT_MAX, semHandle);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_SemDelete(UINT32 semHandle)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosSemCB *semDeleted = NULL;
|
||||
UINT32 errNo;
|
||||
UINT32 errLine;
|
||||
|
||||
if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) {
|
||||
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID);
|
||||
}
|
||||
|
||||
semDeleted = GET_SEM(semHandle);
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
if ((semDeleted->semStat == OS_SEM_UNUSED) || (semDeleted->semID != semHandle)) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
OS_GOTO_ERR_HANDLER(LOS_ERRNO_SEM_INVALID);
|
||||
}
|
||||
|
||||
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));
|
||||
|
||||
OsSemDbgUpdateHook(semDeleted->semID, NULL, 0);
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
|
||||
ERR_HANDLER:
|
||||
OS_RETURN_ERROR_P2(errLine, errNo);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_SemPend(UINT32 semHandle, UINT32 timeout)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosSemCB *semPended = GET_SEM(semHandle);
|
||||
UINT32 retErr = LOS_OK;
|
||||
LosTaskCB *runTask = NULL;
|
||||
|
||||
if (GET_SEM_INDEX(semHandle) >= (UINT32)LOSCFG_BASE_IPC_SEM_LIMIT) {
|
||||
OS_RETURN_ERROR(LOS_ERRNO_SEM_INVALID);
|
||||
}
|
||||
|
||||
if (OS_INT_ACTIVE) {
|
||||
PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_INTERR!!!\n");
|
||||
OsBackTrace();
|
||||
return LOS_ERRNO_SEM_PEND_INTERR;
|
||||
}
|
||||
|
||||
runTask = OsCurrTaskGet();
|
||||
if (runTask->taskStatus & OS_TASK_FLAG_SYSTEM_TASK) {
|
||||
OsBackTrace();
|
||||
return LOS_ERRNO_SEM_PEND_IN_SYSTEM_TASK;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
if ((semPended->semStat == OS_SEM_UNUSED) || (semPended->semID != semHandle)) {
|
||||
retErr = LOS_ERRNO_SEM_INVALID;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
/* Update the operate time, no matter the actual Pend success or not */
|
||||
OsSemDbgTimeUpdateHook(semHandle);
|
||||
|
||||
if (semPended->semCount > 0) {
|
||||
semPended->semCount--;
|
||||
goto OUT;
|
||||
} else if (!timeout) {
|
||||
retErr = LOS_ERRNO_SEM_UNAVAILABLE;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if (!OsPreemptableInSched()) {
|
||||
PRINT_ERR("!!!LOS_ERRNO_SEM_PEND_IN_LOCK!!!\n");
|
||||
OsBackTrace();
|
||||
retErr = LOS_ERRNO_SEM_PEND_IN_LOCK;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
runTask->taskSem = (VOID *)semPended;
|
||||
retErr = OsTaskWait(&semPended->semList, timeout, TRUE);
|
||||
if (retErr == LOS_ERRNO_TSK_TIMEOUT) {
|
||||
runTask->taskSem = NULL;
|
||||
retErr = LOS_ERRNO_SEM_TIMEOUT;
|
||||
}
|
||||
|
||||
OUT:
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return retErr;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 OsSemPostUnsafe(UINT32 semHandle, BOOL *needSched)
|
||||
{
|
||||
LosSemCB *semPosted = NULL;
|
||||
LosTaskCB *resumedTask = NULL;
|
||||
|
||||
if (GET_SEM_INDEX(semHandle) >= LOSCFG_BASE_IPC_SEM_LIMIT) {
|
||||
return LOS_ERRNO_SEM_INVALID;
|
||||
}
|
||||
|
||||
semPosted = GET_SEM(semHandle);
|
||||
if ((semPosted->semID != semHandle) || (semPosted->semStat == OS_SEM_UNUSED)) {
|
||||
return LOS_ERRNO_SEM_INVALID;
|
||||
}
|
||||
|
||||
/* Update the operate time, no matter the actual Post success or not */
|
||||
OsSemDbgTimeUpdateHook(semHandle);
|
||||
|
||||
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)));
|
||||
resumedTask->taskSem = NULL;
|
||||
OsTaskWake(resumedTask);
|
||||
if (needSched != NULL) {
|
||||
*needSched = TRUE;
|
||||
}
|
||||
} else {
|
||||
semPosted->semCount++;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_SemPost(UINT32 semHandle)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 ret;
|
||||
BOOL needSched = FALSE;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
ret = OsSemPostUnsafe(semHandle, &needSched);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if (needSched) {
|
||||
LOS_MpSchedule(OS_MP_CPU_ALL);
|
||||
LOS_Schedule();
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
#endif /* (LOSCFG_BASE_IPC_SEM == YES) */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
311
kernel/base/ipc/los_sem_debug.c
Executable file
311
kernel/base/ipc/los_sem_debug.c
Executable file
@@ -0,0 +1,311 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_sem_debug_pri.h"
|
||||
#include "stdlib.h"
|
||||
#include "los_typedef.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_ipcdebug_pri.h"
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#endif /* LOSCFG_SHELL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_ALL_SEM_MASK 0xffffffff
|
||||
|
||||
#if defined(LOSCFG_DEBUG_SEMAPHORE) || defined(LOSCFG_SHELL_CMD_DEBUG)
|
||||
STATIC VOID OsSemPendedTaskNamePrint(LosSemCB *semNode)
|
||||
{
|
||||
LosTaskCB *tskCB = NULL;
|
||||
CHAR *nameArr[LOSCFG_BASE_CORE_TSK_LIMIT] = {0};
|
||||
UINT32 i, intSave;
|
||||
UINT32 num = 0;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if ((semNode->semStat == OS_SEM_UNUSED) || (LOS_ListEmpty(&semNode->semList))) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(tskCB, &semNode->semList, LosTaskCB, pendList) {
|
||||
nameArr[num++] = tskCB->taskName;
|
||||
if (num == LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
PRINTK("Pended task list : ");
|
||||
for (i = 0; i < num; i++) {
|
||||
if (i == 0) {
|
||||
PRINTK("%s\n", nameArr[i]);
|
||||
} else {
|
||||
PRINTK(", %s", nameArr[i]);
|
||||
}
|
||||
}
|
||||
PRINTK("\n");
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_DEBUG_SEMAPHORE
|
||||
|
||||
typedef struct {
|
||||
UINT16 origSemCount; /* Number of orignal available semaphores */
|
||||
UINT64 lastAccessTime; /* The last operation time */
|
||||
TSK_ENTRY_FUNC creater; /* The task entry who created this sem */
|
||||
} SemDebugCB;
|
||||
STATIC SemDebugCB *g_semDebugArray = NULL;
|
||||
|
||||
STATIC BOOL SemCompareValue(const IpcSortParam *sortParam, UINT32 left, UINT32 right)
|
||||
{
|
||||
return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) >
|
||||
*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right)));
|
||||
}
|
||||
|
||||
UINT32 OsSemDbgInit(VOID)
|
||||
{
|
||||
UINT32 size = LOSCFG_BASE_IPC_SEM_LIMIT * sizeof(SemDebugCB);
|
||||
/* system resident memory, don't free */
|
||||
g_semDebugArray = (SemDebugCB *)LOS_MemAlloc(m_aucSysMem1, size);
|
||||
if (g_semDebugArray == NULL) {
|
||||
PRINT_ERR("%s: malloc failed!\n", __FUNCTION__);
|
||||
return LOS_NOK;
|
||||
}
|
||||
(VOID)memset_s(g_semDebugArray, size, 0, size);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VOID OsSemDbgTimeUpdate(UINT32 semID)
|
||||
{
|
||||
SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)];
|
||||
semDebug->lastAccessTime = LOS_TickCountGet();
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsSemDbgUpdate(UINT32 semID, TSK_ENTRY_FUNC creater, UINT16 count)
|
||||
{
|
||||
SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semID)];
|
||||
semDebug->creater = creater;
|
||||
semDebug->lastAccessTime = LOS_TickCountGet();
|
||||
semDebug->origSemCount = count;
|
||||
return;
|
||||
}
|
||||
|
||||
STATIC VOID OsSemSort(UINT32 *semIndexArray, UINT32 usedCount)
|
||||
{
|
||||
UINT32 i, intSave;
|
||||
LosSemCB *semCB = NULL;
|
||||
LosSemCB semNode = {0};
|
||||
SemDebugCB semDebug = {0};
|
||||
IpcSortParam semSortParam;
|
||||
semSortParam.buf = (CHAR *)g_semDebugArray;
|
||||
semSortParam.ipcDebugCBSize = sizeof(SemDebugCB);
|
||||
semSortParam.ipcDebugCBCnt = LOSCFG_BASE_IPC_SEM_LIMIT;
|
||||
semSortParam.sortElemOff = OFFSET_OF_FIELD(SemDebugCB, lastAccessTime);
|
||||
|
||||
/* It will Print out ALL the Used Semaphore List. */
|
||||
PRINTK("Used Semaphore List: \n");
|
||||
PRINTK("\r\n SemID Count OriginalCount Creater(TaskEntry) LastAccessTime\n");
|
||||
PRINTK(" ------ ------ ------------- ------------------ -------------- \n");
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
OsArraySortByTime(semIndexArray, 0, usedCount - 1, &semSortParam, SemCompareValue);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
for (i = 0; i < usedCount; i++) {
|
||||
semCB = GET_SEM(semIndexArray[i]);
|
||||
SCHEDULER_LOCK(intSave);
|
||||
(VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB));
|
||||
(VOID)memcpy_s(&semDebug, sizeof(SemDebugCB), &g_semDebugArray[semIndexArray[i]], sizeof(SemDebugCB));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if ((semNode.semStat != OS_SEM_USED) || (semDebug.creater == NULL)) {
|
||||
continue;
|
||||
}
|
||||
PRINTK(" 0x%-07x0x%-07u0x%-14u%-22p0x%llx\n", semNode.semID, semDebug.origSemCount,
|
||||
semNode.semCount, semDebug.creater, semDebug.lastAccessTime);
|
||||
if (!LOS_ListEmpty(&semNode.semList)) {
|
||||
OsSemPendedTaskNamePrint(semCB);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 OsSemInfoGetFullData(VOID)
|
||||
{
|
||||
UINT32 usedSemCnt = 0;
|
||||
LosSemCB *semNode = NULL;
|
||||
SemDebugCB *semDebug = NULL;
|
||||
UINT32 i;
|
||||
UINT32 *semIndexArray = NULL;
|
||||
UINT32 count, intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
/* Get the used semaphore count. */
|
||||
for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) {
|
||||
semNode = GET_SEM(i);
|
||||
semDebug = &g_semDebugArray[i];
|
||||
if ((semNode->semStat == OS_SEM_USED) && (semDebug->creater != NULL)) {
|
||||
usedSemCnt++;
|
||||
}
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
if (usedSemCnt > 0) {
|
||||
semIndexArray = (UINT32 *)LOS_MemAlloc((VOID *)OS_SYS_MEM_ADDR, usedSemCnt * sizeof(UINT32));
|
||||
if (semIndexArray == NULL) {
|
||||
PRINTK("LOS_MemAlloc failed in %s \n", __func__);
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
/* Fill the semIndexArray with the real index. */
|
||||
count = 0;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
for (i = 0; i < LOSCFG_BASE_IPC_SEM_LIMIT; i++) {
|
||||
semNode = GET_SEM(i);
|
||||
semDebug = &g_semDebugArray[i];
|
||||
if ((semNode->semStat != OS_SEM_USED) || (semDebug->creater == NULL)) {
|
||||
continue;
|
||||
}
|
||||
*(semIndexArray + count) = i;
|
||||
count++;
|
||||
/* if the count is touched usedSemCnt break. */
|
||||
if (count >= usedSemCnt) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
OsSemSort(semIndexArray, count);
|
||||
|
||||
/* free the index array. */
|
||||
(VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, semIndexArray);
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
#endif /* LOSCFG_DEBUG_SEMAPHORE */
|
||||
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
STATIC UINT32 OsSemInfoOutput(size_t semID)
|
||||
{
|
||||
UINT32 loop, semCnt, intSave;
|
||||
LosSemCB *semCB = NULL;
|
||||
LosSemCB semNode = {0};
|
||||
|
||||
if (semID == OS_ALL_SEM_MASK) {
|
||||
for (loop = 0, semCnt = 0; loop < LOSCFG_BASE_IPC_SEM_LIMIT; loop++) {
|
||||
semCB = GET_SEM(loop);
|
||||
SCHEDULER_LOCK(intSave);
|
||||
if (semCB->semStat == OS_SEM_USED) {
|
||||
(VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
semCnt++;
|
||||
PRINTK("\r\n SemID Count\n ---------- -----\n");
|
||||
PRINTK(" 0x%08x %u\n", semNode.semID, semNode.semCount);
|
||||
continue;
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
PRINTK(" SemUsingNum : %u\n\n", semCnt);
|
||||
return LOS_OK;
|
||||
} else {
|
||||
if (GET_SEM_INDEX(semID) >= LOSCFG_BASE_IPC_SEM_LIMIT) {
|
||||
PRINTK("\nInvalid semphore id!\n");
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
semCB = GET_SEM(semID);
|
||||
SCHEDULER_LOCK(intSave);
|
||||
(VOID)memcpy_s(&semNode, sizeof(LosSemCB), semCB, sizeof(LosSemCB));
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
if ((semNode.semID != semID) || (semNode.semStat != OS_SEM_USED)) {
|
||||
PRINTK("\nThe semphore is not in use!\n");
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
PRINTK("\r\n SemID Count\n ---------- -----\n");
|
||||
PRINTK(" 0x%08x 0x%u\n", semNode.semID, semNode.semCount);
|
||||
|
||||
if (LOS_ListEmpty(&semNode.semList)) {
|
||||
PRINTK("No task is pended on this semphore!\n");
|
||||
return LOS_OK;
|
||||
} else {
|
||||
OsSemPendedTaskNamePrint(semCB);
|
||||
}
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSemInfoGet(UINT32 argc, const CHAR **argv)
|
||||
{
|
||||
size_t semID;
|
||||
CHAR *endPtr = NULL;
|
||||
UINT32 ret;
|
||||
|
||||
if (argc > 1) {
|
||||
#ifdef LOSCFG_DEBUG_SEMAPHORE
|
||||
PRINTK("\nUsage: sem [fulldata|ID]\n");
|
||||
#else
|
||||
PRINTK("\nUsage: sem [ID]\n");
|
||||
#endif
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (argc == 0) {
|
||||
semID = OS_ALL_SEM_MASK;
|
||||
} else {
|
||||
#ifdef LOSCFG_DEBUG_SEMAPHORE
|
||||
if (strcmp(argv[0], "fulldata") == 0) {
|
||||
ret = OsSemInfoGetFullData();
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
semID = strtoul(argv[0], &endPtr, 0);
|
||||
if ((endPtr == NULL) || (*endPtr != 0)) {
|
||||
PRINTK("\nsem ID can't access %s.\n", argv[0]);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
ret = OsSemInfoOutput(semID);
|
||||
return ret;
|
||||
}
|
||||
|
||||
SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
691
kernel/base/ipc/los_signal.c
Executable file
691
kernel/base/ipc/los_signal.c
Executable file
@@ -0,0 +1,691 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_signal.h"
|
||||
#include "pthread.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "los_hw_pri.h"
|
||||
#include "user_copy.h"
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
#include "capability_api.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
int raise(int sig)
|
||||
{
|
||||
(VOID)sig;
|
||||
PRINT_ERR("%s NOT SUPPORT\n", __FUNCTION__);
|
||||
errno = ENOSYS;
|
||||
return -1;
|
||||
}
|
||||
|
||||
#define GETUNMASKSET(procmask, pendFlag) ((~(procmask)) & (sigset_t)(pendFlag))
|
||||
#define UINT64_BIT_SIZE 64
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsTcbDispatch(LosTaskCB *stcb, siginfo_t *info)
|
||||
{
|
||||
bool masked = FALSE;
|
||||
sig_cb *sigcb = &stcb->sig;
|
||||
|
||||
OS_RETURN_IF_NULL(sigcb);
|
||||
/* If signo is 0, not send signal, just check process or pthread exist */
|
||||
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) && OsSigIsMember(&sigcb->sigwaitmask, info->si_signo)) {
|
||||
OsTaskWake(stcb);
|
||||
OsSigEmptySet(&sigcb->sigwaitmask);
|
||||
} else {
|
||||
OsSigAddSet(&sigcb->sigPendFlag, info->si_signo);
|
||||
}
|
||||
} else {
|
||||
/* unmasked signal actions */
|
||||
OsSigAddSet(&sigcb->sigFlag, info->si_signo);
|
||||
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->si_signo)) {
|
||||
OsTaskWake(stcb);
|
||||
OsSigEmptySet(&sigcb->sigwaitmask);
|
||||
}
|
||||
}
|
||||
(void) memcpy_s(&sigcb->sigunbinfo, sizeof(siginfo_t), info, sizeof(siginfo_t));
|
||||
return 0;
|
||||
}
|
||||
|
||||
void OsSigMaskSwitch(LosTaskCB * const rtcb, sigset_t set)
|
||||
{
|
||||
sigset_t unmaskset;
|
||||
|
||||
rtcb->sig.sigprocmask = set;
|
||||
unmaskset = GETUNMASKSET(rtcb->sig.sigprocmask, rtcb->sig.sigPendFlag);
|
||||
if (unmaskset != NULL_SIGNAL_SET) {
|
||||
/* pendlist do */
|
||||
rtcb->sig.sigFlag |= unmaskset;
|
||||
rtcb->sig.sigPendFlag ^= unmaskset;
|
||||
}
|
||||
}
|
||||
|
||||
int OsSigprocMask(int how, const sigset_t_l *setl, sigset_t_l *oldset)
|
||||
{
|
||||
LosTaskCB *spcb = NULL;
|
||||
sigset_t oldSigprocmask;
|
||||
int ret = LOS_OK;
|
||||
unsigned int intSave;
|
||||
sigset_t set;
|
||||
int retVal;
|
||||
|
||||
if (setl != NULL) {
|
||||
retVal = LOS_ArchCopyFromUser(&set, &(setl->sig[0]), sizeof(sigset_t));
|
||||
if (retVal != 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
SCHEDULER_LOCK(intSave);
|
||||
spcb = OsCurrTaskGet();
|
||||
/* If requested, copy the old mask to user. */
|
||||
oldSigprocmask = spcb->sig.sigprocmask;
|
||||
|
||||
/* If requested, modify the current signal mask. */
|
||||
if (setl != NULL) {
|
||||
/* Okay, determine what we are supposed to do */
|
||||
switch (how) {
|
||||
/* Set the union of the current set and the signal
|
||||
* set pointed to by set as the new sigprocmask.
|
||||
*/
|
||||
case SIG_BLOCK:
|
||||
spcb->sig.sigprocmask |= set;
|
||||
break;
|
||||
/* Set the intersection of the current set and the
|
||||
* signal set pointed to by set as the new sigprocmask.
|
||||
*/
|
||||
case SIG_UNBLOCK:
|
||||
spcb->sig.sigprocmask &= ~(set);
|
||||
break;
|
||||
/* Set the signal set pointed to by set as the new sigprocmask. */
|
||||
case SIG_SETMASK:
|
||||
spcb->sig.sigprocmask = set;
|
||||
break;
|
||||
default:
|
||||
ret = -EINVAL;
|
||||
break;
|
||||
}
|
||||
/* If pending mask not in sigmask, need set sigflag. */
|
||||
OsSigMaskSwitch(spcb, spcb->sig.sigprocmask);
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
if (oldset != NULL) {
|
||||
retVal = LOS_ArchCopyToUser(&(oldset->sig[0]), &oldSigprocmask, sizeof(sigset_t));
|
||||
if (retVal != 0) {
|
||||
return -EFAULT;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsSigProcessForeachChild(LosProcessCB *spcb, ForEachTaskCB handler, void *arg)
|
||||
{
|
||||
int ret;
|
||||
|
||||
/* Visit the main thread last (if present) */
|
||||
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;
|
||||
int ret;
|
||||
int isMember;
|
||||
|
||||
if (tcb == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* If the default tcb is not setted, 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)) {
|
||||
/* 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.
|
||||
*/
|
||||
ret = OsTcbDispatch(tcb, info->sigInfo);
|
||||
OS_RETURN_IF(ret < 0, ret);
|
||||
|
||||
/* 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? */
|
||||
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. */
|
||||
if (!info->unblockedTcb) {
|
||||
info->unblockedTcb = tcb;
|
||||
}
|
||||
|
||||
ret = OsTcbDispatch(tcb, info->sigInfo);
|
||||
OS_RETURN_IF(ret < 0, ret);
|
||||
/* set this tcb as receivedTcb */
|
||||
info->receivedTcb = tcb;
|
||||
OS_RETURN_IF(info->awakenedTcb != NULL, SIG_STOP_VISIT); /* Stop search */
|
||||
}
|
||||
return 0; /* Keep searching */
|
||||
}
|
||||
|
||||
static int SigProcessKillSigHandler(LosTaskCB *tcb, void *arg)
|
||||
{
|
||||
struct ProcessSignalInfo *info = (struct ProcessSignalInfo *)arg;
|
||||
|
||||
if ((tcb != NULL) && (info != NULL) && (info->sigInfo != NULL)) {
|
||||
sig_cb *sigcb = &tcb->sig;
|
||||
if (!LOS_ListEmpty(&sigcb->waitList) && OsSigIsMember(&sigcb->sigwaitmask, info->sigInfo->si_signo)) {
|
||||
OsTaskWake(tcb);
|
||||
OsSigEmptySet(&sigcb->sigwaitmask);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void SigProcessLoadTcb(struct ProcessSignalInfo *info, siginfo_t *sigInfo)
|
||||
{
|
||||
LosTaskCB *tcb = NULL;
|
||||
|
||||
if (info->awakenedTcb == NULL && info->receivedTcb == NULL) {
|
||||
if (info->unblockedTcb) {
|
||||
tcb = info->unblockedTcb;
|
||||
} else if (info->defaultTcb) {
|
||||
tcb = info->defaultTcb;
|
||||
} else {
|
||||
return;
|
||||
}
|
||||
/* Deliver the signal to the selected task */
|
||||
(void)OsTcbDispatch(tcb, sigInfo);
|
||||
}
|
||||
}
|
||||
|
||||
int OsSigProcessSend(LosProcessCB *spcb, siginfo_t *sigInfo)
|
||||
{
|
||||
int ret;
|
||||
struct ProcessSignalInfo info = {
|
||||
.sigInfo = sigInfo,
|
||||
.defaultTcb = NULL,
|
||||
.unblockedTcb = NULL,
|
||||
.awakenedTcb = NULL,
|
||||
.receivedTcb = NULL
|
||||
};
|
||||
|
||||
/* visit all taskcb and dispatch signal */
|
||||
if ((info.sigInfo != NULL) && (info.sigInfo->si_signo == SIGKILL)) {
|
||||
(void)OsSigProcessForeachChild(spcb, SigProcessKillSigHandler, &info);
|
||||
OsSigAddSet(&spcb->sigShare, info.sigInfo->si_signo);
|
||||
OsWaitSignalToWakeProcess(spcb);
|
||||
return 0;
|
||||
} else {
|
||||
ret = OsSigProcessForeachChild(spcb, SigProcessSignalHandler, &info);
|
||||
}
|
||||
if (ret < 0) {
|
||||
return ret;
|
||||
}
|
||||
SigProcessLoadTcb(&info, sigInfo);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OsSigEmptySet(sigset_t *set)
|
||||
{
|
||||
*set = NULL_SIGNAL_SET;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Privilege process can't send to kernel and privilege process */
|
||||
static int OsSignalPermissionToCheck(const LosProcessCB *spcb)
|
||||
{
|
||||
UINT32 gid = spcb->group->groupID;
|
||||
|
||||
if (gid == OS_KERNEL_PROCESS_GROUP) {
|
||||
return -EPERM;
|
||||
} else if (gid == OS_USER_PRIVILEGE_PROCESS_GROUP) {
|
||||
return -EPERM;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OsDispatch(pid_t pid, siginfo_t *info, int permission)
|
||||
{
|
||||
LosProcessCB *spcb = OS_PCB_FROM_PID(pid);
|
||||
if (OsProcessIsUnused(spcb)) {
|
||||
return -ESRCH;
|
||||
}
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
LosProcessCB *current = OsCurrProcessGet();
|
||||
|
||||
/* If the process you want to kill had been inactive, but still exist. should return LOS_OK */
|
||||
if (OsProcessIsInactive(spcb)) {
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
/* Kernel process always has kill permission and user process should check permission */
|
||||
if (OsProcessIsUserMode(current) && !(current->processStatus & OS_PROCESS_FLAG_EXIT)) {
|
||||
if ((current != spcb) && (!IsCapPermit(CAP_KILL)) && (current->user->userID != spcb->user->userID)) {
|
||||
return -EPERM;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if ((permission == OS_USER_KILL_PERMISSION) && (OsSignalPermissionToCheck(spcb) < 0)) {
|
||||
return -EPERM;
|
||||
}
|
||||
return OsSigProcessSend(spcb, info);
|
||||
}
|
||||
|
||||
int OsKill(pid_t pid, int sig, int permission)
|
||||
{
|
||||
siginfo_t info;
|
||||
int ret;
|
||||
|
||||
/* Make sure that the para is valid */
|
||||
if (!GOOD_SIGNO(sig) || pid < 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (OsProcessIDUserCheckInvalid(pid)) {
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
/* Create the siginfo structure */
|
||||
info.si_signo = sig;
|
||||
info.si_code = SI_USER;
|
||||
info.si_value.sival_ptr = NULL;
|
||||
|
||||
/* Send the signal */
|
||||
ret = OsDispatch(pid, &info, permission);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsKillLock(pid_t pid, int sig)
|
||||
{
|
||||
int ret;
|
||||
unsigned int intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
ret = OsKill(pid, sig, OS_USER_KILL_PERMISSION);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsPthreadKill(UINT32 tid, int signo)
|
||||
{
|
||||
LosTaskCB *stcb = NULL;
|
||||
siginfo_t info;
|
||||
|
||||
int ret;
|
||||
UINT32 intSave;
|
||||
|
||||
/* Make sure that the signal is valid */
|
||||
OS_RETURN_IF(!GOOD_SIGNO(signo), -EINVAL);
|
||||
if (OS_TID_CHECK_INVALID(tid)) {
|
||||
return -ESRCH;
|
||||
}
|
||||
|
||||
/* Create the siginfo structure */
|
||||
info.si_signo = signo;
|
||||
info.si_code = SI_USER;
|
||||
info.si_value.sival_ptr = NULL;
|
||||
/* Keep things stationary through the following */
|
||||
SCHEDULER_LOCK(intSave);
|
||||
/* Get the TCB associated with the thread */
|
||||
stcb = OsGetTaskCB(tid);
|
||||
OS_GOTO_EXIT_IF(stcb == NULL, -ESRCH);
|
||||
|
||||
ret = OsUserTaskOperatePermissionsCheck(stcb);
|
||||
OS_GOTO_EXIT_IF(ret != LOS_OK, -ret);
|
||||
|
||||
/* Dispatch the signal to thread, bypassing normal task group thread
|
||||
* dispatch rules. */
|
||||
ret = OsTcbDispatch(stcb, &info);
|
||||
EXIT:
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsSigAddSet(sigset_t *set, int signo)
|
||||
{
|
||||
/* Verify the signal */
|
||||
if (!GOOD_SIGNO(signo)) {
|
||||
return -EINVAL;
|
||||
} else {
|
||||
/* In musl, sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
|
||||
signo -= 1;
|
||||
/* Add the signal to the set */
|
||||
*set |= SIGNO2SET((unsigned int)signo);
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
|
||||
int OsSigPending(sigset_t *set)
|
||||
{
|
||||
LosTaskCB *tcb = NULL;
|
||||
unsigned int intSave;
|
||||
|
||||
if (set == NULL) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
tcb = OsCurrTaskGet();
|
||||
*set = tcb->sig.sigPendFlag;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC int FindFirstSetedBit(UINT64 n)
|
||||
{
|
||||
int count;
|
||||
|
||||
if (n == 0) {
|
||||
return -1;
|
||||
}
|
||||
for (count = 0; (count < UINT64_BIT_SIZE) && (n ^ 1ULL); n >>= 1, count++) {}
|
||||
return (count < UINT64_BIT_SIZE) ? count : (-1);
|
||||
}
|
||||
|
||||
int OsSigTimedWaitNoLock(sigset_t *set, siginfo_t *info, unsigned int timeout)
|
||||
{
|
||||
LosTaskCB *task = NULL;
|
||||
sig_cb *sigcb = NULL;
|
||||
int ret;
|
||||
|
||||
task = OsCurrTaskGet();
|
||||
sigcb = &task->sig;
|
||||
|
||||
if (sigcb->waitList.pstNext == NULL) {
|
||||
LOS_ListInit(&sigcb->waitList);
|
||||
}
|
||||
/* If pendingflag & set > 0, shound clear pending flag */
|
||||
sigset_t clear = sigcb->sigPendFlag & *set;
|
||||
if (clear) {
|
||||
sigcb->sigPendFlag ^= clear;
|
||||
ret = FindFirstSetedBit((UINT64)clear) + 1;
|
||||
} else {
|
||||
OsSigAddSet(set, SIGKILL);
|
||||
OsSigAddSet(set, SIGSTOP);
|
||||
|
||||
sigcb->sigwaitmask |= *set;
|
||||
ret = OsTaskWait(&sigcb->waitList, timeout, TRUE);
|
||||
if (ret == LOS_ERRNO_TSK_TIMEOUT) {
|
||||
ret = -EAGAIN;
|
||||
}
|
||||
sigcb->sigwaitmask = NULL_SIGNAL_SET;
|
||||
}
|
||||
if (info != NULL) {
|
||||
(void) memcpy_s(info, sizeof(siginfo_t), &sigcb->sigunbinfo, sizeof(siginfo_t));
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsSigTimedWait(sigset_t *set, siginfo_t *info, unsigned int timeout)
|
||||
{
|
||||
int ret;
|
||||
unsigned int intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
ret = OsSigTimedWaitNoLock(set, info, timeout);
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int OsPause(void)
|
||||
{
|
||||
LosTaskCB *spcb = NULL;
|
||||
sigset_t oldSigprocmask;
|
||||
|
||||
spcb = OsCurrTaskGet();
|
||||
oldSigprocmask = spcb->sig.sigprocmask;
|
||||
return OsSigSuspend(&oldSigprocmask);
|
||||
}
|
||||
|
||||
int OsSigSuspend(const sigset_t *set)
|
||||
{
|
||||
unsigned int intSave;
|
||||
LosTaskCB *rtcb = NULL;
|
||||
unsigned int sigTempProcMask;
|
||||
sigset_t setSuspend;
|
||||
int ret;
|
||||
|
||||
if (set == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
SCHEDULER_LOCK(intSave);
|
||||
rtcb = OsCurrTaskGet();
|
||||
sigTempProcMask = rtcb->sig.sigprocmask;
|
||||
|
||||
/* Wait signal calc */
|
||||
setSuspend = FULL_SIGNAL_SET & (~(*set));
|
||||
|
||||
/* If pending mask not in sigmask, need set sigflag */
|
||||
OsSigMaskSwitch(rtcb, *set);
|
||||
ret = OsSigTimedWaitNoLock(&setSuspend, NULL, LOS_WAIT_FOREVER);
|
||||
if (ret < 0) {
|
||||
PRINT_ERR("FUNC %s LINE = %d, ret = %x\n", __FUNCTION__, __LINE__, ret);
|
||||
}
|
||||
/* Restore old sigprocmask */
|
||||
OsSigMaskSwitch(rtcb, sigTempProcMask);
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return -EINTR;
|
||||
}
|
||||
|
||||
int OsSigAction(int sig, const sigaction_t *act, sigaction_t *oact)
|
||||
{
|
||||
UINTPTR addr;
|
||||
sigaction_t action;
|
||||
|
||||
if (!GOOD_SIGNO(sig) || sig < 1 || act == NULL) {
|
||||
return -EINVAL;
|
||||
}
|
||||
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);
|
||||
return LOS_OK;
|
||||
}
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
void OsSaveSignalContext(unsigned int *sp)
|
||||
{
|
||||
UINTPTR sigHandler;
|
||||
UINT32 intSave;
|
||||
LosTaskCB *task = NULL;
|
||||
LosProcessCB *process = NULL;
|
||||
sig_cb *sigcb = NULL;
|
||||
unsigned long cpsr;
|
||||
|
||||
OS_RETURN_IF_VOID(sp == NULL);
|
||||
cpsr = OS_SYSCALL_GET_CPSR(sp);
|
||||
|
||||
OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE));
|
||||
SCHEDULER_LOCK(intSave);
|
||||
task = OsCurrTaskGet();
|
||||
process = OsCurrProcessGet();
|
||||
sigcb = &task->sig;
|
||||
|
||||
if ((sigcb->context.count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) {
|
||||
sigHandler = OsGetSigHandler();
|
||||
if (sigHandler == 0) {
|
||||
sigcb->sigFlag = 0;
|
||||
process->sigShare = 0;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
PRINT_ERR("The signal processing function for the current process pid =%d is NULL!\n", task->processID);
|
||||
return;
|
||||
}
|
||||
/* One pthread do the share signal */
|
||||
sigcb->sigFlag |= process->sigShare;
|
||||
unsigned int signo = (unsigned int)FindFirstSetedBit(sigcb->sigFlag) + 1;
|
||||
OsProcessExitCodeSignalSet(process, signo);
|
||||
sigcb->context.CPSR = cpsr;
|
||||
sigcb->context.PC = sp[REG_PC];
|
||||
sigcb->context.USP = sp[REG_SP];
|
||||
sigcb->context.ULR = sp[REG_LR];
|
||||
sigcb->context.R0 = sp[REG_R0];
|
||||
sigcb->context.R1 = sp[REG_R1];
|
||||
sigcb->context.R2 = sp[REG_R2];
|
||||
sigcb->context.R3 = sp[REG_R3];
|
||||
sigcb->context.R7 = sp[REG_R7];
|
||||
sigcb->context.R12 = sp[REG_R12];
|
||||
sp[REG_PC] = sigHandler;
|
||||
sp[REG_R0] = signo;
|
||||
sp[REG_R1] = (unsigned int)(UINTPTR)(sigcb->sigunbinfo.si_value.sival_ptr);
|
||||
/* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
|
||||
sigcb->sigFlag ^= 1ULL << (signo - 1);
|
||||
sigcb->context.count++;
|
||||
}
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
void OsSaveSignalContextIrq(unsigned int *sp, unsigned int r7)
|
||||
{
|
||||
UINTPTR sigHandler;
|
||||
LosTaskCB *task = NULL;
|
||||
LosProcessCB *process = NULL;
|
||||
sig_cb *sigcb = NULL;
|
||||
unsigned long cpsr;
|
||||
UINT32 intSave;
|
||||
TaskIrqContext *context = (TaskIrqContext *)(sp);
|
||||
|
||||
OS_RETURN_IF_VOID(sp == NULL);
|
||||
cpsr = context->CPSR;
|
||||
OS_RETURN_IF_VOID(((cpsr & CPSR_MASK_MODE) != CPSR_USER_MODE));
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
task = OsCurrTaskGet();
|
||||
process = OsCurrProcessGet();
|
||||
sigcb = &task->sig;
|
||||
if ((sigcb->context.count == 0) && ((sigcb->sigFlag != 0) || (process->sigShare != 0))) {
|
||||
sigHandler = OsGetSigHandler();
|
||||
if (sigHandler == 0) {
|
||||
sigcb->sigFlag = 0;
|
||||
process->sigShare = 0;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
PRINT_ERR("The current process pid =%d starts fail!\n", task->processID);
|
||||
return;
|
||||
}
|
||||
sigcb->sigFlag |= process->sigShare;
|
||||
unsigned int signo = (unsigned int)FindFirstSetedBit(sigcb->sigFlag) + 1;
|
||||
OsProcessExitCodeSignalSet(process, signo);
|
||||
(VOID)memcpy_s(&sigcb->context.R0, sizeof(TaskIrqDataSize), &context->R0, sizeof(TaskIrqDataSize));
|
||||
sigcb->context.R7 = r7;
|
||||
context->PC = sigHandler;
|
||||
context->R0 = signo;
|
||||
context->R1 = (UINT32)(UINTPTR)sigcb->sigunbinfo.si_value.sival_ptr;
|
||||
/* sig No bits 00000100 present sig No 3, but 1<< 3 = 00001000, so signo needs minus 1 */
|
||||
sigcb->sigFlag ^= 1ULL << (signo - 1);
|
||||
sigcb->context.count++;
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
void OsRestorSignalContext(unsigned int *sp)
|
||||
{
|
||||
LosTaskCB *task = NULL; /* Do not adjust this statement */
|
||||
LosProcessCB *process = NULL;
|
||||
sig_cb *sigcb = NULL;
|
||||
UINT32 intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
task = OsCurrTaskGet();
|
||||
sigcb = &task->sig;
|
||||
|
||||
if (sigcb->context.count != 1) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
PRINT_ERR("sig error count : %d\n", sigcb->context.count);
|
||||
return;
|
||||
}
|
||||
|
||||
process = OsCurrProcessGet();
|
||||
sp[REG_PC] = sigcb->context.PC;
|
||||
OS_SYSCALL_SET_CPSR(sp, sigcb->context.CPSR);
|
||||
sp[REG_SP] = sigcb->context.USP;
|
||||
sp[REG_LR] = sigcb->context.ULR;
|
||||
sp[REG_R0] = sigcb->context.R0;
|
||||
sp[REG_R1] = sigcb->context.R1;
|
||||
sp[REG_R2] = sigcb->context.R2;
|
||||
sp[REG_R3] = sigcb->context.R3;
|
||||
sp[REG_R7] = sigcb->context.R7;
|
||||
sp[REG_R12] = sigcb->context.R12;
|
||||
sigcb->context.count--;
|
||||
process->sigShare = 0;
|
||||
OsProcessExitCodeSignalClear(process);
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
2971
kernel/base/mem/bestfit/los_memory.c
Executable file
2971
kernel/base/mem/bestfit/los_memory.c
Executable file
File diff suppressed because it is too large
Load Diff
74
kernel/base/mem/bestfit/los_multipledlinkhead.c
Executable file
74
kernel/base/mem/bestfit/los_multipledlinkhead.c
Executable file
@@ -0,0 +1,74 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_multipledlinkhead_pri.h"
|
||||
#include "los_bitmap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
STATIC INLINE UINT32 OsLog2(UINT32 size)
|
||||
{
|
||||
return (size > 0) ? (UINT32)LOS_HighBitGet(size) : 0;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID OsDLnkInitMultiHead(VOID *headAddr)
|
||||
{
|
||||
LosMultipleDlinkHead *dlinkHead = (LosMultipleDlinkHead *)headAddr;
|
||||
LOS_DL_LIST *listNodeHead = dlinkHead->listHead;
|
||||
UINT32 index;
|
||||
|
||||
for (index = 0; index < OS_MULTI_DLNK_NUM; ++index, ++listNodeHead) {
|
||||
LOS_ListInit(listNodeHead);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR LOS_DL_LIST *OsDLnkMultiHead(VOID *headAddr, UINT32 size)
|
||||
{
|
||||
LosMultipleDlinkHead *dlinkHead = (LosMultipleDlinkHead *)headAddr;
|
||||
UINT32 index = OsLog2(size);
|
||||
if (index > OS_MAX_MULTI_DLNK_LOG2) {
|
||||
return NULL;
|
||||
} else if (index <= OS_MIN_MULTI_DLNK_LOG2) {
|
||||
index = OS_MIN_MULTI_DLNK_LOG2;
|
||||
}
|
||||
|
||||
return dlinkHead->listHead + (index - OS_MIN_MULTI_DLNK_LOG2);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
424
kernel/base/mem/bestfit_little/los_heap.c
Executable file
424
kernel/base/mem/bestfit_little/los_heap.c
Executable file
@@ -0,0 +1,424 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "string.h"
|
||||
#include "securec.h"
|
||||
#include "los_hwi.h"
|
||||
#include "los_typedef.h"
|
||||
#include "los_heap_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
static UINT32 g_memAllocCount = 0;
|
||||
static UINT32 g_memFreeCount = 0;
|
||||
|
||||
#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES)
|
||||
static UINT32 g_memCurHeapUsed = 0;
|
||||
static UINT32 g_memMaxHeapUsed = 0;
|
||||
#endif
|
||||
|
||||
#define HEAP_CAST(t, exp) ((t)(exp))
|
||||
#define HEAP_ALIGN 4
|
||||
#define HEAP_TAIL_NODE_SIZE_THRESHOLD 1024
|
||||
|
||||
/*
|
||||
* Description : look up the next memory node according to one memory node in the memory block list.
|
||||
* Input : struct LosHeapManager *heapMan --- Pointer to the manager,to distinguish heap
|
||||
* struct LosHeapNode *node --- Size of memory in bytes to allocate
|
||||
* Return : Pointer to next memory node
|
||||
*/
|
||||
struct LosHeapNode* OsHeapPrvGetNext(struct LosHeapManager *heapMan, struct LosHeapNode *node)
|
||||
{
|
||||
return (heapMan->tail == node) ? NULL : (struct LosHeapNode *)(UINTPTR)(node->data + node->size);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description : To initialize the heap memory and get the begin address and size of heap memory,
|
||||
* then initialize LosHeapManager.
|
||||
* Input : VOID *pool --- begin address of the heap memory pool
|
||||
* UITN32 size --- size of the heap memory pool
|
||||
* Return : 1:success 0:error
|
||||
*/
|
||||
BOOL OsHeapInit(VOID *pool, UINT32 size)
|
||||
{
|
||||
struct LosHeapNode *node = NULL;
|
||||
struct LosHeapManager *heapMan = HEAP_CAST(struct LosHeapManager *, pool);
|
||||
|
||||
if ((heapMan == NULL) || (size <= (sizeof(struct LosHeapNode) + sizeof(struct LosHeapManager)))) {
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
// Ignore the return code when matching CSEC rule 6.6(2).
|
||||
(VOID)memset_s(pool, size, 0, size);
|
||||
|
||||
heapMan->size = size;
|
||||
|
||||
node = heapMan->head = (struct LosHeapNode *)((UINT8*)pool + sizeof(struct LosHeapManager));
|
||||
|
||||
heapMan->tail = node;
|
||||
|
||||
node->used = 0;
|
||||
node->prev = NULL;
|
||||
node->size = size - sizeof(struct LosHeapNode) - sizeof(struct LosHeapManager);
|
||||
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description : update used size
|
||||
* Input : size --- alloc memory size
|
||||
* ret --- memory chunk
|
||||
*/
|
||||
VOID OsHeapUpdateUsedSize(UINT32 size, VOID *ret)
|
||||
{
|
||||
#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES)
|
||||
g_memCurHeapUsed += (size + sizeof(struct LosHeapNode));
|
||||
if (g_memCurHeapUsed > g_memMaxHeapUsed) {
|
||||
g_memMaxHeapUsed = g_memCurHeapUsed;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (ret != NULL) {
|
||||
g_memAllocCount++;
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Description : To alloc memory block from the heap memory poll
|
||||
* Input : VOID *pool --- Pointer to the manager,to distinguish heap
|
||||
* UINT32 size --- size of the heap memory pool
|
||||
* Return : NULL:error, other value:the address of the memory we alloced
|
||||
*/
|
||||
VOID* OsHeapAlloc(VOID *pool, UINT32 size)
|
||||
{
|
||||
struct LosHeapNode *node = NULL;
|
||||
struct LosHeapNode *next = NULL;
|
||||
struct LosHeapNode *best = NULL;
|
||||
VOID *ret = NULL;
|
||||
UINT32 alignSize = ALIGNE(size);
|
||||
|
||||
struct LosHeapManager *heapMan = HEAP_CAST(struct LosHeapManager *, pool);
|
||||
if (heapMan == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
node = heapMan->tail;
|
||||
while (node != NULL) {
|
||||
if ((node->used == 0) && (node->size >= alignSize) &&
|
||||
((best == NULL) || (best->size > node->size))) {
|
||||
best = node;
|
||||
if (best->size == alignSize) {
|
||||
goto SIZE_MATCH;
|
||||
}
|
||||
}
|
||||
node = node->prev;
|
||||
}
|
||||
|
||||
/* alloc failed */
|
||||
if (best == NULL) {
|
||||
PRINT_ERR("there's not enough whole to alloc %x Bytes!\n", alignSize);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if ((best->size - alignSize) > sizeof(struct LosHeapNode)) {
|
||||
/* hole divide into 2 */
|
||||
node = (struct LosHeapNode*)(UINTPTR)(best->data + alignSize);
|
||||
|
||||
node->used = 0;
|
||||
node->size = best->size - alignSize - sizeof(struct LosHeapNode);
|
||||
node->prev = best;
|
||||
|
||||
if (best != heapMan->tail) {
|
||||
next = OsHeapPrvGetNext(heapMan, node);
|
||||
if (next != NULL) {
|
||||
next->prev = node;
|
||||
}
|
||||
} else {
|
||||
heapMan->tail = node;
|
||||
}
|
||||
|
||||
best->size = alignSize;
|
||||
}
|
||||
|
||||
SIZE_MATCH:
|
||||
best->align = 0;
|
||||
best->used = 1;
|
||||
ret = best->data;
|
||||
|
||||
OsHeapUpdateUsedSize(alignSize, ret);
|
||||
OUT:
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description : To alloc memory block from the heap memory poll with
|
||||
* Input : VOID *pool --- Pointer to the manager,to distinguish heap
|
||||
* UINT32 size --- size of the heap memory pool
|
||||
* UINT32 boundary --- boundary the heap needs align
|
||||
* Return : NULL:error, other value:the address of the memory we alloced
|
||||
*/
|
||||
VOID* OsHeapAllocAlign(VOID *pool, UINT32 size, UINT32 boundary)
|
||||
{
|
||||
UINT32 useSize;
|
||||
UINT32 gapSize;
|
||||
VOID *ret = NULL;
|
||||
VOID *alignedPtr = NULL;
|
||||
|
||||
if ((pool == NULL) || (size == 0) || (boundary < sizeof(VOID *)) || !IS_ALIGNED(boundary, boundary)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* worst case is that the node happen to be 4 bytes ahead of the boundary */
|
||||
useSize = (size + boundary) - sizeof(VOID*);
|
||||
if (useSize < size) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ret = OsHeapAlloc(pool, useSize);
|
||||
if (ret != NULL) {
|
||||
alignedPtr = (VOID *)(UINTPTR)OS_MEM_ALIGN(ret, boundary);
|
||||
if (ret == alignedPtr) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
gapSize = (UINTPTR)alignedPtr - (UINTPTR)ret;
|
||||
OS_MEM_SET_ALIGN_FLAG(gapSize);
|
||||
*((UINT32 *)((UINTPTR)alignedPtr - (sizeof(UINTPTR) / sizeof(UINT8)))) = gapSize;
|
||||
|
||||
ret = alignedPtr;
|
||||
}
|
||||
OUT:
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATIC VOID OsDoHeapFree(struct LosHeapManager *heapMan, struct LosHeapNode *curNode)
|
||||
{
|
||||
struct LosHeapNode *node = curNode;
|
||||
struct LosHeapNode *next = NULL;
|
||||
/* set to unused status */
|
||||
node->used = 0;
|
||||
|
||||
#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES)
|
||||
if (g_memCurHeapUsed >= (node->size + sizeof(struct LosHeapNode))) {
|
||||
g_memCurHeapUsed -= (node->size + sizeof(struct LosHeapNode));
|
||||
}
|
||||
#endif
|
||||
|
||||
/* unused region before and after combination */
|
||||
while (node->prev && !node->prev->used) {
|
||||
node = node->prev;
|
||||
}
|
||||
|
||||
next = OsHeapPrvGetNext(heapMan, node);
|
||||
while (next != NULL) {
|
||||
if (next->used) {
|
||||
next->prev = node;
|
||||
break;
|
||||
}
|
||||
node->size += sizeof(struct LosHeapNode) + next->size;
|
||||
if (heapMan->tail == next) {
|
||||
heapMan->tail = node;
|
||||
}
|
||||
next = OsHeapPrvGetNext(heapMan, node);
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Description : To free the memory block from heap memory poll
|
||||
* Input : VOID* pool --- Pointer to the manager,to distinguish heap
|
||||
* VOID* ptr --- the pointer of heap memory we want to free
|
||||
* Return : 1:success 0:error
|
||||
*/
|
||||
BOOL OsHeapFree(VOID *pool, VOID *ptr)
|
||||
{
|
||||
struct LosHeapNode *node = NULL;
|
||||
|
||||
UINT32 gapSize;
|
||||
BOOL ret = TRUE;
|
||||
|
||||
struct LosHeapManager *heapMan = HEAP_CAST(struct LosHeapManager *, pool);
|
||||
if ((heapMan == NULL) || (ptr == NULL)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
/* find the real ptr through gap size */
|
||||
gapSize = *((UINT32 *)((UINTPTR)ptr - (sizeof(UINTPTR) / sizeof(UINT8))));
|
||||
if (OS_MEM_GET_ALIGN_FLAG(gapSize)) {
|
||||
gapSize = OS_MEM_GET_ALIGN_GAPSIZE(gapSize);
|
||||
ptr = (VOID *)((UINTPTR)ptr - gapSize);
|
||||
}
|
||||
|
||||
if (((UINTPTR)ptr < (UINTPTR)heapMan->head) ||
|
||||
((UINTPTR)ptr > ((UINTPTR)heapMan->tail + sizeof(struct LosHeapNode)))) {
|
||||
PRINT_ERR("0x%x out of range!\n", (UINTPTR)ptr);
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
node = ((struct LosHeapNode *)ptr) - 1;
|
||||
/* check if the address is a node of the heap memory list */
|
||||
if ((node->used == 0) || (!((UINTPTR)node == (UINTPTR)heapMan->head) &&
|
||||
(((UINTPTR)node->prev < (UINTPTR)heapMan->head) ||
|
||||
((UINTPTR)node->prev > ((UINTPTR)heapMan->tail + sizeof(struct LosHeapNode))) ||
|
||||
((UINTPTR)OsHeapPrvGetNext(heapMan, node->prev) != (UINTPTR)node)))) {
|
||||
ret = FALSE;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
OsDoHeapFree(heapMan, node);
|
||||
|
||||
OUT:
|
||||
if (ret == TRUE) {
|
||||
g_memFreeCount++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Description : print heap information
|
||||
* Input : pool --- Pointer to the manager, to distinguish heap
|
||||
*/
|
||||
VOID OsAlarmHeapInfo(VOID *pool)
|
||||
{
|
||||
struct LosHeapManager *heapMan = HEAP_CAST(struct LosHeapManager *, pool);
|
||||
LosHeapStatus status = {0};
|
||||
(VOID)heapMan;
|
||||
|
||||
if (OsHeapStatisticsGet(pool, &status) == LOS_NOK) {
|
||||
return;
|
||||
}
|
||||
|
||||
PRINT_INFO("pool addr pool size used size free size max free alloc Count free Count\n");
|
||||
PRINT_INFO("0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-8x 0x%-8x\n",
|
||||
pool, heapMan->size, status.totalUsedSize, status.totalFreeSize, status.maxFreeNodeSize,
|
||||
status.usedNodeNum, status.freeNodeNum);
|
||||
}
|
||||
|
||||
/*
|
||||
* Description : collect heap statistics
|
||||
* Input : pool --- Pointer to the manager, to distinguish heap
|
||||
* Output : status --- heap statistics
|
||||
* Return : LOS_OK on success or error code on failure
|
||||
*/
|
||||
UINT32 OsHeapStatisticsGet(VOID *pool, LosHeapStatus *status)
|
||||
{
|
||||
UINT32 heapUsed = 0;
|
||||
UINT32 maxFreeNodeSize = 0;
|
||||
UINT32 freeNodeNum = 0;
|
||||
UINT32 usedNodeNum = 0;
|
||||
|
||||
struct LosHeapNode *node = NULL;
|
||||
struct LosHeapManager *ramHeap = HEAP_CAST(struct LosHeapManager *, pool);
|
||||
|
||||
if (ramHeap == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
if (status == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
/* heap mannager header use heap space */
|
||||
heapUsed += sizeof(struct LosHeapManager);
|
||||
|
||||
node = ramHeap->tail;
|
||||
while (node != NULL) {
|
||||
if (node->used) {
|
||||
heapUsed += (node->size + sizeof(struct LosHeapNode));
|
||||
usedNodeNum++;
|
||||
} else {
|
||||
if (node->size > maxFreeNodeSize) {
|
||||
maxFreeNodeSize = node->size;
|
||||
}
|
||||
freeNodeNum++;
|
||||
}
|
||||
node = node->prev;
|
||||
}
|
||||
|
||||
if (ramHeap->size < heapUsed) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
status->totalUsedSize = heapUsed;
|
||||
status->maxFreeNodeSize = maxFreeNodeSize;
|
||||
status->totalFreeSize = ramHeap->size - status->totalUsedSize;
|
||||
status->usedNodeNum = usedNodeNum;
|
||||
status->freeNodeNum = freeNodeNum;
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#if (LOSCFG_HEAP_MEMORY_PEAK_STATISTICS == YES)
|
||||
UINT32 LOS_HeapGetHeapMemoryPeak(VOID)
|
||||
{
|
||||
return g_memMaxHeapUsed;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* Description : get max free block size
|
||||
* Input : pool --- Pointer to the manager, to distinguish heap
|
||||
* Return : max free block size
|
||||
*/
|
||||
UINT32 OsHeapGetMaxFreeBlkSize(VOID *pool)
|
||||
{
|
||||
UINT32 size = 0;
|
||||
UINT32 temp;
|
||||
struct LosHeapNode *node = NULL;
|
||||
struct LosHeapManager *ramHeap = HEAP_CAST(struct LosHeapManager *, pool);
|
||||
|
||||
if (ramHeap == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
node = ramHeap->tail;
|
||||
while (node != NULL) {
|
||||
if (!(node->used)) {
|
||||
temp = node->size;
|
||||
if (temp > size) {
|
||||
size = temp;
|
||||
}
|
||||
}
|
||||
node = node->prev;
|
||||
}
|
||||
return size;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
126
kernel/base/mem/common/los_memstat.c
Executable file
126
kernel/base/mem/common/los_memstat.c
Executable file
@@ -0,0 +1,126 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_memstat_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_BSS_MINOR STATIC TskMemUsedInfo g_tskMemUsedInfo[LOSCFG_BASE_CORE_TSK_LIMIT];
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedInc(UINT32 usedSize, UINT32 taskID)
|
||||
{
|
||||
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
return;
|
||||
}
|
||||
if (OS_INT_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
g_tskMemUsedInfo[taskID].memUsed += usedSize;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemUsedDec(UINT32 usedSize, UINT32 taskID)
|
||||
{
|
||||
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
return;
|
||||
}
|
||||
if (OS_INT_ACTIVE) {
|
||||
return;
|
||||
}
|
||||
if (g_tskMemUsedInfo[taskID].memUsed < usedSize) {
|
||||
PRINT_WARN("mem used of current task '%s':0x%x, decrease size:0x%x\n",
|
||||
OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed, usedSize);
|
||||
return;
|
||||
}
|
||||
g_tskMemUsedInfo[taskID].memUsed -= usedSize;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskMemUsage(UINT32 taskID)
|
||||
{
|
||||
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
return g_tskMemUsedInfo[taskID].memUsed;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsTaskMemClear(UINT32 taskID)
|
||||
{
|
||||
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
return;
|
||||
}
|
||||
if (g_tskMemUsedInfo[taskID].memUsed != 0) {
|
||||
PRINT_WARN("mem used of task '%s' is:0x%x, not zero when task being deleted\n",
|
||||
OsCurrTaskGet()->taskName, g_tskMemUsedInfo[taskID].memUsed);
|
||||
}
|
||||
g_tskMemUsedInfo[taskID].memUsed = 0;
|
||||
}
|
||||
|
||||
#ifdef LOS_MEM_SLAB
|
||||
|
||||
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)
|
||||
{
|
||||
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_tskSlabUsedInfo[taskID].slabUsed += usedSize;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsTaskSlabUsedDec(UINT32 usedSize, UINT32 taskID)
|
||||
{
|
||||
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_tskSlabUsedInfo[taskID].slabUsed -= usedSize;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsTaskSlabUsage(UINT32 taskID)
|
||||
{
|
||||
if (taskID >= LOSCFG_BASE_CORE_TSK_LIMIT) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
return g_tskSlabUsedInfo[taskID].slabUsed;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
260
kernel/base/mem/common/memrecord/los_binarytree.c
Executable file
260
kernel/base/mem/common/memrecord/los_binarytree.c
Executable file
@@ -0,0 +1,260 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#ifdef LOSCFG_MEM_RECORDINFO
|
||||
#include "los_binarytree_pri.h"
|
||||
#include "los_typedef.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
UINT32 OsBinTreeInsert(const VOID *node, UINT32 nodeLen, BinNode **leaf,
|
||||
BinNode *(*GetMyBinNode)(UINT32 *nodeID),
|
||||
INT32 (*CompareNode)(const VOID *node1, const VOID *node2))
|
||||
{
|
||||
UINT32 nodeID;
|
||||
INT32 result;
|
||||
BinNode **currentNode = leaf;
|
||||
|
||||
if (leaf == NULL) {
|
||||
return OS_INVALID;
|
||||
}
|
||||
|
||||
do {
|
||||
if (*currentNode != NULL) {
|
||||
result = CompareNode(node, (const VOID *)(*currentNode));
|
||||
if (result == 0) {
|
||||
return (*currentNode)->nodeID;
|
||||
} else if (result < 0) {
|
||||
currentNode = (BinNode **)(&((*currentNode)->left));
|
||||
} else {
|
||||
currentNode = (BinNode **)(&((*currentNode)->right));
|
||||
}
|
||||
} else {
|
||||
(*currentNode) = GetMyBinNode(&nodeID);
|
||||
if (*currentNode == NULL) {
|
||||
return OS_INVALID;
|
||||
}
|
||||
|
||||
(VOID)memcpy_s((*currentNode)->keyValue, (nodeLen - sizeof(BinNode)),
|
||||
((BinNode *)node)->keyValue, (nodeLen - sizeof(BinNode)));
|
||||
(*currentNode)->nodeID = nodeID;
|
||||
/* initialize the children to NULL */
|
||||
(*currentNode)->left = NULL;
|
||||
(*currentNode)->right = NULL;
|
||||
|
||||
return (*currentNode)->nodeID;
|
||||
}
|
||||
} while (1);
|
||||
}
|
||||
|
||||
/* LRNODE */
|
||||
LinkRegNode g_linkRegNode[LR_COUNT];
|
||||
UINT32 g_linkRegNodeIndex = 0;
|
||||
LinkRegNode *g_linkRegRoot = NULL;
|
||||
INT32 OsCompareLRNode(const VOID *node1, const VOID *node2)
|
||||
{
|
||||
LinkRegNode *linkRegNode1 = (LinkRegNode *)node1;
|
||||
LinkRegNode *linkRegNode2 = (LinkRegNode *)node2;
|
||||
if (linkRegNode1->linkReg1 < linkRegNode2->linkReg1) {
|
||||
return -1;
|
||||
} else if ((linkRegNode1->linkReg1 == linkRegNode2->linkReg1) &&
|
||||
(linkRegNode1->linkReg2 < linkRegNode2->linkReg2)) {
|
||||
return -1;
|
||||
} else if ((linkRegNode1->linkReg1 == linkRegNode2->linkReg1) &&
|
||||
(linkRegNode1->linkReg2 == linkRegNode2->linkReg2) &&
|
||||
(linkRegNode1->linkReg3 < linkRegNode2->linkReg3)) {
|
||||
return -1;
|
||||
} else if ((linkRegNode1->linkReg1 == linkRegNode2->linkReg1) &&
|
||||
(linkRegNode1->linkReg2 == linkRegNode2->linkReg2) &&
|
||||
(linkRegNode1->linkReg3 == linkRegNode2->linkReg3)) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
BinNode *OsGetLRBinNode(UINT32 *nodeID)
|
||||
{
|
||||
if (g_linkRegNodeIndex < LR_COUNT) {
|
||||
*nodeID = g_linkRegNodeIndex;
|
||||
return (BinNode *)(&g_linkRegNode[g_linkRegNodeIndex++]);
|
||||
} else {
|
||||
*nodeID = (UINT32)-1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* ADDRNODE */
|
||||
AddrNode g_addrNode[ADDR_COUNT];
|
||||
UINT32 g_addrNodeIndex = 0;
|
||||
AddrNode *g_addrRoot = NULL;
|
||||
INT32 OsCompareAddrNode(const VOID *node1, const VOID *node2)
|
||||
{
|
||||
AddrNode *addrNode1 = (AddrNode *)node1;
|
||||
AddrNode *addrNode2 = (AddrNode *)node2;
|
||||
if (addrNode1->addr < addrNode2->addr) {
|
||||
return -1;
|
||||
} else if (addrNode1->addr == addrNode2->addr) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
BinNode *OsGetAddrBinNode(UINT32 *nodeID)
|
||||
{
|
||||
if (g_addrNodeIndex < ADDR_COUNT) {
|
||||
*nodeID = g_addrNodeIndex;
|
||||
return (BinNode *)(&g_addrNode[g_addrNodeIndex++]);
|
||||
} else {
|
||||
*nodeID = (UINT32)-1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* REQSIZENODE */
|
||||
ReqSizeNode g_reqSizeNode[REQ_SIZE_COUNT];
|
||||
UINT32 g_reqSizeNodeIndex = 0;
|
||||
ReqSizeNode *g_reqSizeRoot = NULL;
|
||||
|
||||
INT32 OsCompareReqSizeNode(const VOID *node1, const VOID *node2)
|
||||
{
|
||||
ReqSizeNode *reqSizeNode1 = (ReqSizeNode *)node1;
|
||||
ReqSizeNode *reqSizeNode2 = (ReqSizeNode *)node2;
|
||||
if (reqSizeNode1->reqSize < reqSizeNode2->reqSize) {
|
||||
return -1;
|
||||
} else if (reqSizeNode1->reqSize == reqSizeNode2->reqSize) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
BinNode *OsGetReqSizeBinNode(UINT32 *nodeID)
|
||||
{
|
||||
if (g_reqSizeNodeIndex < REQ_SIZE_COUNT) {
|
||||
*nodeID = g_reqSizeNodeIndex;
|
||||
return (BinNode *)(&g_reqSizeNode[g_reqSizeNodeIndex++]);
|
||||
} else {
|
||||
*nodeID = (UINT32)-1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
/* TASKIDNODE */
|
||||
STATIC TaskIDNode g_taskIDNode[TASK_ID_COUNT];
|
||||
STATIC UINT32 g_taskIDNodeIndex = 0;
|
||||
STATIC TaskIDNode *g_taskIDRoot = NULL;
|
||||
INT32 OsCompareTaskIDNode(const VOID *node1, const VOID *node2)
|
||||
{
|
||||
TaskIDNode *taskIDNode1 = (TaskIDNode *)node1;
|
||||
TaskIDNode *taskIDNode2 = (TaskIDNode *)node2;
|
||||
if (taskIDNode1->taskID < taskIDNode2->taskID) {
|
||||
return -1;
|
||||
} else if (taskIDNode1->taskID == taskIDNode2->taskID) {
|
||||
return 0;
|
||||
} else {
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
|
||||
BinNode *OsGetTaskIDBinNode(UINT32 *nodeID)
|
||||
{
|
||||
if (g_taskIDNodeIndex < TASK_ID_COUNT) {
|
||||
*nodeID = g_taskIDNodeIndex;
|
||||
return (BinNode *)(&g_taskIDNode[g_taskIDNodeIndex++]);
|
||||
} else {
|
||||
*nodeID = (UINT32)-1;
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
#define BINARYTREE_TASKID_COUNT 11
|
||||
#define BINARYTREE_REQSIZE_COUNT 4
|
||||
STATIC const UINT32 g_binaryTreeTaskID[BINARYTREE_TASKID_COUNT] = { 33, 10, 20, 9, 42, 34, 45, 47, 46, 50, 49 };
|
||||
STATIC const UINT32 g_binaryTreeReqSize[BINARYTREE_REQSIZE_COUNT] = { 616, 136, 1708, 1580 };
|
||||
|
||||
VOID OsBinaryTreeInit(VOID)
|
||||
{
|
||||
INT32 index;
|
||||
LinkRegNode linkRegNode;
|
||||
AddrNode node;
|
||||
TaskIDNode taskNode;
|
||||
ReqSizeNode reqNode;
|
||||
UINT32 ret;
|
||||
|
||||
/* equal to the middle address of __text_start and __text_end */
|
||||
linkRegNode.linkReg1 = (UINTPTR)(((&__text_end - &__text_start) / 2) + &__text_start);
|
||||
linkRegNode.linkReg2 = linkRegNode.linkReg1;
|
||||
linkRegNode.linkReg3 = linkRegNode.linkReg1;
|
||||
ret = OsBinTreeInsert(&linkRegNode, sizeof(LinkRegNode), (BinNode **)&g_linkRegRoot,
|
||||
OsGetLRBinNode, OsCompareLRNode);
|
||||
if (ret == OS_INVALID) {
|
||||
PRINT_ERR("binary tree init failed\n");
|
||||
}
|
||||
|
||||
/* equal to the middle address of __bss_end and OS_SYS_FUNC_ADDR_END */
|
||||
node.addr = ((OS_SYS_FUNC_ADDR_END - (UINTPTR)(&__bss_end)) >> 1) + (UINTPTR)(&__bss_end);
|
||||
ret = OsBinTreeInsert(&node, sizeof(AddrNode), (BinNode **)&g_addrRoot,
|
||||
OsGetAddrBinNode, OsCompareAddrNode);
|
||||
if (ret == OS_INVALID) {
|
||||
PRINT_ERR("binary tree init failed\n");
|
||||
}
|
||||
|
||||
for (index = 0; index < BINARYTREE_TASKID_COUNT; index++) {
|
||||
taskNode.taskID = g_binaryTreeTaskID[index];
|
||||
ret = OsBinTreeInsert(&taskNode, sizeof(TaskIDNode), (BinNode **)&g_taskIDRoot,
|
||||
OsGetTaskIDBinNode, OsCompareTaskIDNode);
|
||||
if (ret == OS_INVALID) {
|
||||
PRINT_ERR("binary tree init failed\n");
|
||||
}
|
||||
}
|
||||
|
||||
for (index = 0; index < BINARYTREE_REQSIZE_COUNT; index++) {
|
||||
reqNode.reqSize = g_binaryTreeReqSize[index];
|
||||
ret = OsBinTreeInsert(&reqNode, sizeof(ReqSizeNode), (BinNode **)&g_reqSizeRoot,
|
||||
OsGetReqSizeBinNode, OsCompareReqSizeNode);
|
||||
if (ret == OS_INVALID) {
|
||||
PRINT_ERR("binary tree init failed\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#endif
|
||||
87
kernel/base/mem/common/memrecord/los_interto64radix.c
Executable file
87
kernel/base/mem/common/memrecord/los_interto64radix.c
Executable file
@@ -0,0 +1,87 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_printf.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
/* array used for 64 binary conversion, include 64 characters */
|
||||
const CHAR g_base64Array[] = {
|
||||
'0', '1', '2', '3', '4', '5', '6', '7', '8', '9',
|
||||
'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
|
||||
'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
|
||||
'u', 'v', 'w', 'x', 'y', 'z', 'A', 'B', 'C', 'D',
|
||||
'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N',
|
||||
'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X',
|
||||
'Y', 'Z', '~', '!'
|
||||
};
|
||||
|
||||
#define LOGARITHM 6 /* the logarithm of 64 to base 2 */
|
||||
#define BASE64_MARK ((1U << LOGARITHM) - 1)
|
||||
|
||||
VOID OsDecTo64F(UINT32 num, CHAR *base64, INT32 base64Len)
|
||||
{
|
||||
INT32 len = base64Len - 1;
|
||||
UINT32 tempNum = num;
|
||||
if (base64 == NULL) {
|
||||
PRINT_ERR("%s:%d input null buf\n", __FUNCTION__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
if (base64Len <= 0) {
|
||||
PRINT_ERR("%s:%d input illegal Len\n", __FUNCTION__, __LINE__);
|
||||
return;
|
||||
}
|
||||
|
||||
while (num) {
|
||||
if (len < 0) {
|
||||
PRINT_ERR("Len[%d] is too short, input num: %u\n", base64Len, tempNum);
|
||||
break;
|
||||
}
|
||||
base64[len--] = g_base64Array[num & BASE64_MARK];
|
||||
num >>= LOGARITHM;
|
||||
}
|
||||
for (; len >= 0; len--) {
|
||||
base64[len] = '0';
|
||||
}
|
||||
base64[base64Len] = '\0';
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
356
kernel/base/mem/common/memrecord/los_memrecord.c
Executable file
356
kernel/base/mem/common/memrecord/los_memrecord.c
Executable file
@@ -0,0 +1,356 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_memrecord_pri.h"
|
||||
#include "stdio.h"
|
||||
#include "los_binarytree_pri.h"
|
||||
#include "los_event.h"
|
||||
#include "los_exc.h"
|
||||
#include "los_task_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
enum MemActType {
|
||||
OS_MEM_VALIDFREE,
|
||||
OS_MEM_INVALIDFREE,
|
||||
OS_MEM_ALLOC
|
||||
};
|
||||
|
||||
STATIC MemRecordInfo g_memRecord1[RECORD_LEN] = {0};
|
||||
STATIC MemRecordInfo g_memRecord2[RECORD_LEN] = {0};
|
||||
STATIC MemRecordInfo *g_saveMemRecord = g_memRecord1;
|
||||
STATIC MemRecordInfo *g_printMemRecord = NULL;
|
||||
STATIC MemRecordInfo *g_curPtr = NULL;
|
||||
|
||||
STATIC volatile UINT32 g_memRecordIndex = 0;
|
||||
STATIC volatile UINT32 g_memLastEndIndex = 0;
|
||||
STATIC EVENT_CB_S g_memShowEvent;
|
||||
|
||||
UINT32 g_memRecordShowEnable = 1;
|
||||
STATIC UINT32 g_lastAddrNodeIndex = 0;
|
||||
STATIC UINT32 g_lastReqSizeNodeIndex = 0;
|
||||
STATIC UINT32 g_lastlinkRegNodeIndex = 0;
|
||||
|
||||
#define INDEX_LENGTH 2
|
||||
#define ADDR_ID_LENGTH 3
|
||||
#define REQSIZE_ID_LENGTH 2
|
||||
#define ACTTYPE_LENGTH 4
|
||||
#define TASK_ID_LENGTH 2
|
||||
#define SYS_TICK_LENGTH 6
|
||||
#define LINK_REG_ID_LENGTH 2
|
||||
#define INFO_STR_LENGTH 20
|
||||
#define PRINT_STR_LENGTH 32
|
||||
#define NODE_VALUE_LENGTH 7
|
||||
#define READ_EVENT_MASK 0xFFF
|
||||
#define WRITE_EVENT 0x112
|
||||
|
||||
STATIC VOID OsMemRecordCompressInfo(VOID)
|
||||
{
|
||||
UINT32 count;
|
||||
CHAR infoStr[INFO_STR_LENGTH];
|
||||
|
||||
UINT32 currentIndex = g_addrNodeIndex;
|
||||
for (count = g_lastAddrNodeIndex; count < currentIndex; count++) {
|
||||
OsDecTo64F(g_addrNode[count].leaf.nodeID, infoStr, ADDR_ID_LENGTH);
|
||||
printf("~^%s%x^~\n", infoStr, g_addrNode[count].addr);
|
||||
}
|
||||
g_lastAddrNodeIndex = currentIndex;
|
||||
|
||||
currentIndex = g_reqSizeNodeIndex;
|
||||
for (count = g_lastReqSizeNodeIndex; count < currentIndex; count++) {
|
||||
OsDecTo64F(g_reqSizeNode[count].leaf.nodeID, infoStr, REQSIZE_ID_LENGTH);
|
||||
printf("*^%s%u^*\n", infoStr, g_reqSizeNode[count].reqSize);
|
||||
}
|
||||
g_lastReqSizeNodeIndex = currentIndex;
|
||||
|
||||
currentIndex = g_linkRegNodeIndex;
|
||||
for (count = g_lastlinkRegNodeIndex; count < currentIndex; count++) {
|
||||
OsDecTo64F(g_linkRegNode[count].leaf.nodeID, infoStr, LINK_REG_ID_LENGTH);
|
||||
printf("$^%s%x%x%x^$\n", infoStr, g_linkRegNode[count].linkReg1, g_linkRegNode[count].linkReg2,
|
||||
g_linkRegNode[count].linkReg3);
|
||||
}
|
||||
g_lastlinkRegNodeIndex = currentIndex;
|
||||
}
|
||||
|
||||
STATIC VOID PrintPtrAssign(CHAR *printStr, UINT32 strLen, UINT32 startIndex, UINT32 index)
|
||||
{
|
||||
CHAR nodeValue[NODE_VALUE_LENGTH];
|
||||
UINT32 tmpIndex = 0;
|
||||
|
||||
/* 3 bytes for ending "!~" and '\0'. */
|
||||
if (strLen < (INDEX_LENGTH + ADDR_ID_LENGTH + REQSIZE_ID_LENGTH + ACTTYPE_LENGTH +
|
||||
TASK_ID_LENGTH + SYS_TICK_LENGTH + LINK_REG_ID_LENGTH + index + 3)) {
|
||||
PRINT_ERR("printStr is not big enough\n");
|
||||
return;
|
||||
}
|
||||
|
||||
OsDecTo64F(startIndex, nodeValue, INDEX_LENGTH);
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex];
|
||||
|
||||
tmpIndex = 0;
|
||||
OsDecTo64F(g_curPtr[startIndex].addrID, nodeValue, ADDR_ID_LENGTH);
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex];
|
||||
|
||||
tmpIndex = 0;
|
||||
OsDecTo64F(g_curPtr[startIndex].reqSizeID, nodeValue, REQSIZE_ID_LENGTH);
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex];
|
||||
|
||||
tmpIndex = 0;
|
||||
OsDecTo64F(g_curPtr[startIndex].actType, nodeValue, ACTTYPE_LENGTH);
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex];
|
||||
|
||||
tmpIndex = 0;
|
||||
OsDecTo64F(g_curPtr[startIndex].taskID, nodeValue, TASK_ID_LENGTH);
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex];
|
||||
|
||||
tmpIndex = 0;
|
||||
OsDecTo64F(g_curPtr[startIndex].sysTick, nodeValue, SYS_TICK_LENGTH);
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex];
|
||||
|
||||
tmpIndex = 0;
|
||||
OsDecTo64F(g_curPtr[startIndex].linkRegID, nodeValue, LINK_REG_ID_LENGTH);
|
||||
printStr[index++] = nodeValue[tmpIndex++];
|
||||
printStr[index++] = nodeValue[tmpIndex];
|
||||
|
||||
printStr[index++] = '!';
|
||||
printStr[index++] = '~';
|
||||
printStr[index++] = '\0';
|
||||
|
||||
printf("%s\n", printStr);
|
||||
}
|
||||
|
||||
STATIC VOID OsMemRecordShow(VOID)
|
||||
{
|
||||
UINT32 index = 0;
|
||||
UINT32 startIndex = g_memLastEndIndex;
|
||||
UINT32 endIndex;
|
||||
MemRecordInfo *printMemRecord = g_printMemRecord;
|
||||
CHAR printStr[PRINT_STR_LENGTH];
|
||||
|
||||
if (g_curPtr == NULL) {
|
||||
g_curPtr = g_printMemRecord;
|
||||
}
|
||||
|
||||
OsMemRecordCompressInfo();
|
||||
|
||||
if (g_curPtr != NULL) {
|
||||
printStr[index++] = '~';
|
||||
printStr[index++] = '!';
|
||||
if (g_curPtr == printMemRecord) {
|
||||
while (startIndex < RECORD_LEN) {
|
||||
PrintPtrAssign(printStr, PRINT_STR_LENGTH, startIndex, index);
|
||||
startIndex++;
|
||||
}
|
||||
g_memLastEndIndex = 0;
|
||||
}
|
||||
}
|
||||
|
||||
startIndex = g_memLastEndIndex;
|
||||
endIndex = g_memRecordIndex;
|
||||
if ((g_curPtr == g_saveMemRecord) && (g_printMemRecord != NULL) && (startIndex >= endIndex)) {
|
||||
printf("Rec:error:the printf speed is low,Rnd\n");
|
||||
startIndex = 0;
|
||||
}
|
||||
|
||||
g_curPtr = g_saveMemRecord;
|
||||
index = 0;
|
||||
printStr[index++] = '~';
|
||||
printStr[index++] = '!';
|
||||
while (startIndex < endIndex) {
|
||||
PrintPtrAssign(printStr, PRINT_STR_LENGTH, startIndex, index);
|
||||
startIndex++;
|
||||
}
|
||||
|
||||
g_memLastEndIndex = endIndex;
|
||||
}
|
||||
|
||||
STATIC VOID OsMemRecordExchange(VOID)
|
||||
{
|
||||
if (g_saveMemRecord == g_memRecord1) {
|
||||
g_saveMemRecord = g_memRecord2;
|
||||
g_printMemRecord = g_memRecord1;
|
||||
} else {
|
||||
g_saveMemRecord = g_memRecord1;
|
||||
g_printMemRecord = g_memRecord2;
|
||||
}
|
||||
g_memRecordIndex = 0;
|
||||
(VOID)LOS_EventWrite(&g_memShowEvent, WRITE_EVENT);
|
||||
}
|
||||
|
||||
#define LINK_REG1_INDEX 1
|
||||
#define LINK_REG2_INDEX 2
|
||||
#define LINK_REG3_INDEX 3
|
||||
#define LINK_REG_NUM 3
|
||||
|
||||
STATIC INLINE VOID OsMemRecordLR(LinkRegNode *linkRegNode)
|
||||
{
|
||||
UINTPTR framePtr, framePtrTmp;
|
||||
UINT32 index = 0;
|
||||
|
||||
linkRegNode->linkReg1 = 0;
|
||||
linkRegNode->linkReg2 = 0;
|
||||
linkRegNode->linkReg3 = 0;
|
||||
|
||||
framePtr = Get_Fp();
|
||||
while ((framePtr > OS_SYS_FUNC_ADDR_START) &&
|
||||
(framePtr < OS_SYS_FUNC_ADDR_END) &&
|
||||
((framePtr % sizeof(CHAR *)) == 0)) {
|
||||
framePtrTmp = framePtr;
|
||||
if (index == LINK_REG1_INDEX) {
|
||||
linkRegNode->linkReg1 = *((UINTPTR *)(framePtrTmp));
|
||||
} else if (index == LINK_REG2_INDEX) {
|
||||
linkRegNode->linkReg2 = *((UINTPTR *)(framePtrTmp));
|
||||
} else if (index == LINK_REG3_INDEX) {
|
||||
linkRegNode->linkReg3 = *((UINTPTR *)(framePtrTmp));
|
||||
}
|
||||
framePtr = *((UINTPTR *)(framePtrTmp - sizeof(UINTPTR *)));
|
||||
index++;
|
||||
if (index == (LINK_REG_NUM + 1)) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsMemRecordTaskID(VOID)
|
||||
{
|
||||
LosTaskCB *runTask = OsCurrTaskGet();
|
||||
if (runTask != NULL) {
|
||||
g_saveMemRecord[g_memRecordIndex].taskID = LOS_CurTaskIDGet();
|
||||
} else {
|
||||
g_saveMemRecord[g_memRecordIndex].taskID = 0;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsMemRecord(const VOID *ptr, UINT32 size)
|
||||
{
|
||||
UINT64 tickCount = LOS_TickCountGet();
|
||||
UINT32 nodeID;
|
||||
LinkRegNode linkRegNode;
|
||||
AddrNode node;
|
||||
ReqSizeNode reqNode;
|
||||
|
||||
OsMemRecordLR(&linkRegNode);
|
||||
nodeID = OsBinTreeInsert(&linkRegNode, sizeof(linkRegNode), (BinNode **)&g_linkRegRoot, OsGetLRBinNode,
|
||||
OsCompareLRNode);
|
||||
if (nodeID == OS_INVALID) {
|
||||
PRINT_WARN("LIST g_linkRegRoot insert linkRegNode failed!\n");
|
||||
}
|
||||
g_saveMemRecord[g_memRecordIndex].linkRegID = nodeID;
|
||||
|
||||
node.addr = (UINTPTR)ptr;
|
||||
nodeID = OsBinTreeInsert(&node, sizeof(AddrNode), (BinNode **)&g_addrRoot, OsGetAddrBinNode,
|
||||
OsCompareAddrNode);
|
||||
if (nodeID == OS_INVALID) {
|
||||
PRINT_WARN("LIST g_addrRoot insert addrNode failed!\n");
|
||||
}
|
||||
g_saveMemRecord[g_memRecordIndex].addrID = nodeID;
|
||||
g_saveMemRecord[g_memRecordIndex].sysTick = tickCount;
|
||||
|
||||
OsMemRecordTaskID();
|
||||
|
||||
reqNode.reqSize = size;
|
||||
nodeID = OsBinTreeInsert(&reqNode, sizeof(ReqSizeNode), (BinNode **)&g_reqSizeRoot, OsGetReqSizeBinNode,
|
||||
OsCompareReqSizeNode);
|
||||
if (nodeID == OS_INVALID) {
|
||||
PRINT_WARN("LIST g_reqSizeRoot insert reqSizeNode failed!\n");
|
||||
}
|
||||
g_saveMemRecord[g_memRecordIndex].reqSizeID = nodeID;
|
||||
|
||||
g_memRecordIndex++;
|
||||
if (g_memRecordIndex == RECORD_LEN) {
|
||||
OsMemRecordExchange();
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_MEM_RECORDINFO
|
||||
VOID OsMemRecordMalloc(const VOID *ptr, UINT32 size)
|
||||
{
|
||||
if (g_memRecordShowEnable == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsMemRecord(ptr, size);
|
||||
g_saveMemRecord[g_memRecordIndex].actType = OS_MEM_ALLOC;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_MEM_RECORDINFO
|
||||
VOID OsMemRecordFree(const VOID *ptr, UINT32 size)
|
||||
{
|
||||
UINT32 actType;
|
||||
if (g_memRecordShowEnable == 0) {
|
||||
return;
|
||||
}
|
||||
actType = (size == 0) ? OS_MEM_INVALIDFREE : OS_MEM_VALIDFREE;
|
||||
OsMemRecord(ptr, size);
|
||||
g_saveMemRecord[g_memRecordIndex].actType = actType;
|
||||
}
|
||||
#endif
|
||||
|
||||
VOID OsMemRecordShowTask(VOID)
|
||||
{
|
||||
(VOID)LOS_EventInit(&g_memShowEvent);
|
||||
while (1) {
|
||||
(VOID)LOS_EventRead(&g_memShowEvent, READ_EVENT_MASK,
|
||||
LOS_WAITMODE_OR | LOS_WAITMODE_CLR, MEM_RECORDSHOW_TIMEOUT);
|
||||
if (g_memRecordShowEnable) {
|
||||
OsMemRecordShow();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsMemRecordShowSet(UINT32 value)
|
||||
{
|
||||
g_memRecordShowEnable = value;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
237
kernel/base/mem/membox/los_membox.c
Executable file
237
kernel/base/mem/membox/los_membox.c
Executable file
@@ -0,0 +1,237 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_membox.h"
|
||||
#include "los_hwi.h"
|
||||
#include "los_spinlock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#ifdef LOSCFG_AARCH64
|
||||
#define OS_MEMBOX_MAGIC 0xa55a5aa5a55a5aa5
|
||||
#else
|
||||
#define OS_MEMBOX_MAGIC 0xa55a5aa5
|
||||
#endif
|
||||
#define OS_MEMBOX_SET_MAGIC(addr) \
|
||||
((LOS_MEMBOX_NODE *)(addr))->pstNext = (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC
|
||||
#define OS_MEMBOX_CHECK_MAGIC(addr) \
|
||||
((((LOS_MEMBOX_NODE *)(addr))->pstNext == (LOS_MEMBOX_NODE *)OS_MEMBOX_MAGIC) ? LOS_OK : LOS_NOK)
|
||||
|
||||
#define OS_MEMBOX_USER_ADDR(addr) \
|
||||
((VOID *)((UINT8 *)(addr) + OS_MEMBOX_NODE_HEAD_SIZE))
|
||||
#define OS_MEMBOX_NODE_ADDR(addr) \
|
||||
((LOS_MEMBOX_NODE *)(VOID *)((UINT8 *)(addr) - OS_MEMBOX_NODE_HEAD_SIZE))
|
||||
/* spinlock for mem module, only available on SMP mode */
|
||||
LITE_OS_SEC_BSS SPIN_LOCK_INIT(g_memboxSpin);
|
||||
#define MEMBOX_LOCK(state) LOS_SpinLockSave(&g_memboxSpin, &(state))
|
||||
#define MEMBOX_UNLOCK(state) LOS_SpinUnlockRestore(&g_memboxSpin, (state))
|
||||
|
||||
STATIC INLINE UINT32 OsCheckBoxMem(const LOS_MEMBOX_INFO *boxInfo, const VOID *node)
|
||||
{
|
||||
UINT32 offset;
|
||||
|
||||
if (boxInfo->uwBlkSize == 0) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
offset = (UINT32)((UINTPTR)node - (UINTPTR)(boxInfo + 1));
|
||||
if ((offset % boxInfo->uwBlkSize) != 0) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
if ((offset / boxInfo->uwBlkSize) >= boxInfo->uwBlkNum) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
return OS_MEMBOX_CHECK_MAGIC(node);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_MemboxInit(VOID *pool, UINT32 poolSize, UINT32 blkSize)
|
||||
{
|
||||
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
|
||||
LOS_MEMBOX_NODE *node = NULL;
|
||||
UINT32 index;
|
||||
UINT32 intSave;
|
||||
|
||||
if (pool == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
if (blkSize == 0) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
if (poolSize < sizeof(LOS_MEMBOX_INFO)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
MEMBOX_LOCK(intSave);
|
||||
boxInfo->uwBlkSize = LOS_MEMBOX_ALLIGNED(blkSize + OS_MEMBOX_NODE_HEAD_SIZE);
|
||||
if (boxInfo->uwBlkSize == 0) {
|
||||
MEMBOX_UNLOCK(intSave);
|
||||
return LOS_NOK;
|
||||
}
|
||||
boxInfo->uwBlkNum = (poolSize - sizeof(LOS_MEMBOX_INFO)) / boxInfo->uwBlkSize;
|
||||
boxInfo->uwBlkCnt = 0;
|
||||
if (boxInfo->uwBlkNum == 0) {
|
||||
MEMBOX_UNLOCK(intSave);
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);
|
||||
|
||||
boxInfo->stFreeList.pstNext = node;
|
||||
|
||||
for (index = 0; index < boxInfo->uwBlkNum - 1; ++index) {
|
||||
node->pstNext = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize);
|
||||
node = node->pstNext;
|
||||
}
|
||||
|
||||
node->pstNext = NULL;
|
||||
|
||||
MEMBOX_UNLOCK(intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT VOID *LOS_MemboxAlloc(VOID *pool)
|
||||
{
|
||||
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
|
||||
LOS_MEMBOX_NODE *node = NULL;
|
||||
LOS_MEMBOX_NODE *nodeTmp = NULL;
|
||||
UINT32 intSave;
|
||||
|
||||
if (pool == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
MEMBOX_LOCK(intSave);
|
||||
node = &(boxInfo->stFreeList);
|
||||
if (node->pstNext != NULL) {
|
||||
nodeTmp = node->pstNext;
|
||||
node->pstNext = nodeTmp->pstNext;
|
||||
OS_MEMBOX_SET_MAGIC(nodeTmp);
|
||||
boxInfo->uwBlkCnt++;
|
||||
}
|
||||
MEMBOX_UNLOCK(intSave);
|
||||
|
||||
return (nodeTmp == NULL) ? NULL : OS_MEMBOX_USER_ADDR(nodeTmp);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT UINT32 LOS_MemboxFree(VOID *pool, VOID *box)
|
||||
{
|
||||
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
|
||||
UINT32 ret = LOS_NOK;
|
||||
UINT32 intSave;
|
||||
|
||||
if ((pool == NULL) || (box == NULL)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
MEMBOX_LOCK(intSave);
|
||||
do {
|
||||
LOS_MEMBOX_NODE *node = OS_MEMBOX_NODE_ADDR(box);
|
||||
if (OsCheckBoxMem(boxInfo, node) != LOS_OK) {
|
||||
break;
|
||||
}
|
||||
|
||||
node->pstNext = boxInfo->stFreeList.pstNext;
|
||||
boxInfo->stFreeList.pstNext = node;
|
||||
boxInfo->uwBlkCnt--;
|
||||
ret = LOS_OK;
|
||||
} while (0);
|
||||
MEMBOX_UNLOCK(intSave);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID LOS_MemboxClr(VOID *pool, VOID *box)
|
||||
{
|
||||
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
|
||||
|
||||
if ((pool == NULL) || (box == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
(VOID)memset_s(box, (boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE), 0,
|
||||
(boxInfo->uwBlkSize - OS_MEMBOX_NODE_HEAD_SIZE));
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID LOS_ShowBox(VOID *pool)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 intSave;
|
||||
LOS_MEMBOX_INFO *boxInfo = (LOS_MEMBOX_INFO *)pool;
|
||||
LOS_MEMBOX_NODE *node = NULL;
|
||||
|
||||
if (pool == NULL) {
|
||||
return;
|
||||
}
|
||||
MEMBOX_LOCK(intSave);
|
||||
PRINT_INFO("membox(%p,0x%x,0x%x):\r\n", pool, boxInfo->uwBlkSize, boxInfo->uwBlkNum);
|
||||
PRINT_INFO("free node list:\r\n");
|
||||
|
||||
for (node = boxInfo->stFreeList.pstNext, index = 0; node != NULL;
|
||||
node = node->pstNext, ++index) {
|
||||
PRINT_INFO("(%u,%p)\r\n", index, node);
|
||||
}
|
||||
|
||||
PRINT_INFO("all node list:\r\n");
|
||||
node = (LOS_MEMBOX_NODE *)(boxInfo + 1);
|
||||
for (index = 0; index < boxInfo->uwBlkNum; ++index, node = OS_MEMBOX_NEXT(node, boxInfo->uwBlkSize)) {
|
||||
PRINT_INFO("(%u,%p,%p)\r\n", index, node, node->pstNext);
|
||||
}
|
||||
MEMBOX_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 LOS_MemboxStatisticsGet(const VOID *boxMem, UINT32 *maxBlk,
|
||||
UINT32 *blkCnt, UINT32 *blkSize)
|
||||
{
|
||||
if ((boxMem == NULL) || (maxBlk == NULL) || (blkCnt == NULL) || (blkSize == NULL)) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
*maxBlk = ((OS_MEMBOX_S *)boxMem)->uwBlkNum;
|
||||
*blkCnt = ((OS_MEMBOX_S *)boxMem)->uwBlkCnt;
|
||||
*blkSize = ((OS_MEMBOX_S *)boxMem)->uwBlkSize;
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
93
kernel/base/misc/kill_shellcmd.c
Executable file
93
kernel/base/misc/kill_shellcmd.c
Executable file
@@ -0,0 +1,93 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdio.h"
|
||||
#include "stdlib.h"
|
||||
#include "los_signal.h"
|
||||
#include "los_printf.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "log.h"
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#endif
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsPrintKillUsage(VOID)
|
||||
{
|
||||
PRINTK("\nkill: usage: kill [sigspec] [pid]\n");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdKill(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
#define ARG_NUM 2
|
||||
INT32 sigNo = 0;
|
||||
INT32 pidNo = 0;
|
||||
INT32 ret;
|
||||
CHAR *endPtr = NULL;
|
||||
|
||||
if (argc == ARG_NUM) {
|
||||
sigNo = strtoul(argv[0], &endPtr, 0);
|
||||
if (*endPtr != 0) {
|
||||
PRINTK("\nsigNo can't access %s.\n", argv[0]);
|
||||
goto ERROR;
|
||||
}
|
||||
endPtr = NULL;
|
||||
pidNo = strtoul(argv[1], &endPtr, 0);
|
||||
if (*endPtr != 0) {
|
||||
PRINTK("\npidNo can't access %s.\n", argv[1]);
|
||||
goto ERROR;
|
||||
}
|
||||
|
||||
ret = OsKill(pidNo, abs(sigNo), OS_USER_KILL_PERMISSION);
|
||||
HILOG_INFO(LOG_CORE, "Send signal(%d) to pidNo = %d!\n", abs(sigNo), pidNo);
|
||||
if (ret == -1) {
|
||||
HILOG_ERROR(LOG_CORE, "Kill fail ret = %d! Operation not permitted\n", ret);
|
||||
goto ERROR;
|
||||
}
|
||||
if (ret < 0) {
|
||||
PRINTK("\n Kill fail ret = %d! process not exist or sigNo is invalid\n", ret);
|
||||
goto ERROR;
|
||||
}
|
||||
} else {
|
||||
PRINTK("\nPara number errno!\n");
|
||||
goto ERROR;
|
||||
}
|
||||
return 0;
|
||||
ERROR:
|
||||
OsPrintKillUsage();
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL
|
||||
SHELLCMD_ENTRY(kill_shellcmd, CMD_TYPE_EX, "kill", 2, (CmdCallBackFunc)OsShellCmdKill);
|
||||
#endif
|
||||
|
||||
69
kernel/base/misc/los_misc.c
Executable file
69
kernel/base/misc/los_misc.c
Executable file
@@ -0,0 +1,69 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_task_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_TEXT UINTPTR LOS_Align(UINTPTR addr, UINT32 boundary)
|
||||
{
|
||||
if ((addr + boundary - 1) > addr) {
|
||||
return (addr + boundary - 1) & ~((UINTPTR)(boundary - 1));
|
||||
} else {
|
||||
return addr & ~((UINTPTR)(boundary - 1));
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID LOS_Msleep(UINT32 msecs)
|
||||
{
|
||||
UINT32 interval;
|
||||
|
||||
if (msecs == 0) {
|
||||
interval = 0;
|
||||
} else {
|
||||
interval = LOS_MS2Tick(msecs);
|
||||
if (interval == 0) {
|
||||
interval = 1;
|
||||
}
|
||||
}
|
||||
|
||||
(VOID)LOS_TaskDelay(interval);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
125
kernel/base/misc/los_stackinfo.c
Executable file
125
kernel/base/misc/los_stackinfo.c
Executable file
@@ -0,0 +1,125 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_stackinfo_pri.h"
|
||||
#include "los_printf_pri.h"
|
||||
#include "los_config.h"
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#endif
|
||||
|
||||
const StackInfo *g_stackInfo = NULL;
|
||||
UINT32 g_stackNum;
|
||||
|
||||
UINT32 OsStackWaterLineGet(const UINTPTR *stackBottom, const UINTPTR *stackTop, UINT32 *peakUsed)
|
||||
{
|
||||
UINT32 size;
|
||||
const UINTPTR *tmp = NULL;
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsExcStackCheck(VOID)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 cpuid;
|
||||
UINTPTR *stackTop = NULL;
|
||||
|
||||
if (g_stackInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
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);
|
||||
if (*stackTop != OS_STACK_MAGIC_WORD) {
|
||||
PRINT_ERR("cpu:%u %s overflow , magic word changed to 0x%x\n",
|
||||
LOSCFG_KERNEL_CORE_NUM - 1 - cpuid, g_stackInfo[index].stackName, *stackTop);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsExcStackInfo(VOID)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 cpuid;
|
||||
UINT32 size;
|
||||
UINTPTR *stackTop = NULL;
|
||||
UINTPTR *stack = NULL;
|
||||
|
||||
if (g_stackInfo == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
PrintExcInfo("\n stack name cpu id stack addr total size used size\n"
|
||||
" ---------- ------ --------- -------- --------\n");
|
||||
|
||||
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);
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
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 */
|
||||
(VOID)memset_s(stacktop, stacksize, (INT32)OS_STACK_INIT, stacksize);
|
||||
*((UINTPTR *)stacktop) = OS_STACK_MAGIC_WORD;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
SHELLCMD_ENTRY(stack_shellcmd, CMD_TYPE_EX, "stack", 1, (CmdCallBackFunc)OsExcStackInfo);
|
||||
#endif
|
||||
342
kernel/base/misc/mempt_shellcmd.c
Executable file
342
kernel/base/misc/mempt_shellcmd.c
Executable file
@@ -0,0 +1,342 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "los_memory_pri.h"
|
||||
#ifdef LOSCFG_MEM_RECORDINFO
|
||||
#include "los_memrecord_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_SHELL_EXCINFO
|
||||
#include "los_excinfo_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#endif
|
||||
#include "los_vm_common.h"
|
||||
#include "los_vm_boot.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_vm_dump.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define MEM_SIZE_1K 0x400
|
||||
#define MEM_SIZE_1M 0x100000
|
||||
#define MEMPT_ARG_NUM_2 2
|
||||
|
||||
#define MEM_SIZE_TO_KB(size) (((size) + (MEM_SIZE_1K >> 1)) / MEM_SIZE_1K)
|
||||
#define MEM_SIZE_TO_MB(size) (((size) + (MEM_SIZE_1M >> 1)) / MEM_SIZE_1M)
|
||||
|
||||
VOID OsDumpMemByte(size_t length, UINTPTR addr)
|
||||
{
|
||||
size_t dataLen;
|
||||
UINTPTR *alignAddr = NULL;
|
||||
UINT32 count = 0;
|
||||
|
||||
dataLen = ALIGN(length, sizeof(UINTPTR));
|
||||
alignAddr = (UINTPTR *)TRUNCATE(addr, sizeof(UINTPTR));
|
||||
if ((dataLen == 0) || (alignAddr == NULL)) {
|
||||
return;
|
||||
}
|
||||
while (dataLen) {
|
||||
if (IS_ALIGNED(count, sizeof(CHAR *))) {
|
||||
PRINTK("\n 0x%lx :", alignAddr);
|
||||
#ifdef LOSCFG_SHELL_EXCINFO
|
||||
WriteExcInfoToBuf("\n 0x%lx :", alignAddr);
|
||||
#endif
|
||||
}
|
||||
#ifdef __LP64__
|
||||
PRINTK("%0+16lx ", *alignAddr);
|
||||
#else
|
||||
PRINTK("%0+8lx ", *alignAddr);
|
||||
#endif
|
||||
#ifdef LOSCFG_SHELL_EXCINFO
|
||||
#ifdef __LP64__
|
||||
WriteExcInfoToBuf("0x%0+16x ", *alignAddr);
|
||||
#else
|
||||
WriteExcInfoToBuf("0x%0+8x ", *alignAddr);
|
||||
#endif
|
||||
#endif
|
||||
alignAddr++;
|
||||
dataLen -= sizeof(CHAR *);
|
||||
count++;
|
||||
}
|
||||
PRINTK("\n");
|
||||
#ifdef LOSCFG_SHELL_EXCINFO
|
||||
WriteExcInfoToBuf("\n");
|
||||
#endif
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemCheck(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
if (argc > 0) {
|
||||
PRINTK("\nUsage: memcheck\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (LOS_MemIntegrityCheck(m_aucSysMem1) == LOS_OK) {
|
||||
PRINTK("system memcheck over, all passed!\n");
|
||||
#ifdef LOSCFG_SHELL_EXCINFO
|
||||
WriteExcInfoToBuf("system memcheck over, all passed!\n");
|
||||
#endif
|
||||
}
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
if (LOS_MemIntegrityCheck(m_aucSysMem0) == LOS_OK) {
|
||||
PRINTK("exc interaction memcheck over, all passed!\n");
|
||||
#ifdef LOSCFG_SHELL_EXCINFO
|
||||
WriteExcInfoToBuf("exc interaction memcheck over, all passed!\n");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemRead(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
size_t tempAddr;
|
||||
size_t length;
|
||||
CHAR *ptrlen = NULL;
|
||||
CHAR *ptrAddr = NULL;
|
||||
|
||||
if ((argc == 0) || (argc > 2)) { /* argc is num of parameters */
|
||||
PRINTK("\nUsage: readreg [ADDRESS] [LENGTH]\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
length = 0;
|
||||
} else {
|
||||
length = strtoul(argv[1], &ptrlen, 0);
|
||||
if ((ptrlen == NULL) || (*ptrlen != 0)) {
|
||||
PRINTK("readreg invalid length %s\n", argv[1]);
|
||||
return OS_ERROR;
|
||||
}
|
||||
}
|
||||
tempAddr = strtoul(argv[0], &ptrAddr, 0);
|
||||
if ((ptrAddr == NULL) || (*ptrAddr != 0)) {
|
||||
PRINTK("readreg invalid address %s\n", argv[0]);
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (OsVmAddrCheck(tempAddr, length) == LOS_OK) {
|
||||
goto DONE;
|
||||
}
|
||||
|
||||
PRINTK("readreg invalid address %s\n", argv[0]);
|
||||
return OS_ERROR;
|
||||
|
||||
DONE:
|
||||
OsDumpMemByte(length, tempAddr);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC VOID OsShellCmdSectionInfo(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
size_t textLen = &__text_end - &__text_start;
|
||||
size_t dataLen = &__ram_data_end - &__ram_data_start;
|
||||
size_t rodataLen = &__rodata_end - &__rodata_start;
|
||||
size_t bssLen = &__bss_end - &__bss_start;
|
||||
|
||||
PRINTK("\r\n text data rodata bss\n");
|
||||
if ((argc == 1) && (strcmp(argv[0], "-k") == 0)) {
|
||||
PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", MEM_SIZE_TO_KB(textLen), MEM_SIZE_TO_KB(dataLen),
|
||||
MEM_SIZE_TO_KB(rodataLen), MEM_SIZE_TO_KB(bssLen));
|
||||
} else if ((argc == 1) && (strcmp(argv[0], "-m") == 0)) {
|
||||
PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", MEM_SIZE_TO_MB(textLen), MEM_SIZE_TO_MB(dataLen),
|
||||
MEM_SIZE_TO_MB(rodataLen), MEM_SIZE_TO_MB(bssLen));
|
||||
} else {
|
||||
PRINTK("Mem: %-9lu %-10lu %-10lu %-10lu\n", textLen, dataLen, rodataLen, bssLen);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OsShellCmdFreeInfo(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
UINT32 memUsed0 = LOS_MemTotalUsedGet(m_aucSysMem0);
|
||||
UINT32 totalMem0 = LOS_MemPoolSizeGet(m_aucSysMem0);
|
||||
UINT32 freeMem0 = totalMem0 - memUsed0;
|
||||
#endif
|
||||
UINT32 memUsed = LOS_MemTotalUsedGet(m_aucSysMem1);
|
||||
UINT32 totalMem = LOS_MemPoolSizeGet(m_aucSysMem1);
|
||||
UINT32 freeMem = totalMem - memUsed;
|
||||
UINT32 usedCount, totalCount;
|
||||
UINT32 memUsedHeap = memUsed;
|
||||
|
||||
OsVmPhysUsedInfoGet(&usedCount, &totalCount);
|
||||
totalMem = SYS_MEM_SIZE_DEFAULT;
|
||||
memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT);
|
||||
memUsed += (usedCount << PAGE_SHIFT) - freeMem;
|
||||
freeMem = totalMem - memUsed;
|
||||
|
||||
if ((argc == 0) ||
|
||||
((argc == 1) && (strcmp(argv[0], "-k") == 0)) ||
|
||||
((argc == 1) && (strcmp(argv[0], "-m") == 0))) {
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
PRINTK("\r\n***** Mem:system mem Mem1:exception interaction mem *****\n");
|
||||
#endif
|
||||
PRINTK("\r\n total used free heap\n");
|
||||
}
|
||||
|
||||
if ((argc == 1) && (strcmp(argv[0], "-k") == 0)) {
|
||||
PRINTK("Mem: %-9u %-10u %-10u %-10u\n", MEM_SIZE_TO_KB(totalMem), MEM_SIZE_TO_KB(memUsed),
|
||||
MEM_SIZE_TO_KB(freeMem), MEM_SIZE_TO_KB(memUsedHeap));
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
PRINTK("Mem1: %-9u %-10u %-10u\n", MEM_SIZE_TO_KB(totalMem), MEM_SIZE_TO_KB(memUsed),
|
||||
MEM_SIZE_TO_KB(freeMem));
|
||||
#endif
|
||||
} else if ((argc == 1) && (strcmp(argv[0], "-m") == 0)) {
|
||||
PRINTK("Mem: %-9u %-10u %-10u %-10u\n", MEM_SIZE_TO_MB(totalMem), MEM_SIZE_TO_MB(memUsed),
|
||||
MEM_SIZE_TO_MB(freeMem), MEM_SIZE_TO_MB(memUsedHeap));
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
PRINTK("Mem1: %-9u %-10u %-10u\n", MEM_SIZE_TO_MB(totalMem), MEM_SIZE_TO_MB(memUsed),
|
||||
MEM_SIZE_TO_MB(freeMem));
|
||||
#endif
|
||||
} else if (argc == 0) {
|
||||
PRINTK("Mem: %-9u %-10u %-10u %-10u\n", totalMem, memUsed, freeMem, memUsedHeap);
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
PRINTK("Mem1: %-9u %-10u %-10u\n", totalMem0, memUsed0, freeMem0);
|
||||
#endif
|
||||
} else {
|
||||
PRINTK("\nUsage: free or free [-k/-m]\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdFree(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
if (argc > 1) {
|
||||
PRINTK("\nUsage: free or free [-k/-m]\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
if (OsShellCmdFreeInfo(argc, argv) != 0) {
|
||||
return OS_ERROR;
|
||||
}
|
||||
OsShellCmdSectionInfo(argc, argv);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdUname(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
if (argc == 0) {
|
||||
PRINTK("%s\n", KERNEL_NAME);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (argc == 1) {
|
||||
if (strcmp(argv[0], "-a") == 0) {
|
||||
PRINTK("%s %d.%d.%d.%d %s %s\n", KERNEL_NAME, KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE,\
|
||||
__DATE__, __TIME__);
|
||||
return 0;
|
||||
} else if (strcmp(argv[0], "-s") == 0) {
|
||||
PRINTK("%s\n", KERNEL_NAME);
|
||||
return 0;
|
||||
} else if (strcmp(argv[0], "-t") == 0) {
|
||||
PRINTK("build date : %s %s\n", __DATE__, __TIME__);
|
||||
return 0;
|
||||
} else if (strcmp(argv[0], "-v") == 0) {
|
||||
PRINTK("%d.%d.%d.%d\n", KERNEL_MAJOR, KERNEL_MINOR, KERNEL_PATCH, KERNEL_ITRE);
|
||||
return 0;
|
||||
} else if (strcmp(argv[0], "--help") == 0) {
|
||||
PRINTK("-a, print all information\n"
|
||||
"-s, print the kernel name\n"
|
||||
"-t, print the build date\n"
|
||||
"-v, print the kernel version\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
PRINTK("uname: invalid option %s\n"
|
||||
"Try 'uname --help' for more information.\n",
|
||||
argv[0]);
|
||||
return OS_ERROR;
|
||||
}
|
||||
#ifdef LOSCFG_MEM_LEAKCHECK
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemUsed(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
if (argc > 0) {
|
||||
PRINTK("\nUsage: memused\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
OsMemUsedNodeShow(m_aucSysMem1);
|
||||
|
||||
#ifdef LOSCFG_EXC_INTERACTION
|
||||
PRINTK("\n exc interaction memory\n");
|
||||
OsMemUsedNodeShow(m_aucSysMem0);
|
||||
#endif
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
#ifdef LOSCFG_MEM_RECORDINFO
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemRecordEnable(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
OsMemRecordShowSet(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMemRecordDisable(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
OsMemRecordShowSet(0);
|
||||
return 0;
|
||||
}
|
||||
|
||||
SHELLCMD_ENTRY(memshowenable_shellcmd, CMD_TYPE_EX, "memshowenable", 0,
|
||||
(CmdCallBackFunc)OsShellCmdMemRecordEnable);
|
||||
SHELLCMD_ENTRY(memshowdisable_shellcmd, CMD_TYPE_EX, "memshowdisable", 0,
|
||||
(CmdCallBackFunc)OsShellCmdMemRecordDisable);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_MEM_LEAKCHECK
|
||||
SHELLCMD_ENTRY(memused_shellcmd, CMD_TYPE_EX, "memused", 0, (CmdCallBackFunc)OsShellCmdMemUsed);
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
SHELLCMD_ENTRY(memcheck_shellcmd, CMD_TYPE_EX, "memcheck", 0, (CmdCallBackFunc)OsShellCmdMemCheck);
|
||||
SHELLCMD_ENTRY(readreg_shellcmd, CMD_TYPE_EX, "readreg", MEMPT_ARG_NUM_2, (CmdCallBackFunc)OsShellCmdMemRead);
|
||||
#endif
|
||||
SHELLCMD_ENTRY(free_shellcmd, CMD_TYPE_EX, "free", XARGS, (CmdCallBackFunc)OsShellCmdFree);
|
||||
SHELLCMD_ENTRY(uname_shellcmd, CMD_TYPE_EX, "uname", XARGS, (CmdCallBackFunc)OsShellCmdUname);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
147
kernel/base/misc/swtmr_shellcmd.c
Executable file
147
kernel/base/misc/swtmr_shellcmd.c
Executable file
@@ -0,0 +1,147 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_config.h"
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
#include "stdlib.h"
|
||||
#include "los_swtmr_pri.h"
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define SWTMR_STRLEN 12
|
||||
|
||||
LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrMode[][SWTMR_STRLEN] = {
|
||||
"Once",
|
||||
"Period",
|
||||
"NSD",
|
||||
"OPP",
|
||||
};
|
||||
|
||||
LITE_OS_SEC_DATA_MINOR STATIC CHAR g_shellSwtmrStatus[][SWTMR_STRLEN] = {
|
||||
"UnUsed",
|
||||
"Created",
|
||||
"Ticking",
|
||||
};
|
||||
|
||||
STATIC VOID OsPrintSwtmrMsg(const SWTMR_CTRL_S *swtmr)
|
||||
{
|
||||
PRINTK("0x%08x "
|
||||
"%-7s "
|
||||
"%-6s "
|
||||
"%-6u "
|
||||
"%-6u "
|
||||
"0x%08x "
|
||||
"%p\n",
|
||||
swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT,
|
||||
g_shellSwtmrStatus[swtmr->ucState],
|
||||
g_shellSwtmrMode[swtmr->ucMode],
|
||||
swtmr->uwInterval,
|
||||
swtmr->uwCount,
|
||||
swtmr->uwArg,
|
||||
swtmr->pfnHandler);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsPrintSwtmrMsgHead(VOID)
|
||||
{
|
||||
PRINTK("\r\nSwTmrID State Mode Interval Count Arg handlerAddr\n");
|
||||
PRINTK("---------- ------- ------- --------- ------- ---------- --------\n");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdSwtmrInfoGet(INT32 argc, const UINT8 **argv)
|
||||
{
|
||||
#define OS_ALL_SWTMR_MASK 0xffffffff
|
||||
SWTMR_CTRL_S *swtmr = g_swtmrCBArray;
|
||||
SWTMR_CTRL_S *swtmr1 = g_swtmrCBArray;
|
||||
UINT16 index;
|
||||
size_t timerID;
|
||||
UINT16 num = 0;
|
||||
CHAR *endPtr = NULL;
|
||||
|
||||
if (argc > 1) {
|
||||
PRINTK("\nUsage: swtmr [ID]\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (argc == 0) {
|
||||
timerID = OS_ALL_SWTMR_MASK;
|
||||
} else {
|
||||
timerID = strtoul((CHAR *)argv[0], &endPtr, 0);
|
||||
if ((endPtr == NULL) || (*endPtr != 0) || (timerID > LOSCFG_BASE_CORE_SWTMR_LIMIT)) {
|
||||
PRINTK("\nswtmr ID can't access %s.\n", argv[0]);
|
||||
return OS_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr1++) {
|
||||
if (swtmr1->ucState == 0) {
|
||||
num = num + 1;
|
||||
}
|
||||
}
|
||||
|
||||
if (num == LOSCFG_BASE_CORE_SWTMR_LIMIT) {
|
||||
PRINTK("\r\nThere is no swtmr was created!\n");
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
if (timerID == OS_ALL_SWTMR_MASK) {
|
||||
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
|
||||
if (swtmr->ucState != 0) {
|
||||
OsPrintSwtmrMsgHead();
|
||||
OsPrintSwtmrMsg(swtmr);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
for (index = 0; index < LOSCFG_BASE_CORE_SWTMR_LIMIT; index++, swtmr++) {
|
||||
if ((timerID == (size_t)(swtmr->usTimerID % LOSCFG_BASE_CORE_SWTMR_LIMIT)) && (swtmr->ucState != 0)) {
|
||||
OsPrintSwtmrMsgHead();
|
||||
OsPrintSwtmrMsg(swtmr);
|
||||
return LOS_OK;
|
||||
}
|
||||
}
|
||||
PRINTK("\r\nThe SwTimerID is not exist.\n");
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
SHELLCMD_ENTRY(swtmr_shellcmd, CMD_TYPE_EX, "swtmr", 1, (CmdCallBackFunc)OsShellCmdSwtmrInfoGet);
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
#endif /* LOSCFG_SHELL */
|
||||
170
kernel/base/misc/sysinfo_shellcmd.c
Executable file
170
kernel/base/misc/sysinfo_shellcmd.c
Executable file
@@ -0,0 +1,170 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_config.h"
|
||||
#include "los_swtmr.h"
|
||||
#include "los_sem_pri.h"
|
||||
#include "los_queue_pri.h"
|
||||
#include "los_swtmr_pri.h"
|
||||
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define SYSINFO_ENABLED(x) (((x) == YES) ? "YES" : "NO")
|
||||
UINT32 OsShellCmdTaskCntGet(VOID)
|
||||
{
|
||||
UINT32 loop;
|
||||
UINT32 taskCnt = 0;
|
||||
UINT32 intSave;
|
||||
LosTaskCB *taskCB = NULL;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
for (loop = 0; loop < g_taskMaxNum; loop++) {
|
||||
taskCB = (LosTaskCB *)g_taskCBArray + loop;
|
||||
if (OsTaskIsUnused(taskCB)) {
|
||||
continue;
|
||||
}
|
||||
taskCnt++;
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return taskCnt;
|
||||
}
|
||||
|
||||
UINT32 OsShellCmdSemCntGet(VOID)
|
||||
{
|
||||
UINT32 loop;
|
||||
UINT32 semCnt = 0;
|
||||
UINT32 intSave;
|
||||
LosSemCB *semNode = NULL;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
for (loop = 0; loop < LOSCFG_BASE_IPC_SEM_LIMIT; loop++) {
|
||||
semNode = GET_SEM(loop);
|
||||
if (semNode->semStat == OS_SEM_USED) {
|
||||
semCnt++;
|
||||
}
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return semCnt;
|
||||
}
|
||||
|
||||
UINT32 OsShellCmdQueueCntGet(VOID)
|
||||
{
|
||||
UINT32 loop;
|
||||
UINT32 queueCnt = 0;
|
||||
UINT32 intSave;
|
||||
LosQueueCB *queueCB = NULL;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
queueCB = g_allQueue;
|
||||
for (loop = 0; loop < LOSCFG_BASE_IPC_QUEUE_LIMIT; loop++, queueCB++) {
|
||||
if (queueCB->queueState == OS_QUEUE_INUSED) {
|
||||
queueCnt++;
|
||||
}
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return queueCnt;
|
||||
}
|
||||
|
||||
UINT32 OsShellCmdSwtmrCntGet(VOID)
|
||||
{
|
||||
UINT32 loop;
|
||||
UINT32 swtmrCnt = 0;
|
||||
UINT32 intSave;
|
||||
SWTMR_CTRL_S *swtmrCB = NULL;
|
||||
|
||||
intSave = LOS_IntLock();
|
||||
swtmrCB = g_swtmrCBArray;
|
||||
for (loop = 0; loop < LOSCFG_BASE_CORE_SWTMR_LIMIT; loop++, swtmrCB++) {
|
||||
if (swtmrCB->ucState != OS_SWTMR_STATUS_UNUSED) {
|
||||
swtmrCnt++;
|
||||
}
|
||||
}
|
||||
LOS_IntRestore(intSave);
|
||||
return swtmrCnt;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdSystemInfoGet(VOID)
|
||||
{
|
||||
UINT8 isTaskEnable = YES;
|
||||
UINT8 isSemEnable = LOSCFG_BASE_IPC_SEM;
|
||||
UINT8 isQueueEnable = LOSCFG_BASE_IPC_QUEUE;
|
||||
UINT8 isSwtmrEnable = LOSCFG_BASE_CORE_SWTMR;
|
||||
|
||||
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));
|
||||
}
|
||||
|
||||
INT32 OsShellCmdSystemInfo(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
if (argc == 0) {
|
||||
OsShellCmdSystemInfoGet();
|
||||
return 0;
|
||||
}
|
||||
PRINTK("systeminfo: invalid option %s\n"
|
||||
"Systeminfo has NO ARGS.\n",
|
||||
argv[0]);
|
||||
return -1;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL
|
||||
SHELLCMD_ENTRY(systeminfo_shellcmd, CMD_TYPE_EX, "systeminfo", 1, (CmdCallBackFunc)OsShellCmdSystemInfo);
|
||||
#endif /* LOSCFG_SHELL */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
501
kernel/base/misc/task_shellcmd.c
Executable file
501
kernel/base/misc/task_shellcmd.c
Executable file
@@ -0,0 +1,501 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "los_config.h"
|
||||
#include "los_exc.h"
|
||||
#include "los_memstat_pri.h"
|
||||
#include "los_sem_pri.h"
|
||||
#include "los_seq_buf.h"
|
||||
#include "los_task_pri.h"
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
#include "los_cpup_pri.h"
|
||||
#endif
|
||||
#ifdef LOSCFG_SHELL_EXCINFO
|
||||
#include "los_excinfo_pri.h"
|
||||
#endif
|
||||
#include "los_process_pri.h"
|
||||
#include "los_vm_dump.h"
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "fs/fs.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define OS_PROCESS_MEM_INFO 0x2U
|
||||
#define OS_PROCESS_INFO_LEN (g_processMaxNum * (sizeof(LosProcessCB)))
|
||||
#define OS_PROCESS_GROUP_INFO_LEN (g_processMaxNum * sizeof(UINT32))
|
||||
#define OS_PROCESS_UID_INFO_LEN (g_processMaxNum * sizeof(UINT32))
|
||||
#define OS_PROCESS_MEM_ALL_INFO_LEN (g_processMaxNum * PROCESS_MEMINFO_LEN)
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
#define OS_PROCESS_CPUP_INFO_LEN (g_processMaxNum * sizeof(CPUP_INFO_S))
|
||||
#define OS_PROCESS_CPUP_ALLINFO_LEN (OS_PROCESS_CPUP_INFO_LEN * 3)
|
||||
#else
|
||||
#define OS_PROCESS_CPUP_ALLINFO_LEN 0
|
||||
#endif
|
||||
#define OS_PROCESS_ALL_INFO_LEN (g_processMaxNum * (sizeof(LosProcessCB) + sizeof(UINT32)) + \
|
||||
OS_PROCESS_CPUP_ALLINFO_LEN + OS_PROCESS_UID_INFO_LEN)
|
||||
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
LITE_OS_SEC_BSS STATIC CPUP_INFO_S *g_processCpupAll = NULL;
|
||||
LITE_OS_SEC_BSS STATIC CPUP_INFO_S *g_processCpup10s = NULL;
|
||||
LITE_OS_SEC_BSS STATIC CPUP_INFO_S *g_processCpup1s = NULL;
|
||||
#endif
|
||||
|
||||
STATIC UINT32 *g_taskWaterLine = NULL;
|
||||
#define OS_INVALID_SEM_ID 0xFFFFFFFF
|
||||
#define OS_TASK_WATER_LINE_SIZE (g_taskMaxNum * sizeof(UINT32))
|
||||
#define OS_TASK_INFO_LEN (g_taskMaxNum * sizeof(LosTaskCB))
|
||||
#define OS_TASK_ALL_INFO_LEN (g_taskMaxNum * (sizeof(LosTaskCB) + sizeof(UINT32)))
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#define PROCESS_INFO_SHOW(seqBuf, arg...) do { \
|
||||
if (seqBuf != NULL) { \
|
||||
(void)LosBufPrintf((struct SeqBuf *)seqBuf, ##arg); \
|
||||
} else { \
|
||||
PRINTK(arg); \
|
||||
} \
|
||||
} while (0)
|
||||
#else
|
||||
#define PROCESS_INFO_SHOW(seqBuf, arg...) PRINTK(arg)
|
||||
#endif
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdProcessMode(UINT16 mode)
|
||||
{
|
||||
if (mode == OS_KERNEL_MODE) {
|
||||
return (UINT8 *)"kernel";
|
||||
} else if (mode == OS_USER_MODE) {
|
||||
return (UINT8 *)"user";
|
||||
}
|
||||
|
||||
return (UINT8 *)"ERROR";
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdSchedPolicy(UINT16 policy)
|
||||
{
|
||||
if (policy == LOS_SCHED_RR) {
|
||||
return (UINT8 *)"RR";
|
||||
} else if (policy == LOS_SCHED_FIFO) {
|
||||
return (UINT8 *)"FIFO";
|
||||
}
|
||||
|
||||
return (UINT8 *)"ERROR";
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellProcessStatus(UINT16 status)
|
||||
{
|
||||
status = status & OS_PROCESS_STATUS_MASK;
|
||||
if (status & OS_PROCESS_STATUS_ZOMBIES) {
|
||||
return (UINT8 *)"Zombies";
|
||||
} else if (status & OS_PROCESS_STATUS_INIT) {
|
||||
return (UINT8 *)"Init";
|
||||
} else if (status & OS_PROCESS_STATUS_RUNNING) {
|
||||
return (UINT8 *)"Running";
|
||||
} else if (status & OS_PROCESS_STATUS_READY) {
|
||||
return (UINT8 *)"Ready";
|
||||
} else {
|
||||
if (status & OS_PROCESS_STATUS_PEND) {
|
||||
return (UINT8 *)"Pend";
|
||||
}
|
||||
}
|
||||
|
||||
return (UINT8 *)"Invalid";
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdProcessTitle(VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
PROCESS_INFO_SHOW(seqBuf, "\r\n PID PPID PGID UID Status ");
|
||||
if (flag & OS_PROCESS_MEM_INFO) {
|
||||
PROCESS_INFO_SHOW(seqBuf, "VirtualMem ShareMem PhysicalMem ");
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
if (flag & OS_PROCESS_INFO_ALL) {
|
||||
PROCESS_INFO_SHOW(seqBuf, "CPUUSE CPUUSE10s CPUUSE1s ");
|
||||
} else {
|
||||
PROCESS_INFO_SHOW(seqBuf, "CPUUSE10s ");
|
||||
}
|
||||
#endif /* LOSCFG_KERNEL_CPUP */
|
||||
if (flag & OS_PROCESS_INFO_ALL) {
|
||||
PROCESS_INFO_SHOW(seqBuf, "Policy Priority MTID TaskTotal Mode ");
|
||||
}
|
||||
PROCESS_INFO_SHOW(seqBuf, " PName\n");
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdProcessInfoShow(const LosProcessCB *processCB, const INT32 *group,
|
||||
const UINT32 *memArray, VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
const UINT32 *procMemUsage = NULL;
|
||||
const INT32 *user = (const INT32 *)((UINTPTR)group + OS_PROCESS_GROUP_INFO_LEN);
|
||||
UINT32 pid = processCB->processID;
|
||||
PROCESS_INFO_SHOW(seqBuf, "%5u%6d%5d%10d%8s", pid, (INT32)processCB->parentProcessID, group[pid], user[pid],
|
||||
OsShellProcessStatus(processCB->processStatus));
|
||||
|
||||
if (flag & OS_PROCESS_MEM_INFO) {
|
||||
procMemUsage = &memArray[pid * PROCESS_VM_INDEX_MAX];
|
||||
PROCESS_INFO_SHOW(seqBuf, "%#11x%#9x%#12x", procMemUsage[PROCESS_VM_INDEX], procMemUsage[PROCESS_SM_INDEX],
|
||||
procMemUsage[PROCESS_PM_INDEX]);
|
||||
}
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
if (flag & OS_PROCESS_INFO_ALL) {
|
||||
PROCESS_INFO_SHOW(seqBuf, "%5u.%1u%8u.%1u%7u.%-1u ",
|
||||
g_processCpupAll[pid].uwUsage / LOS_CPUP_PRECISION_MULT,
|
||||
g_processCpupAll[pid].uwUsage % LOS_CPUP_PRECISION_MULT,
|
||||
g_processCpup10s[pid].uwUsage / LOS_CPUP_PRECISION_MULT,
|
||||
g_processCpup10s[pid].uwUsage % LOS_CPUP_PRECISION_MULT,
|
||||
g_processCpup1s[pid].uwUsage / LOS_CPUP_PRECISION_MULT,
|
||||
g_processCpup1s[pid].uwUsage % LOS_CPUP_PRECISION_MULT);
|
||||
} else {
|
||||
PROCESS_INFO_SHOW(seqBuf, "%8u.%1u ",
|
||||
g_processCpup10s[pid].uwUsage / LOS_CPUP_PRECISION_MULT,
|
||||
g_processCpup10s[pid].uwUsage % LOS_CPUP_PRECISION_MULT);
|
||||
}
|
||||
#endif /* LOSCFG_KERNEL_CPUP */
|
||||
if (flag & OS_PROCESS_INFO_ALL) {
|
||||
PROCESS_INFO_SHOW(seqBuf, "%6s%9u%5d%10u%7s ",
|
||||
OsShellCmdSchedPolicy(processCB->policy), processCB->priority,
|
||||
(INT32)processCB->threadGroupID, processCB->threadNumber,
|
||||
OsShellCmdProcessMode(processCB->processMode));
|
||||
}
|
||||
PROCESS_INFO_SHOW(seqBuf, " %-32s\n", processCB->processName);
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdAllProcessInfoShow(const LosProcessCB *pcbArray, const INT32 *group,
|
||||
const UINT32 *memArray, VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
const LosProcessCB *processCB = NULL;
|
||||
UINT32 pid;
|
||||
|
||||
for (pid = 1; pid < g_processMaxNum; ++pid) {
|
||||
processCB = pcbArray + pid;
|
||||
if (OsProcessIsUnused(processCB)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OsShellCmdProcessInfoShow(processCB, group, memArray, seqBuf, flag);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsProcessMemUsageGet(UINT32 *memArray)
|
||||
{
|
||||
UINT32 pid;
|
||||
LosProcessCB *processCB = NULL;
|
||||
UINT32 *proMemUsage = NULL;
|
||||
|
||||
for (pid = 0; pid < g_processMaxNum; ++pid) {
|
||||
processCB = g_processCBArray + pid;
|
||||
if (OsProcessIsUnused(processCB)) {
|
||||
continue;
|
||||
}
|
||||
proMemUsage = &memArray[pid * PROCESS_VM_INDEX_MAX];
|
||||
|
||||
/* Process memory usage statistics, idle task defaults to 0 */
|
||||
if (pid == OsGetIdleProcessID()) {
|
||||
proMemUsage[PROCESS_VM_INDEX] = 0;
|
||||
proMemUsage[PROCESS_SM_INDEX] = 0;
|
||||
proMemUsage[PROCESS_PM_INDEX] = 0;
|
||||
} else {
|
||||
proMemUsage[PROCESS_VM_INDEX] = OsShellCmdProcessVmUsage(processCB->vmSpace);
|
||||
OsShellCmdProcessPmUsage(processCB->vmSpace, &proMemUsage[PROCESS_SM_INDEX],
|
||||
&proMemUsage[PROCESS_PM_INDEX]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 OsProcessInfoGet(LosProcessCB **pcbArray, INT32 **group, UINT32 **memArray, UINT16 flag)
|
||||
{
|
||||
UINT32 len = OS_PROCESS_ALL_INFO_LEN;
|
||||
LosProcessCB *processCB = NULL;
|
||||
INT32 *user = NULL;
|
||||
|
||||
(VOID)memcpy_s(*pcbArray, OS_PROCESS_INFO_LEN, g_processCBArray, OS_PROCESS_INFO_LEN);
|
||||
*group = (INT32 *)((UINTPTR)*pcbArray + OS_PROCESS_INFO_LEN);
|
||||
user = (INT32 *)((UINTPTR)*group + OS_PROCESS_GROUP_INFO_LEN);
|
||||
for (UINT32 pid = 0; pid < g_processMaxNum; ++pid) {
|
||||
processCB = *pcbArray + pid;
|
||||
if (OsProcessIsUnused(processCB)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (processCB->group != NULL) {
|
||||
(*group)[processCB->processID] = processCB->group->groupID;
|
||||
} else {
|
||||
(*group)[processCB->processID] = -1;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SECURITY_CAPABILITY
|
||||
if (processCB->user != NULL) {
|
||||
user[processCB->processID] = processCB->user->userID;
|
||||
} else {
|
||||
user[processCB->processID] = -1;
|
||||
}
|
||||
#else
|
||||
user[processCB->processID] = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
g_processCpupAll = (CPUP_INFO_S *)((UINTPTR)user + OS_PROCESS_UID_INFO_LEN);
|
||||
g_processCpup10s = (CPUP_INFO_S *)((UINTPTR)g_processCpupAll + OS_PROCESS_CPUP_INFO_LEN);
|
||||
g_processCpup1s = (CPUP_INFO_S *)((UINTPTR)g_processCpup10s + OS_PROCESS_CPUP_INFO_LEN);
|
||||
(VOID)OsAllCpuUsageUnsafe(LOSCFG_BASE_CORE_PROCESS_LIMIT, g_processCpupAll, CPUP_ALL_TIME, 1);
|
||||
(VOID)OsAllCpuUsageUnsafe(LOSCFG_BASE_CORE_PROCESS_LIMIT, g_processCpup10s, CPUP_LAST_TEN_SECONDS, 1);
|
||||
(VOID)OsAllCpuUsageUnsafe(LOSCFG_BASE_CORE_PROCESS_LIMIT, g_processCpup1s, CPUP_LAST_ONE_SECONDS, 1);
|
||||
#endif
|
||||
|
||||
if (flag & OS_PROCESS_MEM_INFO) {
|
||||
*memArray = (UINT32 *)((UINTPTR)*pcbArray + OS_PROCESS_ALL_INFO_LEN);
|
||||
OsProcessMemUsageGet(*memArray);
|
||||
len += OS_PROCESS_MEM_ALL_INFO_LEN;
|
||||
}
|
||||
|
||||
return len;
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdProcessInfoData(const LosProcessCB *pcbArray, const INT32 *group,
|
||||
const UINT32 *memArray, VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
OsShellCmdProcessTitle(seqBuf, flag);
|
||||
OsShellCmdAllProcessInfoShow(pcbArray, group, memArray, seqBuf, flag);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT8 *OsShellCmdConvertTskStatus(UINT16 taskStatus)
|
||||
{
|
||||
if (taskStatus & OS_TASK_STATUS_INIT) {
|
||||
return (UINT8 *)"Init";
|
||||
} else if (taskStatus & OS_TASK_STATUS_RUNNING) {
|
||||
return (UINT8 *)"Running";
|
||||
} else if (taskStatus & OS_TASK_STATUS_READY) {
|
||||
return (UINT8 *)"Ready";
|
||||
} else {
|
||||
if (taskStatus & OS_TASK_STATUS_DELAY) {
|
||||
return (UINT8 *)"Delay";
|
||||
} else if (taskStatus & OS_TASK_STATUS_PEND_TIME) {
|
||||
if (taskStatus & OS_TASK_STATUS_SUSPEND) {
|
||||
return (UINT8 *)"SuspendTime";
|
||||
} else if (taskStatus & OS_TASK_STATUS_PEND) {
|
||||
return (UINT8 *)"PendTime";
|
||||
}
|
||||
} else if (taskStatus & OS_TASK_STATUS_PEND) {
|
||||
return (UINT8 *)"Pend";
|
||||
} else if (taskStatus & OS_TASK_STATUS_SUSPEND) {
|
||||
return (UINT8 *)"Suspend";
|
||||
} else if (taskStatus & OS_TASK_STATUS_EXIT) {
|
||||
return (UINT8 *)"Exit";
|
||||
}
|
||||
}
|
||||
|
||||
return (UINT8 *)"Invalid";
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdTaskWaterLineGet(const LosTaskCB *allTaskArray)
|
||||
{
|
||||
const LosTaskCB *taskCB = NULL;
|
||||
UINT32 loop;
|
||||
|
||||
for (loop = 0; loop < g_taskMaxNum; ++loop) {
|
||||
taskCB = allTaskArray + loop;
|
||||
if (OsTaskIsUnused(taskCB)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
(VOID)OsStackWaterLineGet((const UINTPTR *)((UINTPTR)taskCB->topOfStack + taskCB->stackSize),
|
||||
(const UINTPTR *)taskCB->topOfStack, &g_taskWaterLine[taskCB->taskID]);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdTskInfoTitle(VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
PROCESS_INFO_SHOW(seqBuf, "\r\n TID PID ");
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
PROCESS_INFO_SHOW(seqBuf, "Affi CPU ");
|
||||
#endif
|
||||
PROCESS_INFO_SHOW(seqBuf, " Status StackSize WaterLine ");
|
||||
if (flag & OS_PROCESS_INFO_ALL) {
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
PROCESS_INFO_SHOW(seqBuf, " StackPoint TopOfStack EventMask SemID ");
|
||||
#endif
|
||||
PROCESS_INFO_SHOW(seqBuf, "Policy Priority ");
|
||||
}
|
||||
PROCESS_INFO_SHOW(seqBuf, " MEMUSE TaskName\n");
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
STATIC INLINE UINT32 OsGetSemID(const LosTaskCB *taskCB)
|
||||
{
|
||||
UINT32 semID = OS_INVALID_SEM_ID;
|
||||
|
||||
if (taskCB->taskSem != NULL) {
|
||||
semID = ((LosSemCB *)taskCB->taskSem)->semID;
|
||||
}
|
||||
|
||||
return semID;
|
||||
}
|
||||
#endif
|
||||
|
||||
STATIC INLINE VOID OsShellTskInfoData(const LosTaskCB *taskCB, VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
PROCESS_INFO_SHOW(seqBuf, " %4u%5u", taskCB->taskID, taskCB->processID);
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
PROCESS_INFO_SHOW(seqBuf, "%#5x%4d ", taskCB->cpuAffiMask, (INT16)(taskCB->currCpu));
|
||||
#endif
|
||||
|
||||
PROCESS_INFO_SHOW(seqBuf, "%12s%#10x%#10x", OsShellCmdConvertTskStatus(taskCB->taskStatus),
|
||||
taskCB->stackSize, g_taskWaterLine[taskCB->taskID]);
|
||||
|
||||
if (flag & OS_PROCESS_INFO_ALL) {
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
PROCESS_INFO_SHOW(seqBuf, "%#12x%#12x%#10x%#12x", taskCB->stackPointer, taskCB->topOfStack,
|
||||
taskCB->eventMask, OsGetSemID(taskCB));
|
||||
#endif
|
||||
PROCESS_INFO_SHOW(seqBuf, "%7s%9u", OsShellCmdSchedPolicy(taskCB->policy), taskCB->priority);
|
||||
}
|
||||
PROCESS_INFO_SHOW(seqBuf, "%#10x %-32s\n", OsTaskMemUsage(taskCB->taskID), taskCB->taskName);
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdAllTaskInfoData(const LosTaskCB *allTaskArray, VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
const LosTaskCB *taskCB = NULL;
|
||||
UINT32 pid;
|
||||
UINT32 loop;
|
||||
|
||||
for (pid = 1; pid < g_processMaxNum; ++pid) {
|
||||
for (loop = 0; loop < g_taskMaxNum; ++loop) {
|
||||
taskCB = allTaskArray + loop;
|
||||
if (OsTaskIsUnused(taskCB) || (taskCB->processID != pid)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
OsShellTskInfoData(taskCB, seqBuf, flag);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsShellCmdTskInfoData(const LosTaskCB *allTaskArray, VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
OsShellCmdTskInfoTitle(seqBuf, flag);
|
||||
OsShellCmdAllTaskInfoData(allTaskArray, seqBuf, flag);
|
||||
}
|
||||
|
||||
STATIC VOID OsProcessAndTaskInfoGet(LosProcessCB **pcbArray, INT32 **group, LosTaskCB **tcbArray,
|
||||
UINT32 **memArray, UINT16 flag)
|
||||
{
|
||||
BOOL lockFlag = FALSE;
|
||||
UINT32 intSave = 0;
|
||||
UINT32 processInfoLen;
|
||||
|
||||
if (LOS_SpinHeld(&g_taskSpin) == FALSE) {
|
||||
SCHEDULER_LOCK(intSave);
|
||||
lockFlag = TRUE;
|
||||
}
|
||||
|
||||
processInfoLen = OsProcessInfoGet(pcbArray, group, memArray, flag);
|
||||
*tcbArray = (LosTaskCB *)((UINTPTR)*pcbArray + processInfoLen);
|
||||
(VOID)memcpy_s(*tcbArray, OS_TASK_INFO_LEN, g_taskCBArray, OS_TASK_INFO_LEN);
|
||||
g_taskWaterLine = (UINT32 *)((UINTPTR)*tcbArray + OS_TASK_INFO_LEN);
|
||||
OsShellCmdTaskWaterLineGet(*tcbArray);
|
||||
if (lockFlag == TRUE) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdTskInfoGet(UINT32 taskID, VOID *seqBuf, UINT16 flag)
|
||||
{
|
||||
UINT32 size;
|
||||
LosProcessCB *pcbArray = NULL;
|
||||
INT32 *group = NULL;
|
||||
LosTaskCB *tcbArray = NULL;
|
||||
UINT32 *memArray = NULL;
|
||||
|
||||
if (taskID == OS_ALL_TASK_MASK) {
|
||||
if (flag & OS_PROCESS_MEM_INFO) {
|
||||
size = OS_PROCESS_ALL_INFO_LEN + OS_PROCESS_MEM_ALL_INFO_LEN + OS_TASK_ALL_INFO_LEN;
|
||||
} else {
|
||||
size = OS_PROCESS_ALL_INFO_LEN + OS_TASK_ALL_INFO_LEN;
|
||||
}
|
||||
pcbArray = (LosProcessCB *)LOS_MemAlloc(m_aucSysMem1, size);
|
||||
if (pcbArray == NULL) {
|
||||
PRINT_ERR("Memory is not enough to save task info!\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
(VOID)memset_s(pcbArray, size, 0, size);
|
||||
OsProcessAndTaskInfoGet(&pcbArray, &group, &tcbArray, &memArray, flag);
|
||||
OsShellCmdProcessInfoData(pcbArray, group, memArray, seqBuf, flag);
|
||||
OsShellCmdTskInfoData(tcbArray, seqBuf, flag);
|
||||
|
||||
(VOID)LOS_MemFree(m_aucSysMem1, pcbArray);
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpTask(INT32 argc, const CHAR **argv)
|
||||
{
|
||||
UINT32 flag = 0;
|
||||
|
||||
flag |= OS_PROCESS_MEM_INFO;
|
||||
|
||||
if (argc < 2) { /* 2:Just as number of parameters */
|
||||
if (argc == 1) {
|
||||
if (strcmp("-a", argv[0]) == 0) {
|
||||
flag |= OS_PROCESS_INFO_ALL;
|
||||
} else {
|
||||
PRINTK("Unknown option: %s\n", argv[0]);
|
||||
goto TASK_HELP;
|
||||
}
|
||||
}
|
||||
|
||||
return OsShellCmdTskInfoGet(OS_ALL_TASK_MASK, NULL, flag);
|
||||
}
|
||||
|
||||
TASK_HELP:
|
||||
PRINTK("usage: task or task -a\n");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL
|
||||
SHELLCMD_ENTRY(task_shellcmd, CMD_TYPE_EX, "task", 1, (CmdCallBackFunc)OsShellCmdDumpTask);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
265
kernel/base/misc/vm_shellcmd.c
Executable file
265
kernel/base/misc/vm_shellcmd.c
Executable file
@@ -0,0 +1,265 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "stdlib.h"
|
||||
#include "stdio.h"
|
||||
#include "ctype.h"
|
||||
#include "los_printf.h"
|
||||
#include "string.h"
|
||||
#include "securec.h"
|
||||
#ifdef LOSCFG_SHELL
|
||||
#include "shcmd.h"
|
||||
#include "shell.h"
|
||||
#endif
|
||||
#include "los_oom.h"
|
||||
#include "los_vm_dump.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define ARGC_2 2
|
||||
#define ARGC_1 1
|
||||
#define ARGC_0 0
|
||||
#define VMM_CMD "vmm"
|
||||
#define OOM_CMD "oom"
|
||||
#define VMM_PMM_CMD "v2p"
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsDumpKernelAspace(VOID)
|
||||
{
|
||||
LosVmSpace *kAspace = LOS_GetKVmSpace();
|
||||
if (kAspace != NULL) {
|
||||
OsDumpAspace(kAspace);
|
||||
} else {
|
||||
VM_ERR("kernel aspace is NULL");
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR INT32 OsPid(const CHAR *str)
|
||||
{
|
||||
UINT32 len = strlen(str);
|
||||
if (len <= 2) { // pid range is 0~63, max pid string length is 2
|
||||
for (UINT32 i = 0; i < len; i++) {
|
||||
if (isdigit(str[i]) == 0) {
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
return atoi(str);
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsPrintUsage(VOID)
|
||||
{
|
||||
PRINTK("-a, print all vm address space information\n"
|
||||
"-k, print the kernel vm address space information\n"
|
||||
"pid(0~63), print process[pid] vm address space information\n"
|
||||
"-h | --help, print vmm command usage\n");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsDoDumpVm(pid_t pid)
|
||||
{
|
||||
LosProcessCB *processCB = NULL;
|
||||
|
||||
if (OsProcessIDUserCheckInvalid(pid)) {
|
||||
PRINTK("\tThe process [%d] not valid\n", pid);
|
||||
return;
|
||||
}
|
||||
|
||||
processCB = OS_PCB_FROM_PID(pid);
|
||||
if (!OsProcessIsUnused(processCB) && (processCB->vmSpace != NULL)) {
|
||||
OsDumpAspace(processCB->vmSpace);
|
||||
} else {
|
||||
PRINTK("\tThe process [%d] not active\n", pid);
|
||||
}
|
||||
}
|
||||
|
||||
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 {
|
||||
OsPrintUsage();
|
||||
}
|
||||
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdV2P(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
UINT32 vaddr;
|
||||
PADDR_T paddr;
|
||||
CHAR *endPtr = NULL;
|
||||
|
||||
if (argc == 0) {
|
||||
V2PPrintUsage();
|
||||
} else if (argc == 1) {
|
||||
if (strcmp(argv[0], "-h") == 0 || strcmp(argv[0], "--help") == 0) {
|
||||
V2PPrintUsage();
|
||||
}
|
||||
} else if (argc == 2) {
|
||||
pid_t pid = OsPid(argv[0]);
|
||||
vaddr = strtoul((CHAR *)argv[1], &endPtr, 0);
|
||||
if ((endPtr == NULL) || (*endPtr != 0)) {
|
||||
PRINTK("vaddr %s invalid. should be in range(0x1000000~0x3e000000) \n", argv[1]);
|
||||
return OS_ERROR;
|
||||
} else {
|
||||
if (pid >= 0) {
|
||||
if (pid < g_taskMaxNum) {
|
||||
LosProcessCB *processCB = OS_PCB_FROM_PID(pid);
|
||||
if (!OsProcessIsUnused(processCB)) {
|
||||
paddr = 0;
|
||||
LOS_ArchMmuQuery(&processCB->vmSpace->archMmu, (VADDR_T)vaddr, &paddr, 0);
|
||||
if (paddr == 0) {
|
||||
PRINTK("vaddr %#x is not in range or mapped\n", vaddr);
|
||||
} else {
|
||||
PRINTK("vaddr %#x is paddr %#x\n", vaddr, paddr);
|
||||
}
|
||||
} else {
|
||||
PRINTK("\tThe process [%d] not active\n", pid);
|
||||
}
|
||||
} else {
|
||||
PRINTK("\tThe process [%d] not valid\n", pid);
|
||||
}
|
||||
} else {
|
||||
PRINTK("%s: invalid option: %s %s\n", VMM_PMM_CMD, argv[0], argv[1]);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdDumpPmm(VOID)
|
||||
{
|
||||
OsVmPhysDump();
|
||||
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomPrintUsage(VOID)
|
||||
{
|
||||
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");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdOom(INT32 argc, const CHAR *argv[])
|
||||
{
|
||||
UINT32 lowMemThreshold;
|
||||
UINT32 reclaimMemThreshold;
|
||||
UINT32 checkInterval;
|
||||
CHAR *endPtr = NULL;
|
||||
|
||||
if (argc == ARGC_0) {
|
||||
OomInfodump();
|
||||
} else if (argc == ARGC_1) {
|
||||
if (strcmp(argv[0], "-h") != 0 && strcmp(argv[0], "--help") != 0) {
|
||||
PRINTK("%s: invalid option: %s\n", OOM_CMD, argv[0]);
|
||||
}
|
||||
OomPrintUsage();
|
||||
} else if (argc == ARGC_2) {
|
||||
if (strcmp(argv[0], "-m") == 0) {
|
||||
lowMemThreshold = strtoul((CHAR *)argv[1], &endPtr, 0);
|
||||
if ((endPtr == NULL) || (*endPtr != 0)) {
|
||||
PRINTK("[oom] low mem threshold %s(byte) invalid.\n", argv[1]);
|
||||
return OS_ERROR;
|
||||
} else {
|
||||
OomSetLowMemThreashold(lowMemThreshold);
|
||||
}
|
||||
} else if (strcmp(argv[0], "-i") == 0) {
|
||||
checkInterval = strtoul((CHAR *)argv[1], &endPtr, 0);
|
||||
if ((endPtr == NULL) || (*endPtr != 0)) {
|
||||
PRINTK("[oom] check interval %s(us) invalid.\n", argv[1]);
|
||||
return OS_ERROR;
|
||||
} else {
|
||||
OomSetCheckInterval(checkInterval);
|
||||
}
|
||||
} else if (strcmp(argv[0], "-r") == 0) {
|
||||
reclaimMemThreshold = strtoul((CHAR *)argv[1], &endPtr, 0);
|
||||
if ((endPtr == NULL) || (*endPtr != 0)) {
|
||||
PRINTK("[oom] reclaim mem threshold %s(byte) invalid.\n", argv[1]);
|
||||
return OS_ERROR;
|
||||
} else {
|
||||
OomSetReclaimMemThreashold(reclaimMemThreshold);
|
||||
}
|
||||
} else {
|
||||
PRINTK("%s: invalid option: %s %s\n", OOM_CMD, argv[0], argv[1]);
|
||||
OomPrintUsage();
|
||||
}
|
||||
} else {
|
||||
PRINTK("%s: invalid option\n", OOM_CMD);
|
||||
OomPrintUsage();
|
||||
}
|
||||
|
||||
return OS_ERROR;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
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);
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
323
kernel/base/mp/los_lockdep.c
Executable file
323
kernel/base/mp/los_lockdep.c
Executable file
@@ -0,0 +1,323 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_base.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_printf_pri.h"
|
||||
#include "los_atomic.h"
|
||||
#include "los_exc.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP_LOCKDEP == YES)
|
||||
|
||||
#define LOCKDEP_GET_NAME(lockDep, index) (((SPIN_LOCK_S *)((lockDep)->heldLocks[(index)].lockPtr))->name)
|
||||
#define LOCKDEP_GET_ADDR(lockDep, index) ((lockDep)->heldLocks[(index)].lockAddr)
|
||||
|
||||
STATIC Atomic g_lockdepAvailable = 1;
|
||||
|
||||
/* atomic insurance for lockdep check */
|
||||
STATIC INLINE VOID OsLockDepRequire(UINT32 *intSave)
|
||||
{
|
||||
*intSave = LOS_IntLock();
|
||||
while (LOS_AtomicCmpXchg32bits(&g_lockdepAvailable, 0, 1)) {
|
||||
/* busy waiting */
|
||||
}
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsLockDepRelease(UINT32 intSave)
|
||||
{
|
||||
LOS_AtomicSet(&g_lockdepAvailable, 1);
|
||||
LOS_IntRestore(intSave);
|
||||
}
|
||||
|
||||
STATIC INLINE UINT64 OsLockDepGetCycles(VOID)
|
||||
{
|
||||
UINT32 high, low;
|
||||
|
||||
LOS_GetCpuCycle(&high, &low);
|
||||
/* combine cycleHi and cycleLo into 8 bytes cycles */
|
||||
return (((UINT64)high << 32) + low); // 32 bits for lower half of UINT64
|
||||
}
|
||||
|
||||
STATIC INLINE CHAR *OsLockDepErrorStringGet(enum LockDepErrType type)
|
||||
{
|
||||
CHAR *errorString = NULL;
|
||||
|
||||
switch (type) {
|
||||
case LOCKDEP_ERR_DOUBLE_LOCK:
|
||||
errorString = "double lock";
|
||||
break;
|
||||
case LOCKDEP_ERR_DEAD_LOCK:
|
||||
errorString = "dead lock";
|
||||
break;
|
||||
case LOCKDEP_ERR_UNLOCK_WITOUT_LOCK:
|
||||
errorString = "unlock without lock";
|
||||
break;
|
||||
case LOCKDEP_ERR_OVERFLOW:
|
||||
errorString = "lockdep overflow";
|
||||
break;
|
||||
default:
|
||||
errorString = "unknow error code";
|
||||
break;
|
||||
}
|
||||
|
||||
return errorString;
|
||||
}
|
||||
|
||||
WEAK VOID OsLockDepPanic(enum LockDepErrType errType)
|
||||
{
|
||||
/* halt here */
|
||||
(VOID)errType;
|
||||
(VOID)LOS_IntLock();
|
||||
OsBackTrace();
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
STATIC VOID OsLockDepDumpLock(const LosTaskCB *task, const SPIN_LOCK_S *lock,
|
||||
const VOID *requestAddr, enum LockDepErrType errType)
|
||||
{
|
||||
INT32 i;
|
||||
const LockDep *lockDep = &task->lockDep;
|
||||
const LosTaskCB *temp = task;
|
||||
|
||||
PrintExcInfo("lockdep check failed\n");
|
||||
PrintExcInfo("error type : %s\n", OsLockDepErrorStringGet(errType));
|
||||
PrintExcInfo("request addr : 0x%x\n", requestAddr);
|
||||
|
||||
while (1) {
|
||||
PrintExcInfo("task name : %s\n", temp->taskName);
|
||||
PrintExcInfo("task id : %u\n", temp->taskID);
|
||||
PrintExcInfo("cpu num : %u\n", temp->currCpu);
|
||||
PrintExcInfo("start dumping lockdep infomation\n");
|
||||
for (i = 0; i < lockDep->lockDepth; i++) {
|
||||
if (lockDep->heldLocks[i].lockPtr == lock) {
|
||||
PrintExcInfo("[%d] %s <-- addr:0x%x\n", i, LOCKDEP_GET_NAME(lockDep, i),
|
||||
LOCKDEP_GET_ADDR(lockDep, i));
|
||||
} else {
|
||||
PrintExcInfo("[%d] %s \n", i, LOCKDEP_GET_NAME(lockDep, i));
|
||||
}
|
||||
}
|
||||
PrintExcInfo("[%d] %s <-- now\n", i, lock->name);
|
||||
|
||||
if (errType == LOCKDEP_ERR_DEAD_LOCK) {
|
||||
temp = lock->owner;
|
||||
lock = temp->lockDep.waitLock;
|
||||
lockDep = &temp->lockDep;
|
||||
}
|
||||
|
||||
if (temp == task) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
OsLockDepPanic(errType);
|
||||
}
|
||||
|
||||
STATIC BOOL OsLockDepCheckDependancy(const LosTaskCB *current, LosTaskCB *lockOwner)
|
||||
{
|
||||
BOOL checkResult = TRUE;
|
||||
SPIN_LOCK_S *lockTemp = NULL;
|
||||
|
||||
do {
|
||||
if (current == lockOwner) {
|
||||
checkResult = FALSE;
|
||||
return checkResult;
|
||||
}
|
||||
if (lockOwner->lockDep.waitLock != NULL) {
|
||||
lockTemp = lockOwner->lockDep.waitLock;
|
||||
lockOwner = lockTemp->owner;
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
} while (lockOwner != SPINLOCK_OWNER_INIT);
|
||||
|
||||
return checkResult;
|
||||
}
|
||||
|
||||
VOID OsLockDepCheckIn(SPIN_LOCK_S *lock)
|
||||
{
|
||||
UINT32 intSave;
|
||||
enum LockDepErrType checkResult = LOCKDEP_SUCEESS;
|
||||
VOID *requestAddr = (VOID *)__builtin_return_address(0);
|
||||
LosTaskCB *current = OsCurrTaskGet();
|
||||
LockDep *lockDep = ¤t->lockDep;
|
||||
LosTaskCB *lockOwner = NULL;
|
||||
|
||||
OsLockDepRequire(&intSave);
|
||||
|
||||
if (lockDep->lockDepth >= (INT32)MAX_LOCK_DEPTH) {
|
||||
checkResult = LOCKDEP_ERR_OVERFLOW;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
lockOwner = lock->owner;
|
||||
/* not owned by any tasks yet, not doing following checks */
|
||||
if (lockOwner == SPINLOCK_OWNER_INIT) {
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if (current == lockOwner) {
|
||||
checkResult = LOCKDEP_ERR_DOUBLE_LOCK;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
if (OsLockDepCheckDependancy(current, lockOwner) != TRUE) {
|
||||
checkResult = LOCKDEP_ERR_DEAD_LOCK;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
OUT:
|
||||
if (checkResult == LOCKDEP_SUCEESS) {
|
||||
/*
|
||||
* though the check may succeed, the waitLock still need to be set.
|
||||
* because the OsLockDepCheckIn and OsLockDepRecord is not strictly muti-core
|
||||
* sequential, there would be more than two tasks can pass the checking, but
|
||||
* only one task can successfully obtain the lock.
|
||||
*/
|
||||
lockDep->waitLock = lock;
|
||||
lockDep->heldLocks[lockDep->lockDepth].lockAddr = requestAddr;
|
||||
lockDep->heldLocks[lockDep->lockDepth].waitTime = OsLockDepGetCycles(); /* start time */
|
||||
} else {
|
||||
OsLockDepDumpLock(current, lock, requestAddr, checkResult);
|
||||
}
|
||||
|
||||
OsLockDepRelease(intSave);
|
||||
}
|
||||
|
||||
VOID OsLockDepRecord(SPIN_LOCK_S *lock)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT64 cycles;
|
||||
LosTaskCB *current = OsCurrTaskGet();
|
||||
LockDep *lockDep = ¤t->lockDep;
|
||||
HeldLocks *heldlock = &lockDep->heldLocks[lockDep->lockDepth];
|
||||
|
||||
OsLockDepRequire(&intSave);
|
||||
|
||||
/*
|
||||
* OsLockDepCheckIn records start time t1, after the lock is obtained, we
|
||||
* get the time t2, (t2 - t1) is the time of waiting for the lock
|
||||
*/
|
||||
cycles = OsLockDepGetCycles();
|
||||
heldlock->waitTime = cycles - heldlock->waitTime;
|
||||
heldlock->holdTime = cycles;
|
||||
|
||||
/* record lock info */
|
||||
lock->owner = current;
|
||||
lock->cpuid = ArchCurrCpuid();
|
||||
|
||||
/* record lockdep info */
|
||||
heldlock->lockPtr = lock;
|
||||
lockDep->lockDepth++;
|
||||
lockDep->waitLock = NULL;
|
||||
|
||||
OsLockDepRelease(intSave);
|
||||
}
|
||||
|
||||
VOID OsLockDepCheckOut(SPIN_LOCK_S *lock)
|
||||
{
|
||||
UINT32 intSave;
|
||||
INT32 depth;
|
||||
enum LockDepErrType checkResult = LOCKDEP_SUCEESS;
|
||||
VOID *requestAddr = (VOID *)__builtin_return_address(0);
|
||||
LosTaskCB *current = OsCurrTaskGet();
|
||||
LosTaskCB *owner = NULL;
|
||||
LockDep *lockDep = NULL;
|
||||
HeldLocks *heldlocks = NULL;
|
||||
|
||||
OsLockDepRequire(&intSave);
|
||||
|
||||
owner = lock->owner;
|
||||
if (owner == SPINLOCK_OWNER_INIT) {
|
||||
checkResult = LOCKDEP_ERR_UNLOCK_WITOUT_LOCK;
|
||||
OsLockDepDumpLock(current, lock, requestAddr, checkResult);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
lockDep = &owner->lockDep;
|
||||
heldlocks = &lockDep->heldLocks[0];
|
||||
depth = lockDep->lockDepth;
|
||||
|
||||
/* find the lock position */
|
||||
while (depth-- >= 0) {
|
||||
if (heldlocks[depth].lockPtr == lock) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
LOS_ASSERT(depth >= 0);
|
||||
|
||||
/* record lock holding time */
|
||||
heldlocks[depth].holdTime = OsLockDepGetCycles() - heldlocks[depth].holdTime;
|
||||
|
||||
/* if unlock a older lock, needs move heldLock records */
|
||||
while (depth < lockDep->lockDepth - 1) {
|
||||
lockDep->heldLocks[depth] = lockDep->heldLocks[depth + 1];
|
||||
depth++;
|
||||
}
|
||||
|
||||
lockDep->lockDepth--;
|
||||
lock->cpuid = (UINT32)(-1);
|
||||
lock->owner = SPINLOCK_OWNER_INIT;
|
||||
|
||||
OUT:
|
||||
OsLockDepRelease(intSave);
|
||||
}
|
||||
|
||||
VOID OsLockdepClearSpinlocks(VOID)
|
||||
{
|
||||
LosTaskCB *task = OsCurrTaskGet();
|
||||
LockDep *lockDep = &task->lockDep;
|
||||
SPIN_LOCK_S *lock = NULL;
|
||||
|
||||
/*
|
||||
* Unlock spinlocks that running task has held.
|
||||
* lockDepth will decrease after each spinlock is unlockded.
|
||||
*/
|
||||
while (lockDep->lockDepth) {
|
||||
lock = lockDep->heldLocks[lockDep->lockDepth - 1].lockPtr;
|
||||
LOS_SpinUnlock(lock);
|
||||
}
|
||||
}
|
||||
|
||||
#endif /* LOSCFG_KERNEL_SMP_LOCKDEP */
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
119
kernel/base/mp/los_mp.c
Executable file
119
kernel/base/mp/los_mp.c
Executable file
@@ -0,0 +1,119 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_mp.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_percpu_pri.h"
|
||||
#include "los_sched_pri.h"
|
||||
#include "los_swtmr.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
|
||||
VOID LOS_MpSchedule(UINT32 target)
|
||||
{
|
||||
UINT32 cpuid = ArchCurrCpuid();
|
||||
target &= ~(1U << cpuid);
|
||||
HalIrqSendIpi(target, LOS_MP_IPI_SCHEDULE);
|
||||
}
|
||||
|
||||
VOID OsMpWakeHandler(VOID)
|
||||
{
|
||||
/* generic wakeup ipi, do nothing */
|
||||
}
|
||||
|
||||
VOID OsMpScheduleHandler(VOID)
|
||||
{
|
||||
/*
|
||||
* set schedule flag to differ from wake function,
|
||||
* so that the scheduler can be triggered at the end of irq.
|
||||
*/
|
||||
OsPercpuGet()->schedFlag = INT_PEND_RESCH;
|
||||
}
|
||||
|
||||
VOID OsMpHaltHandler(VOID)
|
||||
{
|
||||
(VOID)LOS_IntLock();
|
||||
OsPercpuGet()->excFlag = CPU_HALT;
|
||||
|
||||
while (1) {}
|
||||
}
|
||||
|
||||
VOID OsMpCollectTasks(VOID)
|
||||
{
|
||||
LosTaskCB *taskCB = NULL;
|
||||
UINT32 taskID = 0;
|
||||
UINT32 ret;
|
||||
|
||||
/* recursive checking all the available task */
|
||||
for (; taskID <= g_taskMaxNum; taskID++) {
|
||||
taskCB = &g_taskCBArray[taskID];
|
||||
|
||||
if (OsTaskIsUnused(taskCB) || OsTaskIsRunning(taskCB)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/*
|
||||
* 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);
|
||||
if (ret != LOS_OK) {
|
||||
PRINT_WARN("GC collect task failed err:0x%x\n", ret);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 OsMpInit(VOID)
|
||||
{
|
||||
UINT16 swtmrId;
|
||||
|
||||
(VOID)LOS_SwtmrCreate(OS_MP_GC_PERIOD, LOS_SWTMR_MODE_PERIOD,
|
||||
(SWTMR_PROC_FUNC)OsMpCollectTasks, &swtmrId, 0);
|
||||
(VOID)LOS_SwtmrStart(swtmrId);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
46
kernel/base/mp/los_percpu.c
Executable file
46
kernel/base/mp/los_percpu.c
Executable file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_percpu_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
Percpu g_percpu[LOSCFG_KERNEL_CORE_NUM];
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
333
kernel/base/mp/los_stat.c
Executable file
333
kernel/base/mp/los_stat.c
Executable file
@@ -0,0 +1,333 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_task_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES)
|
||||
#define HIGHTASKPRI 16
|
||||
#define NS_PER_MS 1000000
|
||||
#define DECIMAL_TO_PERCENTAGE 100
|
||||
|
||||
typedef struct {
|
||||
UINT64 idleRuntime;
|
||||
UINT64 idleStarttime;
|
||||
UINT64 highTaskRuntime;
|
||||
UINT64 highTaskStarttime;
|
||||
UINT64 spinWaitRuntime;
|
||||
UINT64 sumPriority;
|
||||
UINT32 prioritySwitch;
|
||||
UINT32 highTaskSwitch;
|
||||
UINT32 contexSwitch;
|
||||
UINT32 hwiNum;
|
||||
UINT32 ipiIrqNum;
|
||||
} MpStatPercpu;
|
||||
|
||||
STATIC BOOL g_mpStaticStartFlag = FALSE;
|
||||
STATIC UINT64 g_mpStaticStartTime;
|
||||
STATIC MpStatPercpu g_mpStatPercpu[LOSCFG_KERNEL_SMP_CORE_NUM] = {0};
|
||||
|
||||
STATIC VOID OsMpSchedStatistics(LosTaskCB *runTask, LosTaskCB *newTask)
|
||||
{
|
||||
UINT32 cpuid;
|
||||
UINT32 idleTaskID;
|
||||
UINT64 now, runtime;
|
||||
|
||||
if (g_mpStaticStartFlag != TRUE) {
|
||||
return;
|
||||
}
|
||||
|
||||
cpuid = ArchCurrCpuid();
|
||||
idleTaskID = OsGetIdleTaskId();
|
||||
now = LOS_CurrNanosec();
|
||||
|
||||
g_mpStatPercpu[cpuid].contexSwitch++;
|
||||
|
||||
if ((runTask->taskID != idleTaskID) && (newTask->taskID == idleTaskID)) {
|
||||
g_mpStatPercpu[cpuid].idleStarttime = now;
|
||||
}
|
||||
|
||||
if ((runTask->taskID == idleTaskID) && (newTask->taskID != idleTaskID)) {
|
||||
runtime = now - g_mpStatPercpu[cpuid].idleStarttime;
|
||||
g_mpStatPercpu[cpuid].idleRuntime += runtime;
|
||||
g_mpStatPercpu[cpuid].idleStarttime = 0;
|
||||
}
|
||||
|
||||
if ((runTask->priority >= HIGHTASKPRI) && (newTask->priority < HIGHTASKPRI)) {
|
||||
g_mpStatPercpu[cpuid].highTaskStarttime = now;
|
||||
}
|
||||
|
||||
if ((runTask->priority < HIGHTASKPRI) && (newTask->priority >= HIGHTASKPRI)) {
|
||||
runtime = now - g_mpStatPercpu[cpuid].highTaskStarttime;
|
||||
g_mpStatPercpu[cpuid].highTaskRuntime += runtime;
|
||||
g_mpStatPercpu[cpuid].highTaskStarttime = 0;
|
||||
}
|
||||
|
||||
if (newTask->priority < HIGHTASKPRI) {
|
||||
g_mpStatPercpu[cpuid].highTaskSwitch++;
|
||||
}
|
||||
|
||||
if (newTask->taskID != idleTaskID) {
|
||||
g_mpStatPercpu[cpuid].sumPriority += newTask->priority;
|
||||
g_mpStatPercpu[cpuid].prioritySwitch++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsSchedStatistics(LosTaskCB *runTask, LosTaskCB *newTask)
|
||||
{
|
||||
UINT64 runtime;
|
||||
UINT32 cpuid = ArchCurrCpuid();
|
||||
UINT64 now = LOS_CurrNanosec();
|
||||
|
||||
SchedStat *schedRun = &runTask->schedStat;
|
||||
SchedStat *schedNew = &newTask->schedStat;
|
||||
SchedPercpu *cpuRun = &schedRun->schedPercpu[cpuid];
|
||||
SchedPercpu *cpuNew = &schedNew->schedPercpu[cpuid];
|
||||
|
||||
/* calculate one chance of running time */
|
||||
runtime = now - schedRun->startRuntime;
|
||||
|
||||
/* add running timer to running task statistics */
|
||||
cpuRun->runtime += runtime;
|
||||
schedRun->allRuntime += runtime;
|
||||
|
||||
/* add context switch counters and schedule start time */
|
||||
cpuNew->contexSwitch++;
|
||||
schedNew->allContextSwitch++;
|
||||
schedNew->startRuntime = now;
|
||||
OsMpSchedStatistics(runTask, newTask);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsSpinWaitStatistics(UINT64 spinWaitRuntime)
|
||||
{
|
||||
UINT32 cpuid = ArchCurrCpuid();
|
||||
g_mpStatPercpu[cpuid].spinWaitRuntime += spinWaitRuntime;
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsHwiStatistics(size_t intNum)
|
||||
{
|
||||
UINT32 cpuid = ArchCurrCpuid();
|
||||
|
||||
if ((g_mpStaticStartFlag != TRUE) || (intNum == OS_TICK_INT_NUM)) {
|
||||
return;
|
||||
}
|
||||
|
||||
g_mpStatPercpu[cpuid].hwiNum++;
|
||||
/* 16: 0~15 is ipi interrupts */
|
||||
if (intNum < 16) {
|
||||
g_mpStatPercpu[cpuid].ipiIrqNum++;
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdDumpSched(VOID)
|
||||
{
|
||||
LosTaskCB *taskCB = NULL;
|
||||
UINT32 loop;
|
||||
UINT32 cpuid;
|
||||
UINT32 affinity;
|
||||
|
||||
PRINTK("\n");
|
||||
PRINTK("Task TID Total Time Total CST "
|
||||
"CPU Time CST\n");
|
||||
PRINTK("---- --- ------------------ ---------- -"
|
||||
"--- ------------------ ----------\n");
|
||||
|
||||
for (loop = 0; loop < g_taskMaxNum; loop++) {
|
||||
taskCB = (((LosTaskCB *)g_taskCBArray) + loop);
|
||||
if (OsTaskIsUnused(taskCB)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
affinity = (UINT32)taskCB->cpuAffiMask;
|
||||
|
||||
PRINTK("%-30s0x%-6x%+16lf ms %10d\n", taskCB->taskName, taskCB->taskID,
|
||||
(DOUBLE)(taskCB->schedStat.allRuntime) / NS_PER_MS,
|
||||
taskCB->schedStat.allContextSwitch);
|
||||
|
||||
for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
|
||||
if (!((1U << cpuid) & affinity)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
PRINTK(" "
|
||||
"CPU%d %+16lf ms %12d\n", cpuid,
|
||||
(DOUBLE)(taskCB->schedStat.schedPercpu[cpuid].runtime) / NS_PER_MS,
|
||||
taskCB->schedStat.schedPercpu[cpuid].contexSwitch);
|
||||
}
|
||||
}
|
||||
|
||||
PRINTK("\n");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsShellMpStaticStart(VOID)
|
||||
{
|
||||
LosTaskCB *taskCB = NULL;
|
||||
UINT32 loop;
|
||||
UINT32 cpuid = 0;
|
||||
UINT32 intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
if (g_mpStaticStartFlag) {
|
||||
PRINT_WARN("mp static has started\n");
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
g_mpStaticStartTime = LOS_CurrNanosec();
|
||||
|
||||
for (loop = 0; loop < g_taskMaxNum; loop++) {
|
||||
taskCB = (((LosTaskCB *)g_taskCBArray) + loop);
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
cpuid = taskCB->currCpu;
|
||||
#endif
|
||||
if ((UINT32)(OS_TASK_INVALID_CPUID) == cpuid) {
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(taskCB->taskName, "Idle")) {
|
||||
g_mpStatPercpu[cpuid].idleStarttime = g_mpStaticStartTime;
|
||||
}
|
||||
if (taskCB->priority < HIGHTASKPRI) {
|
||||
g_mpStatPercpu[cpuid].highTaskStarttime = g_mpStaticStartTime;
|
||||
g_mpStatPercpu[cpuid].highTaskSwitch++;
|
||||
}
|
||||
if (strcmp(taskCB->taskName, "Idle")) {
|
||||
g_mpStatPercpu[cpuid].sumPriority += taskCB->priority;
|
||||
g_mpStatPercpu[cpuid].prioritySwitch++;
|
||||
}
|
||||
}
|
||||
}
|
||||
g_mpStaticStartFlag = TRUE;
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
|
||||
PRINTK("mp static start\n");
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsMpStaticShow(UINT64 mpStaticPastTime)
|
||||
{
|
||||
UINT32 cpuid;
|
||||
PRINTK("\n");
|
||||
PRINTK("Passed Time: %+16lf ms\n", (DOUBLE)mpStaticPastTime / NS_PER_MS);
|
||||
PRINTK("--------------------------------\n");
|
||||
PRINTK("CPU Idle(%%) schedule noTick Hwi MP Hwi MP Loss(%%) "
|
||||
"avg PRI HiTSK(%%) HiTSK SCH HiTSK P(ms)\n");
|
||||
PRINTK("---- --------- ---------- ---------- ---------- ---------- "
|
||||
"---------- ---------- ---------- ----------\n");
|
||||
|
||||
for (cpuid = 0; cpuid < LOSCFG_KERNEL_CORE_NUM; cpuid++) {
|
||||
PRINTK("CPU%d %+10lf%14d%14d%14d %+11lf %+11lf %+11lf%14d %+11lf\n", cpuid,
|
||||
((DOUBLE)(g_mpStatPercpu[cpuid].idleRuntime) / mpStaticPastTime) * DECIMAL_TO_PERCENTAGE,
|
||||
g_mpStatPercpu[cpuid].contexSwitch,
|
||||
g_mpStatPercpu[cpuid].hwiNum,
|
||||
g_mpStatPercpu[cpuid].ipiIrqNum,
|
||||
((DOUBLE)(g_mpStatPercpu[cpuid].spinWaitRuntime) / mpStaticPastTime) * DECIMAL_TO_PERCENTAGE,
|
||||
(g_mpStatPercpu[cpuid].prioritySwitch == 0) ? OS_TASK_PRIORITY_LOWEST :
|
||||
((DOUBLE)(g_mpStatPercpu[cpuid].sumPriority) / (g_mpStatPercpu[cpuid].prioritySwitch)),
|
||||
((DOUBLE)(g_mpStatPercpu[cpuid].highTaskRuntime) / mpStaticPastTime) * DECIMAL_TO_PERCENTAGE,
|
||||
g_mpStatPercpu[cpuid].highTaskSwitch,
|
||||
(g_mpStatPercpu[cpuid].highTaskSwitch == 0) ? 0 :
|
||||
((DOUBLE)(g_mpStatPercpu[cpuid].highTaskRuntime) / (g_mpStatPercpu[cpuid].highTaskSwitch)) / NS_PER_MS);
|
||||
}
|
||||
|
||||
PRINTK("\n");
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OsShellMpStaticStop(VOID)
|
||||
{
|
||||
LosTaskCB *taskCB = NULL;
|
||||
UINT32 loop;
|
||||
UINT32 cpuid = 0;
|
||||
UINT64 mpStaticStopTime;
|
||||
UINT64 mpStaticPastTime;
|
||||
UINT64 runtime;
|
||||
UINT32 intSave;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
if (g_mpStaticStartFlag != TRUE) {
|
||||
PRINT_WARN("Please set mp static start\n");
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
g_mpStaticStartFlag = FALSE;
|
||||
mpStaticStopTime = LOS_CurrNanosec();
|
||||
mpStaticPastTime = mpStaticStopTime - g_mpStaticStartTime;
|
||||
|
||||
for (loop = 0; loop < g_taskMaxNum; loop++) {
|
||||
taskCB = (((LosTaskCB *)g_taskCBArray) + loop);
|
||||
if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) {
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
cpuid = taskCB->currCpu;
|
||||
#endif
|
||||
if (cpuid == (UINT32)(OS_TASK_INVALID_CPUID)) {
|
||||
continue;
|
||||
}
|
||||
if (!strcmp(taskCB->taskName, "Idle")) {
|
||||
runtime = mpStaticStopTime - g_mpStatPercpu[cpuid].idleStarttime;
|
||||
g_mpStatPercpu[cpuid].idleRuntime += runtime;
|
||||
g_mpStatPercpu[cpuid].idleStarttime = 0;
|
||||
}
|
||||
if (taskCB->priority < HIGHTASKPRI) {
|
||||
runtime = mpStaticStopTime - g_mpStatPercpu[cpuid].highTaskStarttime;
|
||||
g_mpStatPercpu[cpuid].highTaskRuntime += runtime;
|
||||
g_mpStatPercpu[cpuid].highTaskStarttime = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
OsMpStaticShow(mpStaticPastTime);
|
||||
|
||||
(VOID)memset_s(g_mpStatPercpu, sizeof(g_mpStatPercpu), 0, sizeof(g_mpStatPercpu));
|
||||
g_mpStaticStartTime = 0;
|
||||
return;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
61
kernel/base/om/los_err.c
Executable file
61
kernel/base/om/los_err.c
Executable file
@@ -0,0 +1,61 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_err.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_BSS STATIC LOS_ERRORHANDLE_FUNC g_errHandleHook = NULL;
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT UINT32 LOS_ErrHandle(CHAR *fileName, UINT32 lineNo, UINT32 errorNo,
|
||||
UINT32 paraLen, VOID *para)
|
||||
{
|
||||
if (g_errHandleHook != NULL) {
|
||||
g_errHandleHook(fileName, lineNo, errorNo, paraLen, para);
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_INIT VOID LOS_SetErrHandleHook(LOS_ERRORHANDLE_FUNC fun)
|
||||
{
|
||||
g_errHandleHook = fun;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
235
kernel/base/sched/sched_sq/los_priqueue.c
Executable file
235
kernel/base/sched/sched_sq/los_priqueue.c
Executable file
@@ -0,0 +1,235 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_priqueue_pri.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_memory.h"
|
||||
#include "los_toolchain.h"
|
||||
#include "los_spinlock.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define PRIQUEUE_PRIOR0_BIT 0x80000000U
|
||||
|
||||
LITE_OS_SEC_BSS LOS_DL_LIST *g_priQueueList = NULL;
|
||||
LITE_OS_SEC_BSS UINT32 g_priQueueBitmap;
|
||||
|
||||
UINT32 OsPriQueueInit(VOID)
|
||||
{
|
||||
UINT32 priority;
|
||||
|
||||
/* system resident resource */
|
||||
g_priQueueList = (LOS_DL_LIST *)LOS_MemAlloc(m_aucSysMem0, (OS_PRIORITY_QUEUE_NUM * sizeof(LOS_DL_LIST)));
|
||||
if (g_priQueueList == NULL) {
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
for (priority = 0; priority < OS_PRIORITY_QUEUE_NUM; ++priority) {
|
||||
LOS_ListInit(&g_priQueueList[priority]);
|
||||
}
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LOS_DL_LIST *OsPriQueueTop(LOS_DL_LIST *priQueueList, UINT32 *bitMap)
|
||||
{
|
||||
UINT32 priority;
|
||||
|
||||
if (*bitMap != 0) {
|
||||
priority = CLZ(*bitMap);
|
||||
return LOS_DL_LIST_FIRST(&priQueueList[priority]);
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID OsPriQueueEnqueueHead(LOS_DL_LIST *priQueueList, UINT32 *bitMap, LOS_DL_LIST *priqueueItem, UINT32 priority)
|
||||
{
|
||||
/*
|
||||
* Task control blocks are inited as zero. And when task is deleted,
|
||||
* and at the same time would be deleted from priority queue or
|
||||
* other lists, task pend node will restored as zero.
|
||||
*/
|
||||
LOS_ASSERT(priqueueItem->pstNext == NULL);
|
||||
|
||||
if (LOS_ListEmpty(&priQueueList[priority])) {
|
||||
*bitMap |= PRIQUEUE_PRIOR0_BIT >> priority;
|
||||
}
|
||||
|
||||
LOS_ListHeadInsert(&priQueueList[priority], priqueueItem);
|
||||
}
|
||||
|
||||
VOID OsPriQueueEnqueue(LOS_DL_LIST *priQueueList, UINT32 *bitMap, LOS_DL_LIST *priqueueItem, UINT32 priority)
|
||||
{
|
||||
/*
|
||||
* Task control blocks are inited as zero. And when task is deleted,
|
||||
* and at the same time would be deleted from priority queue or
|
||||
* other lists, task pend node will restored as zero.
|
||||
*/
|
||||
LOS_ASSERT(priqueueItem->pstNext == NULL);
|
||||
|
||||
if (LOS_ListEmpty(&priQueueList[priority])) {
|
||||
*bitMap |= PRIQUEUE_PRIOR0_BIT >> priority;
|
||||
}
|
||||
|
||||
LOS_ListTailInsert(&priQueueList[priority], priqueueItem);
|
||||
}
|
||||
|
||||
VOID OsPriQueueDequeue(LOS_DL_LIST *priQueueList, UINT32 *bitMap, LOS_DL_LIST *priqueueItem)
|
||||
{
|
||||
LosTaskCB *task = NULL;
|
||||
LOS_ListDelete(priqueueItem);
|
||||
|
||||
task = LOS_DL_LIST_ENTRY(priqueueItem, LosTaskCB, pendList);
|
||||
if (LOS_ListEmpty(&priQueueList[task->priority])) {
|
||||
*bitMap &= ~(PRIQUEUE_PRIOR0_BIT >> task->priority);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsPriQueueProcessDequeue(LOS_DL_LIST *priqueueItem)
|
||||
{
|
||||
LosProcessCB *runProcess = NULL;
|
||||
LOS_ListDelete(priqueueItem);
|
||||
|
||||
runProcess = LOS_DL_LIST_ENTRY(priqueueItem, LosProcessCB, pendList);
|
||||
if (LOS_ListEmpty(&g_priQueueList[runProcess->priority])) {
|
||||
g_priQueueBitmap &= ~(PRIQUEUE_PRIOR0_BIT >> runProcess->priority);
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 OsPriQueueProcessSize(LOS_DL_LIST *priQueueList, UINT32 priority)
|
||||
{
|
||||
UINT32 itemCnt = 0;
|
||||
LOS_DL_LIST *curNode = NULL;
|
||||
|
||||
LOS_ASSERT(OsIntLocked());
|
||||
LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));
|
||||
|
||||
LOS_DL_LIST_FOR_EACH(curNode, &priQueueList[priority]) {
|
||||
++itemCnt;
|
||||
}
|
||||
|
||||
return itemCnt;
|
||||
}
|
||||
|
||||
UINT32 OsPriQueueSize(LOS_DL_LIST *priQueueList, UINT32 priority)
|
||||
{
|
||||
UINT32 itemCnt = 0;
|
||||
LOS_DL_LIST *curNode = NULL;
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
LosTaskCB *task = NULL;
|
||||
UINT32 cpuID = ArchCurrCpuid();
|
||||
#endif
|
||||
|
||||
LOS_ASSERT(OsIntLocked());
|
||||
LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));
|
||||
|
||||
LOS_DL_LIST_FOR_EACH(curNode, &priQueueList[priority]) {
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
task = OS_TCB_FROM_PENDLIST(curNode);
|
||||
if (!(task->cpuAffiMask & (1U << cpuID))) {
|
||||
continue;
|
||||
}
|
||||
#endif
|
||||
++itemCnt;
|
||||
}
|
||||
|
||||
return itemCnt;
|
||||
}
|
||||
|
||||
|
||||
LOS_DL_LIST *OsTaskPriQueueTop(VOID)
|
||||
{
|
||||
LosProcessCB *processCB = LOS_DL_LIST_ENTRY(OsPriQueueTop(g_priQueueList, &g_priQueueBitmap),
|
||||
LosProcessCB,
|
||||
pendList);
|
||||
return OsPriQueueTop(processCB->threadPriQueueList, &processCB->threadScheduleMap);
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsDequeEmptySchedMap(LosProcessCB *processCB)
|
||||
{
|
||||
if (processCB->threadScheduleMap == 0) {
|
||||
processCB->processStatus &= ~OS_PROCESS_STATUS_READY;
|
||||
OsPriQueueProcessDequeue(&processCB->pendList);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR LosTaskCB *OsGetTopTask(VOID)
|
||||
{
|
||||
UINT32 priority, processPriority;
|
||||
UINT32 bitmap;
|
||||
UINT32 processBitmap;
|
||||
LosTaskCB *newTask = NULL;
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
UINT32 cpuid = ArchCurrCpuid();
|
||||
#endif
|
||||
LosProcessCB *processCB = NULL;
|
||||
processBitmap = g_priQueueBitmap;
|
||||
while (processBitmap) {
|
||||
processPriority = CLZ(processBitmap);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(processCB, &g_priQueueList[processPriority], LosProcessCB, pendList) {
|
||||
bitmap = processCB->threadScheduleMap;
|
||||
while (bitmap) {
|
||||
priority = CLZ(bitmap);
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(newTask, &processCB->threadPriQueueList[priority], LosTaskCB, pendList) {
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
if (newTask->cpuAffiMask & (1U << cpuid)) {
|
||||
#endif
|
||||
newTask->taskStatus &= ~OS_TASK_STATUS_READY;
|
||||
OsPriQueueDequeue(processCB->threadPriQueueList,
|
||||
&processCB->threadScheduleMap,
|
||||
&newTask->pendList);
|
||||
OsDequeEmptySchedMap(processCB);
|
||||
goto OUT;
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
}
|
||||
#endif
|
||||
}
|
||||
bitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - priority - 1));
|
||||
}
|
||||
}
|
||||
processBitmap &= ~(1U << (OS_PRIORITY_QUEUE_NUM - processPriority - 1));
|
||||
}
|
||||
|
||||
OUT:
|
||||
return newTask;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif /* __cplusplus */
|
||||
|
||||
176
kernel/base/sched/sched_sq/los_sched.c
Executable file
176
kernel/base/sched/sched_sq/los_sched.c
Executable file
@@ -0,0 +1,176 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_base.h"
|
||||
#include "los_task_pri.h"
|
||||
#include "los_percpu_pri.h"
|
||||
#include "los_hw_pri.h"
|
||||
#include "los_arch_mmu.h"
|
||||
#include "los_process_pri.h"
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
#include "los_cpup_pri.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
STATIC VOID OsSchedSwitchProcess(LosProcessCB *runProcess, LosProcessCB *newProcess)
|
||||
{
|
||||
if (runProcess == newProcess) {
|
||||
return;
|
||||
}
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
runProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_DEC(runProcess->processStatus);
|
||||
newProcess->processStatus = OS_PROCESS_RUNTASK_COUNT_ADD(newProcess->processStatus);
|
||||
|
||||
LOS_ASSERT(!(OS_PROCESS_GET_RUNTASK_COUNT(newProcess->processStatus) > LOSCFG_KERNEL_CORE_NUM));
|
||||
if (OS_PROCESS_GET_RUNTASK_COUNT(runProcess->processStatus) == 0) {
|
||||
#endif
|
||||
runProcess->processStatus &= ~OS_PROCESS_STATUS_RUNNING;
|
||||
if ((runProcess->threadNumber > 1) && !(runProcess->processStatus & OS_PROCESS_STATUS_READY)) {
|
||||
runProcess->processStatus |= OS_PROCESS_STATUS_PEND;
|
||||
}
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
}
|
||||
#endif
|
||||
LOS_ASSERT(!(newProcess->processStatus & OS_PROCESS_STATUS_PEND));
|
||||
newProcess->processStatus |= OS_PROCESS_STATUS_RUNNING;
|
||||
|
||||
if (OsProcessIsUserMode(newProcess)) {
|
||||
LOS_ArchMmuContextSwitch(&newProcess->vmSpace->archMmu);
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_KERNEL_CPUP
|
||||
OsProcessCycleEndStart(newProcess->processID, OS_PROCESS_GET_RUNTASK_COUNT(runProcess->processStatus) + 1);
|
||||
#endif /* LOSCFG_KERNEL_CPUP */
|
||||
|
||||
OsCurrProcessSet(newProcess);
|
||||
|
||||
if ((newProcess->timeSlice == 0) && (newProcess->policy == LOS_SCHED_RR)) {
|
||||
newProcess->timeSlice = OS_PROCESS_SCHED_RR_INTERVAL;
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsSchedResched(VOID)
|
||||
{
|
||||
LosTaskCB *runTask = NULL;
|
||||
LosTaskCB *newTask = NULL;
|
||||
LosProcessCB *runProcess = NULL;
|
||||
LosProcessCB *newProcess = NULL;
|
||||
|
||||
LOS_ASSERT(LOS_SpinHeld(&g_taskSpin));
|
||||
|
||||
if (!OsPreemptableInSched()) {
|
||||
return;
|
||||
}
|
||||
|
||||
runTask = OsCurrTaskGet();
|
||||
newTask = OsGetTopTask();
|
||||
|
||||
/* always be able to get one task */
|
||||
LOS_ASSERT(newTask != NULL);
|
||||
|
||||
if (runTask == newTask) {
|
||||
return;
|
||||
}
|
||||
|
||||
runTask->taskStatus &= ~OS_TASK_STATUS_RUNNING;
|
||||
newTask->taskStatus |= OS_TASK_STATUS_RUNNING;
|
||||
|
||||
runProcess = OS_PCB_FROM_PID(runTask->processID);
|
||||
newProcess = OS_PCB_FROM_PID(newTask->processID);
|
||||
|
||||
OsSchedSwitchProcess(runProcess, newProcess);
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP == YES)
|
||||
/* mask new running task's owner processor */
|
||||
runTask->currCpu = OS_TASK_INVALID_CPUID;
|
||||
newTask->currCpu = ArchCurrCpuid();
|
||||
#endif
|
||||
|
||||
(VOID)OsTaskSwitchCheck(runTask, newTask);
|
||||
|
||||
#if (LOSCFG_KERNEL_SCHED_STATISTICS == YES)
|
||||
OsSchedStatistics(runTask, newTask);
|
||||
#endif
|
||||
|
||||
if ((newTask->timeSlice == 0) && (newTask->policy == LOS_SCHED_RR)) {
|
||||
newTask->timeSlice = LOSCFG_BASE_CORE_TIMESLICE_TIMEOUT;
|
||||
}
|
||||
|
||||
OsCurrTaskSet((VOID*)newTask);
|
||||
|
||||
if (OsProcessIsUserMode(newProcess)) {
|
||||
OsCurrUserTaskSet(newTask->userArea);
|
||||
}
|
||||
|
||||
PRINT_TRACE("cpu%d run process name: (%s) pid: %d status: %x threadMap: %x task name: (%s) tid: %d status: %x ->\n"
|
||||
" new process name: (%s) pid: %d status: %x threadMap: %x task name: (%s) tid: %d status: %x!\n",
|
||||
ArchCurrCpuid(),
|
||||
runProcess->processName, runProcess->processID, runProcess->processStatus,
|
||||
runProcess->threadScheduleMap, runTask->taskName, runTask->taskID, runTask->taskStatus,
|
||||
newProcess->processName, newProcess->processID, newProcess->processStatus,
|
||||
newProcess->threadScheduleMap, newTask->taskName, newTask->taskID, newTask->taskStatus);
|
||||
|
||||
/* do the task context switch */
|
||||
OsTaskSchedule(newTask, runTask);
|
||||
}
|
||||
|
||||
VOID OsSchedPreempt(VOID)
|
||||
{
|
||||
LosTaskCB *runTask = NULL;
|
||||
UINT32 intSave;
|
||||
|
||||
if (!OsPreemptable()) {
|
||||
return;
|
||||
}
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
|
||||
/* add run task back to ready queue */
|
||||
runTask = OsCurrTaskGet();
|
||||
OS_TASK_SCHED_QUEUE_ENQUEUE(runTask, 0);
|
||||
|
||||
/* reschedule to new thread */
|
||||
OsSchedResched();
|
||||
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
102
kernel/base/vm/los_vm_boot.c
Executable file
102
kernel/base/vm/los_vm_boot.c
Executable file
@@ -0,0 +1,102 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_vm_boot.h"
|
||||
#include "los_config.h"
|
||||
#include "los_base.h"
|
||||
#include "los_vm_zone.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_memory_pri.h"
|
||||
#include "los_vm_page.h"
|
||||
#include "los_arch_mmu.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
UINTPTR g_vmBootMemBase = (UINTPTR)&__bss_end;
|
||||
BOOL g_kHeapInited = FALSE;
|
||||
|
||||
UINT32 OsVmAddrCheck(size_t tempAddr, size_t length)
|
||||
{
|
||||
if ((tempAddr >= KERNEL_VMM_BASE) && ((tempAddr + length) <= (PERIPH_UNCACHED_BASE + PERIPH_UNCACHED_SIZE))) {
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
VOID *OsVmBootMemAlloc(size_t len)
|
||||
{
|
||||
UINTPTR ptr;
|
||||
|
||||
if (g_kHeapInited) {
|
||||
VM_ERR("kernel heap has been inited, should not to use boot mem alloc!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
ptr = LOS_Align(g_vmBootMemBase, sizeof(UINTPTR));
|
||||
g_vmBootMemBase = ptr + LOS_Align(len, sizeof(UINTPTR));
|
||||
|
||||
return (VOID *)ptr;
|
||||
}
|
||||
|
||||
UINT32 OsSysMemInit(VOID)
|
||||
{
|
||||
STATUS_T ret;
|
||||
|
||||
OsKSpaceInit();
|
||||
|
||||
ret = OsKHeapInit(OS_KHEAP_BLOCK_SIZE);
|
||||
if (ret != LOS_OK) {
|
||||
VM_ERR("OsKHeapInit fail");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
OsVmPageStartup();
|
||||
OsInitMappingStartUp();
|
||||
|
||||
ret = ShmInit();
|
||||
if (ret < 0) {
|
||||
VM_ERR("ShmInit fail");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
545
kernel/base/vm/los_vm_dump.c
Executable file
545
kernel/base/vm/los_vm_dump.c
Executable file
@@ -0,0 +1,545 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_dump virtual memory dump operation
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#include "los_vm_dump.h"
|
||||
#include "los_mmu_descriptor_v6.h"
|
||||
#include "fs/fs.h"
|
||||
#include "los_printf.h"
|
||||
#include "los_vm_page.h"
|
||||
#include "los_vm_phys.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "los_atomic.h"
|
||||
#include "los_vm_lock.h"
|
||||
#include "los_memory_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define FLAG_SIZE 4
|
||||
#define FLAG_START 2
|
||||
|
||||
const CHAR *OsGetRegionNameOrFilePath(LosVmMapRegion *region)
|
||||
{
|
||||
struct file *filep = NULL;
|
||||
if (region == NULL) {
|
||||
return "";
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
} else if (LOS_IsRegionFileValid(region)) {
|
||||
filep = region->unTypeData.rf.file;
|
||||
return filep->f_path;
|
||||
#endif
|
||||
} else if (region->regionFlags & VM_MAP_REGION_FLAG_HEAP) {
|
||||
return "HEAP";
|
||||
} else if (region->regionFlags & VM_MAP_REGION_FLAG_STACK) {
|
||||
return "STACK";
|
||||
} else if (region->regionFlags & VM_MAP_REGION_FLAG_TEXT) {
|
||||
return "Text";
|
||||
} else if (region->regionFlags & VM_MAP_REGION_FLAG_VDSO) {
|
||||
return "VDSO";
|
||||
} else if (region->regionFlags & VM_MAP_REGION_FLAG_MMAP) {
|
||||
return "MMAP";
|
||||
} else if (region->regionFlags & VM_MAP_REGION_FLAG_SHM) {
|
||||
return "SHM";
|
||||
} else {
|
||||
return "";
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
INT32 OsRegionOverlapCheckUnlock(LosVmSpace *space, LosVmMapRegion *region)
|
||||
{
|
||||
LosVmMapRegion *regionTemp = NULL;
|
||||
LosRbNode *pstRbNode = NULL;
|
||||
LosRbNode *pstRbNodeNext = NULL;
|
||||
|
||||
/* search the region list */
|
||||
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
regionTemp = (LosVmMapRegion *)pstRbNode;
|
||||
if (region->range.base == regionTemp->range.base && region->range.size == regionTemp->range.size) {
|
||||
continue;
|
||||
}
|
||||
if (((region->range.base + region->range.size) > regionTemp->range.base) &&
|
||||
(region->range.base < (regionTemp->range.base + regionTemp->range.size))) {
|
||||
VM_ERR("overlap between regions:\n"
|
||||
"flals:%#x base:%p size:%08x space:%p\n"
|
||||
"flags:%#x base:%p size:%08x space:%p",
|
||||
region->regionFlags, region->range.base, region->range.size, region->space,
|
||||
regionTemp->regionFlags, regionTemp->range.base, regionTemp->range.size, regionTemp->space);
|
||||
return -1;
|
||||
}
|
||||
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
UINT32 OsShellCmdProcessVmUsage(LosVmSpace *space)
|
||||
{
|
||||
LosVmMapRegion *region = NULL;
|
||||
LosRbNode *pstRbNode = NULL;
|
||||
LosRbNode *pstRbNodeNext = NULL;
|
||||
UINT32 used = 0;
|
||||
|
||||
if (space == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (space == LOS_GetKVmSpace()) {
|
||||
OsShellCmdProcessPmUsage(space, NULL, &used);
|
||||
} else {
|
||||
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
region = (LosVmMapRegion *)pstRbNode;
|
||||
used += region->range.size;
|
||||
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
}
|
||||
|
||||
return used;
|
||||
}
|
||||
|
||||
VOID OsKProcessPmUsage(LosVmSpace *kSpace, UINT32 *actualPm)
|
||||
{
|
||||
UINT32 memUsed;
|
||||
UINT32 totalMem;
|
||||
UINT32 freeMem;
|
||||
UINT32 usedCount = 0;
|
||||
UINT32 totalCount = 0;
|
||||
LosVmSpace *space = NULL;
|
||||
LOS_DL_LIST *spaceList = NULL;
|
||||
UINT32 UProcessUsed = 0;
|
||||
UINT32 pmTmp;
|
||||
|
||||
if (actualPm == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
memUsed = LOS_MemTotalUsedGet(m_aucSysMem1);
|
||||
totalMem = LOS_MemPoolSizeGet(m_aucSysMem1);
|
||||
freeMem = totalMem - memUsed;
|
||||
|
||||
OsVmPhysUsedInfoGet(&usedCount, &totalCount);
|
||||
/* Kernel resident memory, include default heap memory */
|
||||
memUsed = SYS_MEM_SIZE_DEFAULT - (totalCount << PAGE_SHIFT);
|
||||
|
||||
spaceList = LOS_GetVmSpaceList();
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(space, spaceList, LosVmSpace, node) {
|
||||
if (space == LOS_GetKVmSpace()) {
|
||||
continue;
|
||||
}
|
||||
OsUProcessPmUsage(space, NULL, &pmTmp);
|
||||
UProcessUsed += pmTmp;
|
||||
}
|
||||
|
||||
/* Kernel dynamic memory, include extended heap memory */
|
||||
memUsed += ((usedCount << PAGE_SHIFT) - UProcessUsed);
|
||||
/* Remaining heap memory */
|
||||
memUsed -= freeMem;
|
||||
|
||||
*actualPm = memUsed;
|
||||
}
|
||||
|
||||
VOID OsShellCmdProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
|
||||
{
|
||||
if (space == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ((sharePm == NULL) && (actualPm == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (space == LOS_GetKVmSpace()) {
|
||||
OsKProcessPmUsage(space, actualPm);
|
||||
} else {
|
||||
OsUProcessPmUsage(space, sharePm, actualPm);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsUProcessPmUsage(LosVmSpace *space, UINT32 *sharePm, UINT32 *actualPm)
|
||||
{
|
||||
LosVmMapRegion *region = NULL;
|
||||
LosRbNode *pstRbNode = NULL;
|
||||
LosRbNode *pstRbNodeNext = NULL;
|
||||
LosVmPage *page = NULL;
|
||||
VADDR_T vaddr;
|
||||
size_t size;
|
||||
PADDR_T paddr;
|
||||
STATUS_T ret;
|
||||
INT32 shareRef;
|
||||
|
||||
if (sharePm != NULL) {
|
||||
*sharePm = 0;
|
||||
}
|
||||
|
||||
if (actualPm != NULL) {
|
||||
*actualPm = 0;
|
||||
}
|
||||
|
||||
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
region = (LosVmMapRegion *)pstRbNode;
|
||||
vaddr = region->range.base;
|
||||
size = region->range.size;
|
||||
for (; size > 0; vaddr += PAGE_SIZE, size -= PAGE_SIZE) {
|
||||
ret = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL);
|
||||
if (ret < 0) {
|
||||
continue;
|
||||
}
|
||||
page = LOS_VmPageGet(paddr);
|
||||
if (page == NULL) {
|
||||
continue;
|
||||
}
|
||||
|
||||
shareRef = LOS_AtomicRead(&page->refCounts);
|
||||
if (shareRef > 1) {
|
||||
if (sharePm != NULL) {
|
||||
*sharePm += PAGE_SIZE;
|
||||
}
|
||||
if (actualPm != NULL) {
|
||||
*actualPm += PAGE_SIZE / shareRef;
|
||||
}
|
||||
} else {
|
||||
if (actualPm != NULL) {
|
||||
*actualPm += PAGE_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
RB_SCAN_SAFE_END(&oldVmSpace->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
}
|
||||
|
||||
LosProcessCB *OsGetPIDByAspace(LosVmSpace *space)
|
||||
{
|
||||
UINT32 pid;
|
||||
UINT32 intSave;
|
||||
LosProcessCB *processCB = NULL;
|
||||
|
||||
SCHEDULER_LOCK(intSave);
|
||||
for (pid = 0; pid < g_processMaxNum; ++pid) {
|
||||
processCB = g_processCBArray + pid;
|
||||
if (OsProcessIsUnused(processCB)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (processCB->vmSpace == space) {
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return processCB;
|
||||
}
|
||||
}
|
||||
SCHEDULER_UNLOCK(intSave);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
UINT32 OsCountRegionPages(LosVmSpace *space, LosVmMapRegion *region, UINT32 *pssPages)
|
||||
{
|
||||
UINT32 regionPages = 0;
|
||||
PADDR_T paddr;
|
||||
VADDR_T vaddr;
|
||||
UINT32 ref;
|
||||
STATUS_T status;
|
||||
float pss = 0;
|
||||
LosVmPage *page = NULL;
|
||||
|
||||
for (vaddr = region->range.base; vaddr < region->range.base + region->range.size; vaddr = vaddr + PAGE_SIZE) {
|
||||
status = LOS_ArchMmuQuery(&space->archMmu, vaddr, &paddr, NULL);
|
||||
if (status == LOS_OK) {
|
||||
regionPages++;
|
||||
if (pssPages == NULL) {
|
||||
continue;
|
||||
}
|
||||
page = LOS_VmPageGet(paddr);
|
||||
if (page != NULL) {
|
||||
ref = LOS_AtomicRead(&page->refCounts);
|
||||
pss += ((ref > 0) ? (1.0 / ref) : 1);
|
||||
} else {
|
||||
pss += 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (pssPages != NULL) {
|
||||
*pssPages = (UINT32)(pss + 0.5);
|
||||
}
|
||||
|
||||
return regionPages;
|
||||
}
|
||||
|
||||
UINT32 OsCountAspacePages(LosVmSpace *space)
|
||||
{
|
||||
UINT32 spacePages = 0;
|
||||
LosVmMapRegion *region = NULL;
|
||||
LosRbNode *pstRbNode = NULL;
|
||||
LosRbNode *pstRbNodeNext = NULL;
|
||||
|
||||
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
region = (LosVmMapRegion *)pstRbNode;
|
||||
spacePages += OsCountRegionPages(space, region, NULL);
|
||||
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
return spacePages;
|
||||
}
|
||||
|
||||
CHAR *OsArchFlagsToStr(const UINT32 archFlags)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 cacheFlags = archFlags & VM_MAP_REGION_FLAG_CACHE_MASK;
|
||||
UINT32 flagSize = FLAG_SIZE * BITMAP_BITS_PER_WORD * sizeof(CHAR);
|
||||
CHAR *archMmuFlagsStr = (CHAR *)LOS_MemAlloc(m_aucSysMem0, flagSize);
|
||||
if (archMmuFlagsStr == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
(VOID)memset_s(archMmuFlagsStr, flagSize, 0, flagSize);
|
||||
switch (cacheFlags) {
|
||||
case 0UL:
|
||||
strcat_s(archMmuFlagsStr, flagSize, " CH\0");
|
||||
break;
|
||||
case 1UL:
|
||||
strcat_s(archMmuFlagsStr, flagSize, " UC\0");
|
||||
break;
|
||||
case 2UL:
|
||||
strcat_s(archMmuFlagsStr, flagSize, " UD\0");
|
||||
break;
|
||||
case 3UL:
|
||||
strcat_s(archMmuFlagsStr, flagSize, " WC\0");
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
static const CHAR FLAGS[BITMAP_BITS_PER_WORD][FLAG_SIZE] = {
|
||||
[0 ... (__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_USER) - 2)] = "???\0",
|
||||
[__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_USER) - 1] = " US\0",
|
||||
[__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_READ) - 1] = " RD\0",
|
||||
[__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_WRITE) - 1] = " WR\0",
|
||||
[__builtin_ffsl(VM_MAP_REGION_FLAG_PERM_EXECUTE) - 1] = " EX\0",
|
||||
[__builtin_ffsl(VM_MAP_REGION_FLAG_NS) - 1] = " NS\0",
|
||||
[__builtin_ffsl(VM_MAP_REGION_FLAG_INVALID) - 1] = " IN\0",
|
||||
[__builtin_ffsl(VM_MAP_REGION_FLAG_INVALID) ... (BITMAP_BITS_PER_WORD - 1)] = "???\0",
|
||||
};
|
||||
|
||||
for (index = FLAG_START; index < BITMAP_BITS_PER_WORD; index++) {
|
||||
if (FLAGS[index][0] == '?') {
|
||||
continue;
|
||||
}
|
||||
|
||||
if (archFlags & (1UL << index)) {
|
||||
UINT32 status = strcat_s(archMmuFlagsStr, flagSize, FLAGS[index]);
|
||||
if (status != 0) {
|
||||
PRINTK("error\n");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return archMmuFlagsStr;
|
||||
}
|
||||
|
||||
VOID OsDumpRegion2(LosVmSpace *space, LosVmMapRegion *region)
|
||||
{
|
||||
UINT32 pssPages = 0;
|
||||
UINT32 regionPages;
|
||||
|
||||
regionPages = OsCountRegionPages(space, region, &pssPages);
|
||||
CHAR *flagsStr = OsArchFlagsToStr(region->regionFlags);
|
||||
if (flagsStr == NULL) {
|
||||
return;
|
||||
}
|
||||
PRINTK("\t %#010x %-32.32s %#010x %#010x %-15.15s %4d %4d\n",
|
||||
region, OsGetRegionNameOrFilePath(region), region->range.base,
|
||||
region->range.size, flagsStr, regionPages, pssPages);
|
||||
(VOID)LOS_MemFree(m_aucSysMem0, flagsStr);
|
||||
}
|
||||
|
||||
VOID OsDumpAspace(LosVmSpace *space)
|
||||
{
|
||||
LosVmMapRegion *region = NULL;
|
||||
LosRbNode *pstRbNode = NULL;
|
||||
LosRbNode *pstRbNodeNext = NULL;
|
||||
UINT32 spacePages;
|
||||
LosProcessCB *pcb = OsGetPIDByAspace(space);
|
||||
|
||||
if (pcb == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
spacePages = OsCountAspacePages(space);
|
||||
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);
|
||||
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 = (LosVmMapRegion *)pstRbNode;
|
||||
if (region != NULL) {
|
||||
OsDumpRegion2(space, region);
|
||||
(VOID)OsRegionOverlapCheck(space, region);
|
||||
} else {
|
||||
PRINTK("region is NULL\n");
|
||||
}
|
||||
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeNext)
|
||||
return;
|
||||
}
|
||||
|
||||
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)LOS_MuxRelease(&space->regionMux);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
STATUS_T OsRegionOverlapCheck(LosVmSpace *space, LosVmMapRegion *region)
|
||||
{
|
||||
int ret;
|
||||
|
||||
if (space == NULL || region == NULL) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
ret = OsRegionOverlapCheckUnlock(space, region);
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID OsDumpPte(VADDR_T vaddr)
|
||||
{
|
||||
UINT32 l1Index = vaddr >> MMU_DESCRIPTOR_L1_SMALL_SHIFT;
|
||||
LosVmSpace *space = LOS_SpaceGet(vaddr);
|
||||
UINT32 ttEntry;
|
||||
LosVmPage *page = NULL;
|
||||
PTE_T *l2Table = NULL;
|
||||
UINT32 l2Index;
|
||||
|
||||
if (space == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
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));
|
||||
if (page == NULL) {
|
||||
goto ERR;
|
||||
}
|
||||
PRINTK("vaddr %p, l1Index %d, ttEntry %p, l2Table %p, l2Index %d, pfn %p count %d\n",
|
||||
vaddr, l1Index, ttEntry, l2Table, l2Index, l2Table[l2Index], LOS_AtomicRead(&page->refCounts));
|
||||
} else {
|
||||
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);
|
||||
}
|
||||
|
||||
UINT32 OsVmPhySegPagesGet(LosVmPhysSeg *seg)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 flindex;
|
||||
UINT32 segFreePages = 0;
|
||||
|
||||
LOS_SpinLockSave(&seg->freeListLock, &intSave);
|
||||
for (flindex = 0; flindex < VM_LIST_ORDER_MAX; flindex++) {
|
||||
segFreePages += ((1 << flindex) * seg->freeList[flindex].listCnt);
|
||||
}
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
|
||||
return segFreePages;
|
||||
}
|
||||
|
||||
VOID OsVmPhysDump(VOID)
|
||||
{
|
||||
LosVmPhysSeg *seg = NULL;
|
||||
UINT32 segFreePages;
|
||||
UINT32 totalFreePages = 0;
|
||||
UINT32 totalPages = 0;
|
||||
UINT32 segIndex;
|
||||
|
||||
for (segIndex = 0; segIndex < g_vmPhysSegNum; segIndex++) {
|
||||
seg = &g_vmPhysSeg[segIndex];
|
||||
if (seg->size > 0) {
|
||||
segFreePages = OsVmPhySegPagesGet(seg);
|
||||
#ifdef LOSCFG_SHELL_CMD_DEBUG
|
||||
PRINTK("\r\n phys_seg base size free_pages \n");
|
||||
PRINTK(" -------- ------- ---------- --------- \n");
|
||||
#endif
|
||||
PRINTK(" %08p %08p 0x%08x %8u \n", seg, seg->start, seg->size, segFreePages);
|
||||
totalFreePages += segFreePages;
|
||||
totalPages += (seg->size >> PAGE_SHIFT);
|
||||
|
||||
PRINTK("active anon %d\n", seg->lruSize[VM_LRU_ACTIVE_ANON]);
|
||||
PRINTK("inactive anon %d\n", seg->lruSize[VM_LRU_INACTIVE_ANON]);
|
||||
PRINTK("active file %d\n", seg->lruSize[VM_LRU_ACTIVE_FILE]);
|
||||
PRINTK("inactice file %d\n", seg->lruSize[VM_LRU_INACTIVE_FILE]);
|
||||
}
|
||||
}
|
||||
PRINTK("\n\rpmm pages: total = %u, used = %u, free = %u\n",
|
||||
totalPages, (totalPages - totalFreePages), totalFreePages);
|
||||
}
|
||||
|
||||
VOID OsVmPhysUsedInfoGet(UINT32 *usedCount, UINT32 *totalCount)
|
||||
{
|
||||
UINT32 index;
|
||||
UINT32 segFreePages;
|
||||
LosVmPhysSeg *physSeg = NULL;
|
||||
|
||||
if (usedCount == NULL || totalCount == NULL) {
|
||||
return;
|
||||
}
|
||||
*usedCount = 0;
|
||||
*totalCount = 0;
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
468
kernel/base/vm/los_vm_fault.c
Executable file
468
kernel/base/vm/los_vm_fault.c
Executable file
@@ -0,0 +1,468 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_fault vm fault definition
|
||||
* @ingroup kernel
|
||||
*/
|
||||
#include "los_vm_fault.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_vm_dump.h"
|
||||
#include "los_vm_filemap.h"
|
||||
#include "los_vm_page.h"
|
||||
#include "los_vm_lock.h"
|
||||
#include "los_exc.h"
|
||||
#include "los_oom.h"
|
||||
#include "los_printf.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "arm.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
extern char __exc_table_start[];
|
||||
extern char __exc_table_end[];
|
||||
|
||||
STATIC STATUS_T OsVmRegionRightCheck(LosVmMapRegion *region, UINT32 flags)
|
||||
{
|
||||
if ((flags & VM_MAP_PF_FLAG_WRITE) == VM_MAP_PF_FLAG_WRITE) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
if ((flags & VM_MAP_PF_FLAG_INSTRUCTION) == VM_MAP_PF_FLAG_INSTRUCTION) {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATIC VOID OsFaultTryFixup(ExcContext *frame, VADDR_T excVaddr, STATUS_T *status)
|
||||
{
|
||||
INT32 tableNum = (__exc_table_end - __exc_table_start) / sizeof(LosExcTable);
|
||||
LosExcTable *excTable = (LosExcTable *)__exc_table_start;
|
||||
#ifdef LOSCFG_DEBUG_VERSION
|
||||
LosVmSpace *space = NULL;
|
||||
VADDR_T vaddr;
|
||||
#endif
|
||||
|
||||
if ((frame->regCPSR & CPSR_MODE_MASK) != CPSR_MODE_USR) {
|
||||
for (int i = 0; i < tableNum; ++i, ++excTable) {
|
||||
if (frame->PC == (UINTPTR)excTable->excAddr) {
|
||||
frame->PC = (UINTPTR)excTable->fixAddr;
|
||||
frame->R2 = (UINTPTR)excVaddr;
|
||||
*status = LOS_OK;
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_DEBUG_VERSION
|
||||
vaddr = ROUNDDOWN(excVaddr, PAGE_SIZE);
|
||||
space = LOS_SpaceGet(vaddr);
|
||||
if (space != NULL) {
|
||||
LOS_DumpMemRegion(vaddr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
STATIC STATUS_T OsDoReadFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
{
|
||||
status_t ret;
|
||||
PADDR_T paddr;
|
||||
LosVmPage *page = NULL;
|
||||
VADDR_T vaddr = (VADDR_T)vmPgFault->vaddr;
|
||||
LosVmSpace *space = region->space;
|
||||
|
||||
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) {
|
||||
VM_ERR("region args invalid, file path: %s", region->unTypeData.rf.file->f_path);
|
||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
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));
|
||||
if (ret < 0) {
|
||||
VM_ERR("LOS_ArchMmuMap fial");
|
||||
OsDelMapInfo(region, vmPgFault, false);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
return LOS_OK;
|
||||
}
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
|
||||
/* numap a page when cow happend only */
|
||||
STATIC LosVmPage *OsCowUnmapOrg(LosArchMmu *archMmu, LosVmMapRegion *region, LosVmPgFault *vmf)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosVmPage *oldPage = NULL;
|
||||
LosMapInfo *mapInfo = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
VADDR_T vaddr = (VADDR_T)vmf->vaddr;
|
||||
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.file->f_mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(region->unTypeData.rf.file->f_mapping, vmf->pgoff);
|
||||
if (fpage != NULL) {
|
||||
oldPage = fpage->vmPage;
|
||||
OsSetPageLocked(oldPage);
|
||||
mapInfo = OsGetMapInfo(fpage, archMmu, vaddr);
|
||||
if (mapInfo != NULL) {
|
||||
OsUnmapPageLocked(fpage, mapInfo);
|
||||
} else {
|
||||
LOS_ArchMmuUnmap(archMmu, vaddr, 1);
|
||||
}
|
||||
} else {
|
||||
LOS_ArchMmuUnmap(archMmu, vaddr, 1);
|
||||
}
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
|
||||
return oldPage;
|
||||
}
|
||||
#endif
|
||||
|
||||
status_t OsDoCowFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
{
|
||||
STATUS_T ret;
|
||||
VOID *kvaddr = NULL;
|
||||
PADDR_T oldPaddr = 0;
|
||||
PADDR_T newPaddr;
|
||||
LosVmPage *oldPage = NULL;
|
||||
LosVmPage *newPage = NULL;
|
||||
LosVmSpace *space = NULL;
|
||||
|
||||
if ((vmPgFault == NULL) || (region == NULL) ||
|
||||
(region->unTypeData.rf.vmFOps == NULL) || (region->unTypeData.rf.vmFOps->fault == NULL)) {
|
||||
VM_ERR("region args invalid");
|
||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||
}
|
||||
|
||||
space = region->space;
|
||||
ret = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vmPgFault->vaddr, &oldPaddr, NULL);
|
||||
if (ret == LOS_OK) {
|
||||
oldPage = OsCowUnmapOrg(&space->archMmu, region, vmPgFault);
|
||||
}
|
||||
|
||||
newPage = LOS_PhysPageAlloc();
|
||||
if (newPage == NULL) {
|
||||
VM_ERR("pmm_alloc_page fail");
|
||||
ret = LOS_ERRNO_VM_NO_MEMORY;
|
||||
goto ERR_OUT;
|
||||
}
|
||||
|
||||
newPaddr = VM_PAGE_TO_PHYS(newPage);
|
||||
kvaddr = OsVmPageToVaddr(newPage);
|
||||
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
|
||||
if (ret != LOS_OK) {
|
||||
VM_ERR("call region->vm_ops->fault fail");
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
goto ERR_OUT;
|
||||
}
|
||||
|
||||
/**
|
||||
* here we get two conditions, 1.this page hasn't mapped or mapped from pagecache,
|
||||
* 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.
|
||||
*/
|
||||
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);
|
||||
newPage = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
ret = LOS_ArchMmuMap(&space->archMmu, (VADDR_T)vmPgFault->vaddr, newPaddr, 1, region->regionFlags);
|
||||
if (ret < 0) {
|
||||
VM_ERR("LOS_ArchMmuMap fial");
|
||||
ret = LOS_ERRNO_VM_NO_MEMORY;
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
goto ERR_OUT;
|
||||
}
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
|
||||
if (oldPage != NULL) {
|
||||
OsCleanPageLocked(oldPage);
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
|
||||
ERR_OUT:
|
||||
if (newPage != NULL) {
|
||||
LOS_PhysPageFree(newPage);
|
||||
}
|
||||
if (oldPage != NULL) {
|
||||
OsCleanPageLocked(oldPage);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
status_t OsDoSharedFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault)
|
||||
{
|
||||
STATUS_T ret;
|
||||
UINT32 intSave;
|
||||
PADDR_T paddr = 0;
|
||||
VADDR_T vaddr = (VADDR_T)vmPgFault->vaddr;
|
||||
LosVmSpace *space = region->space;
|
||||
LosVmPage *page = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
if ((region->unTypeData.rf.vmFOps == NULL) || (region->unTypeData.rf.vmFOps->fault == NULL)) {
|
||||
VM_ERR("region args invalid");
|
||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret < 0) {
|
||||
VM_ERR("LOS_ArchMmuMap failed. ret=%d", ret);
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.file->f_mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(region->unTypeData.rf.file->f_mapping, vmPgFault->pgoff);
|
||||
if (fpage) {
|
||||
OsMarkPageDirty(fpage, region, 0, 0);
|
||||
}
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
ret = region->unTypeData.rf.vmFOps->fault(region, vmPgFault);
|
||||
if (ret == LOS_OK) {
|
||||
paddr = LOS_PaddrQuery(vmPgFault->pageKVaddr);
|
||||
page = LOS_VmPageGet(paddr);
|
||||
/* just in case of page null */
|
||||
if (page != NULL) {
|
||||
LOS_AtomicInc(&page->refCounts);
|
||||
OsCleanPageLocked(page);
|
||||
}
|
||||
ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, 1, region->regionFlags);
|
||||
if (ret < 0) {
|
||||
VM_ERR("LOS_ArchMmuMap failed. ret=%d", ret);
|
||||
OsDelMapInfo(region, vmPgFault, TRUE);
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
return LOS_ERRNO_VM_NO_MEMORY;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
return LOS_OK;
|
||||
}
|
||||
(VOID)LOS_MuxRelease(®ion->unTypeData.rf.file->f_mapping->mux_lock);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/**
|
||||
* Page read operation is a simple case, just share the pagecache(save memory)
|
||||
* and make a read permission mmapping (region->arch_mmu_flags & (~ARCH_MMU_FLAG_PERM_WRITE)).
|
||||
* However for write operation, vmflag (VM_PRIVATE|VM_SHREAD) decides COW or SHARED fault.
|
||||
* 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
|
||||
*/
|
||||
STATIC STATUS_T OsDoFileFault(LosVmMapRegion *region, LosVmPgFault *vmPgFault, UINT32 flags)
|
||||
{
|
||||
STATUS_T ret;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
STATUS_T OsVmPageFaultHandler(VADDR_T vaddr, UINT32 flags, ExcContext *frame)
|
||||
{
|
||||
LosVmSpace *space = LOS_SpaceGet(vaddr);
|
||||
LosVmMapRegion *region = NULL;
|
||||
STATUS_T status;
|
||||
PADDR_T oldPaddr;
|
||||
PADDR_T newPaddr;
|
||||
VADDR_T excVaddr = vaddr;
|
||||
LosVmPage *newPage = NULL;
|
||||
LosVmPgFault vmPgFault = { 0 };
|
||||
|
||||
if (space == NULL) {
|
||||
VM_ERR("vm space not exists, vaddr: %#x", vaddr);
|
||||
status = LOS_ERRNO_VM_NOT_FOUND;
|
||||
OsFaultTryFixup(frame, excVaddr, &status);
|
||||
return status;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
region = LOS_RegionFind(space, vaddr);
|
||||
if (region == NULL) {
|
||||
VM_ERR("region not exists, vaddr: %#x", vaddr);
|
||||
status = LOS_ERRNO_VM_NOT_FOUND;
|
||||
goto CHECK_FAILED;
|
||||
}
|
||||
|
||||
status = OsVmRegionRightCheck(region, flags);
|
||||
if (status != LOS_OK) {
|
||||
status = LOS_ERRNO_VM_ACCESS_DENIED;
|
||||
goto CHECK_FAILED;
|
||||
}
|
||||
|
||||
if (OomCheckProcess()) {
|
||||
/*
|
||||
* under low memory, when user process request memory allocation
|
||||
* it will fail, and result is LOS_NOK and current user process
|
||||
* will be deleted. memory usage detail will be printed.
|
||||
*/
|
||||
status = LOS_ERRNO_VM_NO_MEMORY;
|
||||
goto CHECK_FAILED;
|
||||
}
|
||||
|
||||
vaddr = ROUNDDOWN(vaddr, PAGE_SIZE);
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
if (LOS_IsRegionFileValid(region)) {
|
||||
if (region->unTypeData.rf.file->f_mapping == 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);
|
||||
if (status) {
|
||||
VM_ERR("vm fault error, status=%d", status);
|
||||
goto CHECK_FAILED;
|
||||
}
|
||||
goto DONE;
|
||||
}
|
||||
#endif
|
||||
|
||||
newPage = LOS_PhysPageAlloc();
|
||||
if (newPage == NULL) {
|
||||
status = LOS_ERRNO_VM_NO_MEMORY;
|
||||
goto CHECK_FAILED;
|
||||
}
|
||||
|
||||
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);
|
||||
newPage = NULL;
|
||||
}
|
||||
|
||||
/* map all of the pages */
|
||||
status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);
|
||||
if (status < 0) {
|
||||
VM_ERR("failed to map replacement page, status:%d", status);
|
||||
status = LOS_ERRNO_VM_MAP_FAILED;
|
||||
goto VMM_MAP_FAILED;
|
||||
}
|
||||
|
||||
status = LOS_OK;
|
||||
goto DONE;
|
||||
} else {
|
||||
/* map all of the pages */
|
||||
LOS_AtomicInc(&newPage->refCounts);
|
||||
status = LOS_ArchMmuMap(&space->archMmu, vaddr, newPaddr, 1, region->regionFlags);
|
||||
if (status < 0) {
|
||||
VM_ERR("failed to map page, status:%d", status);
|
||||
status = LOS_ERRNO_VM_MAP_FAILED;
|
||||
goto VMM_MAP_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
status = LOS_OK;
|
||||
goto DONE;
|
||||
VMM_MAP_FAILED:
|
||||
if (newPage != NULL) {
|
||||
LOS_PhysPageFree(newPage);
|
||||
}
|
||||
CHECK_FAILED:
|
||||
OsFaultTryFixup(frame, excVaddr, &status);
|
||||
DONE:
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return status;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
775
kernel/base/vm/los_vm_filemap.c
Executable file
775
kernel/base/vm/los_vm_filemap.c
Executable file
@@ -0,0 +1,775 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_filemap vm filemap definition
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#include "los_vm_filemap.h"
|
||||
#include "los_vm_page.h"
|
||||
#include "los_vm_phys.h"
|
||||
#include "los_vm_common.h"
|
||||
#include "los_vm_fault.h"
|
||||
#include "los_process_pri.h"
|
||||
#include "inode/inode.h"
|
||||
#include "los_vm_lock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
STATIC VOID OsPageCacheAdd(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff)
|
||||
{
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
|
||||
if (fpage->pgoff > pgoff) {
|
||||
LOS_ListTailInsert(&fpage->node, &page->node);
|
||||
goto done_add;
|
||||
}
|
||||
}
|
||||
|
||||
LOS_ListTailInsert(&mapping->page_list, &page->node);
|
||||
|
||||
OsSetPageLRU(page->vmPage);
|
||||
|
||||
done_add:
|
||||
mapping->nrpages++;
|
||||
}
|
||||
|
||||
VOID OsAddToPageacheLru(LosFilePage *page, struct page_mapping *mapping, VM_OFFSET_T pgoff)
|
||||
{
|
||||
OsPageCacheAdd(page, mapping, pgoff);
|
||||
OsLruCacheAdd(page, VM_LRU_ACTIVE_FILE);
|
||||
}
|
||||
|
||||
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 OsAddMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr)
|
||||
{
|
||||
LosMapInfo *info = NULL;
|
||||
|
||||
info = (LosMapInfo *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosMapInfo));
|
||||
if (info == NULL) {
|
||||
VM_ERR("OsAddMapInfo alloc memory failed!");
|
||||
return;
|
||||
}
|
||||
info->page = page;
|
||||
info->archMmu = archMmu;
|
||||
info->vaddr = vaddr;
|
||||
|
||||
LOS_ListAdd(&page->i_mmap, &info->node);
|
||||
page->n_maps++;
|
||||
}
|
||||
|
||||
LosMapInfo *OsGetMapInfo(LosFilePage *page, LosArchMmu *archMmu, VADDR_T vaddr)
|
||||
{
|
||||
LosMapInfo *info = NULL;
|
||||
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 form lru list */
|
||||
OsLruCacheDel(page);
|
||||
/* delete from cache lits and free pmm if need */
|
||||
OsPageCacheDel(page);
|
||||
}
|
||||
|
||||
STATIC LosFilePage *OsPagecacheGetPageAndFill(struct file *filp, VM_OFFSET_T pgOff, size_t *readSize, VADDR_T *kvaddr)
|
||||
{
|
||||
LosFilePage *page = NULL;
|
||||
struct page_mapping *mapping = filp->f_mapping;
|
||||
|
||||
page = OsFindGetEntry(mapping, pgOff);
|
||||
if (page != NULL) {
|
||||
OsSetPageLocked(page->vmPage);
|
||||
OsPageRefIncLocked(page);
|
||||
*kvaddr = (VADDR_T)(UINTPTR)OsVmPageToVaddr(page->vmPage);
|
||||
*readSize = PAGE_SIZE;
|
||||
} else {
|
||||
page = OsPageCacheAlloc(mapping, pgOff);
|
||||
if (page == NULL) {
|
||||
VM_ERR("Failed to alloc a page frame");
|
||||
return page;
|
||||
}
|
||||
OsSetPageLocked(page->vmPage);
|
||||
*kvaddr = (VADDR_T)(UINTPTR)OsVmPageToVaddr(page->vmPage);
|
||||
|
||||
file_seek(filp, pgOff << PAGE_SHIFT, SEEK_SET);
|
||||
/* "ReadPage" func exists definitely in this procedure */
|
||||
*readSize = filp->f_inode->u.i_mops->readpage(filp, (char *)(UINTPTR)*kvaddr, PAGE_SIZE);
|
||||
if (*readSize == 0) {
|
||||
VM_ERR("read 0 bytes");
|
||||
OsCleanPageLocked(page->vmPage);
|
||||
}
|
||||
OsAddToPageacheLru(page, mapping, pgOff);
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
ssize_t OsMappingRead(struct file *filp, char *buf, size_t size)
|
||||
{
|
||||
INT32 ret;
|
||||
vaddr_t kvaddr = 0;
|
||||
UINT32 intSave;
|
||||
struct stat bufStat;
|
||||
size_t readSize = 0;
|
||||
size_t readTotal = 0;
|
||||
size_t readLeft = size;
|
||||
LosFilePage *page = NULL;
|
||||
VM_OFFSET_T pos = file_seek(filp, 0, SEEK_CUR);
|
||||
VM_OFFSET_T pgOff = pos >> PAGE_SHIFT;
|
||||
INT32 offInPage = pos % PAGE_SIZE;
|
||||
struct page_mapping *mapping = filp->f_mapping;
|
||||
INT32 nPages = (ROUNDUP(pos + size, PAGE_SIZE) - ROUNDDOWN(pos, PAGE_SIZE)) >> PAGE_SHIFT;
|
||||
|
||||
ret = stat(filp->f_path, &bufStat);
|
||||
if (ret != OK) {
|
||||
VM_ERR("Get file size failed. (filepath=%s)", filp->f_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pos >= bufStat.st_size) {
|
||||
PRINT_INFO("%s filp->f_pos >= bufStat.st_size (pos=%ld, fileSize=%ld)\n", filp->f_path, pos, bufStat.st_size);
|
||||
return 0;
|
||||
}
|
||||
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
|
||||
for (INT32 i = 0; (i < nPages) && readLeft; i++, pgOff++) {
|
||||
page = OsPagecacheGetPageAndFill(filp, pgOff, &readSize, &kvaddr);
|
||||
if ((page == NULL) || (readSize == 0)) {
|
||||
break;
|
||||
}
|
||||
if (readSize < PAGE_SIZE) {
|
||||
readLeft = readSize;
|
||||
}
|
||||
|
||||
readSize = MIN2((PAGE_SIZE - offInPage), readLeft);
|
||||
|
||||
(VOID)memcpy_s((VOID *)buf, readLeft, (char *)kvaddr + offInPage, readSize);
|
||||
buf += readSize;
|
||||
readLeft -= readSize;
|
||||
readTotal += readSize;
|
||||
|
||||
offInPage = 0;
|
||||
|
||||
OsCleanPageLocked(page->vmPage);
|
||||
}
|
||||
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
file_seek(filp, pos + readTotal, SEEK_SET);
|
||||
|
||||
return readTotal;
|
||||
}
|
||||
|
||||
ssize_t OsMappingWrite(struct file *filp, const char *buf, size_t size)
|
||||
{
|
||||
VADDR_T kvaddr;
|
||||
UINT32 intSave;
|
||||
INT32 writeSize = 0;
|
||||
size_t writeLeft = size;
|
||||
VM_OFFSET_T pos = file_seek(filp, 0, SEEK_CUR);
|
||||
VM_OFFSET_T pgOff = pos >> PAGE_SHIFT;
|
||||
INT32 offInPage = pos % PAGE_SIZE;
|
||||
LosFilePage *page = NULL;
|
||||
struct page_mapping *mapping = filp->f_mapping;
|
||||
INT32 nPages = (ROUNDUP(pos + size, PAGE_SIZE) - ROUNDDOWN(pos, PAGE_SIZE)) >> PAGE_SHIFT;
|
||||
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
|
||||
for (INT32 i = 0; i < nPages; i++, pgOff++) {
|
||||
page = OsFindGetEntry(mapping, pgOff);
|
||||
if (page) {
|
||||
kvaddr = (VADDR_T)(UINTPTR)OsVmPageToVaddr(page->vmPage);
|
||||
OsSetPageLocked(page->vmPage);
|
||||
OsPageRefIncLocked(page);
|
||||
} else {
|
||||
page = OsPageCacheAlloc(mapping, pgOff);
|
||||
if (page == NULL) {
|
||||
VM_ERR("Failed to alloc a page frame");
|
||||
break;
|
||||
}
|
||||
kvaddr = (VADDR_T)(UINTPTR)OsVmPageToVaddr(page->vmPage);
|
||||
OsAddToPageacheLru(page, mapping, pgOff);
|
||||
OsSetPageLocked(page->vmPage);
|
||||
}
|
||||
|
||||
writeSize = MIN2((PAGE_SIZE - offInPage), writeLeft);
|
||||
|
||||
(VOID)memcpy_s((char *)(UINTPTR)kvaddr + offInPage, writeLeft, buf, writeSize);
|
||||
buf += writeSize;
|
||||
writeLeft -= writeSize;
|
||||
|
||||
OsMarkPageDirty(page, NULL, offInPage, writeSize);
|
||||
|
||||
offInPage = 0;
|
||||
|
||||
OsCleanPageLocked(page->vmPage);
|
||||
}
|
||||
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
|
||||
file_seek(filp, pos + size - writeLeft, SEEK_SET);
|
||||
return (size - writeLeft);
|
||||
}
|
||||
|
||||
STATIC VOID OsPageCacheUnmap(LosFilePage *fpage, LosArchMmu *archMmu, VADDR_T vaddr)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosMapInfo *info = NULL;
|
||||
|
||||
LOS_SpinLockSave(&fpage->physSeg->lruLock, &intSave);
|
||||
info = OsGetMapInfo(fpage, archMmu, vaddr);
|
||||
if (info == NULL) {
|
||||
VM_ERR("OsPageCacheUnmap get map info fail!");
|
||||
} else {
|
||||
OsUnmapPageLocked(fpage, info);
|
||||
}
|
||||
if (!(OsIsPageMapped(fpage) && ((fpage->flags & VM_MAP_REGION_FLAG_PERM_EXECUTE) ||
|
||||
OsIsPageDirty(fpage->vmPage)))) {
|
||||
OsPageRefDecNoLock(fpage);
|
||||
}
|
||||
|
||||
LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave);
|
||||
}
|
||||
|
||||
VOID OsVmmFileRemove(LosVmMapRegion *region, LosArchMmu *archMmu, VM_OFFSET_T pgoff)
|
||||
{
|
||||
UINT32 intSave;
|
||||
vaddr_t vaddr;
|
||||
paddr_t paddr = 0;
|
||||
struct file *file = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
LosFilePage *tmpPage = NULL;
|
||||
LosVmPage *mapPage = NULL;
|
||||
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL)) {
|
||||
return;
|
||||
}
|
||||
file = region->unTypeData.rf.file;
|
||||
mapping = file->f_mapping;
|
||||
vaddr = region->range.base + ((UINT32)(pgoff - region->pgOff) << PAGE_SHIFT);
|
||||
|
||||
status_t status = LOS_ArchMmuQuery(archMmu, vaddr, &paddr, NULL);
|
||||
if (status != LOS_OK) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
|
||||
if (tmpPage) {
|
||||
OsDoFlushDirtyPage(tmpPage);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
VOID OsMarkPageDirty(LosFilePage *fpage, LosVmMapRegion *region, INT32 off, INT32 len)
|
||||
{
|
||||
if (region != NULL) {
|
||||
OsSetPageDirty(fpage->vmPage);
|
||||
fpage->dirtyOff = off;
|
||||
fpage->dirtyEnd = len;
|
||||
} else {
|
||||
OsSetPageDirty(fpage->vmPage);
|
||||
if ((off + len) > fpage->dirtyEnd) {
|
||||
fpage->dirtyEnd = off + len;
|
||||
}
|
||||
|
||||
if (off < fpage->dirtyOff) {
|
||||
fpage->dirtyOff = off;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
STATIC UINT32 GetDirtySize(LosFilePage *fpage, struct file *file)
|
||||
{
|
||||
UINT32 fileSize;
|
||||
UINT32 dirtyBegin;
|
||||
UINT32 dirtyEnd;
|
||||
struct stat buf_stat;
|
||||
|
||||
if (stat(file->f_path, &buf_stat) != OK) {
|
||||
VM_ERR("FlushDirtyPage get file size failed. (filepath=%s)", file->f_path);
|
||||
return 0;
|
||||
}
|
||||
|
||||
fileSize = buf_stat.st_size;
|
||||
dirtyBegin = ((UINT32)fpage->pgoff << PAGE_SHIFT);
|
||||
dirtyEnd = dirtyBegin + PAGE_SIZE;
|
||||
|
||||
if (dirtyBegin >= fileSize) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (dirtyEnd >= fileSize) {
|
||||
return fileSize - dirtyBegin;
|
||||
}
|
||||
|
||||
return PAGE_SIZE;
|
||||
}
|
||||
|
||||
STATIC INT32 OsFlushDirtyPage(LosFilePage *fpage)
|
||||
{
|
||||
UINT32 ret;
|
||||
size_t len;
|
||||
char *buff = NULL;
|
||||
VM_OFFSET_T oldPos;
|
||||
struct file *file = fpage->mapping->host;
|
||||
if ((file == NULL) || (file->f_inode == NULL)) {
|
||||
VM_ERR("page cache file error");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
oldPos = file_seek(file, 0, SEEK_CUR);
|
||||
buff = (char *)OsVmPageToVaddr(fpage->vmPage);
|
||||
file_seek(file, (((UINT32)fpage->pgoff << PAGE_SHIFT) + fpage->dirtyOff), SEEK_SET);
|
||||
len = fpage->dirtyEnd - fpage->dirtyOff;
|
||||
len = (len == 0) ? GetDirtySize(fpage, file) : len;
|
||||
if (len == 0) {
|
||||
OsCleanPageDirty(fpage->vmPage);
|
||||
(VOID)file_seek(file, oldPos, SEEK_SET);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
if (file->f_inode && file->f_inode->u.i_mops->writepage) {
|
||||
ret = file->f_inode->u.i_mops->writepage(file, (buff + fpage->dirtyOff), len);
|
||||
} else {
|
||||
ret = file_write(file, (VOID *)buff, len);
|
||||
}
|
||||
if (ret <= 0) {
|
||||
VM_ERR("WritePage error ret %d", ret);
|
||||
}
|
||||
ret = (ret <= 0) ? LOS_NOK : LOS_OK;
|
||||
OsCleanPageDirty(fpage->vmPage);
|
||||
(VOID)file_seek(file, oldPos, SEEK_SET);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
LosFilePage *OsDumpDirtyPage(LosFilePage *oldFPage)
|
||||
{
|
||||
LosFilePage *newFPage = NULL;
|
||||
|
||||
newFPage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage));
|
||||
if (newFPage == NULL) {
|
||||
VM_ERR("Failed to allocate for temp page!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
OsCleanPageDirty(oldFPage->vmPage);
|
||||
LOS_AtomicInc(&oldFPage->vmPage->refCounts);
|
||||
/* no map page cache */
|
||||
if (LOS_AtomicRead(&oldFPage->vmPage->refCounts) == 1) {
|
||||
LOS_AtomicInc(&oldFPage->vmPage->refCounts);
|
||||
}
|
||||
(VOID)memcpy_s(newFPage, sizeof(LosFilePage), oldFPage, sizeof(LosFilePage));
|
||||
|
||||
return newFPage;
|
||||
}
|
||||
|
||||
VOID OsDoFlushDirtyPage(LosFilePage *fpage)
|
||||
{
|
||||
if (fpage == NULL) {
|
||||
return;
|
||||
}
|
||||
(VOID)OsFlushDirtyPage(fpage);
|
||||
LOS_PhysPageFree(fpage->vmPage);
|
||||
LOS_MemFree(m_aucSysMem0, fpage);
|
||||
}
|
||||
|
||||
STATIC VOID OsReleaseFpage(struct page_mapping *mapping, LosFilePage *fpage)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 lruSave;
|
||||
SPIN_LOCK_S *lruLock = &fpage->physSeg->lruLock;
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
LOS_SpinLockSave(lruLock, &lruSave);
|
||||
OsCleanPageLocked(fpage->vmPage);
|
||||
OsDeletePageCacheLru(fpage);
|
||||
LOS_SpinUnlockRestore(lruLock, lruSave);
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
}
|
||||
|
||||
VOID OsDelMapInfo(LosVmMapRegion *region, LosVmPgFault *vmf, BOOL cleanDirty)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosMapInfo *info = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL) || (vmf == NULL)) {
|
||||
return;
|
||||
}
|
||||
|
||||
LOS_SpinLockSave(®ion->unTypeData.rf.file->f_mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(region->unTypeData.rf.file->f_mapping, vmf->pgoff);
|
||||
if (fpage == NULL) {
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
if (cleanDirty) {
|
||||
OsCleanPageDirty(fpage->vmPage);
|
||||
}
|
||||
info = OsGetMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr);
|
||||
if (info != NULL) {
|
||||
fpage->n_maps--;
|
||||
LOS_ListDelete(&info->node);
|
||||
LOS_AtomicDec(&fpage->vmPage->refCounts);
|
||||
LOS_MemFree(m_aucSysMem0, info);
|
||||
}
|
||||
LOS_SpinUnlockRestore(®ion->unTypeData.rf.file->f_mapping->list_lock, intSave);
|
||||
}
|
||||
|
||||
INT32 OsVmmFileFault(LosVmMapRegion *region, LosVmPgFault *vmf)
|
||||
{
|
||||
INT32 ret;
|
||||
VM_OFFSET_T oldPos;
|
||||
VOID *kvaddr = NULL;
|
||||
|
||||
UINT32 intSave;
|
||||
bool newCache = false;
|
||||
struct file *file = NULL;
|
||||
struct page_mapping *mapping = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
if (!LOS_IsRegionFileValid(region) || (region->unTypeData.rf.file->f_mapping == NULL) || (vmf == NULL)) {
|
||||
VM_ERR("Input param is NULL");
|
||||
return LOS_NOK;
|
||||
}
|
||||
file = region->unTypeData.rf.file;
|
||||
mapping = file->f_mapping;
|
||||
|
||||
/* get or create a new cache node */
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
fpage = OsFindGetEntry(mapping, vmf->pgoff);
|
||||
if (fpage != NULL) {
|
||||
OsPageRefIncLocked(fpage);
|
||||
} else {
|
||||
fpage = OsPageCacheAlloc(mapping, vmf->pgoff);
|
||||
if (fpage == NULL) {
|
||||
VM_ERR("Failed to alloc a page frame");
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
return LOS_NOK;
|
||||
}
|
||||
newCache = true;
|
||||
}
|
||||
OsSetPageLocked(fpage->vmPage);
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
kvaddr = OsVmPageToVaddr(fpage->vmPage);
|
||||
|
||||
/* read file to new page cache */
|
||||
if (newCache) {
|
||||
oldPos = file_seek(file, 0, SEEK_CUR);
|
||||
file_seek(file, fpage->pgoff << PAGE_SHIFT, SEEK_SET);
|
||||
if (file->f_inode && file->f_inode->u.i_mops->readpage) {
|
||||
ret = file->f_inode->u.i_mops->readpage(file, (char *)kvaddr, PAGE_SIZE);
|
||||
} else {
|
||||
ret = file_read(file, kvaddr, PAGE_SIZE);
|
||||
}
|
||||
file_seek(file, oldPos, SEEK_SET);
|
||||
if (ret == 0) {
|
||||
VM_ERR("Failed to read from file!");
|
||||
OsReleaseFpage(mapping, fpage);
|
||||
return LOS_NOK;
|
||||
}
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
OsAddToPageacheLru(fpage, mapping, vmf->pgoff);
|
||||
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))) {
|
||||
OsAddMapInfo(fpage, ®ion->space->archMmu, (vaddr_t)vmf->vaddr);
|
||||
fpage->flags = region->regionFlags;
|
||||
}
|
||||
|
||||
/* share page fault, mark the page dirty */
|
||||
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;
|
||||
}
|
||||
|
||||
VOID OsFileCacheFlush(struct page_mapping *mapping)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 lruLock;
|
||||
LOS_DL_LIST_HEAD(dirtyList);
|
||||
LosFilePage *ftemp = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
if (mapping == NULL) {
|
||||
return;
|
||||
}
|
||||
LOS_SpinLockSave(&mapping->list_lock, &intSave);
|
||||
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_SpinUnlockRestore(&fpage->physSeg->lruLock, lruLock);
|
||||
}
|
||||
LOS_SpinUnlockRestore(&mapping->list_lock, intSave);
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, ftemp, &dirtyList, LosFilePage, node) {
|
||||
OsDoFlushDirtyPage(fpage);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsFileCacheRemove(struct page_mapping *mapping)
|
||||
{
|
||||
UINT32 intSave;
|
||||
UINT32 lruSave;
|
||||
SPIN_LOCK_S *lruLock = NULL;
|
||||
LOS_DL_LIST_HEAD(dirtyList);
|
||||
LosFilePage *ftemp = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
LosFilePage *fnext = NULL;
|
||||
|
||||
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;
|
||||
region->unTypeData.rf.file = filep;
|
||||
region->unTypeData.rf.fileMagic = filep->f_magicnum;
|
||||
return ENOERR;
|
||||
}
|
||||
|
||||
STATUS_T OsNamedMMap(struct file *filep, LosVmMapRegion *region)
|
||||
{
|
||||
struct inode *inodePtr = NULL;
|
||||
if (filep == NULL) {
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
inodePtr = filep->f_inode;
|
||||
if (inodePtr == NULL) {
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
if (INODE_IS_MOUNTPT(inodePtr)) {
|
||||
if (inodePtr->u.i_mops->mmap) {
|
||||
LOS_SetRegionTypeFile(region);
|
||||
return inodePtr->u.i_mops->mmap(filep, region);
|
||||
} else {
|
||||
VM_ERR("file mmap not support");
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
} else if (INODE_IS_DRIVER(inodePtr)) {
|
||||
if (inodePtr->u.i_ops->mmap) {
|
||||
LOS_SetRegionTypeDev(region);
|
||||
return inodePtr->u.i_ops->mmap(filep, region);
|
||||
} else {
|
||||
VM_ERR("dev mmap not support");
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
} else {
|
||||
VM_ERR("mmap file type unknown");
|
||||
return LOS_ERRNO_VM_MAP_FAILED;
|
||||
}
|
||||
}
|
||||
|
||||
LosFilePage *OsFindGetEntry(struct page_mapping *mapping, VM_OFFSET_T pgoff)
|
||||
{
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY(fpage, &mapping->page_list, LosFilePage, node) {
|
||||
if (fpage->pgoff == pgoff) {
|
||||
return fpage;
|
||||
}
|
||||
|
||||
if (fpage->pgoff > pgoff) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* need mutex & change memory to dma zone. */
|
||||
LosFilePage *OsPageCacheAlloc(struct page_mapping *mapping, VM_OFFSET_T pgoff)
|
||||
{
|
||||
VOID *kvaddr = NULL;
|
||||
LosVmPhysSeg *physSeg = NULL;
|
||||
LosVmPage *vmPage = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
|
||||
vmPage = LOS_PhysPageAlloc();
|
||||
if (vmPage == NULL) {
|
||||
VM_ERR("alloc vm page failed");
|
||||
return NULL;
|
||||
}
|
||||
physSeg = OsVmPhysSegGet(vmPage);
|
||||
kvaddr = OsVmPageToVaddr(vmPage);
|
||||
if ((physSeg == NULL) || (kvaddr == NULL)) {
|
||||
LOS_PhysPageFree(vmPage);
|
||||
VM_ERR("alloc vm page failed!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
fpage = (LosFilePage *)LOS_MemAlloc(m_aucSysMem0, sizeof(LosFilePage));
|
||||
if (fpage == NULL) {
|
||||
LOS_PhysPageFree(vmPage);
|
||||
VM_ERR("Failed to allocate for page!");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
(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);
|
||||
|
||||
return fpage;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
VOID OsVmmFileRegionFree(struct file *filep, LosProcessCB *processCB)
|
||||
{
|
||||
int ret;
|
||||
LosVmSpace *space = NULL;
|
||||
LosVmMapRegion *region = NULL;
|
||||
LosRbNode *pstRbNode = NULL;
|
||||
LosRbNode *pstRbNodeTmp = NULL;
|
||||
|
||||
if (processCB == NULL) {
|
||||
processCB = OsCurrProcessGet();
|
||||
}
|
||||
|
||||
space = processCB->vmSpace;
|
||||
if (space != NULL) {
|
||||
/* free the regions associated with filep */
|
||||
RB_SCAN_SAFE(&space->regionRbTree, pstRbNode, pstRbNodeTmp)
|
||||
region = (LosVmMapRegion *)pstRbNode;
|
||||
if (LOS_IsRegionFileValid(region)) {
|
||||
if (region->unTypeData.rf.file != filep) {
|
||||
continue;
|
||||
}
|
||||
ret = LOS_RegionFree(space, region);
|
||||
if (ret != LOS_OK) {
|
||||
VM_ERR("free region error, space %p, region %p", space, region);
|
||||
}
|
||||
}
|
||||
RB_SCAN_SAFE_END(&space->regionRbTree, pstRbNode, pstRbNodeTmp)
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
218
kernel/base/vm/los_vm_iomap.c
Executable file
218
kernel/base/vm/los_vm_iomap.c
Executable file
@@ -0,0 +1,218 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_vm_iomap.h"
|
||||
#include "los_printf.h"
|
||||
#include "los_vm_zone.h"
|
||||
#include "los_vm_common.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_vm_lock.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
VOID *ioremap(PADDR_T paddr, unsigned long size)
|
||||
{
|
||||
if (IS_PERIPH_ADDR(paddr) && IS_PERIPH_ADDR(paddr + size)) {
|
||||
return (VOID *)(UINTPTR)IO_DEVICE_ADDR(paddr);
|
||||
}
|
||||
|
||||
VM_ERR("ioremap failed invalid addr or size %p %d", paddr, size);
|
||||
return (VOID *)(UINTPTR)paddr;
|
||||
}
|
||||
|
||||
VOID iounmap(VOID *vaddr) {}
|
||||
|
||||
VOID *ioremap_nocache(PADDR_T paddr, unsigned long size)
|
||||
{
|
||||
if (IS_PERIPH_ADDR(paddr) && IS_PERIPH_ADDR(paddr + size)) {
|
||||
return (VOID *)(UINTPTR)IO_UNCACHED_ADDR(paddr);
|
||||
}
|
||||
|
||||
if (IS_MEMORY_ADDR(paddr) && IS_MEMORY_ADDR(paddr + size)) {
|
||||
return (VOID *)(UINTPTR)MEM_UNCACHED_ADDR(paddr);
|
||||
}
|
||||
|
||||
VM_ERR("ioremap_nocache failed invalid addr or size %p %d", paddr, size);
|
||||
return (VOID *)(UINTPTR)paddr;
|
||||
}
|
||||
|
||||
VOID *ioremap_cached(PADDR_T paddr, unsigned long size)
|
||||
{
|
||||
if (IS_PERIPH_ADDR(paddr) && IS_PERIPH_ADDR(paddr + size)) {
|
||||
return (VOID *)(UINTPTR)IO_CACHED_ADDR(paddr);
|
||||
}
|
||||
|
||||
if (IS_MEMORY_ADDR(paddr) && IS_MEMORY_ADDR(paddr + size)) {
|
||||
return (VOID *)(UINTPTR)MEM_CACHED_ADDR(paddr);
|
||||
}
|
||||
|
||||
VM_ERR("ioremap_cached failed invalid addr or size %p %d", paddr, size);
|
||||
return (VOID *)(UINTPTR)paddr;
|
||||
}
|
||||
|
||||
int remap_pfn_range(VADDR_T vaddr, unsigned long pfn, unsigned long size, unsigned long prot)
|
||||
{
|
||||
STATUS_T status = LOS_OK;
|
||||
int ret;
|
||||
LosVmMapRegion *region = NULL;
|
||||
unsigned long vpos;
|
||||
unsigned long end;
|
||||
unsigned long paddr = pfn << PAGE_SHIFT;
|
||||
LosVmSpace *space = LOS_SpaceGet(vaddr);
|
||||
|
||||
if (size == 0) {
|
||||
VM_ERR("invalid map size %u", size);
|
||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||
}
|
||||
size = ROUNDUP(size, PAGE_SIZE);
|
||||
|
||||
if (!IS_PAGE_ALIGNED(vaddr) || pfn == 0) {
|
||||
VM_ERR("invalid map map vaddr %x or pfn %x", vaddr, pfn);
|
||||
return LOS_ERRNO_VM_INVALID_ARGS;
|
||||
}
|
||||
|
||||
if (space == NULL) {
|
||||
VM_ERR("aspace not exists");
|
||||
return LOS_ERRNO_VM_NOT_FOUND;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
|
||||
region = LOS_RegionFind(space, vaddr);
|
||||
if (region == NULL) {
|
||||
VM_ERR("region not exists");
|
||||
status = LOS_ERRNO_VM_NOT_FOUND;
|
||||
goto OUT;
|
||||
}
|
||||
end = vaddr + size;
|
||||
if (region->range.base + region->range.size < end) {
|
||||
VM_ERR("out of range:base=%x size=%d vaddr=%x len=%u",
|
||||
region->range.base, region->range.size, vaddr, size);
|
||||
status = LOS_ERRNO_VM_INVALID_ARGS;
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
/* check */
|
||||
for (vpos = vaddr; vpos < end; vpos += PAGE_SIZE) {
|
||||
status = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)vpos, NULL, NULL);
|
||||
if (status == LOS_OK) {
|
||||
VM_ERR("remap_pfn_range, address mapping already exist");
|
||||
status = LOS_ERRNO_VM_INVALID_ARGS;
|
||||
goto OUT;
|
||||
}
|
||||
}
|
||||
|
||||
/* map all */
|
||||
ret = LOS_ArchMmuMap(&space->archMmu, vaddr, paddr, size >> PAGE_SHIFT, prot);
|
||||
if (ret <= 0) {
|
||||
VM_ERR("ioremap LOS_ArchMmuMap failed err = %d", ret);
|
||||
goto OUT;
|
||||
}
|
||||
|
||||
status = LOS_OK;
|
||||
|
||||
OUT:
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return status;
|
||||
}
|
||||
|
||||
VOID *LOS_DmaMemAlloc(DMA_ADDR_T *dmaAddr, size_t size, size_t align, enum DmaMemType type)
|
||||
{
|
||||
VOID *kVaddr = NULL;
|
||||
|
||||
if (size == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((type != DMA_CACHE) && (type != DMA_NOCACHE)) {
|
||||
VM_ERR("The dma type = %d is not support!", type);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
kVaddr = LOS_KernelMallocAlign(size, align);
|
||||
if (kVaddr == NULL) {
|
||||
VM_ERR("failed, size = %u, align = %u", size, align);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (dmaAddr != NULL) {
|
||||
*dmaAddr = (DMA_ADDR_T)LOS_PaddrQuery(kVaddr);
|
||||
}
|
||||
|
||||
if (type == DMA_NOCACHE) {
|
||||
kVaddr = (VOID *)VMM_TO_UNCACHED_ADDR((UINTPTR)kVaddr);
|
||||
}
|
||||
|
||||
return kVaddr;
|
||||
}
|
||||
|
||||
VOID LOS_DmaMemFree(VOID *vaddr)
|
||||
{
|
||||
UINTPTR addr;
|
||||
|
||||
if (vaddr == NULL) {
|
||||
return;
|
||||
}
|
||||
addr = (UINTPTR)vaddr;
|
||||
|
||||
if ((addr >= UNCACHED_VMM_BASE) && (addr < UNCACHED_VMM_BASE + UNCACHED_VMM_SIZE)) {
|
||||
addr = UNCACHED_TO_VMM_ADDR(addr);
|
||||
LOS_KernelFree((VOID *)addr);
|
||||
} else if ((addr >= KERNEL_VMM_BASE) && (addr < KERNEL_VMM_BASE + KERNEL_VMM_SIZE)) {
|
||||
LOS_KernelFree((VOID *)addr);
|
||||
} else {
|
||||
VM_ERR("addr %#x not in dma area!!!", vaddr);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
DMA_ADDR_T LOS_DmaVaddrToPaddr(VOID *vaddr)
|
||||
{
|
||||
status_t ret;
|
||||
paddr_t pa;
|
||||
LosVmSpace *space = LOS_GetKVmSpace();
|
||||
|
||||
ret = LOS_ArchMmuQuery(&space->archMmu, (VADDR_T)(UINTPTR)vaddr, &pa, NULL);
|
||||
if (ret != LOS_OK) {
|
||||
return (DMA_ADDR_T)NULL;
|
||||
}
|
||||
|
||||
return (DMA_ADDR_T)pa;
|
||||
}
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
1209
kernel/base/vm/los_vm_map.c
Executable file
1209
kernel/base/vm/los_vm_map.c
Executable file
File diff suppressed because it is too large
Load Diff
111
kernel/base/vm/los_vm_page.c
Executable file
111
kernel/base/vm/los_vm_page.c
Executable file
@@ -0,0 +1,111 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_vm_page.h"
|
||||
#include "los_vm_common.h"
|
||||
#include "los_vm_phys.h"
|
||||
#include "los_vm_boot.h"
|
||||
#include "los_vm_filemap.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsVmPageOrderListInit(LosVmPage *page, size_t nPages)
|
||||
{
|
||||
OsVmPhysPagesFreeContiguous(page, nPages);
|
||||
}
|
||||
|
||||
VOID OsVmPageStartup(VOID)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
LosVmPage *page = NULL;
|
||||
paddr_t pa;
|
||||
UINT32 nPage;
|
||||
INT32 segID;
|
||||
|
||||
OsVmPhysAreaSizeAdjust(ROUNDUP((g_vmBootMemBase - KERNEL_ASPACE_BASE), PAGE_SIZE));
|
||||
|
||||
nPage = OsVmPhysPageNumGet();
|
||||
g_vmPageArraySize = nPage * sizeof(LosVmPage);
|
||||
g_vmPageArray = (LosVmPage *)OsVmBootMemAlloc(g_vmPageArraySize);
|
||||
|
||||
OsVmPhysAreaSizeAdjust(ROUNDUP(g_vmPageArraySize, PAGE_SIZE));
|
||||
|
||||
OsVmPhysSegAdd();
|
||||
OsVmPhysInit();
|
||||
|
||||
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
|
||||
seg = &g_vmPhysSeg[segID];
|
||||
nPage = seg->size >> PAGE_SHIFT;
|
||||
for (page = seg->pageBase, pa = seg->start; page <= seg->pageBase + nPage;
|
||||
page++, pa += PAGE_SIZE) {
|
||||
OsVmPageInit(page, pa, segID);
|
||||
}
|
||||
OsVmPageOrderListInit(seg->pageBase, nPage);
|
||||
}
|
||||
}
|
||||
|
||||
LosVmPage *LOS_VmPageGet(PADDR_T paddr)
|
||||
{
|
||||
INT32 segID;
|
||||
LosVmPage *page = NULL;
|
||||
|
||||
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
|
||||
page = OsVmPhysToPage(paddr, segID);
|
||||
if (page != NULL) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return page;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
585
kernel/base/vm/los_vm_phys.c
Executable file
585
kernel/base/vm/los_vm_phys.c
Executable file
@@ -0,0 +1,585 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "los_vm_phys.h"
|
||||
#include "los_vm_boot.h"
|
||||
#include "los_vm_common.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_vm_dump.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
#define ONE_PAGE 1
|
||||
|
||||
/* 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;
|
||||
|
||||
LosVmPhysSeg *OsGVmPhysSegGet()
|
||||
{
|
||||
return g_vmPhysSeg;
|
||||
}
|
||||
|
||||
STATIC VOID OsVmPhysLruInit(struct VmPhysSeg *seg)
|
||||
{
|
||||
INT32 i;
|
||||
UINT32 intSave;
|
||||
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);
|
||||
}
|
||||
|
||||
STATIC INT32 OsVmPhysSegCreate(paddr_t start, size_t size)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
|
||||
if (g_vmPhysSegNum >= VM_PHYS_SEG_MAX) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
seg = &g_vmPhysSeg[g_vmPhysSegNum++];
|
||||
for (; (seg > g_vmPhysSeg) && ((seg - 1)->start > (start + size)); seg--) {
|
||||
*seg = *(seg - 1);
|
||||
}
|
||||
seg->start = start;
|
||||
seg->size = size;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
VOID OsVmPhysSegAdd(VOID)
|
||||
{
|
||||
INT32 i, ret;
|
||||
|
||||
LOS_ASSERT(g_vmPhysSegNum <= VM_PHYS_SEG_MAX);
|
||||
|
||||
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
|
||||
ret = OsVmPhysSegCreate(g_physArea[i].start, g_physArea[i].size);
|
||||
if (ret != 0) {
|
||||
VM_ERR("create phys seg failed");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsVmPhysAreaSizeAdjust(size_t size)
|
||||
{
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
|
||||
g_physArea[i].start += size;
|
||||
g_physArea[i].size -= size;
|
||||
}
|
||||
}
|
||||
|
||||
UINT32 OsVmPhysPageNumGet(VOID)
|
||||
{
|
||||
UINT32 nPages = 0;
|
||||
INT32 i;
|
||||
|
||||
for (i = 0; i < (sizeof(g_physArea) / sizeof(g_physArea[0])); i++) {
|
||||
nPages += g_physArea[i].size >> PAGE_SHIFT;
|
||||
}
|
||||
|
||||
return nPages;
|
||||
}
|
||||
|
||||
STATIC INLINE VOID OsVmPhysFreeListInit(struct VmPhysSeg *seg)
|
||||
{
|
||||
int i;
|
||||
UINT32 intSave;
|
||||
struct VmFreeList *list = NULL;
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
VOID OsVmPhysInit(VOID)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
UINT32 nPages = 0;
|
||||
int i;
|
||||
|
||||
for (i = 0; i < g_vmPhysSegNum; i++) {
|
||||
seg = &g_vmPhysSeg[i];
|
||||
seg->pageBase = &g_vmPageArray[nPages];
|
||||
nPages += seg->size >> PAGE_SHIFT;
|
||||
OsVmPhysFreeListInit(seg);
|
||||
OsVmPhysLruInit(seg);
|
||||
}
|
||||
}
|
||||
|
||||
STATIC VOID OsVmPhysFreeListAdd(LosVmPage *page, UINT8 order)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
struct VmFreeList *list = NULL;
|
||||
|
||||
if (page->segID >= VM_PHYS_SEG_MAX) {
|
||||
LOS_Panic("The page segment id(%d) is invalid\n", page->segID);
|
||||
}
|
||||
|
||||
page->order = order;
|
||||
seg = &g_vmPhysSeg[page->segID];
|
||||
|
||||
list = &seg->freeList[order];
|
||||
LOS_ListTailInsert(&list->node, &page->node);
|
||||
list->listCnt++;
|
||||
}
|
||||
|
||||
STATIC VOID OsVmPhysFreeListAddUnsafe(LosVmPage *page, UINT8 order)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
struct VmFreeList *list = NULL;
|
||||
|
||||
if (page->segID >= VM_PHYS_SEG_MAX) {
|
||||
LOS_Panic("The page segment id(%d) is invalid\n", page->segID);
|
||||
}
|
||||
|
||||
page->order = order;
|
||||
seg = &g_vmPhysSeg[page->segID];
|
||||
|
||||
list = &seg->freeList[order];
|
||||
LOS_ListTailInsert(&list->node, &page->node);
|
||||
list->listCnt++;
|
||||
}
|
||||
|
||||
STATIC VOID OsVmPhysFreeListDelUnsafe(LosVmPage *page)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
struct VmFreeList *list = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
STATIC VOID OsVmPhysFreeListDel(LosVmPage *page)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
struct VmFreeList *list = NULL;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
STATIC VOID OsVmPhysPagesSpiltUnsafe(LosVmPage *page, UINT8 oldOrder, UINT8 newOrder)
|
||||
{
|
||||
UINT32 order;
|
||||
LosVmPage *buddyPage = NULL;
|
||||
|
||||
for (order = newOrder; order > oldOrder;) {
|
||||
order--;
|
||||
buddyPage = &page[VM_ORDER_TO_PAGES(order)];
|
||||
LOS_ASSERT(buddyPage->order == VM_LIST_ORDER_MAX);
|
||||
OsVmPhysFreeListAddUnsafe(buddyPage, order);
|
||||
}
|
||||
}
|
||||
|
||||
LosVmPage *OsVmPhysToPage(paddr_t pa, UINT8 segID)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
paddr_t offset;
|
||||
|
||||
if (segID >= VM_PHYS_SEG_MAX) {
|
||||
LOS_Panic("The page segment id(%d) is invalid\n", segID);
|
||||
}
|
||||
seg = &g_vmPhysSeg[segID];
|
||||
if ((pa < seg->start) || (pa >= (seg->start + seg->size))) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
offset = pa - seg->start;
|
||||
return (seg->pageBase + (offset >> PAGE_SHIFT));
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
LosVmPage *OsVmPhysPagesAlloc(struct VmPhysSeg *seg, size_t nPages)
|
||||
{
|
||||
struct VmFreeList *list = NULL;
|
||||
LosVmPage *page = NULL;
|
||||
UINT32 order;
|
||||
UINT32 newOrder;
|
||||
|
||||
if ((seg == NULL) || (nPages == 0)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
order = OsVmPagesToOrder(nPages);
|
||||
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);
|
||||
goto DONE;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
DONE:
|
||||
OsVmPhysFreeListDelUnsafe(page);
|
||||
OsVmPhysPagesSpiltUnsafe(page, order, newOrder);
|
||||
return page;
|
||||
}
|
||||
|
||||
VOID OsVmPhysPagesFree(LosVmPage *page, UINT8 order)
|
||||
{
|
||||
paddr_t pa;
|
||||
LosVmPage *buddyPage = NULL;
|
||||
|
||||
if ((page == NULL) || (order >= VM_LIST_ORDER_MAX)) {
|
||||
return;
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
OsVmPhysFreeListDel(buddyPage);
|
||||
order++;
|
||||
pa &= ~(VM_ORDER_TO_PHYS(order) - 1);
|
||||
page = OsVmPhysToPage(pa, page->segID);
|
||||
} while (order < VM_LIST_ORDER_MAX - 1);
|
||||
}
|
||||
|
||||
OsVmPhysFreeListAdd(page, order);
|
||||
}
|
||||
|
||||
VOID OsVmPhysPagesFreeContiguous(LosVmPage *page, size_t nPages)
|
||||
{
|
||||
paddr_t pa;
|
||||
UINT32 order;
|
||||
size_t count;
|
||||
size_t n;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
for (count = 0; count < nPages; count += n) {
|
||||
order = LOS_HighBitGet(nPages);
|
||||
n = VM_ORDER_TO_PAGES(order);
|
||||
OsVmPhysPagesFree(page, order);
|
||||
page += n;
|
||||
}
|
||||
}
|
||||
|
||||
STATIC LosVmPage *OsVmPhysPagesGet(size_t nPages)
|
||||
{
|
||||
UINT32 intSave;
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
LosVmPage *page = NULL;
|
||||
UINT32 segID;
|
||||
|
||||
if (nPages == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
|
||||
seg = &g_vmPhysSeg[segID];
|
||||
LOS_SpinLockSave(&seg->freeListLock, &intSave);
|
||||
page = OsVmPhysPagesAlloc(seg, nPages);
|
||||
if (page != NULL) {
|
||||
/* the first page of continuous physical addresses holds refCounts */
|
||||
LOS_AtomicSet(&page->refCounts, 0);
|
||||
page->nPages = nPages;
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
return page;
|
||||
}
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
VOID *LOS_PhysPagesAllocContiguous(size_t nPages)
|
||||
{
|
||||
LosVmPage *page = NULL;
|
||||
|
||||
if (nPages == 0) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
page = OsVmPhysPagesGet(nPages);
|
||||
if (page == NULL) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return OsVmPageToVaddr(page);
|
||||
}
|
||||
|
||||
VOID LOS_PhysPagesFreeContiguous(VOID *ptr, size_t nPages)
|
||||
{
|
||||
UINT32 intSave;
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
LosVmPage *page = NULL;
|
||||
|
||||
if (ptr == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
page = OsVmVaddrToPage(ptr);
|
||||
if (page == NULL) {
|
||||
VM_ERR("vm page of ptr(%#x) is null", ptr);
|
||||
return;
|
||||
}
|
||||
page->nPages = 0;
|
||||
|
||||
seg = &g_vmPhysSeg[page->segID];
|
||||
LOS_SpinLockSave(&seg->freeListLock, &intSave);
|
||||
|
||||
OsVmPhysPagesFreeContiguous(page, nPages);
|
||||
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
}
|
||||
|
||||
VADDR_T *LOS_PaddrToKVaddr(PADDR_T paddr)
|
||||
{
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
UINT32 segID;
|
||||
|
||||
for (segID = 0; segID < g_vmPhysSegNum; segID++) {
|
||||
seg = &g_vmPhysSeg[segID];
|
||||
if ((paddr >= seg->start) && (paddr < (seg->start + seg->size))) {
|
||||
return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);
|
||||
}
|
||||
}
|
||||
|
||||
return (VADDR_T *)(UINTPTR)(paddr - SYS_MEM_BASE + KERNEL_ASPACE_BASE);
|
||||
}
|
||||
|
||||
VOID LOS_PhysPageFree(LosVmPage *page)
|
||||
{
|
||||
UINT32 intSave;
|
||||
struct VmPhysSeg *seg = NULL;
|
||||
|
||||
if (page == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
||||
|
||||
LosVmPage *LOS_PhysPageAlloc(VOID)
|
||||
{
|
||||
return OsVmPhysPagesGet(ONE_PAGE);
|
||||
}
|
||||
|
||||
size_t LOS_PhysPagesAlloc(size_t nPages, LOS_DL_LIST *list)
|
||||
{
|
||||
LosVmPage *page = NULL;
|
||||
size_t count = 0;
|
||||
|
||||
if ((list == NULL) || (nPages == 0)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
while (nPages--) {
|
||||
page = OsVmPhysPagesGet(ONE_PAGE);
|
||||
if (page == NULL) {
|
||||
break;
|
||||
}
|
||||
LOS_ListTailInsert(list, &page->node);
|
||||
count++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
VOID OsPhysSharePageCopy(PADDR_T oldPaddr, PADDR_T *newPaddr, LosVmPage *newPage)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosVmPage *oldPage = NULL;
|
||||
VOID *newMem = NULL;
|
||||
VOID *oldMem = NULL;
|
||||
LosVmPhysSeg *seg = NULL;
|
||||
|
||||
if ((newPage == NULL) || (newPaddr == NULL)) {
|
||||
VM_ERR("new Page invalid");
|
||||
return;
|
||||
}
|
||||
|
||||
oldPage = LOS_VmPageGet(oldPaddr);
|
||||
if (oldPage == NULL) {
|
||||
VM_ERR("invalid paddr %p", oldPaddr);
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
LOS_SpinUnlockRestore(&seg->freeListLock, intSave);
|
||||
return;
|
||||
}
|
||||
|
||||
struct VmPhysSeg *OsVmPhysSegGet(LosVmPage *page)
|
||||
{
|
||||
if ((page == NULL) || (page->segID >= VM_PHYS_SEG_MAX)) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return (OsGVmPhysSegGet() + page->segID);
|
||||
}
|
||||
|
||||
UINT32 OsVmPagesToOrder(size_t nPages)
|
||||
{
|
||||
UINT32 order;
|
||||
|
||||
for (order = 0; VM_ORDER_TO_PAGES(order) < nPages; order++);
|
||||
|
||||
return order;
|
||||
}
|
||||
|
||||
size_t LOS_PhysPagesFree(LOS_DL_LIST *list)
|
||||
{
|
||||
UINT32 intSave;
|
||||
LosVmPage *page = NULL;
|
||||
LosVmPage *nPage = NULL;
|
||||
LosVmPhysSeg *seg = NULL;
|
||||
size_t count = 0;
|
||||
|
||||
if (list == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
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++;
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
346
kernel/base/vm/los_vm_scan.c
Executable file
346
kernel/base/vm/los_vm_scan.c
Executable file
@@ -0,0 +1,346 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "menuconfig.h"
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
|
||||
#include "fs/file.h"
|
||||
#include "los_vm_filemap.h"
|
||||
|
||||
/* unmap a lru page by map record info caller need lru lock */
|
||||
VOID OsUnmapPageLocked(LosFilePage *page, LosMapInfo *info)
|
||||
{
|
||||
if (page == NULL || info == NULL) {
|
||||
VM_ERR("UnmapPage error input null!");
|
||||
return;
|
||||
}
|
||||
page->n_maps--;
|
||||
LOS_ListDelete(&info->node);
|
||||
LOS_AtomicDec(&page->vmPage->refCounts);
|
||||
LOS_ArchMmuUnmap(info->archMmu, info->vaddr, 1);
|
||||
LOS_MemFree(m_aucSysMem0, info);
|
||||
}
|
||||
|
||||
VOID OsUnmapAllLocked(LosFilePage *page)
|
||||
{
|
||||
LosMapInfo *info = NULL;
|
||||
LosMapInfo *next = NULL;
|
||||
LOS_DL_LIST *immap = &page->i_mmap;
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(info, next, immap, LosMapInfo, node) {
|
||||
OsUnmapPageLocked(page, info);
|
||||
}
|
||||
}
|
||||
|
||||
/* add a new lru node to lru list, lruType can be file or anon */
|
||||
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);
|
||||
}
|
||||
|
||||
/* dellete 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);
|
||||
}
|
||||
|
||||
/* page referced add: (call by page cache get)
|
||||
----------inactive----------|----------active------------
|
||||
[ref:0,act:0], [ref:1,act:0]|[ref:0,act:1], [ref:1,act:1]
|
||||
ref:0, act:0 --> ref:1, act:0
|
||||
ref:1, act:0 --> ref:0, act:1
|
||||
ref:0, act:1 --> ref:1, act:1
|
||||
*/
|
||||
VOID OsPageRefIncLocked(LosFilePage *fpage)
|
||||
{
|
||||
BOOL isOrgActive;
|
||||
UINT32 intSave;
|
||||
LosVmPage *page = NULL;
|
||||
|
||||
if (fpage == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
if (!isOrgActive && OsIsPageActive(page)) {
|
||||
/* move inactive to active */
|
||||
OsMoveToActiveList(fpage);
|
||||
/* no change, move head */
|
||||
} else {
|
||||
if (OsIsPageActive(page)) {
|
||||
OsMoveToActiveHead(fpage);
|
||||
} else {
|
||||
OsMoveToInactiveHead(fpage);
|
||||
}
|
||||
}
|
||||
|
||||
LOS_SpinUnlockRestore(&fpage->physSeg->lruLock, intSave);
|
||||
}
|
||||
|
||||
/* page referced dec: (call by thrinker)
|
||||
----------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
|
||||
*/
|
||||
VOID OsPageRefDecNoLock(LosFilePage *fpage)
|
||||
{
|
||||
BOOL isOrgActive;
|
||||
LosVmPage *page = NULL;
|
||||
|
||||
if (fpage == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
page = fpage->vmPage;
|
||||
isOrgActive = OsIsPageActive(page);
|
||||
|
||||
if (!OsIsPageReferenced(page) && OsIsPageActive(page)) {
|
||||
OsCleanPageActive(page);
|
||||
OsSetPageReferenced(page);
|
||||
} else if (OsIsPageReferenced(page)) {
|
||||
OsCleanPageReferenced(page);
|
||||
}
|
||||
|
||||
if (isOrgActive && !OsIsPageActive(page)) {
|
||||
OsMoveToInactiveList(fpage);
|
||||
}
|
||||
}
|
||||
|
||||
VOID OsShrinkActiveList(LosVmPhysSeg *physSeg, int nScan)
|
||||
{
|
||||
LosFilePage *fpage = NULL;
|
||||
LosFilePage *fnext = NULL;
|
||||
LOS_DL_LIST *activeFile = &physSeg->lruList[VM_LRU_ACTIVE_FILE];
|
||||
|
||||
LOS_DL_LIST_FOR_EACH_ENTRY_SAFE(fpage, fnext, activeFile, LosFilePage, lru) {
|
||||
if (LOS_SpinTrylock(&fpage->mapping->list_lock) != LOS_OK) {
|
||||
continue;
|
||||
}
|
||||
|
||||
/* happend 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);
|
||||
|
||||
if (--nScan <= 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int OsShrinkInactiveList(LosVmPhysSeg *physSeg, int nScan, LOS_DL_LIST *list)
|
||||
{
|
||||
UINT32 nrReclaimed = 0;
|
||||
LosVmPage *page = NULL;
|
||||
SPIN_LOCK_S *flock = NULL;
|
||||
LosFilePage *fpage = NULL;
|
||||
LosFilePage *fnext = NULL;
|
||||
LosFilePage *ftemp = NULL;
|
||||
LOS_DL_LIST *inactive_file = &physSeg->lruList[VM_LRU_INACTIVE_FILE];
|
||||
|
||||
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) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return nrReclaimed;
|
||||
}
|
||||
|
||||
bool InactiveListIsLow(LosVmPhysSeg *physSeg)
|
||||
{
|
||||
return (physSeg->lruSize[VM_LRU_ACTIVE_FILE] > physSeg->lruSize[VM_LRU_INACTIVE_FILE]) ? TRUE : FALSE;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
int OsTryShrinkMemory(size_t nPage)
|
||||
{
|
||||
UINT32 intSave;
|
||||
size_t totalPages;
|
||||
size_t nReclaimed = 0;
|
||||
LosVmPhysSeg *physSeg = NULL;
|
||||
UINT32 index;
|
||||
LOS_DL_LIST_HEAD(dirtyList);
|
||||
LosFilePage *fpage = NULL;
|
||||
LosFilePage *fnext = NULL;
|
||||
|
||||
if (nPage <= 0) {
|
||||
nPage = VM_FILEMAP_MIN_SCAN;
|
||||
}
|
||||
|
||||
if (nPage > VM_FILEMAP_MAX_SCAN) {
|
||||
nPage = VM_FILEMAP_MAX_SCAN;
|
||||
}
|
||||
|
||||
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 (InactiveListIsLow(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);
|
||||
}
|
||||
|
||||
return nReclaimed;
|
||||
}
|
||||
#else
|
||||
int TryShrinkMemory(size_t nPage)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
439
kernel/base/vm/los_vm_syscall.c
Executable file
439
kernel/base/vm/los_vm_syscall.c
Executable file
@@ -0,0 +1,439 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
/**
|
||||
* @defgroup los_vm_syscall vm syscall definition
|
||||
* @ingroup kernel
|
||||
*/
|
||||
|
||||
#include "los_typedef.h"
|
||||
#include "los_vm_syscall.h"
|
||||
#include "los_vm_common.h"
|
||||
#include "los_rbtree.h"
|
||||
#include "los_vm_map.h"
|
||||
#include "los_vm_dump.h"
|
||||
#include "los_vm_lock.h"
|
||||
#include "los_vm_filemap.h"
|
||||
#include "los_process_pri.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
STATUS_T OsCheckMMapParams(VADDR_T vaddr, unsigned prot, unsigned long flags, size_t len, unsigned long pgoff)
|
||||
{
|
||||
if ((vaddr != 0) && !LOS_IsUserAddressRange(vaddr, len)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (len == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
/* we only support some prot and flags */
|
||||
if ((prot & PROT_SUPPORT_MASK) == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if ((flags & MAP_SUPPORT_MASK) == 0) {
|
||||
return -EINVAL;
|
||||
}
|
||||
if (((flags & MAP_SHARED_PRIVATE) == 0) || ((flags & MAP_SHARED_PRIVATE) == MAP_SHARED_PRIVATE)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (((len >> PAGE_SHIFT) + pgoff) < pgoff) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
STATUS_T OsAnonMMap(LosVmMapRegion *region)
|
||||
{
|
||||
LOS_SetRegionTypeAnon(region);
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
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;
|
||||
LosVmMapRegion *newRegion = NULL;
|
||||
struct file *filep = NULL;
|
||||
LosVmSpace *vmSpace = OsCurrProcessGet()->vmSpace;
|
||||
|
||||
vaddr = ROUNDUP(vaddr, PAGE_SIZE);
|
||||
len = ROUNDUP(len, PAGE_SIZE);
|
||||
STATUS_T checkRst = OsCheckMMapParams(vaddr, prot, flags, len, pgoff);
|
||||
if (checkRst != LOS_OK) {
|
||||
return checkRst;
|
||||
}
|
||||
|
||||
if (LOS_IsNamedMapping(flags)) {
|
||||
status = fs_getfilep(fd, &filep);
|
||||
if (status < 0) {
|
||||
return -EBADF;
|
||||
}
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(&vmSpace->regionMux);
|
||||
/* user mode calls mmap to release heap physical memory without releasing heap virtual space */
|
||||
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);
|
||||
resultVaddr = (VADDR_T)-ENOMEM;
|
||||
goto MMAP_DONE;
|
||||
}
|
||||
|
||||
MMAP_DONE:
|
||||
(VOID)LOS_MuxRelease(&vmSpace->regionMux);
|
||||
return resultVaddr;
|
||||
}
|
||||
|
||||
STATUS_T LOS_UnMMap(VADDR_T addr, size_t size)
|
||||
{
|
||||
if ((addr <= 0) || (size <= 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
return OsUnMMap(OsCurrProcessGet()->vmSpace, addr, size);
|
||||
}
|
||||
|
||||
VOID *LOS_DoBrk(VOID *addr)
|
||||
{
|
||||
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
|
||||
size_t size;
|
||||
VOID *ret = NULL;
|
||||
LosVmMapRegion *region = NULL;
|
||||
VOID *alignAddr = NULL;
|
||||
VADDR_T newBrk, oldBrk;
|
||||
|
||||
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);
|
||||
|
||||
if (addr < (VOID *)(UINTPTR)space->heapNow) {
|
||||
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;
|
||||
}
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
if (space->heapBase == space->heapNow) {
|
||||
region = LOS_RegionAlloc(space, space->heapBase, size,
|
||||
VM_MAP_REGION_FLAG_PERM_READ | VM_MAP_REGION_FLAG_PERM_WRITE |
|
||||
VM_MAP_REGION_FLAG_PERM_USER, 0);
|
||||
if (region == NULL) {
|
||||
ret = (VOID *)-ENOMEM;
|
||||
VM_ERR("LOS_RegionAlloc failed");
|
||||
goto REGION_ALLOC_FAILED;
|
||||
}
|
||||
region->regionFlags |= VM_MAP_REGION_FLAG_HEAP;
|
||||
space->heap = region;
|
||||
}
|
||||
|
||||
if ((UINTPTR)alignAddr >= space->mapBase) {
|
||||
VM_ERR("Process heap memory space is insufficient");
|
||||
goto REGION_ALLOC_FAILED;
|
||||
}
|
||||
|
||||
space->heapNow = (VADDR_T)(UINTPTR)alignAddr;
|
||||
space->heap->range.size = size;
|
||||
ret = (VOID *)(UINTPTR)space->heapNow;
|
||||
|
||||
REGION_ALLOC_FAILED:
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int LOS_DoMprotect(VADDR_T vaddr, size_t len, unsigned long prot)
|
||||
{
|
||||
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
|
||||
LosVmMapRegion *region = NULL;
|
||||
UINT32 vmFlags;
|
||||
UINT32 count;
|
||||
int ret;
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
region = LOS_RegionFind(space, vaddr);
|
||||
if (!IS_ALIGNED(vaddr, PAGE_SIZE) || (region == NULL) || (vaddr > vaddr + len)) {
|
||||
ret = -EINVAL;
|
||||
goto OUT_MPROTECT;
|
||||
}
|
||||
|
||||
if ((prot & ~(PROT_READ | PROT_WRITE | PROT_EXEC))) {
|
||||
ret = -EINVAL;
|
||||
goto OUT_MPROTECT;
|
||||
}
|
||||
|
||||
len = LOS_Align(len, PAGE_SIZE);
|
||||
/* can't operation cross region */
|
||||
if (region->range.base + region->range.size < vaddr + len) {
|
||||
ret = -EINVAL;
|
||||
goto OUT_MPROTECT;
|
||||
}
|
||||
|
||||
/* if only move some part of region, we need to split first */
|
||||
if (region->range.size > len) {
|
||||
OsVmRegionAdjust(space, vaddr, len);
|
||||
}
|
||||
|
||||
vmFlags = OsCvtProtFlagsToRegionFlags(prot, 0);
|
||||
vmFlags |= (region->regionFlags & VM_MAP_REGION_FLAG_SHARED) ? VM_MAP_REGION_FLAG_SHARED : 0;
|
||||
region = LOS_RegionFind(space, vaddr);
|
||||
if (region == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MPROTECT;
|
||||
}
|
||||
region->regionFlags = vmFlags;
|
||||
count = len >> PAGE_SHIFT;
|
||||
ret = LOS_ArchMmuChangeProt(&space->archMmu, vaddr, count, region->regionFlags);
|
||||
if (ret) {
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MPROTECT;
|
||||
}
|
||||
ret = LOS_OK;
|
||||
|
||||
OUT_MPROTECT:
|
||||
#ifdef LOSCFG_VM_OVERLAP_CHECK
|
||||
if (VmmAspaceRegionsOverlapCheck(aspace) < 0) {
|
||||
(VOID)OsShellCmdDumpVm(0, NULL);
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return ret;
|
||||
}
|
||||
|
||||
STATUS_T OsMremapCheck(VADDR_T addr, size_t oldLen, VADDR_T newAddr, size_t newLen, unsigned int flags)
|
||||
{
|
||||
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
|
||||
LosVmMapRegion *region = LOS_RegionFind(space, addr);
|
||||
VADDR_T regionEnd;
|
||||
|
||||
if ((region == NULL) || (region->range.base > addr) || (newLen == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (flags & ~(MREMAP_FIXED | MREMAP_MAYMOVE)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (((flags & MREMAP_FIXED) == MREMAP_FIXED) && ((flags & MREMAP_MAYMOVE) == 0)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(addr, PAGE_SIZE)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
regionEnd = region->range.base + region->range.size;
|
||||
|
||||
/* we can't operate across region */
|
||||
if (oldLen > regionEnd - addr) {
|
||||
return -EFAULT;
|
||||
}
|
||||
|
||||
/* avoiding overflow */
|
||||
if (newLen > oldLen) {
|
||||
if ((addr + newLen) < addr) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
/* avoid new region overlaping with the old one */
|
||||
if (flags & MREMAP_FIXED) {
|
||||
if (((region->range.base + region->range.size) > newAddr) &&
|
||||
(region->range.base < (newAddr + newLen))) {
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
if (!IS_ALIGNED(newAddr, PAGE_SIZE)) {
|
||||
return -EINVAL;
|
||||
}
|
||||
}
|
||||
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
VADDR_T LOS_DoMremap(VADDR_T oldAddress, size_t oldSize, size_t newSize, int flags, VADDR_T newAddr)
|
||||
{
|
||||
LosVmMapRegion *regionOld = NULL;
|
||||
LosVmMapRegion *regionNew = NULL;
|
||||
STATUS_T status;
|
||||
VADDR_T ret;
|
||||
LosVmSpace *space = OsCurrProcessGet()->vmSpace;
|
||||
|
||||
oldSize = LOS_Align(oldSize, PAGE_SIZE);
|
||||
newSize = LOS_Align(newSize, PAGE_SIZE);
|
||||
|
||||
(VOID)LOS_MuxAcquire(&space->regionMux);
|
||||
|
||||
status = OsMremapCheck(oldAddress, oldSize, newAddr, newSize, (unsigned int)flags);
|
||||
if (status) {
|
||||
ret = status;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
|
||||
/* if only move some part of region, we need to split first */
|
||||
status = OsVmRegionAdjust(space, oldAddress, oldSize);
|
||||
if (status) {
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
|
||||
regionOld = LOS_RegionFind(space, oldAddress);
|
||||
if (regionOld == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
|
||||
if ((unsigned int)flags & MREMAP_FIXED) {
|
||||
regionNew = OsVmRegionDup(space, regionOld, newAddr, newSize);
|
||||
if (!regionNew) {
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
status = LOS_ArchMmuMove(&space->archMmu, oldAddress, newAddr, newSize >> PAGE_SHIFT, regionOld->regionFlags);
|
||||
if (status) {
|
||||
LOS_RegionFree(space, regionNew);
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
LOS_RegionFree(space, regionOld);
|
||||
ret = newAddr;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
// take it as shrink operation
|
||||
if (oldSize > newSize) {
|
||||
LOS_UnMMap(oldAddress + newSize, oldSize - newSize);
|
||||
ret = oldAddress;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
status = OsIsRegionCanExpand(space, regionOld, newSize);
|
||||
// we can expand directly.
|
||||
if (!status) {
|
||||
regionOld->range.size = newSize;
|
||||
ret = oldAddress;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
|
||||
if ((unsigned int)flags & MREMAP_MAYMOVE) {
|
||||
regionNew = OsVmRegionDup(space, regionOld, 0, newSize);
|
||||
if (regionNew == NULL) {
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
status = LOS_ArchMmuMove(&space->archMmu, oldAddress, regionNew->range.base, newSize >> PAGE_SHIFT,
|
||||
regionOld->regionFlags);
|
||||
if (status) {
|
||||
LOS_RegionFree(space, regionNew);
|
||||
ret = -ENOMEM;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
LOS_RegionFree(space, regionOld);
|
||||
ret = regionNew->range.base;
|
||||
goto OUT_MREMAP;
|
||||
}
|
||||
|
||||
ret = -EINVAL;
|
||||
OUT_MREMAP:
|
||||
#ifdef LOSCFG_VM_OVERLAP_CHECK
|
||||
if (VmmAspaceRegionsOverlapCheck(aspace) < 0) {
|
||||
(VOID)OsShellCmdDumpVm(0, NULL);
|
||||
ret = -ENOMEM;
|
||||
}
|
||||
#endif
|
||||
|
||||
(VOID)LOS_MuxRelease(&space->regionMux);
|
||||
return ret;
|
||||
}
|
||||
|
||||
VOID LOS_DumpMemRegion(VADDR_T vaddr)
|
||||
{
|
||||
LosVmSpace *space = NULL;
|
||||
|
||||
space = OsCurrProcessGet()->vmSpace;
|
||||
if (space == NULL) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (LOS_IsRangeInSpace(space, ROUNDDOWN(vaddr, MB), MB) == FALSE) {
|
||||
return;
|
||||
}
|
||||
|
||||
OsDumpPte(vaddr);
|
||||
OsDumpAspace(space);
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
253
kernel/base/vm/oom.c
Executable file
253
kernel/base/vm/oom.c
Executable file
@@ -0,0 +1,253 @@
|
||||
/*
|
||||
* Copyright (c) 2013-2019, Huawei Technologies Co., Ltd. All rights reserved.
|
||||
* Copyright (c) 2020, Huawei Device Co., Ltd. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without modification,
|
||||
* are permitted provided that the following conditions are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright notice, this list of
|
||||
* conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright notice, this list
|
||||
* of conditions and the following disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* 3. Neither the name of the copyright holder nor the names of its contributors may be used
|
||||
* to endorse or promote products derived from this software without specific prior written
|
||||
* permission.
|
||||
*
|
||||
* 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
|
||||
* PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
|
||||
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
|
||||
* EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
|
||||
* PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
|
||||
* OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
|
||||
* OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
|
||||
* ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||
*/
|
||||
|
||||
#include "sys_config.h"
|
||||
#include "los_oom.h"
|
||||
#include "los_vm_dump.h"
|
||||
#include "los_vm_lock.h"
|
||||
#include "los_vm_phys.h"
|
||||
#include "los_vm_filemap.h"
|
||||
#include "los_process_pri.h"
|
||||
#if (LOSCFG_BASE_CORE_SWTMR == YES)
|
||||
#include "los_swtmr_pri.h"
|
||||
#endif
|
||||
|
||||
#ifdef LOSCFG_FS_VFS
|
||||
#include "console.h"
|
||||
#endif
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
extern "C" {
|
||||
#endif /* __cplusplus */
|
||||
#endif /* __cplusplus */
|
||||
|
||||
LITE_OS_SEC_BSS OomCB *g_oomCB = NULL;
|
||||
static SPIN_LOCK_INIT(g_oomSpinLock);
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomScoreProcess(LosProcessCB *candidateProcess)
|
||||
{
|
||||
UINT32 actualPm;
|
||||
|
||||
#if (LOSCFG_KERNEL_SMP != YES)
|
||||
(VOID)LOS_MuxAcquire(&candidateProcess->vmSpace->regionMux);
|
||||
#endif
|
||||
/* we only consider actual physical memory here. */
|
||||
OsUProcessPmUsage(candidateProcess->vmSpace, NULL, &actualPm);
|
||||
#if (LOSCFG_KERNEL_SMP != YES)
|
||||
(VOID)LOS_MuxRelease(&candidateProcess->vmSpace->regionMux);
|
||||
#endif
|
||||
return actualPm;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomKillProcess(UINTPTR param)
|
||||
{
|
||||
/* we will not kill process, and do nothing here */
|
||||
return LOS_OK;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC UINT32 OomForceShrinkMemory(VOID)
|
||||
{
|
||||
UINT32 i;
|
||||
UINT32 reclaimMemPages = 0;
|
||||
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) {
|
||||
reclaimMemPages += OsTryShrinkMemory(0);
|
||||
}
|
||||
|
||||
return reclaimMemPages;
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR STATIC BOOL OomReclaimPageCache(VOID)
|
||||
{
|
||||
UINT32 totalPm = 0;
|
||||
UINT32 usedPm = 0;
|
||||
BOOL isReclaimMemory = FALSE;
|
||||
UINT32 reclaimMemPages;
|
||||
UINT32 i;
|
||||
|
||||
for (i = 0; i < MAX_SHRINK_PAGECACHE_TRY; i++) {
|
||||
OsVmPhysUsedInfoGet(&usedPm, &totalPm);
|
||||
isReclaimMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->reclaimMemThreshold;
|
||||
if (isReclaimMemory) {
|
||||
/*
|
||||
* 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.
|
||||
*/
|
||||
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)
|
||||
{
|
||||
UINT32 totalPm;
|
||||
UINT32 usedPm;
|
||||
BOOL isLowMemory = FALSE;
|
||||
|
||||
/*
|
||||
* spinlock the current core schedule, make sure oom process atomic
|
||||
* spinlock other place entering OomCheckProcess, make sure oom process mutex
|
||||
*/
|
||||
LOS_SpinLock(&g_oomSpinLock);
|
||||
|
||||
/* first we will check if we need to reclaim pagecache memory */
|
||||
if (OomReclaimPageCache() == FALSE) {
|
||||
goto NO_VICTIM_PROCESS;
|
||||
}
|
||||
|
||||
/* get free bytes */
|
||||
OsVmPhysUsedInfoGet(&usedPm, &totalPm);
|
||||
isLowMemory = ((totalPm - usedPm) << PAGE_SHIFT) < g_oomCB->lowMemThreshold;
|
||||
if (isLowMemory) {
|
||||
PRINTK("[oom] OS is in low memory state\n"
|
||||
"total physical memory: %#x(byte), used: %#x(byte),"
|
||||
"free: %#x(byte), low memory threshold: %#x(byte)\n",
|
||||
totalPm << PAGE_SHIFT, usedPm << PAGE_SHIFT,
|
||||
(totalPm - usedPm) << PAGE_SHIFT, g_oomCB->lowMemThreshold);
|
||||
}
|
||||
|
||||
NO_VICTIM_PROCESS:
|
||||
LOS_SpinUnlock(&g_oomSpinLock);
|
||||
return isLowMemory;
|
||||
}
|
||||
|
||||
#ifdef LOSCFG_ENABLE_OOM_LOOP_TASK
|
||||
STATIC VOID OomWriteEvent(VOID)
|
||||
{
|
||||
OsWriteResourceEvent(OS_RESOURCE_EVENT_OOM);
|
||||
}
|
||||
#endif
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomInfodump(VOID)
|
||||
{
|
||||
PRINTK("[oom] oom loop task status: %s\n"
|
||||
" oom low memory threshold: %#x(byte)\n"
|
||||
" oom reclaim memory threshold: %#x(byte)\n"
|
||||
" oom check interval: %d(microsecond)\n",
|
||||
g_oomCB->enabled ? "enabled" : "disabled",
|
||||
g_oomCB->lowMemThreshold, g_oomCB->reclaimMemThreshold,
|
||||
g_oomCB->checkInterval);
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomSetLowMemThreashold(UINT32 lowMemThreshold)
|
||||
{
|
||||
if ((lowMemThreshold > OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX)) {
|
||||
PRINTK("[oom] low memory threshold %#x(byte) invalid,"
|
||||
"should be in [%#x, %#x](byte)\n",
|
||||
lowMemThreshold, OOM_DEFAULT_LOW_MEM_THRESHOLD_MIN,
|
||||
OOM_DEFAULT_LOW_MEM_THRESHOLD_MAX);
|
||||
} else {
|
||||
g_oomCB->lowMemThreshold = lowMemThreshold;
|
||||
PRINTK("[oom] set oom low memory threshold %#x(byte) successful\n",
|
||||
g_oomCB->lowMemThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomSetReclaimMemThreashold(UINT32 reclaimMemThreshold)
|
||||
{
|
||||
UINT32 totalPm = 0;
|
||||
UINT32 usedPm = 0;
|
||||
|
||||
OsVmPhysUsedInfoGet(&usedPm, &totalPm);
|
||||
if ((reclaimMemThreshold >= (totalPm << PAGE_SHIFT)) ||
|
||||
(reclaimMemThreshold < g_oomCB->lowMemThreshold)) {
|
||||
PRINTK("[oom] reclaim memory threshold %#x(byte) invalid,"
|
||||
"should be in [%#x, %#x)(byte)\n",
|
||||
reclaimMemThreshold, g_oomCB->lowMemThreshold, (totalPm << PAGE_SHIFT));
|
||||
} else {
|
||||
g_oomCB->reclaimMemThreshold = reclaimMemThreshold;
|
||||
PRINTK("[oom] set oom reclaim memory threshold %#x(byte) successful\n",
|
||||
g_oomCB->reclaimMemThreshold);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR VOID OomSetCheckInterval(UINT32 checkInterval)
|
||||
{
|
||||
if ((checkInterval >= OOM_CHECK_MIN) && (checkInterval <= OOM_CHECK_MAX)) {
|
||||
g_oomCB->checkInterval = checkInterval;
|
||||
PRINTK("[oom] set oom check interval (%d)ms successful\n",
|
||||
g_oomCB->checkInterval);
|
||||
} else {
|
||||
PRINTK("[oom] set oom check interval (%d)ms failed, should be in [%d, %d]\n",
|
||||
g_oomCB->checkInterval, OOM_CHECK_MIN, OOM_CHECK_MAX);
|
||||
}
|
||||
}
|
||||
|
||||
LITE_OS_SEC_TEXT_MINOR UINT32 OomTaskInit(VOID)
|
||||
{
|
||||
g_oomCB = (OomCB *)LOS_MemAlloc(m_aucSysMem0, sizeof(OomCB));
|
||||
if (g_oomCB == NULL) {
|
||||
VM_ERR("oom task init failed, malloc OomCB failed.");
|
||||
return LOS_NOK;
|
||||
}
|
||||
|
||||
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);
|
||||
if (ret != LOS_OK) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
return LOS_SwtmrStart(g_oomCB->swtmrID);
|
||||
#else
|
||||
return LOS_OK;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef __cplusplus
|
||||
#if __cplusplus
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user