00001 #include <stdio.h>
00002 #include <sys/time.h>
00003 #ifdef __FreeBSD__
00004 #include <machine/cpufunc.h>
00005 #include <sys/types.h>
00006 #include <sys/sysctl.h>
00007 #endif
00008 #include "mb_timer.h"
00009
00010
00011 #ifdef __FreeBSD__
00012 void get_now(mb_timeval_t *tmo) {
00013 struct timeval tv;
00014 static uint64_t cpufreq;
00015 static uint64_t diff;
00016 static mb_timeval_t tm = {0, 0};
00017 static uint64_t last_ts;
00018 mb_timeval_t diff_tm;
00019 uint64_t ts, udiff, sdiff;
00020 size_t sysctl_sz;
00021 int r;
00022
00023 if(MB_TIMEVAL_SEC(&tm) == 0) {
00024 sysctl_sz = sizeof(uint64_t);
00025 r = sysctlbyname("kern.timecounter.tc.TSC.frequency",
00026 &cpufreq, &sysctl_sz,
00027 NULL, 0);
00028 if(r == -1) {
00029 perror("sysctl");
00030 return;
00031 }
00032
00033 gettimeofday(&tv, NULL);
00034 last_ts = rdtsc();
00035
00036 MB_TIMEVAL_SET(tmo, tv.tv_sec, tv.tv_usec);
00037 MB_TIMEVAL_CP(&tm, tmo);
00038 diff = 0;
00039 } else {
00040 ts = rdtsc();
00041 diff += ts - last_ts;
00042 sdiff = diff / cpufreq;
00043 udiff = (diff % cpufreq) * 1000000 / cpufreq;
00044
00045 MB_TIMEVAL_SET(&diff_tm, sdiff, udiff);
00046 MB_TIMEVAL_CP(tmo, &tm);
00047 MB_TIMEVAL_ADD(tmo, &diff_tm);
00048
00049 MB_TIMEVAL_SET(&diff_tm, sdiff, 0);
00050 MB_TIMEVAL_ADD(&tm, &diff_tm);
00051
00052 diff %= cpufreq;
00053 last_ts = ts;
00054 }
00055 }
00056 #else
00057 void get_now(mb_timeval_t *tmo) {
00058 struct timeval tv;
00059
00060 gettimeofday(&tv, NULL);
00061 MB_TIMEVAL_SET(tmo, tv.tv_sec, tv.tv_usec);
00062 }
00063 #endif
00064