/erts/emulator/sys/unix/sys_time.c

https://github.com/dustin/otp · C · 134 lines · 77 code · 20 blank · 37 comment · 9 complexity · 268a5d3926633c2eef3e60470420ce3b MD5 · raw file

  1. /*
  2. * %CopyrightBegin%
  3. *
  4. * Copyright Ericsson AB 2005-2009. All Rights Reserved.
  5. *
  6. * The contents of this file are subject to the Erlang Public License,
  7. * Version 1.1, (the "License"); you may not use this file except in
  8. * compliance with the License. You should have received a copy of the
  9. * Erlang Public License along with this software. If not, it can be
  10. * retrieved online at http://www.erlang.org/.
  11. *
  12. * Software distributed under the License is distributed on an "AS IS"
  13. * basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
  14. * the License for the specific language governing rights and limitations
  15. * under the License.
  16. *
  17. * %CopyrightEnd%
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. # include "config.h"
  21. #endif
  22. /* These need to be undef:ed to not break activation of
  23. * micro level process accounting on /proc/self
  24. */
  25. #ifdef _LARGEFILE_SOURCE
  26. # undef _LARGEFILE_SOURCE
  27. #endif
  28. #ifdef _FILE_OFFSET_BITS
  29. # undef _FILE_OFFSET_BITS
  30. #endif
  31. #include "sys.h"
  32. #include "global.h"
  33. #ifdef NO_SYSCONF
  34. # define TICKS_PER_SEC() HZ
  35. #else
  36. #define TICKS_PER_SEC() sysconf(_SC_CLK_TCK)
  37. #endif
  38. #ifdef HAVE_GETHRVTIME_PROCFS_IOCTL
  39. # include <unistd.h>
  40. # include <sys/types.h>
  41. # include <sys/stat.h>
  42. # include <sys/signal.h>
  43. # include <sys/fault.h>
  44. # include <sys/syscall.h>
  45. # include <sys/procfs.h>
  46. # include <fcntl.h>
  47. #endif
  48. /******************* Routines for time measurement *********************/
  49. int erts_ticks_per_sec = 0; /* Will be SYS_CLK_TCK in erl_unix_sys.h */
  50. int erts_ticks_per_sec_wrap = 0; /* Will be SYS_CLK_TCK_WRAP */
  51. static int ticks_bsr = 0; /* Shift wrapped tick value this much to the right */
  52. /*
  53. * init timers, chose a tick length, and return it.
  54. * Unix is priviliged when it comes to time, as erl_time_sup.c
  55. * does almost everything. Other platforms have to
  56. * emulate Unix in this sense.
  57. */
  58. int sys_init_time(void)
  59. {
  60. /*
  61. * This (erts_ticks_per_sec) is only for times() (CLK_TCK),
  62. * the resolution is always one millisecond..
  63. */
  64. if ((erts_ticks_per_sec = TICKS_PER_SEC()) < 0)
  65. erl_exit(1, "Can't get clock ticks/sec\n");
  66. if (erts_ticks_per_sec >= 1000) {
  67. /* Workaround for beta linux kernels, need to be done in runtime
  68. to make erlang run on both 2.4 and 2.5 kernels. In the future,
  69. the kernel ticks might as
  70. well be used as a high res timer instead, but that's for when the
  71. majority uses kernels with HZ == 1024 */
  72. ticks_bsr = 3;
  73. } else {
  74. ticks_bsr = 0;
  75. }
  76. erts_ticks_per_sec_wrap = (erts_ticks_per_sec >> ticks_bsr);
  77. return SYS_CLOCK_RESOLUTION;
  78. }
  79. clock_t sys_times_wrap(void)
  80. {
  81. SysTimes dummy;
  82. clock_t result = (sys_times(&dummy) >> ticks_bsr);
  83. return result;
  84. }
  85. #ifdef HAVE_GETHRVTIME_PROCFS_IOCTL
  86. int sys_start_hrvtime(void)
  87. {
  88. long msacct = PR_MSACCT;
  89. int fd;
  90. if ( (fd = open("/proc/self", O_WRONLY)) == -1) {
  91. return -1;
  92. }
  93. if (ioctl(fd, PIOCSET, &msacct) < 0) {
  94. close(fd);
  95. return -2;
  96. }
  97. close(fd);
  98. return 0;
  99. }
  100. int sys_stop_hrvtime(void)
  101. {
  102. long msacct = PR_MSACCT;
  103. int fd;
  104. if ( (fd = open("/proc/self", O_WRONLY)) == -1) {
  105. return -1;
  106. }
  107. if (ioctl(fd, PIOCRESET, &msacct) < 0) {
  108. close(fd);
  109. return -2;
  110. }
  111. close(fd);
  112. return 0;
  113. }
  114. #endif /* HAVE_GETHRVTIME_PROCFS_IOCTL */