From f09b7e400f25f196ee3548a116ddb00104543777 Mon Sep 17 00:00:00 2001 From: Gregory Nutt Date: Thu, 31 Dec 2015 09:16:38 -0600 Subject: [PATCH] NSH: Add a time command that can be used to time other commands --- ChangeLog.txt | 3 +- nshlib/Kconfig | 5 ++++ nshlib/README.txt | 25 ++++++++++++++-- nshlib/nsh.h | 3 ++ nshlib/nsh_command.c | 10 +++++-- nshlib/nsh_timcmds.c | 69 ++++++++++++++++++++++++++++++++++++++++++-- 6 files changed, 105 insertions(+), 10 deletions(-) diff --git a/ChangeLog.txt b/ChangeLog.txt index 13a2dec7a..773a206dc 100644 --- a/ChangeLog.txt +++ b/ChangeLog.txt @@ -1506,4 +1506,5 @@ driver. From Alan Carvalho de Assis (2015-12-15). * apps/examples/ostest: Add a test of POSIX timers using SIGEV_THREAD (20156-12-30). - + * apps/nshlib: Add a 'time' command that may be used to time the + execution of other commands (2015-12-31). diff --git a/nshlib/Kconfig b/nshlib/Kconfig index 5ebd30f3c..072b5b814 100644 --- a/nshlib/Kconfig +++ b/nshlib/Kconfig @@ -395,6 +395,11 @@ config NSH_DISABLE_SLEEP bool "Disable sleep" default n +config NSH_DISABLE_TIME + bool "Disable time" + default y if DEFAULT_SMALL + default n if !DEFAULT_SMALL + config NSH_DISABLE_TEST bool "Disable test" default n diff --git a/nshlib/README.txt b/nshlib/README.txt index 5c83f32db..78c1c13f8 100644 --- a/nshlib/README.txt +++ b/nshlib/README.txt @@ -1000,6 +1000,23 @@ o sleep Pause execution (sleep) of seconds. +o time "" + + Perform command timing. This command will execute the following + string and then show how much time was required to execute the command. + Time is shown with a resolution of 100 microseconds which may be beyond + the resolution of many configurations. Note that the string + must be enclosed in quotation marks. + + Example: + + nsh> time "sleep 2" + + 2.0001 sec + + The addition 100 microseconds in this example is the additional overhead + of the time command execution itself which is included in the total. + o unset Remove the value associated with the environment variable @@ -1133,6 +1150,7 @@ Command Dependencies on Configuration Settings shutdown CONFIG_BOARDCTL_POWEROFF || CONFIG_BOARDCTL_RESET sleep !CONFIG_DISABLE_SIGNALS test !CONFIG_NSH_DISABLESCRIPT + time --- umount !CONFIG_DISABLE_MOUNTPOINT && CONFIG_NFILE_DESCRIPTORS > 0 && CONFIG_FS_READABLE uname !CONFIG_NSH_DISABLE_UNAME unset !CONFIG_DISABLE_ENVIRON @@ -1173,9 +1191,10 @@ also allow it to squeeze into very small memory footprints. CONFIG_NSH_DISABLE_PING6, CONFIG_NSH_DISABLE_PUT, CONFIG_NSH_DISABLE_PWD, CONFIG_NSH_DISABLE_REBOOT, CONFIG_NSH_DISABLE_RM, CONFIG_NSH_DISABLE_RMDIR, CONFIG_NSH_DISABLE_SET, CONFIG_NSH_DISABLE_SH, CONFIG_NSH_DISABLE_SHUTDOWN, - CONFIG_NSH_DISABLE_SLEEP, CONFIG_NSH_DISABLE_TEST, CONFIG_NSH_DISABLE_UMOUNT, - CONFIG_NSH_DISABLE_UNSET, CONFIG_NSH_DISABLE_URLDECODE, CONFIG_NSH_DISABLE_URLENCODE, - CONFIG_NSH_DISABLE_USLEEP, CONFIG_NSH_DISABLE_WGET, CONFIG_NSH_DISABLE_XD + CONFIG_NSH_DISABLE_SLEEP, CONFIG_NSH_DISABLE_TEST, CONFIG_NSH_DIABLE_TIME, + CONFIG_NSH_DISABLE_UMOUNT, CONFIG_NSH_DISABLE_UNSET, CONFIG_NSH_DISABLE_URLDECODE, + CONFIG_NSH_DISABLE_URLENCODE, CONFIG_NSH_DISABLE_USLEEP, CONFIG_NSH_DISABLE_WGET, + CONFIG_NSH_DISABLE_XD Verbose help output can be suppressed by defining CONFIG_NSH_HELP_TERSE. In that case, the help command is still available but will be slightly smaller. diff --git a/nshlib/nsh.h b/nshlib/nsh.h index 0ebd5f9ff..28ebd814c 100644 --- a/nshlib/nsh.h +++ b/nshlib/nsh.h @@ -934,6 +934,9 @@ void nsh_usbtrace(void); #ifndef CONFIG_NSH_DISABLE_FREE int cmd_free(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif +#ifndef CONFIG_NSH_DISABLE_TIME + int cmd_time(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); +#endif #ifndef CONFIG_NSH_DISABLE_PS int cmd_ps(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv); #endif diff --git a/nshlib/nsh_command.c b/nshlib/nsh_command.c index 025edb382..b62510a3b 100644 --- a/nshlib/nsh_command.c +++ b/nshlib/nsh_command.c @@ -435,15 +435,19 @@ static const struct cmdmap_s g_cmdmap[] = { "test", cmd_test, 3, CONFIG_NSH_MAXARGUMENTS, "" }, #endif +#ifndef CONFIG_NSH_DISABLE_TIME + { "time", cmd_time, 2, 2, "\"\"" }, +#endif + #ifndef CONFIG_NSH_DISABLESCRIPT - { "true", cmd_true, 1, 1, NULL }, + { "true", cmd_true, 1, 1, NULL }, #endif #ifndef CONFIG_NSH_DISABLE_UNAME #ifdef CONFIG_NET - { "uname", cmd_uname, 1, 7, "[-a | -imnoprsv]" }, + { "uname", cmd_uname, 1, 7, "[-a | -imnoprsv]" }, #else - { "uname", cmd_uname, 1, 7, "[-a | -imoprsv]" }, + { "uname", cmd_uname, 1, 7, "[-a | -imoprsv]" }, #endif #endif diff --git a/nshlib/nsh_timcmds.c b/nshlib/nsh_timcmds.c index d09c54c1d..1ae56dbc5 100644 --- a/nshlib/nsh_timcmds.c +++ b/nshlib/nsh_timcmds.c @@ -53,9 +53,11 @@ #define MAX_TIME_STRING 80 -/**************************************************************************** - * Private Types - ****************************************************************************/ +#ifdef CONFIG_CLOCK_MONOTONIC +# define TIME_CLOCK CLOCK_MONOTONIC +#else +# define TIME_CLOCK CLOCK_REALTIME +#endif /**************************************************************************** * Private Function Prototypes @@ -283,6 +285,67 @@ errout_bad_parm: * Public Functions ****************************************************************************/ +/**************************************************************************** + * Name: cmd_time + ****************************************************************************/ + +#ifndef CONFIG_NSH_DISABLE_TIME +int cmd_time(FAR struct nsh_vtbl_s *vtbl, int argc, char **argv) +{ + struct timespec start; + bool bgsave; + bool redirsave; + int ret; + + /* Get the current time */ + + ret = clock_gettime(TIME_CLOCK, &start); + if (ret < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "clock_gettime", NSH_ERRNO); + return ERROR; + } + + /* Save state */ + + bgsave = vtbl->np.np_bg; + redirsave = vtbl->np.np_redirect; + + /* Execute the command */ + + ret = nsh_parse(vtbl, argv[1]); + if (ret >= 0) + { + struct timespec end; + struct timespec diff; + + ret = clock_gettime(TIME_CLOCK, &end); + if (ret < 0) + { + nsh_output(vtbl, g_fmtcmdfailed, argv[0], "clock_gettime", NSH_ERRNO); + ret = ERROR; + } + else + { + diff.tv_sec = end.tv_sec - start.tv_sec; + if (start.tv_nsec > end.tv_nsec) + { + diff.tv_sec--; + end.tv_nsec += 1000000000; + } + + diff.tv_nsec = end.tv_nsec - start.tv_nsec; + nsh_output(vtbl, "\n%lu.%04lu sec\n", (unsigned long)diff.tv_sec, + (unsigned long)diff.tv_nsec / 10000000); + } + } + + vtbl->np.np_bg = bgsave; + vtbl->np.np_redirect = redirsave; + return ret; +} +#endif + /**************************************************************************** * Name: cmd_date ****************************************************************************/