1 /*
2 * Copyright (c) 2022-2022 Huawei Device Co., Ltd. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without modification,
5 * are permitted provided that the following conditions are met:
6 *
7 * 1. Redistributions of source code must retain the above copyright notice, this list of
8 * conditions and the following disclaimer.
9 *
10 * 2. Redistributions in binary form must reproduce the above copyright notice, this list
11 * of conditions and the following disclaimer in the documentation and/or other materials
12 * provided with the distribution.
13 *
14 * 3. Neither the name of the copyright holder nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific prior written
16 * permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
20 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
21 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
22 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
23 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
25 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
26 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
27 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
28 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 */
30
31 #include "los_debugtools.h"
32 #include "securec.h"
33 #include "los_debug.h"
34 #include "los_memory.h"
35 #include "los_arch.h"
36
37 #if (LOSCFG_DEBUG_TOOLS == 1)
38 STATIC BOOL g_startTrace = FALSE;
39 STATIC SchedTraceInfo *g_traceRingBuf = NULL;
40 STATIC UINT32 g_schedCount = 0;
41 STATIC SchedTraceRecordCB g_recordCB = NULL;
42 STATIC SchedTraceShowCB g_showCB = NULL;
43
DefaultShowFormat(SchedTraceInfo * buf,UINT32 count)44 STATIC VOID DefaultShowFormat(SchedTraceInfo *buf, UINT32 count)
45 {
46 INT32 i;
47 UINT32 cycle = count / TRACE_NUM;
48 UINT32 point = count % TRACE_NUM;
49
50 PRINTK ("sched %u time, last %u is:\r\n", count, TRACE_NUM);
51 PRINTK("RunTaskID RunTaskName NewTaskID NewTaskName \r\n");
52 if (cycle > 0) {
53 for (i = point; i < TRACE_NUM; i++) {
54 PRINTK("%4u %20s, %4u %20s\n",
55 g_traceRingBuf[i].runTaskID, g_traceRingBuf[i].runTaskName,
56 g_traceRingBuf[i].newTaskID, g_traceRingBuf[i].newTaskName);
57 }
58 }
59
60 for (i = 0; i < point; i++) {
61 PRINTK("%4u %20s, %4u %20s\n",
62 g_traceRingBuf[i].runTaskID, g_traceRingBuf[i].runTaskName,
63 g_traceRingBuf[i].newTaskID, g_traceRingBuf[i].newTaskName);
64 }
65
66 PRINTK("\r\n");
67 }
68
DefaultRecordHandle(LosTaskCB * newTask,LosTaskCB * runTask)69 STATIC VOID DefaultRecordHandle(LosTaskCB *newTask, LosTaskCB *runTask)
70 {
71 UINT32 point = g_schedCount % TRACE_NUM;
72
73 g_traceRingBuf[point].newTaskID = newTask->taskID;
74 (VOID)memcpy_s(g_traceRingBuf[point].newTaskName, LOS_TASK_NAMELEN, newTask->taskName, LOS_TASK_NAMELEN);
75 g_traceRingBuf[point].runTaskID = runTask->taskID;
76 (VOID)memcpy_s(g_traceRingBuf[point].runTaskName, LOS_TASK_NAMELEN, runTask->taskName, LOS_TASK_NAMELEN);
77
78 g_schedCount++;
79 }
80
ShowFormat(SchedTraceInfo * buf,UINT32 count)81 STATIC VOID ShowFormat(SchedTraceInfo *buf, UINT32 count)
82 {
83 if (count == 0) {
84 PRINT_ERR("none shed happened\n");
85 return;
86 }
87
88 if (g_showCB != NULL) {
89 g_showCB(buf, count);
90 }
91 }
92
OsSchedTraceRecord(LosTaskCB * newTask,LosTaskCB * runTask)93 VOID OsSchedTraceRecord(LosTaskCB *newTask, LosTaskCB *runTask)
94 {
95 if (g_startTrace == FALSE) {
96 return;
97 }
98
99 if (g_recordCB != NULL) {
100 g_recordCB(newTask, runTask);
101 }
102 }
103
LOS_SchedTraceStart(VOID)104 VOID LOS_SchedTraceStart(VOID)
105 {
106 if (g_recordCB == NULL) {
107 g_recordCB = DefaultRecordHandle;
108 }
109
110 g_traceRingBuf = (SchedTraceInfo *)LOS_MemAlloc(OS_SYS_MEM_ADDR, TRACE_NUM * sizeof(SchedTraceInfo));
111 if (g_traceRingBuf == NULL) {
112 PRINT_ERR("alloc failed for dump\n");
113 return;
114 }
115 (VOID)memset_s(g_traceRingBuf, TRACE_NUM * sizeof(SchedTraceInfo), 0, TRACE_NUM * sizeof(SchedTraceInfo));
116
117 g_startTrace = TRUE;
118 }
119
LOS_SchedTraceStop(VOID)120 VOID LOS_SchedTraceStop(VOID)
121 {
122 if (g_showCB == NULL) {
123 g_showCB = DefaultShowFormat;
124 }
125 g_startTrace = FALSE;
126 ShowFormat(g_traceRingBuf, g_schedCount);
127 g_schedCount = 0;
128
129 if (g_traceRingBuf != NULL) {
130 (VOID)LOS_MemFree(OS_SYS_MEM_ADDR, g_traceRingBuf);
131 g_traceRingBuf = NULL;
132 }
133
134 return;
135 }
136
LOS_SchedTraceHandleRegister(SchedTraceRecordCB recordCB,SchedTraceShowCB showCB)137 VOID LOS_SchedTraceHandleRegister(SchedTraceRecordCB recordCB, SchedTraceShowCB showCB)
138 {
139 g_recordCB = recordCB;
140 g_showCB = showCB;
141 }
142
OsShellCmdSchedTrace(INT32 argc,const CHAR ** argv)143 UINT32 OsShellCmdSchedTrace(INT32 argc, const CHAR **argv)
144 {
145 if (argc != 1) {
146 PRINT_ERR("\nUsage: st -h\n");
147 return LOS_NOK;
148 }
149
150 if (strcmp(argv[0], "-s") == 0) {
151 LOS_SchedTraceStart();
152 } else if (strcmp(argv[0], "-e") == 0) {
153 LOS_SchedTraceStop();
154 } else if (strcmp(argv[0], "-h") == 0) {
155 PRINTK("\nUsage: \nst -s , SchedTrace start\n");
156 PRINTK("st -e , SchedTrace end and show\n");
157 } else {
158 PRINTK("\nUsage: st -h\n");
159 return OS_ERROR;
160 }
161
162 return LOS_OK;
163 }
164 #endif /* LOSCFG_STACK_DUMP == 1 */
165