Add a stack monitoring daemon

This commit is contained in:
Gregory Nutt 2013-09-24 11:46:49 -06:00
parent 2fa63021d5
commit 2c39b81178
8 changed files with 356 additions and 1 deletions

View File

@ -661,4 +661,6 @@
this the CC3000 option on each 'make oldconfig' (2013-9-18).
* apps/system/usbmonitor/usbmonitor.c: Fix some bad conditional
compilation probably introduced on 2013-9-9 (2013-9-23).
* apps/system/stackmonitor: Add a daemon that can be used to
monitor stack usage by all threads (2013-9-24).

View File

@ -47,6 +47,10 @@ menu "USB Monitor"
source "$APPSDIR/system/usbmonitor/Kconfig"
endmenu
menu "Stack Monitor"
source "$APPSDIR/system/stackmonitor/Kconfig"
endmenu
menu "Zmodem Commands"
source "$APPSDIR/system/zmodem/Kconfig"
endmenu

View File

@ -78,6 +78,10 @@ ifeq ($(CONFIG_SYSTEM_USBMONITOR),y)
CONFIGURED_APPS += system/usbmonitor
endif
ifeq ($(CONFIG_SYSTEM_STACKMONITOR),y)
CONFIGURED_APPS += system/stackmonitor
endif
ifeq ($(CONFIG_SYSTEM_ZMODEM),y)
CONFIGURED_APPS += system/zmodem
endif

View File

@ -38,7 +38,7 @@
# Sub-directories containing system task
SUBDIRS = flash_eraseall free i2c install poweroff ramtest ramtron readline
SUBDIRS += sdcard sysinfo usbmonitor zmodem
SUBDIRS += sdcard stackmonitor sysinfo usbmonitor zmodem
# Create the list of installed runtime modules (INSTALLED_DIRS)

11
system/stackmonitor/.gitignore vendored Normal file
View File

@ -0,0 +1,11 @@
/Make.dep
/.depend
/.built
/*.asm
/*.rel
/*.lst
/*.sym
/*.adb
/*.lib
/*.src
/*.obj

View File

@ -0,0 +1,39 @@
#
# For a description of the syntax of this configuration file,
# see misc/tools/kconfig-language.txt.
#
config SYSTEM_STACKMONITOR
bool "Stack monitor"
default n
depends on DEBUG_STACK && !KERNEL_BUILD
---help---
If the stack debug feature is enabled (DEBUG_STACK) this option will
select the Stack Moitor. The stack monitor is a daemon that will
periodically assess stack usage by all tasks and threads in the
system. This feature depends on internal OS features and, hence, is
not available if the NuttX kernel build is selected.
if SYSTEM_STACKMONITOR
config SYSTEM_STACKMONITOR_STACKSIZE
int "Stack monitor daemon stack size"
default 2048
---help---
The stack size to use the the stack monitor daemon. Default: 2048
config SYSTEM_STACKMONITOR_PRIORITY
int "Stack monitor daemon priority"
default 50
---help---
The priority to use the the stack monitor daemon. Default: 50
config SYSTEM_STACKMONITOR_INTERVAL
int "Stack monitor dump frequency"
default 2
---help---
The rate in seconds that the stack monitor will wait before dumping
the next set stack usage information. Default: 2 seconds.
endif

View File

@ -0,0 +1,117 @@
############################################################################
# apps/system/stackmonitor/Makefile
#
# Copyright (C) 2013 Gregory Nutt. All rights reserved.
# Author: Gregory Nutt <gnutt@nuttx.org>
#
# 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 NuttX 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 OWNER 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 $(TOPDIR)/.config
-include $(TOPDIR)/Make.defs
include $(APPDIR)/Make.defs
ifeq ($(WINTOOL),y)
INCDIROPT = -w
endif
# USB Monitor Application
PRIORITY = SCHED_PRIORITY_DEFAULT
STACKSIZE = 768
ASRCS =
CSRCS = stackmonitor.c
AOBJS = $(ASRCS:.S=$(OBJEXT))
COBJS = $(CSRCS:.c=$(OBJEXT))
SRCS = $(ASRCS) $(CSRCS)
OBJS = $(AOBJS) $(COBJS)
ifeq ($(CONFIG_WINDOWS_NATIVE),y)
BIN = ..\..\libapps$(LIBEXT)
else
ifeq ($(WINTOOL),y)
BIN = ..\\..\\libapps$(LIBEXT)
else
BIN = ../../libapps$(LIBEXT)
endif
endif
ROOTDEPPATH = --dep-path .
# Common build
VPATH =
all: .built
.PHONY: context depend clean distclean
$(AOBJS): %$(OBJEXT): %.S
$(call ASSEMBLE, $<, $@)
$(COBJS): %$(OBJEXT): %.c
$(call COMPILE, $<, $@)
.built: $(OBJS)
$(call ARCHIVE, $(BIN), $(OBJS))
$(Q) touch .built
# Register application
ifeq ($(CONFIG_NSH_BUILTIN_APPS),y)
$(BUILTIN_REGISTRY)$(DELIM)stackmonitor_start.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,"stkmon_start",$(PRIORITY),$(STACKSIZE),stackmonitor_start)
$(BUILTIN_REGISTRY)$(DELIM)stackmonitor_stop.bdat: $(DEPCONFIG) Makefile
$(call REGISTER,"stkmon_stop",$(PRIORITY),$(STACKSIZE),stackmonitor_stop)
context: $(BUILTIN_REGISTRY)$(DELIM)stackmonitor_start.bdat $(BUILTIN_REGISTRY)$(DELIM)stackmonitor_stop.bdat
else
context:
endif
# Create dependencies
.depend: Makefile $(SRCS)
$(Q) $(MKDEP) $(ROOTDEPPATH) "$(CC)" -- $(CFLAGS) -- $(SRCS) >Make.dep
$(Q) touch $@
depend: .depend
clean:
$(call DELFILE, .built)
$(call CLEAN)
distclean: clean
$(call DELFILE, Make.dep)
$(call DELFILE, .depend)
-include Make.dep

View File

@ -0,0 +1,178 @@
/****************************************************************************
* apps/system/stackmonitor/stackmonitor.c
*
* Copyright (C) 2013 Gregory Nutt. All rights reserved.
* Author: Gregory Nutt <gnutt@nuttx.org>
*
* 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 NuttX 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 OWNER 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.
*
****************************************************************************/
/****************************************************************************
* Included Files
****************************************************************************/
#include <nuttx/config.h>
#include <sys/types.h>
#include <stdbool.h>
#include <unistd.h>
#include <sched.h>
#include <syslog.h>
#include <errno.h>
#include <nuttx/arch.h>
#ifdef CONFIG_SYSTEM_STACKMONITOR
/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
#define STKMON_PREFIX "Stack Monitor: "
/* Configuration ************************************************************/
#ifndef CONFIG_SYSTEM_STACKMONITOR_STACKSIZE
# define CONFIG_SYSTEM_STACKMONITOR_STACKSIZE 2048
#endif
#ifndef CONFIG_SYSTEM_STACKMONITOR_PRIORITY
# define CONFIG_SYSTEM_STACKMONITOR_PRIORITY 50
#endif
#ifndef CONFIG_SYSTEM_STACKMONITOR_INTERVAL
# define CONFIG_SYSTEM_STACKMONITOR_INTERVAL 2
#endif
/****************************************************************************
* Private Types
****************************************************************************/
struct stkmon_state_s
{
volatile bool started;
volatile bool stop;
pid_t pid;
};
/****************************************************************************
* Private Data
****************************************************************************/
static struct stkmon_state_s g_stackmonitor;
/****************************************************************************
* Private Functions
****************************************************************************/
static int stackmonitor_daemon(int argc, char **argv)
{
syslog(STKMON_PREFIX "Running: %d\n", g_stackmonitor.pid);
/* Loop until we detect that there is a request to stop. */
while (!g_stackmonitor.stop)
{
sleep(CONFIG_SYSTEM_STACKMONITOR_INTERVAL);
}
/* Stopped */
g_stackmonitor.stop = false;
g_stackmonitor.started = false;
syslog(STKMON_PREFIX "Stopped: %d\n", g_stackmonitor.pid);
return 0;
}
/****************************************************************************
* Public Functions
****************************************************************************/
int stackmonitor_start(int argc, char **argv)
{
/* Has the monitor already started? */
sched_lock();
if (!g_stackmonitor.started)
{
int ret;
/* No.. start it now */
/* Then start the stack monitoring daemon */
g_stackmonitor.started = true;
g_stackmonitor.stop = false;
ret = TASK_CREATE("Stack Monitor", CONFIG_SYSTEM_STACKMONITOR_PRIORITY,
CONFIG_SYSTEM_STACKMONITOR_STACKSIZE,
(main_t)stackmonitor_daemon, (FAR char * const *)NULL);
if (ret < 0)
{
int errcode = errno;
syslog(STKMON_PREFIX
"ERROR: Failed to start the stack monitor: %d\n",
errcode);
}
else
{
g_stackmonitor.pid = ret;
syslog(STKMON_PREFIX "Started: %d\n", g_stackmonitor.pid);
}
sched_unlock();
return 0;
}
sched_unlock();
syslog(STKMON_PREFIX "%s: %d\n",
g_stackmonitor.stop ? "Stopping" : "Running", g_stackmonitor.pid);
return 0;
}
int stackmonitor_stop(int argc, char **argv)
{
/* Has the monitor already started? */
if (g_stackmonitor.started)
{
/* Stop the stack monitor. The next time the monitor wakes up,
* it will see the the stop indication and will exist.
*/
syslog(STKMON_PREFIX "Stopping: %d\n", g_stackmonitor.pid);
g_stackmonitor.stop = true;
}
syslog(STKMON_PREFIX "Stopped: %d\n", g_stackmonitor.pid);
return 0;
}
#endif /* CONFIG_SYSTEM_STACKMONITOR */