/* getrusage replacement for systems which lack it. Copyright (C) 2012-2020 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 __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 __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; } }