Time.cpp 4.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153
  1. #include "il2cpp-config.h"
  2. #if IL2CPP_TARGET_POSIX && !IL2CPP_USE_PLATFORM_SPECIFIC_TIME
  3. #include "os/Time.h"
  4. #include <stdlib.h>
  5. #include <stdio.h>
  6. #include <sys/param.h>
  7. #if IL2CPP_TARGET_DARWIN
  8. #include <sys/sysctl.h>
  9. #include <mach/mach.h>
  10. #include <mach/mach_time.h>
  11. #endif
  12. #include <time.h>
  13. #if IL2CPP_TARGET_LINUX || IL2CPP_TARGET_QNX
  14. #include <sys/time.h>
  15. #endif
  16. /* a made up uptime of 300 seconds */
  17. #define MADEUP_BOOT_TIME (300 * MTICKS_PER_SEC)
  18. namespace il2cpp
  19. {
  20. namespace os
  21. {
  22. const int64_t MTICKS_PER_SEC = 10000000;
  23. static int64_t
  24. GetBootTime()
  25. {
  26. #if IL2CPP_TARGET_DARWIN
  27. int mib[2];
  28. size_t size;
  29. time_t now;
  30. struct timeval boottime;
  31. (void)time(&now);
  32. mib[0] = CTL_KERN;
  33. mib[1] = KERN_BOOTTIME;
  34. size = sizeof(boottime);
  35. if (sysctl(mib, 2, &boottime, &size, NULL, 0) != -1)
  36. return (int64_t)((now - boottime.tv_sec) * MTICKS_PER_SEC);
  37. #else
  38. FILE *uptime = fopen("/proc/uptime", "r");
  39. if (uptime)
  40. {
  41. double upt;
  42. if (fscanf(uptime, "%lf", &upt) == 1)
  43. {
  44. const int64_t now = Time::GetTicks100NanosecondsMonotonic();
  45. fclose(uptime);
  46. return now - (int64_t)(upt * MTICKS_PER_SEC);
  47. }
  48. fclose(uptime);
  49. }
  50. #endif
  51. /* a made up uptime of 300 seconds */
  52. return (int64_t)MADEUP_BOOT_TIME;
  53. }
  54. uint32_t Time::GetTicksMillisecondsMonotonic()
  55. {
  56. #if IL2CPP_TARGET_ANDROID
  57. struct timespec ts;
  58. if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
  59. {
  60. return (int64_t)MADEUP_BOOT_TIME;
  61. }
  62. return (ts.tv_sec * 1000) + (ts.tv_nsec / 1000000);
  63. #else
  64. static int64_t boot_time = 0;
  65. int64_t now;
  66. if (!boot_time)
  67. boot_time = GetBootTime();
  68. now = GetTicks100NanosecondsMonotonic();
  69. return (uint32_t)((now - boot_time) / 10000);
  70. #endif
  71. }
  72. int64_t Time::GetTicks100NanosecondsMonotonic()
  73. {
  74. struct timeval tv;
  75. #if IL2CPP_TARGET_DARWIN
  76. /* http://developer.apple.com/library/mac/#qa/qa1398/_index.html */
  77. static mach_timebase_info_data_t timebase;
  78. uint64_t now = mach_absolute_time();
  79. if (timebase.denom == 0)
  80. {
  81. mach_timebase_info(&timebase);
  82. timebase.denom *= 100; /* we return 100ns ticks */
  83. }
  84. return now * timebase.numer / timebase.denom;
  85. #elif defined(CLOCK_MONOTONIC)
  86. struct timespec tspec;
  87. static struct timespec tspec_freq = {0};
  88. static int can_use_clock = 0;
  89. if (!tspec_freq.tv_nsec)
  90. {
  91. can_use_clock = clock_getres(CLOCK_MONOTONIC, &tspec_freq) == 0;
  92. }
  93. if (can_use_clock)
  94. {
  95. if (clock_gettime(CLOCK_MONOTONIC, &tspec) == 0)
  96. {
  97. return ((int64_t)tspec.tv_sec * MTICKS_PER_SEC + tspec.tv_nsec / 100);
  98. }
  99. }
  100. #endif
  101. if (gettimeofday(&tv, NULL) == 0)
  102. return ((int64_t)tv.tv_sec * 1000000 + tv.tv_usec) * 10;
  103. return 0;
  104. }
  105. /*
  106. * Magic number to convert a time which is relative to
  107. * Jan 1, 1970 into a value which is relative to Jan 1, 0001.
  108. */
  109. const uint64_t EPOCH_ADJUST = ((uint64_t)62135596800LL);
  110. int64_t Time::GetTicks100NanosecondsDateTime()
  111. {
  112. struct timeval tv;
  113. if (gettimeofday(&tv, NULL) == 0)
  114. return (((int64_t)tv.tv_sec + EPOCH_ADJUST) * 1000000 + tv.tv_usec) * 10;
  115. return 0;
  116. }
  117. static const int64_t kSecondsBetween1601And1970 = 11644473600LL;
  118. static const int64_t kSecondsTo100NanoSeconds = 10000000;
  119. int64_t Time::GetSystemTimeAsFileTime()
  120. {
  121. timeval currentTime;
  122. int getTimeOfDayResult = gettimeofday(&currentTime, NULL);
  123. IL2CPP_ASSERT(getTimeOfDayResult == 0 && "gettimeofday() failed");
  124. return kSecondsTo100NanoSeconds * (static_cast<int64_t>(currentTime.tv_sec) + kSecondsBetween1601And1970) + 10 * currentTime.tv_usec;
  125. }
  126. }
  127. }
  128. #endif