times.c 4.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184
  1. /*++
  2. Copyright (c) 2013 Minoca Corp.
  3. This file is licensed under the terms of the GNU General Public License
  4. version 3. Alternative licensing terms are available. Contact
  5. info@minocacorp.com for details. See the LICENSE file at the root of this
  6. project for complete licensing information.
  7. Module Name:
  8. times.c
  9. Abstract:
  10. This module implements support for getting the current process' running
  11. time.
  12. Author:
  13. Evan Green 23-Jun-2013
  14. Environment:
  15. User Mode C Library
  16. --*/
  17. //
  18. // ------------------------------------------------------------------- Includes
  19. //
  20. #include "libcp.h"
  21. #include <errno.h>
  22. #include <unistd.h>
  23. #include <sys/times.h>
  24. //
  25. // ---------------------------------------------------------------- Definitions
  26. //
  27. //
  28. // ------------------------------------------------------ Data Type Definitions
  29. //
  30. //
  31. // ----------------------------------------------- Internal Function Prototypes
  32. //
  33. //
  34. // -------------------------------------------------------------------- Globals
  35. //
  36. //
  37. // ------------------------------------------------------------------ Functions
  38. //
  39. LIBC_API
  40. clock_t
  41. times (
  42. struct tms *Times
  43. )
  44. /*++
  45. Routine Description:
  46. This routine returns the running time for the current process and its
  47. children.
  48. Arguments:
  49. Times - Supplies a pointer where the running time information will be
  50. returned.
  51. Return Value:
  52. On success, returns the elapsed real time, in clock ticks, since an
  53. arbitrary time in the past (like boot time). This point does not change
  54. from one invocation of times within the process to another. On error, -1
  55. will be returned and errno will be set to indicate the error.
  56. --*/
  57. {
  58. RESOURCE_USAGE ChildrenUsage;
  59. ULONGLONG ClockFrequency;
  60. LONG ClockTicksPerSecond;
  61. clock_t ElapsedRealTime;
  62. ULONGLONG Microseconds;
  63. RESOURCE_USAGE ProcessUsage;
  64. KSTATUS Status;
  65. ULONGLONG TimeCounter;
  66. ULONGLONG TimeCounterFrequency;
  67. if (Times == NULL) {
  68. errno = EINVAL;
  69. return -1;
  70. }
  71. //
  72. // Get the clock ticks per second that the caller expects for all the
  73. // clock_t values.
  74. //
  75. ClockTicksPerSecond = sysconf(_SC_CLK_TCK);
  76. if (ClockTicksPerSecond == -1) {
  77. return -1;
  78. }
  79. //
  80. // Query the system for the current process times.
  81. //
  82. Status = OsGetResourceUsage(ResourceUsageRequestProcess,
  83. -1,
  84. &ProcessUsage,
  85. &ClockFrequency);
  86. if (!KSUCCESS(Status)) {
  87. errno = ClConvertKstatusToErrorNumber(Status);
  88. return -1;
  89. }
  90. Status = OsGetResourceUsage(ResourceUsageRequestProcessChildren,
  91. -1,
  92. &ChildrenUsage,
  93. NULL);
  94. if (!KSUCCESS(Status)) {
  95. errno = ClConvertKstatusToErrorNumber(Status);
  96. return -1;
  97. }
  98. //
  99. // Convert each of the process times into the clock_t times expected by the
  100. // caller.
  101. //
  102. Microseconds = (ProcessUsage.UserCycles * MICROSECONDS_PER_SECOND) /
  103. ClockFrequency;
  104. Times->tms_utime = (Microseconds * ClockTicksPerSecond) /
  105. MICROSECONDS_PER_SECOND;
  106. Microseconds = (ProcessUsage.KernelCycles * MICROSECONDS_PER_SECOND) /
  107. ClockFrequency;
  108. Times->tms_stime = (Microseconds * ClockTicksPerSecond) /
  109. MICROSECONDS_PER_SECOND;
  110. Microseconds = (ChildrenUsage.UserCycles * MICROSECONDS_PER_SECOND) /
  111. ClockFrequency;
  112. Times->tms_cutime = (Microseconds * ClockTicksPerSecond) /
  113. MICROSECONDS_PER_SECOND;
  114. Microseconds = (ChildrenUsage.KernelCycles * MICROSECONDS_PER_SECOND) /
  115. ClockFrequency;
  116. Times->tms_cstime = (Microseconds * ClockTicksPerSecond) /
  117. MICROSECONDS_PER_SECOND;
  118. //
  119. // The process time was successfully collected, get the elapsed real time
  120. // and convert it to clock ticks.
  121. //
  122. TimeCounter = OsGetRecentTimeCounter();
  123. TimeCounterFrequency = OsGetTimeCounterFrequency();
  124. Microseconds = (TimeCounter * MICROSECONDS_PER_SECOND) /
  125. TimeCounterFrequency;
  126. ElapsedRealTime = (Microseconds * ClockTicksPerSecond) /
  127. MICROSECONDS_PER_SECOND;
  128. return ElapsedRealTime;
  129. }
  130. //
  131. // --------------------------------------------------------- Internal Functions
  132. //