# HG changeset patch # User John W. Eaton # Date 1466106960 14400 # Node ID f0c5dd1ea2b9aacd4f1669575b507d401e723286 # Parent 7ab7cd327257607887bbbf0562283a226ddbd9b4 hide sys/time.h, sys/times.h, and sys/resource.h headers * bootstrap.conf: Use gnulib getrusage module. * liboctave/wrappers/time-wrappers.c, liboctave/wrappers/time-wrappers.h: New files. * liboctave/wrappers/module.mk: Update. * oct-time.cc, oct-time.h (cpu_time, resource_usage): New classes. Provide C++ interface to low-level cpu time and resource usage wrapper functions. * data.cc, getrusage.cc: Use new classes for cpu time and resource usage. diff -r 7ab7cd327257 -r f0c5dd1ea2b9 bootstrap.conf --- a/bootstrap.conf Thu Jun 16 13:09:54 2016 -0400 +++ b/bootstrap.conf Thu Jun 16 15:56:00 2016 -0400 @@ -52,6 +52,7 @@ getcwd gethostname getopt-gnu + getrusage gettimeofday glob isatty diff -r 7ab7cd327257 -r f0c5dd1ea2b9 libinterp/corefcn/data.cc --- a/libinterp/corefcn/data.cc Thu Jun 16 13:09:54 2016 -0400 +++ b/libinterp/corefcn/data.cc Thu Jun 16 15:56:00 2016 -0400 @@ -28,11 +28,6 @@ #endif #include -#include - -#if defined (HAVE_SYS_RESOURCE_H) -# include -#endif #include #include @@ -69,14 +64,6 @@ #include "pager.h" #include "xnorm.h" -#if ! defined (CLOCKS_PER_SEC) -# if defined (CLK_TCK) -# define CLOCKS_PER_SEC CLK_TCK -# else -# error "no definition for CLOCKS_PER_SEC!" -# endif -#endif - #if ! defined (HAVE_HYPOTF) && defined (HAVE__HYPOTF) # define hypotf _hypotf # define HAVE_HYPOTF 1 @@ -6340,50 +6327,14 @@ @end deftypefn") { if (args.length () != 0) - warning ("cputime: ignoring extra arguments"); - - double usr = 0.0; - double sys = 0.0; - -#if defined (HAVE_GETRUSAGE) - - struct rusage ru; - - getrusage (RUSAGE_SELF, &ru); - - usr = static_cast (ru.ru_utime.tv_sec) + - static_cast (ru.ru_utime.tv_usec) * 1e-6; - - sys = static_cast (ru.ru_stime.tv_sec) + - static_cast (ru.ru_stime.tv_usec) * 1e-6; - -#else - - struct tms t; - - times (&t); - - unsigned long ticks; - unsigned long seconds; - unsigned long fraction; - - ticks = t.tms_utime + t.tms_cutime; - fraction = ticks % CLOCKS_PER_SEC; - seconds = ticks / CLOCKS_PER_SEC; - - usr = static_cast (seconds) + static_cast(fraction) / - static_cast(CLOCKS_PER_SEC); - - ticks = t.tms_stime + t.tms_cstime; - fraction = ticks % CLOCKS_PER_SEC; - seconds = ticks / CLOCKS_PER_SEC; - - sys = static_cast (seconds) + static_cast(fraction) / - static_cast(CLOCKS_PER_SEC); - -#endif - - return ovl (sys + usr, usr, sys); + print_usage (); + + octave::sys::cpu_time cpu_tm; + + double usr = cpu_tm.user (); + double sys = cpu_tm.system (); + + return ovl (usr + sys, usr, sys); } DEFUN (sort, args, nargout, diff -r 7ab7cd327257 -r f0c5dd1ea2b9 libinterp/corefcn/getrusage.cc --- a/libinterp/corefcn/getrusage.cc Thu Jun 16 13:09:54 2016 -0400 +++ b/libinterp/corefcn/getrusage.cc Thu Jun 16 15:56:00 2016 -0400 @@ -24,40 +24,12 @@ # include "config.h" #endif -#include -#include -#include - -#if defined (HAVE_SYS_RESOURCE_H) -# include -#endif - -#if defined (HAVE_SYS_PARAM_H) -# include -#endif +#include "oct-time.h" #include "defun.h" #include "oct-map.h" -#include "sysdep.h" #include "ov.h" #include "ovl.h" -#include "utils.h" - -#if ! defined (HZ) -# if defined (CLK_TCK) -# define HZ CLK_TCK -# elif defined (USG) -# define HZ 100 -# else -# define HZ 60 -# endif -#endif - -#if ! defined (RUSAGE_SELF) -# define RUSAGE_SELF 0 -#endif - -// System resource functions. DEFUN (getrusage, , , "-*- texinfo -*-\n\ @@ -122,87 +94,37 @@ @end table\n\ @end deftypefn") { - octave_scalar_map m; - octave_scalar_map tv_tmp; - - // FIXME: maybe encapsulate all of this in a liboctave class -#if defined (HAVE_GETRUSAGE) - - struct rusage ru; + octave_scalar_map ru_map; + octave_scalar_map tv_map; - getrusage (RUSAGE_SELF, &ru); + octave::sys::resource_usage rusage; - tv_tmp.assign ("sec", static_cast (ru.ru_utime.tv_sec)); - tv_tmp.assign ("usec", static_cast (ru.ru_utime.tv_usec)); - m.assign ("utime", octave_value (tv_tmp)); - - tv_tmp.assign ("sec", static_cast (ru.ru_stime.tv_sec)); - tv_tmp.assign ("usec", static_cast (ru.ru_stime.tv_usec)); - m.assign ("stime", octave_value (tv_tmp)); + octave::sys::cpu_time cpu = rusage.cpu (); -#if ! defined (RUSAGE_TIMES_ONLY) - m.assign ("maxrss", static_cast (ru.ru_maxrss)); - m.assign ("ixrss", static_cast (ru.ru_ixrss)); - m.assign ("idrss", static_cast (ru.ru_idrss)); - m.assign ("isrss", static_cast (ru.ru_isrss)); - m.assign ("minflt", static_cast (ru.ru_minflt)); - m.assign ("majflt", static_cast (ru.ru_majflt)); - m.assign ("nswap", static_cast (ru.ru_nswap)); - m.assign ("inblock", static_cast (ru.ru_inblock)); - m.assign ("oublock", static_cast (ru.ru_oublock)); - m.assign ("msgsnd", static_cast (ru.ru_msgsnd)); - m.assign ("msgrcv", static_cast (ru.ru_msgrcv)); - m.assign ("nsignals", static_cast (ru.ru_nsignals)); - m.assign ("nvcsw", static_cast (ru.ru_nvcsw)); - m.assign ("nivcsw", static_cast (ru.ru_nivcsw)); -#endif + tv_map.assign ("sec", cpu.user_sec ()); + tv_map.assign ("usec", cpu.user_usec ()); + ru_map.assign ("utime", octave_value (tv_map)); -#else - - struct tms t; - - times (&t); + tv_map.assign ("sec", cpu.system_sec ()); + tv_map.assign ("usec", cpu.system_usec ()); + ru_map.assign ("stime", octave_value (tv_map)); - unsigned long ticks; - unsigned long seconds; - unsigned long fraction; - - ticks = t.tms_utime + t.tms_cutime; - fraction = ticks % HZ; - seconds = ticks / HZ; - - tv_tmp.assign ("sec", static_cast (seconds)); - tv_tmp.assign ("usec", static_cast (fraction * 1e6 / HZ)); - m.assign ("utime", octave_value (tv_tmp)); - - ticks = t.tms_stime + t.tms_cstime; - fraction = ticks % HZ; - seconds = ticks / HZ; - - tv_tmp.assign ("sec", static_cast (seconds)); - tv_tmp.assign ("usec", static_cast (fraction * 1e6 / HZ)); - m.assign ("stime", octave_value (tv_tmp)); + ru_map.assign ("maxrss", static_cast (rusage.maxrss ())); + ru_map.assign ("ixrss", static_cast (rusage.ixrss ())); + ru_map.assign ("idrss", static_cast (rusage.idrss ())); + ru_map.assign ("isrss", static_cast (rusage.isrss ())); + ru_map.assign ("minflt", static_cast (rusage.minflt ())); + ru_map.assign ("majflt", static_cast (rusage.majflt ())); + ru_map.assign ("nswap", static_cast (rusage.nswap ())); + ru_map.assign ("inblock", static_cast (rusage.inblock ())); + ru_map.assign ("oublock", static_cast (rusage.oublock ())); + ru_map.assign ("msgsnd", static_cast (rusage.msgsnd ())); + ru_map.assign ("msgrcv", static_cast (rusage.msgrcv ())); + ru_map.assign ("nsignals", static_cast (rusage.nsignals ())); + ru_map.assign ("nvcsw", static_cast (rusage.nvcsw ())); + ru_map.assign ("nivcsw", static_cast (rusage.nivcsw ())); - double tmp = lo_ieee_nan_value (); - - m.assign ("maxrss", tmp); - m.assign ("ixrss", tmp); - m.assign ("idrss", tmp); - m.assign ("isrss", tmp); - m.assign ("minflt", tmp); - m.assign ("majflt", tmp); - m.assign ("nswap", tmp); - m.assign ("inblock", tmp); - m.assign ("oublock", tmp); - m.assign ("msgsnd", tmp); - m.assign ("msgrcv", tmp); - m.assign ("nsignals", tmp); - m.assign ("nvcsw", tmp); - m.assign ("nivcsw", tmp); - -#endif - - return ovl (m); + return ovl (ru_map); } /* diff -r 7ab7cd327257 -r f0c5dd1ea2b9 liboctave/system/oct-time.cc --- a/liboctave/system/oct-time.cc Thu Jun 16 13:09:54 2016 -0400 +++ b/liboctave/system/oct-time.cc Thu Jun 16 15:56:00 2016 -0400 @@ -28,8 +28,6 @@ #include -#include - #include "lo-error.h" #include "lo-math.h" #include "lo-utils.h" @@ -37,6 +35,7 @@ #include "oct-time.h" #include "strftime-wrapper.h" #include "strptime-wrapper.h" +#include "time-wrappers.h" namespace octave { @@ -92,12 +91,7 @@ void time::stamp (void) { - struct ::timeval tp; - - gnulib::gettimeofday (&tp, 0); - - ot_unix_time = tp.tv_sec; - ot_usec = tp.tv_usec; + octave_gettimeofday_wrapper (&ot_unix_time, &ot_usec); } // From the mktime() manual page: @@ -312,5 +306,27 @@ delete [] ps; #endif } + + void + cpu_time::stamp (void) + { + octave_cpu_time (&m_usr_sec, &m_sys_sec, &m_usr_usec, &m_sys_usec); + } + + void + resource_usage::stamp (void) + { + time_t usr_sec, sys_sec; + long usr_usec, sys_usec; + + octave_getrusage_wrapper (&usr_sec, &sys_sec, &usr_usec, + &sys_usec, &m_maxrss, &m_ixrss, + &m_idrss, &m_isrss, &m_minflt, + &m_majflt, &m_nswap, &m_inblock, + &m_oublock, &m_msgsnd, &m_msgrcv, + &m_nsignals, &m_nvcsw, &m_nivcsw); + + m_cpu = cpu_time (usr_sec, sys_sec, usr_usec, sys_usec); + } } } diff -r 7ab7cd327257 -r f0c5dd1ea2b9 liboctave/system/oct-time.h --- a/liboctave/system/oct-time.h Thu Jun 16 13:09:54 2016 -0400 +++ b/liboctave/system/oct-time.h Thu Jun 16 15:56:00 2016 -0400 @@ -94,7 +94,7 @@ time_t unix_time (void) const { return ot_unix_time; } - int usec (void) const { return ot_usec; } + long usec (void) const { return ot_usec; } std::string ctime (void) const; @@ -104,7 +104,7 @@ time_t ot_unix_time; // Additional microseconds. - int ot_usec; + long ot_usec; }; inline bool @@ -363,6 +363,161 @@ void init (const std::string& str, const std::string& fmt); }; + + class + OCTAVE_API + cpu_time + { + public: + + friend class resource_usage; + + cpu_time (void) + : m_usr_sec (0), m_sys_sec (0), m_usr_usec (0), m_sys_usec (0) + { + stamp (); + } + + cpu_time (const cpu_time& tm) + : m_usr_sec (tm.m_usr_sec), m_sys_sec (tm.m_sys_sec), + m_usr_usec (tm.m_usr_usec), m_sys_usec (tm.m_sys_usec) + { } + + cpu_time& operator = (const cpu_time& tm) + { + if (&tm != this) + { + m_usr_sec = tm.m_usr_sec; + m_sys_sec = tm.m_sys_sec; + m_usr_usec = tm.m_usr_usec; + m_sys_usec = tm.m_sys_usec; + } + + return *this; + } + + void stamp (void); + + double user (void) const + { + return (static_cast (m_usr_sec) + + static_cast (m_sys_usec) * 1e-6); + } + + double system (void) const + { + return (static_cast (m_sys_sec) + + static_cast (m_sys_usec) * 1e-6); + } + + time_t user_sec (void) const { return m_usr_sec; } + long user_usec (void) const { return m_usr_usec; } + + time_t system_sec (void) const { return m_sys_sec; } + long system_usec (void) const { return m_sys_usec; } + + private: + + time_t m_usr_sec; + time_t m_sys_sec; + + long m_usr_usec; + long m_sys_usec; + + cpu_time (time_t usr_sec, time_t sys_sec, long usr_usec, long sys_usec) + : m_usr_sec (usr_sec), m_sys_sec (sys_sec), + m_usr_usec (usr_usec), m_sys_usec (sys_usec) + { } + }; + + class + resource_usage + { + public: + + resource_usage (void) + : m_cpu (), m_maxrss (0), m_ixrss (0), m_idrss (0), + m_isrss (0), m_minflt (0), m_majflt (0), m_nswap (0), + m_inblock (0), m_oublock (0), m_msgsnd (0), m_msgrcv (0), + m_nsignals (0), m_nvcsw (0), m_nivcsw (0) + { + stamp (); + } + + resource_usage (const resource_usage& ru) + : m_cpu (ru.m_cpu), m_maxrss (ru.m_maxrss), + m_ixrss (ru.m_ixrss), m_idrss (ru.m_idrss), + m_isrss (ru.m_isrss), m_minflt (ru.m_minflt), + m_majflt (ru.m_majflt), m_nswap (ru.m_nswap), + m_inblock (ru.m_inblock), m_oublock (ru.m_oublock), + m_msgsnd (ru.m_msgsnd), m_msgrcv (ru.m_msgrcv), + m_nsignals (ru.m_nsignals), m_nvcsw (ru.m_nvcsw), + m_nivcsw (ru.m_nivcsw) + { } + + resource_usage& operator = (const resource_usage& ru) + { + if (&ru != this) + { + m_cpu = ru.m_cpu; + + m_maxrss = ru.m_maxrss; + m_ixrss = ru.m_ixrss; + m_idrss = ru.m_idrss; + m_isrss = ru.m_isrss; + m_minflt = ru.m_minflt; + m_majflt = ru.m_majflt; + m_nswap = ru.m_nswap; + m_inblock = ru.m_inblock; + m_oublock = ru.m_oublock; + m_msgsnd = ru.m_msgsnd; + m_msgrcv = ru.m_msgrcv; + m_nsignals = ru.m_nsignals; + m_nvcsw = ru.m_nvcsw; + m_nivcsw = ru.m_nivcsw; + } + + return *this; + } + + void stamp (void); + + cpu_time cpu (void) const { return m_cpu; } + + long maxrss (void) const { return m_maxrss; } + long ixrss (void) const { return m_ixrss; } + long idrss (void) const { return m_idrss; } + long isrss (void) const { return m_isrss; } + long minflt (void) const { return m_minflt; } + long majflt (void) const { return m_majflt; } + long nswap (void) const { return m_nswap; } + long inblock (void) const { return m_inblock; } + long oublock (void) const { return m_oublock; } + long msgsnd (void) const { return m_msgsnd; } + long msgrcv (void) const { return m_msgrcv; } + long nsignals (void) const { return m_nsignals; } + long nvcsw (void) const { return m_nvcsw; } + long nivcsw (void) const { return m_nivcsw; } + + private: + + cpu_time m_cpu; + + long m_maxrss; + long m_ixrss; + long m_idrss; + long m_isrss; + long m_minflt; + long m_majflt; + long m_nswap; + long m_inblock; + long m_oublock; + long m_msgsnd; + long m_msgrcv; + long m_nsignals; + long m_nvcsw; + long m_nivcsw; + }; } } diff -r 7ab7cd327257 -r f0c5dd1ea2b9 liboctave/util/lo-cutils.c --- a/liboctave/util/lo-cutils.c Thu Jun 16 13:09:54 2016 -0400 +++ b/liboctave/util/lo-cutils.c Thu Jun 16 15:56:00 2016 -0400 @@ -24,19 +24,10 @@ # include "config.h" #endif -/* This gives us a better chance of finding a prototype for strptime - on some systems. */ - -#if ! defined (_XOPEN_SOURCE) -# define _XOPEN_SOURCE 1 -#endif - #include #include -#include #include "lo-cutils.h" -#include "lo-error.h" OCTAVE_API void octave_qsort (void *base, size_t n, size_t size, diff -r 7ab7cd327257 -r f0c5dd1ea2b9 liboctave/wrappers/module.mk --- a/liboctave/wrappers/module.mk Thu Jun 16 13:09:54 2016 -0400 +++ b/liboctave/wrappers/module.mk Thu Jun 16 15:56:00 2016 -0400 @@ -19,6 +19,7 @@ liboctave/wrappers/strftime-wrapper.h \ liboctave/wrappers/strmode-wrapper.h \ liboctave/wrappers/strptime-wrapper.h \ + liboctave/wrappers/time-wrappers.h \ liboctave/wrappers/uname-wrapper.h \ liboctave/wrappers/unistd-wrappers.h \ liboctave/wrappers/unsetenv-wrapper.h \ @@ -47,6 +48,7 @@ liboctave/wrappers/strftime-wrapper.c \ liboctave/wrappers/strmode-wrapper.c \ liboctave/wrappers/strptime-wrapper.c \ + liboctave/wrappers/time-wrappers.c \ liboctave/wrappers/uname-wrapper.c \ liboctave/wrappers/unistd-wrappers.c \ liboctave/wrappers/unsetenv-wrapper.c \ diff -r 7ab7cd327257 -r f0c5dd1ea2b9 liboctave/wrappers/time-wrappers.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/wrappers/time-wrappers.c Thu Jun 16 15:56:00 2016 -0400 @@ -0,0 +1,148 @@ +/* + +Copyright (C) 2016 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +// These functions may be provided by gnulib. We don't include gnulib +// headers directly in Octave's C++ source files to avoid problems that +// may be caused by the way that gnulib overrides standard library +// functions. + +#if defined (HAVE_CONFIG_H) +# include "config.h" +#endif + +#include +#include +#include + +#include "time-wrappers.h" + +int +octave_gettimeofday_wrapper (time_t *sec, long *usec) +{ + struct timeval tv; + + int status = gettimeofday (&tv, 0); + + if (status < 0) + { + *sec = 0; + *usec = 0; + } + else + { + *sec = tv.tv_sec; + *usec = tv.tv_usec; + } + + return status; +} + +int +octave_cpu_time (time_t *usr_sec, time_t *sys_sec, + long *usr_usec, long *sys_usec) +{ + struct rusage ru; + + int status = getrusage (RUSAGE_SELF, &ru); + + if (status < 0) + { + *usr_sec = 0; + *sys_sec = 0; + + *usr_usec = 0; + *sys_usec = 0; + } + else + { + *usr_sec = ru.ru_utime.tv_sec; + *usr_usec = ru.ru_utime.tv_usec; + + *sys_sec = ru.ru_stime.tv_sec; + *sys_usec = ru.ru_stime.tv_usec; + } + + return status; +} + +int +octave_getrusage_wrapper (time_t *usr_sec, time_t *sys_sec, + long *usr_usec, long *sys_usec, + long *maxrss, long *ixrss, long *idrss, + long *isrss, long *minflt, long *majflt, + long *nswap, long *inblock, long *oublock, + long *msgsnd, long *msgrcv, long *nsignals, + long *nvcsw, long *nivcsw) +{ + struct rusage ru; + + int status = getrusage (RUSAGE_SELF, &ru); + + if (status < 0) + { + *usr_sec = 0; + *usr_usec = 0; + + *sys_sec = 0; + *sys_usec = 0; + + *maxrss = 0; + *ixrss = 0; + *idrss = 0; + *isrss = 0; + *minflt = 0; + *majflt = 0; + *nswap = 0; + *inblock = 0; + *oublock = 0; + *msgsnd = 0; + *msgrcv = 0; + *nsignals = 0; + *nvcsw = 0; + *nivcsw = 0; + } + else + { + *usr_sec = ru.ru_utime.tv_sec; + *usr_usec = ru.ru_utime.tv_usec; + + *sys_sec = ru.ru_stime.tv_sec; + *sys_usec = ru.ru_stime.tv_usec; + + *maxrss = ru.ru_maxrss; + *ixrss = ru.ru_ixrss; + *idrss = ru.ru_idrss; + *isrss = ru.ru_isrss; + *minflt = ru.ru_minflt; + *majflt = ru.ru_majflt; + *nswap = ru.ru_nswap; + *inblock = ru.ru_inblock; + *oublock = ru.ru_oublock; + *msgsnd = ru.ru_msgsnd; + *msgrcv = ru.ru_msgrcv; + *nsignals = ru.ru_nsignals; + *nvcsw = ru.ru_nvcsw; + *nivcsw = ru.ru_nivcsw; + } + + return status; +} diff -r 7ab7cd327257 -r f0c5dd1ea2b9 liboctave/wrappers/time-wrappers.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/liboctave/wrappers/time-wrappers.h Thu Jun 16 15:56:00 2016 -0400 @@ -0,0 +1,56 @@ +/* + +Copyright (C) 2016 John W. Eaton + +This file is part of Octave. + +Octave is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 3 of the License, or (at your +option) any later version. + +Octave is distributed in the hope that it will be useful, but WITHOUT +ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or +FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License +for more details. + +You should have received a copy of the GNU General Public License +along with Octave; see the file COPYING. If not, see +. + +*/ + +#if ! defined (octave_time_wrappers_h) +#define octave_time_wrappers_h 1 + +#if defined __cplusplus +# include +#else +# include +#endif + +#if defined __cplusplus +extern "C" { +#endif + +extern int octave_gettimeofday_wrapper (time_t *sec, long *usec); + +extern int +octave_cpu_time (time_t *usr_sec, time_t *sys_sec, + long *usr_usec, long *sys_usec); + +extern int +octave_getrusage_wrapper (time_t *usr_sec, time_t *sys_sec, + long *usr_usec, long *sys_usec, + long *maxrss, long *ixrss, long *idrss, + long *isrss, long *minflt, long *majflt, + long *nswap, long *inblock, long *oublock, + long *msgsnd, long *msgrcv, long *nsignals, + long *nvcsw, long *nivcsw); + +#if defined __cplusplus +} +#endif + +#endif +