diff --git a/configure.ac b/configure.ac index 9bb07fccfe..9233515c47 100644 --- a/configure.ac +++ b/configure.ac @@ -833,7 +833,7 @@ AC_SUBST(LIBTOOL_LIB_EXTEN) # Checks for header files. AC_HEADER_DIRENT AC_HEADER_STDC -AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h sys/prctl.h sys/select.h netdb.h execinfo.h]) +AC_CHECK_HEADERS([sys/types.h sys/resource.h sched.h wchar.h sys/filio.h sys/ioctl.h sys/prctl.h sys/select.h netdb.h execinfo.h sys/time.h]) if test x"$ac_cv_header_wchar_h" = xyes; then HAVE_WCHAR_H_DEFINE=1 @@ -880,7 +880,7 @@ AC_FUNC_MALLOC AC_TYPE_SIGNAL AC_FUNC_STRFTIME AC_CHECK_FUNCS([gethostname vasprintf mmap mlock mlockall usleep getifaddrs timerfd_create getdtablesize posix_openpt poll]) -AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups]) +AC_CHECK_FUNCS([sched_setscheduler setpriority setrlimit setgroups initgroups getrusage]) AC_CHECK_FUNCS([wcsncmp setgroups asprintf setenv pselect gettimeofday localtime_r gmtime_r strcasecmp stricmp _stricmp]) # Check availability and return type of strerror_r diff --git a/src/include/switch_utils.h b/src/include/switch_utils.h index 73b6de1241..6f6ee6bef6 100644 --- a/src/include/switch_utils.h +++ b/src/include/switch_utils.h @@ -1279,6 +1279,15 @@ SWITCH_DECLARE(switch_status_t) switch_frame_buffer_dup(switch_frame_buffer_t *f SWITCH_DECLARE(switch_status_t) switch_frame_buffer_destroy(switch_frame_buffer_t **fbP); SWITCH_DECLARE(switch_status_t) switch_frame_buffer_create(switch_frame_buffer_t **fbP); +typedef struct { + int64_t userms; + int64_t kernelms; +} switch_cputime; +/** +/ Return used CPU time in this process for user and kernel code +**/ +SWITCH_DECLARE(void) switch_getcputime(switch_cputime *t); + SWITCH_END_EXTERN_C #endif /* For Emacs: diff --git a/src/mod/applications/mod_commands/mod_commands.c b/src/mod/applications/mod_commands/mod_commands.c index 765ffba1ff..a415c8c7f0 100644 --- a/src/mod/applications/mod_commands/mod_commands.c +++ b/src/mod/applications/mod_commands/mod_commands.c @@ -6059,6 +6059,22 @@ SWITCH_STANDARD_API(quote_shell_arg_function) return SWITCH_STATUS_SUCCESS; } +#define GETCPUTIME_SYNTAX "[reset]" +SWITCH_STANDARD_API(getcputime_function) +{ + static int64_t reset_ums = 0, reset_kms = 0; // Last reset times in ms + switch_cputime t = { 0 }; + switch_getcputime(&t); + t.userms -= reset_ums; + t.kernelms -= reset_kms; + stream->write_function(stream, "%"SWITCH_INT64_T_FMT", %"SWITCH_INT64_T_FMT, t.userms, t.kernelms); + if (cmd && !strncmp(cmd, "reset", 5) && t.userms != -1) { + reset_ums += t.userms; + reset_kms += t.kernelms; + } + return SWITCH_STATUS_SUCCESS; +} + #define UUID_LOGLEVEL_SYNTAX " " SWITCH_STANDARD_API(uuid_loglevel) { @@ -6916,6 +6932,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) SWITCH_ADD_API(commands_api_interface, "xml_locate", "Find some xml", xml_locate_function, "[root |
]"); SWITCH_ADD_API(commands_api_interface, "xml_wrap", "Wrap another api command in xml", xml_wrap_api_function, " "); SWITCH_ADD_API(commands_api_interface, "file_exists", "Check if a file exists on server", file_exists_function, ""); + SWITCH_ADD_API(commands_api_interface, "getcputime", "Gets CPU time in milliseconds (user,kernel)", getcputime_function, GETCPUTIME_SYNTAX); SWITCH_ADD_API(commands_api_interface, "json", "JSON API", json_function, "JSON"); SWITCH_ADD_JSON_API(json_api_interface, "mediaStats", "JSON Media Stats", json_stats_function, ""); @@ -7096,6 +7113,7 @@ SWITCH_MODULE_LOAD_FUNCTION(mod_commands_load) switch_console_set_complete("add uuid_warning ::console::list_uuid"); switch_console_set_complete("add ..."); switch_console_set_complete("add file_exists"); + switch_console_set_complete("add getcputime"); /* indicate that the module should continue to be loaded */ return SWITCH_STATUS_NOUNLOAD; diff --git a/src/switch_utils.c b/src/switch_utils.c index e0851c3c55..c4a2482356 100644 --- a/src/switch_utils.c +++ b/src/switch_utils.c @@ -35,6 +35,10 @@ #include #ifndef WIN32 #include +#if defined(HAVE_SYS_TIME_H) && defined(HAVE_SYS_RESOURCE_H) +#include +#include +#endif #endif #include "private/switch_core_pvt.h" #define ESCAPE_META '\\' @@ -4203,6 +4207,25 @@ SWITCH_DECLARE(void) switch_http_dump_request(switch_http_request_t *request) } } +SWITCH_DECLARE(void) switch_getcputime(switch_cputime *t) +{ +#if defined(_WIN32) + FILETIME ct, et, kt, ut; // Times are in 100-ns ticks (div 10000 to get ms) + GetProcessTimes(GetCurrentProcess(), &ct, &et, &kt, &ut); + t->userms = ((int64_t)ut.dwLowDateTime | ((int64_t)ut.dwHighDateTime << 32)) / 10000; + t->kernelms = ((int64_t)kt.dwLowDateTime | ((int64_t)kt.dwHighDateTime << 32)) / 10000; +#elif defined(HAVE_GETRUSAGE) + struct rusage r; + getrusage(RUSAGE_SELF, &r); + t->userms = r.ru_utime.tv_sec * 1000 + r.ru_utime.tv_usec / 1000; + t->kernelms = r.ru_stime.tv_sec * 1000 + r.ru_stime.tv_usec / 1000; +#else + t->userms = -1; + t->kernelms = -1; +#endif +} + + /* For Emacs: * Local Variables: * mode:c