From 68154d7ad8a4ab69d2218942b4a283375a92419d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=96=87=E8=B1=AA?= <2548632733@qq.com> Date: Mon, 22 Jan 2024 08:23:01 +0800 Subject: [PATCH] wenhao --- doc/文豪-用例描述.docx | Bin 0 -> 14105 bytes src/debug/los_mux_deadlock.c | 257 ++++++++++++++++++++++++++ src/debug/los_mux_debug.c | 189 +++++++++++++++++++ src/debug/los_queue_debug.c | 206 +++++++++++++++++++++ src/debug/los_sched_debug.c | 347 +++++++++++++++++++++++++++++++++++ src/debug/los_sem_debug.c | 299 ++++++++++++++++++++++++++++++ 6 files changed, 1298 insertions(+) create mode 100644 doc/文豪-用例描述.docx create mode 100644 src/debug/los_mux_deadlock.c create mode 100644 src/debug/los_mux_debug.c create mode 100644 src/debug/los_queue_debug.c create mode 100644 src/debug/los_sched_debug.c create mode 100644 src/debug/los_sem_debug.c diff --git a/doc/文豪-用例描述.docx b/doc/文豪-用例描述.docx new file mode 100644 index 0000000000000000000000000000000000000000..a5be5e412a48256759719611f03b383b2d93be84 GIT binary patch literal 14105 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 literal 0 HcmV?d00001 diff --git a/src/debug/los_mux_deadlock.c b/src/debug/los_mux_deadlock.c new file mode 100644 index 0000000..6862541 --- /dev/null +++ b/src/debug/los_mux_deadlock.c @@ -0,0 +1,257 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mutex Deadlock Check + * Author: Huawei LiteOS Team + * Create: 2013-01-01 + * 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_debug_pri.h" +#include "los_typedef.h" +#include "los_task.h" +#include "arch/exception.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */nbb + +typedef struct { + LOS_DL_LIST muxListHead; /* Task-held mutexs list */ //ڹеĻб// + UINT64 lastAccessTime; /* The last operation time */ //¼һβʱ// +} MuxDLinkCB; + +/*еĻб͸*/ +typedef struct { + LOS_DL_LIST muxList; /* Insert mutex into the owner task CB */ //ڽ뵽Ŀƿ// + VOID *muxCB; /* The Mutex CB pointer */ //ָ򻥳ƿָ// +} MuxDLinkNode; + +STATIC MuxDLinkCB *g_muxDeadlockCBArray = NULL; + +/* + * Mutex deadlock detection time threshold, will print out task information + * that has not been scheduled within this time. + * The unit is tick. + */ +#define OS_MUX_DEADLOCK_CHECK_THRESHOLD 60000 //μ黥֮СʱλΪ// + +UINT32 OsMuxDlockCheckInit(VOID) //ڷڴ沢ʼƿб// +{ + UINT32 index; + UINT32 size = (LOSCFG_BASE_CORE_TSK_LIMIT + 1) * sizeof(MuxDLinkCB); + + /* system resident memory, don't free */ + g_muxDeadlockCBArray = (MuxDLinkCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_muxDeadlockCBArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } + + for (index = 0; index < LOSCFG_BASE_CORE_TSK_LIMIT + 1; index++) { + g_muxDeadlockCBArray[index].lastAccessTime = 0; + LOS_ListInit(&g_muxDeadlockCBArray[index].muxListHead); + } + return LOS_OK; +} + +VOID OsMuxDlockNodeInsert(UINT32 taskId, VOID *muxCB) //ָĻвһڵ// +{ + MuxDLinkNode *muxDLNode = NULL; + + if ((taskId > LOSCFG_BASE_CORE_TSK_LIMIT) || (muxCB == NULL)) { + return; + } + + muxDLNode = (MuxDLinkNode *)LOS_MemAlloc(m_aucSysMem1, sizeof(MuxDLinkNode)); + if (muxDLNode == NULL) { + return; + } + (VOID)memset_s(muxDLNode, sizeof(MuxDLinkNode), 0, sizeof(MuxDLinkNode)); + muxDLNode->muxCB = muxCB; + + LOS_ListTailInsert(&g_muxDeadlockCBArray[taskId].muxListHead, &muxDLNode->muxList); +} + +VOID OsMuxDlockNodeDelete(UINT32 taskId, const VOID *muxCB) //ڴָĻɾָĻڵ// +{ + MuxDLinkCB *muxDLCB = NULL; + LOS_DL_LIST *list = NULL; + MuxDLinkNode *muxDLNode = NULL; + + if ((taskId > LOSCFG_BASE_CORE_TSK_LIMIT) || (muxCB == NULL)) { + return; + } + + muxDLCB = &g_muxDeadlockCBArray[taskId]; + LOS_DL_LIST_FOR_EACH(list, &muxDLCB->muxListHead) { + muxDLNode = LOS_DL_LIST_ENTRY(list, MuxDLinkNode, muxList); + if (muxDLNode->muxCB == muxCB) { + LOS_ListDelete(&muxDLNode->muxList); + (VOID)LOS_MemFree(m_aucSysMem1, muxDLNode); + return; + } + } +} + +VOID OsTaskTimeUpdate(UINT32 taskId, UINT64 tickCount) //ڸʱ// +{ + if (taskId > LOSCFG_BASE_CORE_TSK_LIMIT) { + return; + } + + g_muxDeadlockCBArray[taskId].lastAccessTime = tickCount; +} + +STATIC VOID OsDeadlockBackTrace(const LosTaskCB *taskCB) //ڴӡĺջϢ// +{ + TaskContext *context = NULL; + + PRINTK("*******backtrace begin*******\n"); + context = (TaskContext *)taskCB->stackPointer; + ArchBackTraceWithSp(context); + PRINTK("********backtrace end********\n"); + return; +} + +STATIC VOID OsMutexPendTaskList(LOS_DL_LIST *list) //ڴӡȴбϢ// +{ + LOS_DL_LIST *listTmp = NULL; + LosTaskCB *pendedTask = NULL; + CHAR *name = NULL; + UINT32 index = 0; + UINT32 id, intSave; + + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(list) == TRUE) { + SCHEDULER_UNLOCK(intSave); + PRINTK("Pended Task: null\n"); + return; + } + + LOS_DL_LIST_FOR_EACH(listTmp, list) { + pendedTask = OS_TCB_FROM_PENDLIST(listTmp); + name = pendedTask->taskName; + id = pendedTask->taskId; + SCHEDULER_UNLOCK(intSave); + if (index == 0) { + PRINTK("Pended task: %u. name:%-15s, id:0x%-5x\n", index, name, id); + } else { + PRINTK(" %u. name:%-15s, id:0x%-5x\n", index, name, id); + } + index++; + SCHEDULER_LOCK(intSave); + } + SCHEDULER_UNLOCK(intSave); +} + +STATIC VOID OsTaskHoldMutexList(MuxDLinkCB *muxDLCB) //ڴӡеĻϢ// +{ + UINT32 index = 0; + MuxDLinkNode *muxDLNode = NULL; + CHAR *ownerName = NULL; + LosMuxCB *muxCB = NULL; + LOS_DL_LIST *list = NULL; + LOS_DL_LIST *listTmp = NULL; + UINT32 count, intSave; + + SCHEDULER_LOCK(intSave); + if (LOS_ListEmpty(&muxDLCB->muxListHead) == TRUE) { + SCHEDULER_UNLOCK(intSave); + PRINTK("null\n"); + } else { + LOS_DL_LIST_FOR_EACH(list, &muxDLCB->muxListHead) { + muxDLNode = LOS_DL_LIST_ENTRY(list, MuxDLinkNode, muxList); + muxCB = (LosMuxCB *)muxDLNode->muxCB; + count = muxCB->muxCount; + ownerName = muxCB->owner->taskName; + SCHEDULER_UNLOCK(intSave); + PRINTK("\n", index); + PRINTK("Ptr handle:%p\n", muxCB); + PRINTK("Owner:%s\n", ownerName); + PRINTK("Count:%u\n", count); + + listTmp = &muxCB->muxList; + OsMutexPendTaskList(listTmp); + + index++; + SCHEDULER_LOCK(intSave); + } + SCHEDULER_UNLOCK(intSave); + } +} + +VOID OsMutexDlockCheck(VOID) //ڼ⻥Ϣ// +{ + UINT32 loop, intSave; + UINT32 taskId; + CHAR *name = NULL; + LosTaskCB *taskCB = NULL; + MuxDLinkCB *muxDLCB = NULL; + + SCHEDULER_LOCK(intSave); + for (loop = 0; loop < g_taskMaxNum; loop++) { + taskCB = (LosTaskCB *)g_taskCBArray + loop; + if (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } + + muxDLCB = &g_muxDeadlockCBArray[taskCB->taskId]; + if ((LOS_TickCountGet() - muxDLCB->lastAccessTime) > OS_MUX_DEADLOCK_CHECK_THRESHOLD) { + name = taskCB->taskName; + taskId = taskCB->taskId; + SCHEDULER_UNLOCK(intSave); + PRINTK("Task_name:%s, ID:0x%x, holds the Mutexs below:\n", name, taskId); + OsTaskHoldMutexList(muxDLCB); + OsDeadlockBackTrace(taskCB); + PRINTK("\n"); + SCHEDULER_LOCK(intSave); + } + } + SCHEDULER_UNLOCK(intSave); +} + +#ifdef LOSCFG_SHELL //ִл鲢Ϣ// +UINT32 OsShellCmdMuxDeadlockCheck(UINT32 argc, const CHAR **argv) +{ + if (argc > 0) { + PRINTK("\nUsage: dlock\n"); + return OS_ERROR; + } + PRINTK("Start mutexs deadlock check: \n"); + OsMutexDlockCheck(); + PRINTK("-----------End-----------\n"); + return LOS_OK; +} +SHELLCMD_ENTRY(deadlock_shellcmd, CMD_TYPE_EX, "dlock", 0, (CmdCallBackFunc)OsShellCmdMuxDeadlockCheck); +#endif /* LOSCFG_SHELL */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/src/debug/los_mux_debug.c b/src/debug/los_mux_debug.c new file mode 100644 index 0000000..5008bc5 --- /dev/null +++ b/src/debug/los_mux_debug.c @@ -0,0 +1,189 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Mutex Debug + * Author: Huawei LiteOS Team + * Create: 2013-01-01 + * 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_debug_pri.h" +#include "los_typedef.h" +#include "los_task.h" +#include "los_misc_pri.h" +#include "arch/exception.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#ifdef LOSCFG_DEBUG_MUTEX //ڱʾĵϢ// +typedef struct { + TSK_ENTRY_FUNC creator; /* The task entry who created this mutex */ + UINT64 lastAccessTime; /* The last access time */ +} MuxDebugCB; +STATIC MuxDebugCB *g_muxDebugArray = NULL; + +//ڱȽϢʱ// +STATIC BOOL MuxCompareValue(const SortParam *sortParam, UINT32 left, UINT32 right) +{ + return (*((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, left)) > + *((UINT64 *)(VOID *)SORT_ELEM_ADDR(sortParam, right))); +} + +UINT32 OsMuxDbgInit(VOID) //ڳʼϢ// +{ + UINT32 size = LOSCFG_BASE_IPC_MUX_LIMIT * sizeof(MuxDebugCB); + /* system resident memory, don't free */ + g_muxDebugArray = (MuxDebugCB *)LOS_MemAlloc(m_aucSysMem1, size); + if (g_muxDebugArray == NULL) { + PRINT_ERR("%s: malloc failed!\n", __FUNCTION__); + return LOS_NOK; + } + (VOID)memset_s(g_muxDebugArray, size, 0, size); + return LOS_OK; +} + +VOID OsMuxDbgTimeUpdate(UINT32 muxId) //ڸָʱ// +{ + MuxDebugCB *muxDebug = &g_muxDebugArray[GET_MUX_INDEX(muxId)]; + muxDebug->lastAccessTime = LOS_TickCountGet(); +} + +VOID OsMuxDbgUpdate(UINT32 muxId, TSK_ENTRY_FUNC creator) //ڸָĴߺʱ// +{ + MuxDebugCB *muxDebug = &g_muxDebugArray[GET_MUX_INDEX(muxId)]; + muxDebug->creator = creator; + muxDebug->lastAccessTime = LOS_TickCountGet(); +} + +//ڶԻ򣬲ܴڵĻй©// +STATIC VOID SortMuxIndexArray(UINT32 *indexArray, UINT32 count) +{ + LosMuxCB muxNode = {{0, 0}, 0, 0, 0, 0}; + MuxDebugCB muxDebugNode = {0}; + UINT32 index, intSave; + SortParam muxSortParam; + muxSortParam.buf = (CHAR *)g_muxDebugArray; + muxSortParam.ctrlBlockSize = sizeof(MuxDebugCB); + muxSortParam.ctrlBlockCnt = LOSCFG_BASE_IPC_MUX_LIMIT; + muxSortParam.sortElemOff = LOS_OFF_SET_OF(MuxDebugCB, lastAccessTime); + + if (count > 0) { + SCHEDULER_LOCK(intSave); + OsArraySort(indexArray, 0, count - 1, &muxSortParam, MuxCompareValue); + SCHEDULER_UNLOCK(intSave); + for (index = 0; index < count; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&muxNode, sizeof(LosMuxCB), + GET_MUX(indexArray[index]), sizeof(LosMuxCB)); + (VOID)memcpy_s(&muxDebugNode, sizeof(MuxDebugCB), + &g_muxDebugArray[indexArray[index]], sizeof(MuxDebugCB)); + SCHEDULER_UNLOCK(intSave); + /* + * muxStat may be altered after the g_taskSpin is unlocked in OsMutexCheck. + * We should recheck the muxStat before the print. + */ + if ((muxNode.muxStat != LOS_USED) || + ((muxNode.muxStat == LOS_USED) && ((muxDebugNode.creator == NULL) || (muxNode.owner == NULL)))) { + continue; + } + PRINTK("Mutex ID <0x%x> may leak, TaskID of owner:0x%x, TaskEntry of owner: %p," + "TaskEntry of creator: %p,Latest operation time: 0x%llx\n", + muxNode.muxId, muxNode.owner->taskId, muxNode.owner->taskEntry, muxDebugNode.creator, + muxDebugNode.lastAccessTime); + } + } + (VOID)LOS_MemFree((VOID *)OS_SYS_MEM_ADDR, indexArray); +} + +VOID OsMutexCheck(VOID) //ڼ黥״̬ԿܴڵĻй©д// +{ + LosMuxCB muxNode = {{0, 0}, 0, 0, 0, 0}; + MuxDebugCB muxDebugNode = {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_MUX_LIMIT * sizeof(UINT32)); + + for (index = 0; index < LOSCFG_BASE_IPC_MUX_LIMIT; index++) { + SCHEDULER_LOCK(intSave); + (VOID)memcpy_s(&muxNode, sizeof(LosMuxCB), GET_MUX(index), sizeof(LosMuxCB)); + (VOID)memcpy_s(&muxDebugNode, sizeof(MuxDebugCB), &g_muxDebugArray[index], sizeof(MuxDebugCB)); + SCHEDULER_UNLOCK(intSave); + + if ((muxNode.muxStat != LOS_USED) || + ((muxNode.muxStat == LOS_USED) && (muxDebugNode.creator == NULL))) { + continue; + } else if ((muxNode.muxStat == LOS_USED) && (muxNode.owner == NULL)) { + PRINTK("Mutex ID <0x%x> may leak, Owner is null, TaskEntry of creator: %p," + "Latest operation time: 0x%llx\n", + muxNode.muxId, muxDebugNode.creator, muxDebugNode.lastAccessTime); + } else { + if (indexArray != NULL) { + *(indexArray + count) = index; + count++; + } else { + PRINTK("Mutex ID <0x%x> may leak, TaskID of owner:0x%x, TaskEntry of owner: %p," + "TaskEntry of creator: %p,Latest operation time: 0x%llx\n", + muxNode.muxId, muxNode.owner->taskId, muxNode.owner->taskEntry, muxDebugNode.creator, + muxDebugNode.lastAccessTime); + } + } + } + + if (indexArray != NULL) { + SortMuxIndexArray(indexArray, count); + } +} + +#ifdef LOSCFG_SHELL +//ڻȡϢ// +LITE_OS_SEC_TEXT_MINOR UINT32 OsShellCmdMuxInfoGet(UINT32 argc, const CHAR **argv) +{ + if (argc > 0) { + PRINTK("\nUsage: mutex\n"); + return OS_ERROR; + } + PRINTK("used mutexs information: \n"); + OsMutexCheck(); + return LOS_OK; +} +SHELLCMD_ENTRY(mutex_shellcmd, CMD_TYPE_EX, "mutex", 0, (CmdCallBackFunc)OsShellCmdMuxInfoGet); +#endif /* LOSCFG_SHELL */ +#endif /* LOSCFG_DEBUG_MUTEX */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */ diff --git a/src/debug/los_queue_debug.c b/src/debug/los_queue_debug.c new file mode 100644 index 0000000..43ba6ad --- /dev/null +++ b/src/debug/los_queue_debug.c @@ -0,0 +1,206 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Queue Debug + * Author: Huawei LiteOS Team + * Create: 2013-01-01 + * 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_misc_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 creator; /* The task entry who created this queue */ + UINT64 lastAccessTime; /* The last access time */ +} QueueDebugCB; +STATIC QueueDebugCB *g_queueDebugArray = NULL; + +//ڱȽ϶еԪֵ// +STATIC BOOL QueueCompareValue(const SortParam *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->creator = 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 creator:0x%p, Latest operation time: 0x%llx\n", + node->creator, node->lastAccessTime); +} + +STATIC VOID SortQueueIndexArray(UINT32 *indexArray, UINT32 count) //ڶԶӦĶϢ// +{ + LosQueueCB queueNode = {0}; + QueueDebugCB queueDebugNode = {0}; + UINT32 index, intSave; + SortParam queueSortParam; + queueSortParam.buf = (CHAR *)g_queueDebugArray; + queueSortParam.ctrlBlockSize = sizeof(QueueDebugCB); + queueSortParam.ctrlBlockCnt = LOSCFG_BASE_IPC_QUEUE_LIMIT; + queueSortParam.sortElemOff = LOS_OFF_SET_OF(QueueDebugCB, lastAccessTime); + + if (count > 0) { + SCHEDULER_LOCK(intSave); + OsArraySort(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 == LOS_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 == LOS_UNUSED) || + ((queueNode.queueState == LOS_USED) && (queueDebugNode.creator == NULL))) { + continue; + } + if ((queueNode.queueState == LOS_USED) && + (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 +//û "queue" ʱʹöеϢ// +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 */ diff --git a/src/debug/los_sched_debug.c b/src/debug/los_sched_debug.c new file mode 100644 index 0000000..ec4a78b --- /dev/null +++ b/src/debug/los_sched_debug.c @@ -0,0 +1,347 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2018-2019. All rights reserved. + * Description: Schedule Statistics + * Author: Huawei LiteOS Team + * Create: 2018-11-16 + * 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 */ + +#ifdef LOSCFG_DEBUG_SCHED_STATISTICS +#define HIGHTASKPRI 16 +#define NS_PER_MS 1000000 +#define DECIMAL_TO_PERCENTAGE 100 + +typedef struct { + UINT64 idleRuntime; //ʱ// + UINT64 idleStarttime; //ʱ// + UINT64 highTaskRuntime; //ȼʱ// + UINT64 highTaskStarttime; //ȼʱ// + UINT64 sumPriority; //ȼ֮// + UINT32 prioritySwitch; //л// + UINT32 highTaskSwitch; //ȼл// + UINT32 contexSwitch; //л// + UINT32 hwiNum; //Ӳжϴ// +#ifdef LOSCFG_KERNEL_SMP + UINT32 ipiIrqNum; //жϴڶ¶壩// +#endif +} StatPercpu; + +STATIC BOOL g_statisticsStartFlag = FALSE; +STATIC UINT64 g_statisticsStartTime; +STATIC StatPercpu g_statPercpu[LOSCFG_KERNEL_CORE_NUM]; + +//ÿ CPU Ͻеͳ// +STATIC VOID OsSchedStatisticsPerCpu(const LosTaskCB *runTask, const LosTaskCB *newTask) +{ + UINT32 cpuId; + UINT32 idleTaskId; + UINT64 now, runtime; + + if (g_statisticsStartFlag != TRUE) { + return; + } + + cpuId = ArchCurrCpuid(); + idleTaskId = OsGetIdleTaskId(); + now = LOS_CurrNanosec(); + + g_statPercpu[cpuId].contexSwitch++; + + if ((runTask->taskId != idleTaskId) && (newTask->taskId == idleTaskId)) { + g_statPercpu[cpuId].idleStarttime = now; + } + + if ((runTask->taskId == idleTaskId) && (newTask->taskId != idleTaskId)) { + runtime = now - g_statPercpu[cpuId].idleStarttime; + g_statPercpu[cpuId].idleRuntime += runtime; + g_statPercpu[cpuId].idleStarttime = 0; + } + + if ((runTask->priority >= HIGHTASKPRI) && (newTask->priority < HIGHTASKPRI)) { + g_statPercpu[cpuId].highTaskStarttime = now; + } + + if ((runTask->priority < HIGHTASKPRI) && (newTask->priority >= HIGHTASKPRI)) { + runtime = now - g_statPercpu[cpuId].highTaskStarttime; + g_statPercpu[cpuId].highTaskRuntime += runtime; + g_statPercpu[cpuId].highTaskStarttime = 0; + } + + if (newTask->priority < HIGHTASKPRI) { + g_statPercpu[cpuId].highTaskSwitch++; + } + + if (newTask->taskId != idleTaskId) { + g_statPercpu[cpuId].sumPriority += newTask->priority; + g_statPercpu[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; + OsSchedStatisticsPerCpu(runTask, newTask); +} + +LITE_OS_SEC_TEXT_MINOR VOID OsHwiStatistics(size_t intNum) //ڸӲжϵͳϢ// +{ + UINT32 cpuId = ArchCurrCpuid(); + + if ((g_statisticsStartFlag != TRUE) || (intNum == OS_TICK_INT_NUM)) { + return; + } + + g_statPercpu[cpuId].hwiNum++; +#ifdef LOSCFG_KERNEL_SMP + /* 16: 0~15 is ipi interrupts */ + if (intNum < 16) { + g_statPercpu[cpuId].ipiIrqNum++; + } +#endif + return; +} + +LITE_OS_SEC_TEXT_MINOR VOID OsShellCmdDumpSched(VOID) //ڴӡĵͳϢ// +{ + LosTaskCB *taskCB = NULL; + UINT32 loop; + UINT32 cpuId; +#ifdef LOSCFG_KERNEL_SMP + UINT32 affinity; +#endif + + 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 (taskCB->taskStatus & OS_TASK_STATUS_UNUSED) { + continue; + } +#ifdef LOSCFG_KERNEL_SMP + affinity = (UINT32)taskCB->cpuAffiMask; +#endif + PRINTK("%-30s0x%-6x%+16lf ms %10u\n", taskCB->taskName, taskCB->taskId, + (DOUBLE)(taskCB->schedStat.allRuntime) / NS_PER_MS, + taskCB->schedStat.allContextSwitch); + + for (cpuId = 0; cpuId < LOSCFG_KERNEL_CORE_NUM; cpuId++) { +#ifdef LOSCFG_KERNEL_SMP + if (!((1U << cpuId) & affinity)) { + continue; + } +#endif + PRINTK(" " + "CPU%u %+16lf ms %12u\n", cpuId, + (DOUBLE)(taskCB->schedStat.schedPercpu[cpuId].runtime) / NS_PER_MS, + taskCB->schedStat.schedPercpu[cpuId].contexSwitch); + } + } + + PRINTK("\n"); +} + +LITE_OS_SEC_TEXT_MINOR VOID OsStatisticsShow(UINT64 statisticsPastTime) //ʾϵͳͳϢ// +{ + UINT32 cpuId; + PRINTK("\n"); + PRINTK("Passed Time: %+16lf ms\n", ((DOUBLE)statisticsPastTime / NS_PER_MS)); + PRINTK("--------------------------------\n"); + PRINTK("CPU Idle(%%) ContexSwitch HwiNum " + "Avg Pri HiTask(%%) HiTask SwiNum HiTask P(ms)" +#ifdef LOSCFG_KERNEL_SMP + " MP Hwi\n"); +#else + "\n"); +#endif + PRINTK("---- --------- ----------- -------- --------- " + "---------- ------------ ----------" +#ifdef LOSCFG_KERNEL_SMP + " ------\n"); +#else + "\n"); +#endif + + for (cpuId = 0; cpuId < LOSCFG_KERNEL_CORE_NUM; cpuId++) { +#ifdef LOSCFG_KERNEL_SMP + PRINTK("CPU%u %+10lf%14u%14u %+11lf %+11lf%14u %+11lf %11u\n", cpuId, +#else + PRINTK("CPU%u %+10lf%14u%14u %+11lf %+11lf%14u %+11lf\n", cpuId, +#endif + ((DOUBLE)(g_statPercpu[cpuId].idleRuntime) / statisticsPastTime) * DECIMAL_TO_PERCENTAGE, + g_statPercpu[cpuId].contexSwitch, + g_statPercpu[cpuId].hwiNum, + (g_statPercpu[cpuId].prioritySwitch == 0) ? OS_TASK_PRIORITY_LOWEST : + ((DOUBLE)(g_statPercpu[cpuId].sumPriority) / (g_statPercpu[cpuId].prioritySwitch)), + ((DOUBLE)(g_statPercpu[cpuId].highTaskRuntime) / statisticsPastTime) * DECIMAL_TO_PERCENTAGE, + g_statPercpu[cpuId].highTaskSwitch, + (g_statPercpu[cpuId].highTaskSwitch == 0) ? 0 : + ((DOUBLE)(g_statPercpu[cpuId].highTaskRuntime) / (g_statPercpu[cpuId].highTaskSwitch)) / NS_PER_MS +#ifdef LOSCFG_KERNEL_SMP + , g_statPercpu[cpuId].ipiIrqNum); +#else + ); +#endif + } + + PRINTK("\n"); +} + +LITE_OS_SEC_TEXT_MINOR VOID OsShellStatisticsStart(VOID) //ڶϵͳͳƹ// +{ + LosTaskCB *taskCB = NULL; + UINT32 loop; + UINT32 cpuId = 0; + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + + if (g_statisticsStartFlag) { + SCHEDULER_UNLOCK(intSave); + PRINT_WARN("mp static has started\n"); + return; + } + + g_statisticsStartTime = LOS_CurrNanosec(); + + for (loop = 0; loop < g_taskMaxNum; loop++) { + taskCB = (((LosTaskCB *)g_taskCBArray) + loop); + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { +#ifdef LOSCFG_KERNEL_SMP + cpuId = taskCB->currCpu; +#endif + if ((UINT32)(OS_TASK_INVALID_CPUID) == cpuId) { + continue; + } + if (!strcmp(taskCB->taskName, "IdleCore000")) { + g_statPercpu[cpuId].idleStarttime = g_statisticsStartTime; + } + if (taskCB->priority < HIGHTASKPRI) { + g_statPercpu[cpuId].highTaskStarttime = g_statisticsStartTime; + g_statPercpu[cpuId].highTaskSwitch++; + } + if (strcmp(taskCB->taskName, "IdleCore000")) { + g_statPercpu[cpuId].sumPriority += taskCB->priority; + g_statPercpu[cpuId].prioritySwitch++; + } + } + } + g_statisticsStartFlag = TRUE; + SCHEDULER_UNLOCK(intSave); + + PRINTK("mp static start\n"); + + return; +} + +//ڶϵͳֹͣͳƹܣͳݵĴչʾ// +LITE_OS_SEC_TEXT_MINOR VOID OsShellStatisticsStop(VOID) +{ + LosTaskCB *taskCB = NULL; + UINT32 loop; + UINT32 cpuId = 0; + UINT64 statisticsStopTime; + UINT64 statisticsPastTime; + UINT64 runtime; + UINT32 intSave; + + SCHEDULER_LOCK(intSave); + + if (g_statisticsStartFlag != TRUE) { + SCHEDULER_UNLOCK(intSave); + PRINT_WARN("Please set mp static start\n"); + return; + } + + g_statisticsStartFlag = FALSE; + statisticsStopTime = LOS_CurrNanosec(); + statisticsPastTime = statisticsStopTime - g_statisticsStartTime; + + for (loop = 0; loop < g_taskMaxNum; loop++) { + taskCB = (((LosTaskCB *)g_taskCBArray) + loop); + if (taskCB->taskStatus & OS_TASK_STATUS_RUNNING) { +#ifdef LOSCFG_KERNEL_SMP + cpuId = taskCB->currCpu; +#endif + if (cpuId == (UINT32)(OS_TASK_INVALID_CPUID)) { + continue; + } + if (!strcmp(taskCB->taskName, "IdleCore000")) { + runtime = statisticsStopTime - g_statPercpu[cpuId].idleStarttime; + g_statPercpu[cpuId].idleRuntime += runtime; + g_statPercpu[cpuId].idleStarttime = 0; + } + if (taskCB->priority < HIGHTASKPRI) { + runtime = statisticsStopTime - g_statPercpu[cpuId].highTaskStarttime; + g_statPercpu[cpuId].highTaskRuntime += runtime; + g_statPercpu[cpuId].highTaskStarttime = 0; + } + } + } + SCHEDULER_UNLOCK(intSave); + OsStatisticsShow(statisticsPastTime); + + (VOID)memset_s(g_statPercpu, sizeof(g_statPercpu), 0, sizeof(g_statPercpu)); + g_statisticsStartTime = 0; + return; +} +#endif + +#ifdef __cplusplus +#if __cplusplus +} +#endif /* __cplusplus */ +#endif /* __cplusplus */ diff --git a/src/debug/los_sem_debug.c b/src/debug/los_sem_debug.c new file mode 100644 index 0000000..8f1774b --- /dev/null +++ b/src/debug/los_sem_debug.c @@ -0,0 +1,299 @@ +/* ---------------------------------------------------------------------------- + * Copyright (c) Huawei Technologies Co., Ltd. 2013-2019. All rights reserved. + * Description: Sem Debug + * Author: Huawei LiteOS Team + * Create: 2013-01-01 + * 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_misc_pri.h" +#ifdef LOSCFG_SHELL +#include "shcmd.h" +#endif /* LOSCFG_SHELL */ + +#ifdef __cplusplus +#if __cplusplus +extern "C" { +#endif +#endif /* __cplusplus */ + +#ifdef LOSCFG_DEBUG_SEMAPHORE +#define OS_ALL_SEM_MASK 0xffffffff + +STATIC VOID OsSemPendedTaskNamePrint(LosSemCB *semNode) //ڴӡȴijźб// +{ + LosTaskCB *tskCB = NULL; + CHAR *nameArr[LOSCFG_BASE_CORE_TSK_LIMIT] = {0}; + UINT32 i, intSave; + UINT32 num = 0; + + SCHEDULER_LOCK(intSave); + if ((semNode->semStat == LOS_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"); +} + +typedef struct { //ڼ¼źĵϢ// + UINT16 origSemCount; /* Number of original available semaphores */ + UINT64 lastAccessTime; /* The last operation time */ + TSK_ENTRY_FUNC creator; /* The task entry who created this sem */ +} SemDebugCB; +STATIC SemDebugCB *g_semDebugArray = NULL; //ڴ洢źĵϢ// + +//ڱȽԪصֵ// +STATIC BOOL SemCompareValue(const SortParam *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 creator, UINT16 count) //ڸָźĵϢ// +{ + SemDebugCB *semDebug = &g_semDebugArray[GET_SEM_INDEX(semId)]; + semDebug->creator = creator; + 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}; + SortParam semSortParam; + semSortParam.buf = (CHAR *)g_semDebugArray; + semSortParam.ctrlBlockSize = sizeof(SemDebugCB); + semSortParam.ctrlBlockCnt = LOSCFG_BASE_IPC_SEM_LIMIT; + semSortParam.sortElemOff = LOS_OFF_SET_OF(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); + OsArraySort(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 != LOS_USED) || (semDebug.creator == NULL)) { + continue; + } + PRINTK(" 0x%-07x0x%-07u0x%-14u%-22p0x%llx\n", semNode.semId, semDebug.origSemCount, + semNode.semCount, semDebug.creator, 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 == LOS_USED) && (semDebug->creator != 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 != LOS_USED) || (semDebug->creator == 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; +} + +#ifdef LOSCFG_SHELL +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 == LOS_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 { + 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 != LOS_USED)) { + PRINTK("\nThe semaphore 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 semaphore!\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) { + PRINTK("\nUsage: sem [fulldata|ID]\n"); + return OS_ERROR; + } + + if (argc == 0) { + semId = OS_ALL_SEM_MASK; + } else { + if (strcmp(argv[0], "fulldata") == 0) { + ret = OsSemInfoGetFullData(); + return ret; + } + + semId = strtoul(argv[0], &endPtr, 0); + if ((*endPtr != 0) || (GET_SEM_INDEX(semId) >= LOSCFG_BASE_IPC_SEM_LIMIT)) { + PRINTK("\nsem ID can't access %s.\n", argv[0]); + return OS_ERROR; + } + } + + ret = OsSemInfoOutput(semId); + return ret; +} + +SHELLCMD_ENTRY(sem_shellcmd, CMD_TYPE_EX, "sem", 1, (CmdCallBackFunc)OsShellCmdSemInfoGet); +#endif /* LOSCFG_SHELL */ +#endif /* LOSCFG_DEBUG_SEMAPHORE */ + +#ifdef __cplusplus +#if __cplusplus +} +#endif +#endif /* __cplusplus */