(root)/
bison-3.8.2/
lib/
getrusage.c
       1  /* getrusage replacement for systems which lack it.
       2  
       3     Copyright (C) 2012-2021 Free Software Foundation, Inc.
       4  
       5     This file is free software: you can redistribute it and/or modify
       6     it under the terms of the GNU Lesser General Public License as
       7     published by the Free Software Foundation; either version 3 of the
       8     License, or (at your option) any later version.
       9  
      10     This file is distributed in the hope that it will be useful,
      11     but WITHOUT ANY WARRANTY; without even the implied warranty of
      12     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      13     GNU Lesser General Public License for more details.
      14  
      15     You should have received a copy of the GNU Lesser General Public License
      16     along with this program.  If not, see <https://www.gnu.org/licenses/>.  */
      17  
      18  /* Written by Bruno Haible, 2012.  */
      19  
      20  #include <config.h>
      21  
      22  /* Specification.  */
      23  #include <sys/resource.h>
      24  
      25  #include <errno.h>
      26  #include <string.h>
      27  
      28  /* Get uint64_t.  */
      29  #include <stdint.h>
      30  
      31  #if defined _WIN32 && ! defined __CYGWIN__
      32  
      33  # define WIN32_LEAN_AND_MEAN
      34  # include <windows.h>
      35  
      36  #else
      37  
      38  # include <sys/times.h>
      39  # include <unistd.h>
      40  #endif
      41  
      42  int
      43  getrusage (int who, struct rusage *usage_p)
      44  {
      45    if (who == RUSAGE_SELF || who == RUSAGE_CHILDREN)
      46      {
      47        /* Clear all unsupported members of 'struct rusage'.  */
      48        memset (usage_p, '\0', sizeof (struct rusage));
      49  
      50  #if defined _WIN32 && ! defined __CYGWIN__
      51        if (who == RUSAGE_SELF)
      52          {
      53            /* Fill in the ru_utime and ru_stime members.  */
      54            FILETIME creation_time;
      55            FILETIME exit_time;
      56            FILETIME kernel_time;
      57            FILETIME user_time;
      58  
      59            if (GetProcessTimes (GetCurrentProcess (),
      60                                 &creation_time, &exit_time,
      61                                 &kernel_time, &user_time))
      62              {
      63                /* Convert to microseconds, rounding.  */
      64                uint64_t kernel_usec =
      65                  ((((uint64_t) kernel_time.dwHighDateTime << 32)
      66                    | (uint64_t) kernel_time.dwLowDateTime)
      67                   + 5) / 10;
      68                uint64_t user_usec =
      69                  ((((uint64_t) user_time.dwHighDateTime << 32)
      70                    | (uint64_t) user_time.dwLowDateTime)
      71                   + 5) / 10;
      72  
      73                usage_p->ru_utime.tv_sec = user_usec / 1000000U;
      74                usage_p->ru_utime.tv_usec = user_usec % 1000000U;
      75                usage_p->ru_stime.tv_sec = kernel_usec / 1000000U;
      76                usage_p->ru_stime.tv_usec = kernel_usec % 1000000U;
      77              }
      78          }
      79  #else
      80        /* Fill in the ru_utime and ru_stime members.  */
      81        {
      82          struct tms time;
      83  
      84          if (times (&time) != (clock_t) -1)
      85            {
      86              /* Number of clock ticks per second.  */
      87              unsigned int clocks_per_second = sysconf (_SC_CLK_TCK);
      88  
      89              if (clocks_per_second > 0)
      90                {
      91                  clock_t user_ticks;
      92                  clock_t system_ticks;
      93  
      94                  uint64_t user_usec;
      95                  uint64_t system_usec;
      96  
      97                  if (who == RUSAGE_CHILDREN)
      98                    {
      99                      user_ticks   = time.tms_cutime;
     100                      system_ticks = time.tms_cstime;
     101                    }
     102                  else
     103                    {
     104                      user_ticks   = time.tms_utime;
     105                      system_ticks = time.tms_stime;
     106                    }
     107  
     108                  user_usec =
     109                    (((uint64_t) user_ticks * (uint64_t) 1000000U)
     110                     + clocks_per_second / 2) / clocks_per_second;
     111                  system_usec =
     112                    (((uint64_t) system_ticks * (uint64_t) 1000000U)
     113                     + clocks_per_second / 2) / clocks_per_second;
     114  
     115                  usage_p->ru_utime.tv_sec = user_usec / 1000000U;
     116                  usage_p->ru_utime.tv_usec = user_usec % 1000000U;
     117                  usage_p->ru_stime.tv_sec = system_usec / 1000000U;
     118                  usage_p->ru_stime.tv_usec = system_usec % 1000000U;
     119                }
     120            }
     121        }
     122  #endif
     123  
     124        return 0;
     125      }
     126    else
     127      {
     128        errno = EINVAL;
     129        return -1;
     130      }
     131  }