summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog19
-rw-r--r--doc/posix-functions/getrusage.texi8
-rw-r--r--lib/getrusage.c131
-rw-r--r--lib/sys_resource.in.h26
-rw-r--r--m4/getrusage.m414
-rw-r--r--m4/sys_resource_h.m418
-rw-r--r--modules/getrusage28
-rw-r--r--modules/sys_resource10
8 files changed, 248 insertions, 6 deletions
diff --git a/ChangeLog b/ChangeLog
index 82af69de9b..4bf61e56bb 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,24 @@
2012-04-12 Bruno Haible <bruno@clisp.org>
+ 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 <bruno@clisp.org>
+
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 35f711ca14..ce0bbdebf0 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 0000000000..153764cfd8
--- /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 <http://www.gnu.org/licenses/>. */
+
+/* Written by Bruno Haible, 2012. */
+
+#include <config.h>
+
+/* Specification. */
+#include <sys/resource.h>
+
+#include <errno.h>
+#include <string.h>
+
+/* Get uint64_t. */
+#include <stdint.h>
+
+#if (defined _WIN32 || defined __WIN32__) && ! defined __CYGWIN__
+
+# define WIN32_LEAN_AND_MEAN
+# include <windows.h>
+
+#else
+
+# include <sys/times.h>
+# include <unistd.h>
+#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 59bfc6f80c..c255f574d5 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 0000000000..734b2f0e78
--- /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 cb6a03568e..97286e4e04 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 <sys/resource.h>
+ will compile. */
+# include <sys/types.h>
+# include <sys/time.h>
+# include <sys/resource.h>
+#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 0000000000..058c540de4
--- /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:
+<sys/resource.h>
+
+License:
+LGPL
+
+Maintainer:
+Bruno Haible
diff --git a/modules/sys_resource b/modules/sys_resource
index d45ac2a154..afa8077dd2 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 <sys/resource.h> 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 $@