melder_time.cpp 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143
  1. /* melder_time.cpp
  2. *
  3. * Copyright (C) 1992-2008,2011,2014-2018 Paul Boersma
  4. *
  5. * This code is free software; you can redistribute it and/or modify
  6. * it under the terms of the GNU General Public License as published by
  7. * the Free Software Foundation; either version 2 of the License, or (at
  8. * your option) any later version.
  9. *
  10. * This code is distributed in the hope that it will be useful, but
  11. * WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
  13. * See the GNU General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU General Public License
  16. * along with this work. If not, see <http://www.gnu.org/licenses/>.
  17. */
  18. #include "melder.h"
  19. #include <time.h>
  20. #if defined (macintosh) || defined (UNIX)
  21. #include <sys/time.h>
  22. #include <unistd.h>
  23. #elif defined (_WIN32)
  24. #include <windows.h>
  25. #endif
  26. /*
  27. #include <assert.h>
  28. #include <CoreServices/CoreServices.h>
  29. #include <mach/mach.h>
  30. #include <mach/mach_time.h>
  31. #include <unistd.h>
  32. uint64 GetPIDTimeInNanoseconds(void)
  33. {
  34. uint64 start;
  35. uint64 end;
  36. uint64 elapsed;
  37. uint64 elapsedNano;
  38. static mach_timebase_info_data_t sTimebaseInfo;
  39. // Start the clock.
  40. start = mach_absolute_time();
  41. // Call getpid. This will produce inaccurate results because
  42. // we're only making a single system call. For more accurate
  43. // results you should call getpid multiple times and average
  44. // the results.
  45. (void) getpid();
  46. // Stop the clock.
  47. end = mach_absolute_time();
  48. // Calculate the duration.
  49. elapsed = end - start;
  50. // Convert to nanoseconds.
  51. // If this is the first time we've run, get the timebase.
  52. // We can use denom == 0 to indicate that sTimebaseInfo is
  53. // uninitialised because it makes no sense to have a zero
  54. // denominator is a fraction.
  55. if ( sTimebaseInfo.denom == 0 ) {
  56. (void) mach_timebase_info(&sTimebaseInfo);
  57. }
  58. // Do the maths. We hope that the multiplication doesn't
  59. // overflow; the price you pay for working in fixed point.
  60. elapsedNano = elapsed * sTimebaseInfo.numer / sTimebaseInfo.denom;
  61. return elapsedNano;
  62. }
  63. */
  64. double Melder_clock () {
  65. #if defined (macintosh) || defined (UNIX)
  66. /*
  67. * The clock counts the number of seconds elapsed since 1969.
  68. */
  69. struct timeval timeVal;
  70. struct timezone timeZone;
  71. gettimeofday (& timeVal, & timeZone);
  72. return timeVal. tv_sec + 1e-6 * timeVal. tv_usec;
  73. #elif defined (_WIN32)
  74. /*
  75. * The clock counts the number of ticks since system start-up.
  76. */
  77. static double clockFrequency = -1.0; // we can use a static, because the clock frequency does not change while the computer is running
  78. if (clockFrequency == -1.0) { // not initialized?
  79. LARGE_INTEGER clockFrequency_longlong;
  80. QueryPerformanceFrequency (& clockFrequency_longlong); // returns 0 if the system does not have a performance counter
  81. clockFrequency = (double) clockFrequency_longlong.QuadPart; // the compiler has to support 64-bit integers
  82. }
  83. if (clockFrequency == 0.0) { // this will be true if the system does not have a performance counter
  84. return GetTickCount () / 1000.0; // fallback: only millisecond resolution, and potentially jumpy
  85. }
  86. LARGE_INTEGER clockCount;
  87. QueryPerformanceCounter (& clockCount);
  88. return (double) clockCount.QuadPart / clockFrequency;
  89. #else
  90. return 0;
  91. #endif
  92. }
  93. double Melder_stopwatch () {
  94. static double lastTime;
  95. double now = Melder_clock ();
  96. double timeElapsed = ( lastTime == 0 ? -1.0 : now - lastTime );
  97. //Melder_casual ("%ld %ld %ld %lf %lf", now, lastTime, now - lastTime, (now - lastTime) / (double) CLOCKS_PER_SEC, timeElapsed);
  98. lastTime = now;
  99. return timeElapsed;
  100. }
  101. void Melder_sleep (double duration) {
  102. if (duration <= 0.0) return; // already past end time
  103. #if defined (_WIN32)
  104. Sleep (duration * 1e3);
  105. #elif defined (macintosh) || defined (UNIX)
  106. unsigned int seconds = (unsigned int) duration;
  107. unsigned int microseconds = (unsigned int) ((duration - seconds) * 1e6);
  108. if (seconds > 0) sleep (seconds);
  109. if (microseconds > 0) usleep (microseconds);
  110. #endif
  111. }
  112. autostring32 STRdate () {
  113. time_t today = time (nullptr);
  114. autostring32 date = Melder_8to32 (ctime (& today));
  115. mutablestring32 newline = str32chr (date.get(), U'\n');
  116. if (newline) *newline = U'\0';
  117. return date;
  118. }
  119. /* End of file melder_time.cpp */