From: Bruno Haible Date: Thu, 12 Apr 2012 22:48:57 +0000 (+0200) Subject: New module 'getrusage'. X-Git-Tag: v0.1~749 X-Git-Url: http://erislabs.net/gitweb/?p=gnulib.git;a=commitdiff_plain;h=189ef2bce0bea3a3cae08df756a7b2035a9764e0 New module 'getrusage'. * lib/sys_resource.in.h: Include arg-nonnull.h, c++defs.h, warn-on-use.h. (getrusage): New declaration. * lib/getrusage.c: New file. * m4/getrusage.m4: New file. * m4/sys_resource_h.m4 (gl_HEADER_SYS_RESOURCE): Test whether getrusage is declared. (gl_SYS_RESOURCE_H_DEFAULTS): Initialize GNULIB_GETRUSAGE, HAVE_GETRUSAGE. * modules/sys_resource (Depends-on): Add snippet/arg-nonnull, snippet/c++defs, snippet/warn-on-use. (Makefile.am): Update generation of sys/resource.h. Substitute GNULIB_GETRUSAGE, HAVE_GETRUSAGE. * modules/getrusage: New file. * doc/posix-functions/getrusage.texi: Mention the new module. --- diff --git a/ChangeLog b/ChangeLog index 82af69de9..4bf61e56b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,5 +1,24 @@ 2012-04-12 Bruno Haible + New module 'getrusage'. + * lib/sys_resource.in.h: Include arg-nonnull.h, c++defs.h, + warn-on-use.h. + (getrusage): New declaration. + * lib/getrusage.c: New file. + * m4/getrusage.m4: New file. + * m4/sys_resource_h.m4 (gl_HEADER_SYS_RESOURCE): Test whether getrusage + is declared. + (gl_SYS_RESOURCE_H_DEFAULTS): Initialize GNULIB_GETRUSAGE, + HAVE_GETRUSAGE. + * modules/sys_resource (Depends-on): Add snippet/arg-nonnull, + snippet/c++defs, snippet/warn-on-use. + (Makefile.am): Update generation of sys/resource.h. Substitute + GNULIB_GETRUSAGE, HAVE_GETRUSAGE. + * modules/getrusage: New file. + * doc/posix-functions/getrusage.texi: Mention the new module. + +2012-04-12 Bruno Haible + Tests for module 'sys_resource'. * modules/sys_resource-tests: New file. * tests/test-sys_resource.c: New file. diff --git a/doc/posix-functions/getrusage.texi b/doc/posix-functions/getrusage.texi index 35f711ca1..ce0bbdebf 100644 --- a/doc/posix-functions/getrusage.texi +++ b/doc/posix-functions/getrusage.texi @@ -4,18 +4,18 @@ POSIX specification:@* @url{http://www.opengroup.org/onlinepubs/9699919799/functions/getrusage.html} -Gnulib module: --- +Gnulib module: getrusage Portability problems fixed by Gnulib: @itemize +@item +This function is missing on some platforms: +Minix 3.1.8, Solaris 2.4, mingw, MSVC 9. @end itemize Portability problems not fixed by Gnulib: @itemize @item -This function is missing on some platforms: -Minix 3.1.8, Solaris 2.4, mingw, MSVC 9. -@item Many platforms don't fill in all the fields of @code{struct rusage} with meaningful values. @end itemize diff --git a/lib/getrusage.c b/lib/getrusage.c new file mode 100644 index 000000000..153764cfd --- /dev/null +++ b/lib/getrusage.c @@ -0,0 +1,131 @@ +/* getrusage replacement for systems which lack it. + + Copyright (C) 2012 Free Software Foundation, Inc. + + This program 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. + + This program 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 this program. If not, see . */ + +/* Written by Bruno Haible, 2012. */ + +#include + +/* Specification. */ +#include + +#include +#include + +/* Get uint64_t. */ +#include + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + +# define WIN32_LEAN_AND_MEAN +# include + +#else + +# include +# include +#endif + +int +getrusage (int who, struct rusage *usage_p) +{ + if (who == RUSAGE_SELF || who == RUSAGE_CHILDREN) + { + /* Clear all unsupported members of 'struct rusage'. */ + memset (usage_p, '\0', sizeof (struct rusage)); + +#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__ + if (who == RUSAGE_SELF) + { + /* Fill in the ru_utime and ru_stime members. */ + FILETIME creation_time; + FILETIME exit_time; + FILETIME kernel_time; + FILETIME user_time; + + if (GetProcessTimes (GetCurrentProcess (), + &creation_time, &exit_time, + &kernel_time, &user_time)) + { + /* Convert to microseconds, rounding. */ + uint64_t kernel_usec = + ((((uint64_t) kernel_time.dwHighDateTime << 32) + | (uint64_t) kernel_time.dwLowDateTime) + + 5) / 10; + uint64_t user_usec = + ((((uint64_t) user_time.dwHighDateTime << 32) + | (uint64_t) user_time.dwLowDateTime) + + 5) / 10; + + usage_p->ru_utime.tv_sec = user_usec / 1000000U; + usage_p->ru_utime.tv_usec = user_usec % 1000000U; + usage_p->ru_stime.tv_sec = kernel_usec / 1000000U; + usage_p->ru_stime.tv_usec = kernel_usec % 1000000U; + } + } +#else + /* Fill in the ru_utime and ru_stime members. */ + { + struct tms time; + + if (times (&time) != (clock_t) -1) + { + /* Number of clock ticks per second. */ + unsigned int clocks_per_second = sysconf (_SC_CLK_TCK); + + if (clocks_per_second > 0) + { + clock_t user_ticks; + clock_t system_ticks; + + uint64_t user_usec; + uint64_t system_usec; + + if (who == RUSAGE_CHILDREN) + { + user_ticks = time.tms_cutime; + system_ticks = time.tms_cstime; + } + else + { + user_ticks = time.tms_utime; + system_ticks = time.tms_stime; + } + + user_usec = + (((uint64_t) user_ticks * (uint64_t) 1000000U) + + clocks_per_second / 2) / clocks_per_second; + system_usec = + (((uint64_t) system_ticks * (uint64_t) 1000000U) + + clocks_per_second / 2) / clocks_per_second; + + usage_p->ru_utime.tv_sec = user_usec / 1000000U; + usage_p->ru_utime.tv_usec = user_usec % 1000000U; + usage_p->ru_stime.tv_sec = system_usec / 1000000U; + usage_p->ru_stime.tv_usec = system_usec % 1000000U; + } + } + } +#endif + + return 0; + } + else + { + errno = EINVAL; + return -1; + } +} diff --git a/lib/sys_resource.in.h b/lib/sys_resource.in.h index 59bfc6f80..c255f574d 100644 --- a/lib/sys_resource.in.h +++ b/lib/sys_resource.in.h @@ -81,5 +81,31 @@ struct rusage #endif +/* The definitions of _GL_FUNCDECL_RPL etc. are copied here. */ + +/* The definition of _GL_ARG_NONNULL is copied here. */ + +/* The definition of _GL_WARN_ON_USE is copied here. */ + + +/* Declare overridden functions. */ + + +#if @GNULIB_GETRUSAGE@ +# if !@HAVE_GETRUSAGE@ +_GL_FUNCDECL_SYS (getrusage, int, (int who, struct rusage *usage_p) + _GL_ARG_NONNULL ((2))); +# endif +_GL_CXXALIAS_SYS (getrusage, int, (int who, struct rusage *usage_p)); +_GL_CXXALIASWARN (getrusage); +#elif defined GNULIB_POSIXCHECK +# undef getrusage +# if HAVE_RAW_DECL_GETRUSAGE +_GL_WARN_ON_USE (getrusage, "getrusage is unportable - " + "use gnulib module getrusage for portability"); +# endif +#endif + + #endif /* _@GUARD_PREFIX@_SYS_RESOURCE_H */ #endif /* _@GUARD_PREFIX@_SYS_RESOURCE_H */ diff --git a/m4/getrusage.m4 b/m4/getrusage.m4 new file mode 100644 index 000000000..734b2f0e7 --- /dev/null +++ b/m4/getrusage.m4 @@ -0,0 +1,14 @@ +# getrusage.m4 serial 1 +dnl Copyright (C) 2012 Free Software Foundation, Inc. +dnl This file is free software; the Free Software Foundation +dnl gives unlimited permission to copy and/or distribute it, +dnl with or without modifications, as long as this notice is preserved. + +AC_DEFUN([gl_FUNC_GETRUSAGE], +[ + AC_REQUIRE([gl_SYS_RESOURCE_H_DEFAULTS]) + AC_CHECK_FUNCS_ONCE([getrusage]) + if test $ac_cv_func_getrusage = no; then + HAVE_GETRUSAGE=0 + fi +]) diff --git a/m4/sys_resource_h.m4 b/m4/sys_resource_h.m4 index cb6a03568..97286e4e0 100644 --- a/m4/sys_resource_h.m4 +++ b/m4/sys_resource_h.m4 @@ -1,4 +1,4 @@ -# sys_resource_h.m4 serial 1 +# sys_resource_h.m4 serial 2 dnl Copyright (C) 2012 Free Software Foundation, Inc. dnl This file is free software; the Free Software Foundation dnl gives unlimited permission to copy and/or distribute it, @@ -15,6 +15,19 @@ AC_DEFUN([gl_HEADER_SYS_RESOURCE], HAVE_SYS_RESOURCE_H=0 fi AC_SUBST([HAVE_SYS_RESOURCE_H]) + + dnl Check for declarations of anything we want to poison if the + dnl corresponding gnulib module is not in use. + gl_WARN_ON_USE_PREPARE([[ +#if HAVE_SYS_RESOURCE_H +/* At least FreeBSD 5.0 needs extra headers before + will compile. */ +# include +# include +# include +#endif + ]], + [getrusage]) ]) AC_DEFUN([gl_SYS_RESOURCE_MODULE_INDICATOR], @@ -28,4 +41,7 @@ AC_DEFUN([gl_SYS_RESOURCE_MODULE_INDICATOR], AC_DEFUN([gl_SYS_RESOURCE_H_DEFAULTS], [ + GNULIB_GETRUSAGE=0; AC_SUBST([GNULIB_GETRUSAGE]) + dnl Assume proper GNU behavior unless another module says otherwise. + HAVE_GETRUSAGE=1; AC_SUBST([HAVE_GETRUSAGE]) ]) diff --git a/modules/getrusage b/modules/getrusage new file mode 100644 index 000000000..058c540de --- /dev/null +++ b/modules/getrusage @@ -0,0 +1,28 @@ +Description: +getrusage() function: Get resource usage of current process. + +Files: +lib/getrusage.c +m4/getrusage.m4 + +Depends-on: +sys_resource +stdint [test $HAVE_GETRUSAGE = 0] + +configure.ac: +gl_FUNC_GETRUSAGE +if test $HAVE_GETRUSAGE = 0; then + AC_LIBOBJ([getrusage]) +fi +gl_SYS_RESOURCE_MODULE_INDICATOR([getrusage]) + +Makefile.am: + +Include: + + +License: +LGPL + +Maintainer: +Bruno Haible diff --git a/modules/sys_resource b/modules/sys_resource index d45ac2a15..afa8077dd 100644 --- a/modules/sys_resource +++ b/modules/sys_resource @@ -7,6 +7,9 @@ m4/sys_resource_h.m4 Depends-on: include_next +snippet/arg-nonnull +snippet/c++defs +snippet/warn-on-use sys_time configure.ac: @@ -18,7 +21,7 @@ BUILT_SOURCES += sys/resource.h # We need the following in order to create when the system # doesn't have one. -sys/resource.h: sys_resource.in.h $(top_builddir)/config.status +sys/resource.h: sys_resource.in.h $(top_builddir)/config.status $(CXXDEFS_H) $(ARG_NONNULL_H) $(WARN_ON_USE_H) $(AM_V_at)$(MKDIR_P) sys $(AM_V_GEN)rm -f $@-t $@ && \ { echo '/* DO NOT EDIT! GENERATED AUTOMATICALLY! */'; \ @@ -28,6 +31,11 @@ sys/resource.h: sys_resource.in.h $(top_builddir)/config.status -e 's|@''PRAGMA_COLUMNS''@|@PRAGMA_COLUMNS@|g' \ -e 's|@''NEXT_SYS_RESOURCE_H''@|$(NEXT_SYS_RESOURCE_H)|g' \ -e 's|@''HAVE_SYS_RESOURCE_H''@|$(HAVE_SYS_RESOURCE_H)|g' \ + -e 's/@''GNULIB_GETRUSAGE''@/$(GNULIB_GETRUSAGE)/g' \ + -e 's/@''HAVE_GETRUSAGE''@/$(HAVE_GETRUSAGE)/g' \ + -e '/definitions of _GL_FUNCDECL_RPL/r $(CXXDEFS_H)' \ + -e '/definition of _GL_ARG_NONNULL/r $(ARG_NONNULL_H)' \ + -e '/definition of _GL_WARN_ON_USE/r $(WARN_ON_USE_H)' \ < $(srcdir)/sys_resource.in.h; \ } > $@-t && \ mv -f $@-t $@