Add new TASH Command named stkopt
authorminju <alswnzla@gmail.com>
Tue, 8 Aug 2017 08:35:01 +0000 (17:35 +0900)
committerminju <alswnzla@gmail.com>
Wed, 9 Aug 2017 06:31:58 +0000 (15:31 +0900)
apps/system/utils/Kconfig
apps/system/utils/Makefile
apps/system/utils/kdbg_commands.h
apps/system/utils/kdbg_stackopt.c [new file with mode: 0755]
apps/system/utils/kernelcmd.c

index e7b35c9..827b478 100644 (file)
@@ -139,6 +139,13 @@ config STACKMONITOR_INTERVAL
 
 endif #ENABLE_STACKMONITOR
 
+config ENABLE_STACKOPT
+       bool "Stack opt"
+       default y
+       depends on ENABLE_STACKMONITOR && TASH_COMMAND_INTERFACE
+       ---help---
+               Measure optimal stack size of APP
+
 config ENABLE_UPTIME
        bool "uptime"
        default y
index 1336f3f..7017bce 100644 (file)
@@ -138,6 +138,10 @@ ifeq ($(CONFIG_ENABLE_STACKMONITOR),y)
 CSRCS += kdbg_stackmonitor.c
 endif
 
+ifeq ($(CONFIG_ENABLE_STACKOPT),y)
+CSRCS += kdbg_stackopt.c
+endif
+
 ifeq ($(CONFIG_TTRACE),y)
 CSRCS += kdbg_ttrace.c
 endif
index f4da48e..c991b14 100644 (file)
@@ -73,6 +73,10 @@ int kdbg_ps(int argc, char **args);
 int kdbg_stackmonitor(int argc, char **args);
 #endif
 
+#if defined(CONFIG_ENABLE_STACKOPT)
+int kdbg_stackopt(int argc, char **args);
+#endif
+
 #if defined(CONFIG_TTRACE)
 int kdbg_ttrace(int argc, char **args);
 #endif
diff --git a/apps/system/utils/kdbg_stackopt.c b/apps/system/utils/kdbg_stackopt.c
new file mode 100755 (executable)
index 0000000..0c4e798
--- /dev/null
@@ -0,0 +1,163 @@
+/****************************************************************************
+ *
+ * Copyright 2017 Samsung Electronics All Rights Reserved.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing,
+ * software distributed under the License is distributed on an
+ * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
+ * either express or implied. See the License for the specific
+ * language governing permissions and limitations under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+#include <tinyara/config.h>
+#include <sys/types.h>
+#include <stdio.h>
+#include <string.h>
+#include <apps/shell/tash.h>
+#include "kdbg_utils.h"
+
+/****************************************************************************
+ * Pre-processor Definitions
+ ****************************************************************************/
+#ifndef CONFIG_STACK_ALIGNMENT
+
+/* The symbol  __ARM_EABI__ is defined by GCC if EABI is being used.  If you
+ * are not using GCC, make sure that CONFIG_STACK_ALIGNMENT is set correctly!
+ */
+
+#ifdef __ARM_EABI__
+#define CONFIG_STACK_ALIGNMENT 8
+#else
+#define CONFIG_STACK_ALIGNMENT 4
+#endif
+#endif
+
+#define STACK_ALIGN_MASK    (CONFIG_STACK_ALIGNMENT - 1)
+#define STACK_ALIGN_UP(a)   (((a) + STACK_ALIGN_MASK) & ~STACK_ALIGN_MASK)
+
+/****************************************************************************
+ * Extern Data
+ ****************************************************************************/
+extern struct stkmon_save_s stkmon_arr[CONFIG_MAX_TASKS * 2];
+extern tash_taskinfo_t tash_taskinfo_list[];
+
+static bool find_app(TASH_CMD_CALLBACK *cb, char *name)
+{
+       int cmd_idx;
+       bool flag = false;
+       char str[CONFIG_TASK_NAME_SIZE];
+       int count = tash_get_cmdscount();
+       
+       for (cmd_idx = 0; cmd_idx < count; cmd_idx++) {
+               if (tash_get_cmdpair(str, cb, cmd_idx) == OK) {
+                       if (!strncmp(name, str, strlen(name) + 1)) {
+                               flag = true;
+                               break;
+                       }
+               }
+       }
+       return flag;
+}
+
+static int execute_app(char **args)
+{
+       int app_idx;
+       TASH_CMD_CALLBACK cb;
+       int pid = 0;
+       int pri = CONFIG_TASH_CMDTASK_PRIORITY;
+       long stack_size = CONFIG_TASH_CMDTASK_STACKSIZE;
+
+       if (find_app(&cb, args[0])) {
+#if defined(CONFIG_BUILTIN_APPS)
+               for (app_idx = 0; tash_taskinfo_list[app_idx].str != NULL; app_idx++) {
+                       if (!strncmp(args[0], tash_taskinfo_list[app_idx].str, CONFIG_TASK_NAME_SIZE)) {
+                               pri = tash_taskinfo_list[app_idx].task_prio;
+                               stack_size = tash_taskinfo_list[app_idx].task_stacksize;
+                               break;
+                       }
+               }
+#endif
+               pid = task_create(args[0], pri, stack_size, cb , &args[1]);
+       }
+       return pid;
+}
+
+static int get_frame_size(int argc, char **args)
+{
+       int args_idx = 0;
+       size_t strtablen = 0;
+       size_t argvlen = (argc + 1) * sizeof(FAR char *);
+       size_t frame_size = 0;
+       
+       while (args[args_idx]) {
+               strtablen += (strlen(args[args_idx]) + 1);
+               args_idx++;
+       }
+       
+       frame_size = STACK_ALIGN_UP(argvlen + strtablen);
+       return frame_size;
+}
+
+static void print_measure_result(pid_t pid, int argc, char **args)
+{
+       int stkmon_idx;
+       for (stkmon_idx = 0; stkmon_idx < CONFIG_MAX_TASKS * 2; stkmon_idx++) {
+               if (stkmon_arr[stkmon_idx].chk_pid == pid) {
+                       break;
+               }
+       }
+
+       printf("---------------------------------------------------------------\n");
+       printf(">> Stack Size Measure Finish\n");
+       printf("APP Name : %s\n", stkmon_arr[stkmon_idx].chk_name);
+       printf("Allocate %d stack size for measure\n",  stkmon_arr[stkmon_idx].chk_stksize);
+       printf("Optimal Stack Size is %d\n", stkmon_arr[stkmon_idx].chk_peaksize + get_frame_size(argc, args));
+       printf("If the arguments are changed, optimal stack size can be changed\n");
+       printf("---------------------------------------------------------------\n");
+       return;
+}
+
+int kdbg_stackopt(int argc, char **args)
+{
+       int pid;
+       int status;
+
+       if (argc < 2) {
+               printf("Invalid argument\n");
+               goto usage;
+       }
+       
+       if (!strncmp(args[1], "--help", strlen("--help") + 1)) {
+               goto usage;
+       }
+       
+       if ((pid = execute_app(&args[1])) < 0) {
+               printf("Cannot create task\n");
+               goto usage;
+       } else if (pid == 0) {
+               printf("%s : Cannot find APP\n", args[1]);
+               goto usage;
+       } else {
+               waitpid((pid_t)pid, &status, 0);
+               print_measure_result((pid_t)pid, argc - 1, &args[1]);
+       }
+       return OK;
+
+usage:
+       printf("\nUsage: %s NAME [ARGS]\n", args[0]);
+       printf("Measure optimal stack size of APP\n");
+       printf("NAME is the name of the APP you want to measure the optimal stack size\n");
+       printf("ARGS is the arguments of the APP named NAME\n");
+       printf("If the arguments are changed, optimal stack size can be changed\n");
+       return ERROR;
+}
index 6f010fa..a24ba59 100644 (file)
@@ -58,6 +58,9 @@ const static tash_cmdlist_t kdbg_cmds[] = {
 #if defined(CONFIG_ENABLE_STACKMONITOR)
        {"stkmon",   kdbg_stackmonitor, TASH_EXECMD_SYNC},
 #endif
+#if defined(CONFIG_ENABLE_STACKOPT)
+       {"stkopt",   kdbg_stackopt,    TASH_EXECMD_ASYNC},
+#endif
 #if defined(CONFIG_TTRACE)
        {"ttrace",   kdbg_ttrace,       TASH_EXECMD_SYNC},
 #endif