92 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
			
		
		
	
	
			92 lines
		
	
	
		
			2.3 KiB
		
	
	
	
		
			C
		
	
	
| #include "timer.h"
 | |
| #if __MACH__
 | |
|   #include <CoreServices/CoreServices.h>
 | |
|   #include <mach/mach.h>
 | |
|   #include <mach/mach_time.h>
 | |
| #endif
 | |
| #include <stdio.h>
 | |
| #if _WIN32 | _WIN64
 | |
| #include <windows.h>
 | |
| #endif
 | |
| 
 | |
| int64_t setPTime(struct PTime *time, int64_t seconds, int64_t milliseconds, int64_t nanoseconds) {
 | |
|   time->n = nanoseconds + (milliseconds*1000000) + (seconds*1000000000);
 | |
|   time->m = time->n / 1000000;
 | |
|   time->s = time->n / 1000000000;
 | |
|   return time->n;
 | |
| }
 | |
| 
 | |
| int64_t getPTime(struct PTime *time) {
 | |
| #if _WIN32 | _WIN64
 | |
|   int64_t ticks = GetTickCount();
 | |
|   time->s = ticks/1000;
 | |
|   time->m = ticks;
 | |
|   time->n = ticks*1000000;
 | |
| #elif __MACH__
 | |
|   mach_timebase_info_data_t info;
 | |
|   mach_timebase_info(&info);
 | |
| 
 | |
|   uint64_t m_time = mach_absolute_time();
 | |
|   m_time *= info.numer;
 | |
|   m_time /= info.denom;
 | |
| 
 | |
|   time->n = m_time;
 | |
|   time->m = m_time / 1000000;
 | |
|   time->s = time->m / 1000;
 | |
| /*#elif __i586__
 | |
|   struct { int32 low, high; } counter;
 | |
| 
 | |
|   __asm push EAX
 | |
|   __asm push EDX
 | |
|   __asm __emit 0fh __asm __emit 031h // RDTSC
 | |
|   __asm mov counter.low, EAX
 | |
|   __asm mov counter.high, EDX
 | |
|   __asm pop EDX
 | |
|   __asm pop EAX
 | |
| */
 | |
| #else
 | |
|   struct timespec ts;
 | |
|   clock_gettime(CLOCK_MONOTONIC, &ts);
 | |
|   time->s = ts.tv_sec;
 | |
|   time->n = (ts.tv_sec * 1000000000) + ts.tv_nsec;
 | |
|   time->m = time->n / 1000000;
 | |
| #endif
 | |
|   return time->n;
 | |
| }
 | |
| 
 | |
| inline int64_t getPTimeDiff(struct PTime *time_delta, struct PTime *time_a, struct PTime *time_b) {
 | |
|   if (time_a == NULL || time_b == NULL) return 0;
 | |
|   if (time_delta != NULL) {
 | |
|     int64_t s_diff = time_a->s - time_b->s;
 | |
|     int64_t m_diff = time_a->m - time_b->m;
 | |
|     int64_t n_diff = time_a->n - time_b->n;
 | |
| 
 | |
|     time_delta->s = s_diff;
 | |
|     time_delta->m = m_diff;
 | |
|     time_delta->n = n_diff;
 | |
|     return n_diff;
 | |
|   } else {
 | |
|     return time_a->n - time_b->n;
 | |
|   }
 | |
| }
 | |
| 
 | |
| inline void doNanoSleep(int64_t nanoseconds) {
 | |
| #if _WIN32 | _WIN64
 | |
|   Sleep(nanoseconds/1000000);
 | |
| #else
 | |
|   struct timespec ts;
 | |
|   double ns_fraction = nanoseconds / 1000000000;
 | |
|   ts.tv_sec = ns_fraction;
 | |
|   if (ns_fraction >= 1.0f)
 | |
|     ts.tv_nsec = nanoseconds - ns_fraction;
 | |
|   else 
 | |
|     ts.tv_nsec = nanoseconds;
 | |
| 
 | |
|   if (ts.tv_nsec < 0) ts.tv_nsec = 0;
 | |
|   //printf("snoozing for %lds and %ldns\n", ts.tv_sec, ts.tv_nsec);
 | |
|   nanosleep(&ts, NULL);
 | |
|   //if (nanosleep(&ts, NULL) < 0)
 | |
|     //printf("ERR: had trouble sleeping\n"); // FIXME: THIS ERRORS ALOT
 | |
| #endif
 | |
| }
 |