8#define _CRT_SECURE_NO_WARNINGS 1
9#pragma warning(disable : 4996)
14#if defined(__APPLE__) || defined(__ANDROID__)
18#if !(defined(_WIN32) && defined(VRPN_USE_WINSOCK_SOCKETS))
19#include <sys/select.h>
20#include <netinet/in.h>
24 if (a == -1) return -1
26#if defined(VRPN_USE_WINSOCK_SOCKETS)
30#ifndef _TIMEZONE_DEFINED
41static inline void timevalNormalizeInPlace(timeval &in_tv)
43 const long div_77777 = (in_tv.tv_usec / 1000000);
44 in_tv.tv_sec += div_77777;
45 in_tv.tv_usec -= (div_77777 * 1000000);
49 timeval out_tv = in_tv;
50 timevalNormalizeInPlace(out_tv);
62 tvSum.tv_sec += tv2.tv_sec;
63 tvSum.tv_usec += tv2.tv_usec;
67 if (tvSum.tv_sec > 0) {
68 if (tvSum.tv_usec < 0) {
70 tvSum.tv_usec += 1000000;
72 else if (tvSum.tv_usec >= 1000000) {
74 tvSum.tv_usec -= 1000000;
77 else if (tvSum.tv_sec < 0) {
78 if (tvSum.tv_usec > 0) {
80 tvSum.tv_usec -= 1000000;
82 else if (tvSum.tv_usec <= -1000000) {
84 tvSum.tv_usec += 1000000;
89 if (tvSum.tv_usec >= 1000000) {
91 tvSum.tv_usec -= 1000000;
93 else if (tvSum.tv_usec <= -1000000) {
95 tvSum.tv_usec += 1000000;
109 tv.tv_sec = -tv2.tv_sec;
110 tv.tv_usec = -tv2.tv_usec;
118 result.tv_sec = (long)(tv.tv_sec * scale);
120 (long)(tv.tv_usec * scale + fmod(tv.tv_sec * scale, 1.0) * 1000000.0);
121 timevalNormalizeInPlace(result);
128 if (tv1.tv_sec > tv2.tv_sec)
return 1;
129 if ((tv1.tv_sec == tv2.tv_sec) && (tv1.tv_usec > tv2.tv_usec))
return 1;
136 if (tv1.tv_sec == tv2.tv_sec && tv1.tv_usec == tv2.tv_usec)
144 return (endT.tv_usec - startT.tv_usec) +
145 1000000L * (endT.tv_sec - startT.tv_sec);
150 return (endT.tv_usec - startT.tv_usec) / 1000000.0 +
151 (endT.tv_sec - startT.tv_sec);
156 return tv.tv_sec * 1000.0 + tv.tv_usec / 1000.0;
162 tv.tv_sec = (long)floor(dMsecs / 1000.0);
163 tv.tv_usec = (long)((dMsecs / 1000.0 - tv.tv_sec) * 1e6);
173 Sleep((DWORD)dMilliSecs);
178 timeout.tv_sec = (int)(dMilliSecs / 1000.0);
181 dMilliSecs -= timeout.tv_sec * 1000;
184 timeout.tv_usec = (int)(dMilliSecs * 1000);
188 select(0, 0, 0, 0, &timeout);
205 if (!vrpn_big_endian) {
206 vrpn_float64 dSwapped;
207 char *pchSwapped = (
char *)&dSwapped;
208 char *pchOrig = (
char *)&d;
212 for (i = 0; i <
sizeof(vrpn_float64); i++) {
213 pchSwapped[i] = pchOrig[
sizeof(vrpn_float64) - i - 1];
216#if defined(__arm__) && !defined(__ANDROID__)
220#if __FLOAT_WORD_ORDER != __BYTE_ORDER
223 vrpn_uint32 *pwSwapped = (vrpn_uint32 *)&dSwapped;
224 vrpn_uint32 scratch = pwSwapped[0];
225 pwSwapped[0] = pwSwapped[1];
226 pwSwapped[1] = scratch;
256 vrpn_int32 sec, usec;
285 const char *
string, vrpn_int32 length)
287 if (length > *buflen) {
288 fprintf(stderr,
"vrpn_buffer: buffer not long enough for string.\n");
295 if (len > (
unsigned)*buflen) {
297 "vrpn_buffer: buffer not long enough for string.\n");
302 *buflen -=
static_cast<vrpn_int32
>(len);
305 memcpy(*insertPt,
string, length);
327 vrpn_int32 sec, usec;
362 if (!
string)
return -1;
367 size_t max_len =
static_cast<size_t>(-length);
368 strncpy(
string, *buffer, max_len);
371 for (i = 0; i < max_len; i++) {
372 if (
string[i] ==
'\0') {
380 *buffer += strlen(*buffer) + 1;
382 memcpy(
string, *buffer, length);
405#ifdef VRPN_USE_STD_CHRONO
430static bool hr_offset_determined =
false;
432static struct timeval hr_offset;
434static struct timeval high_resolution_time_to_system_time(
435 struct timeval hi_res_time
442 if (!hr_offset_determined) {
443 hr_offset_semaphore.
p();
445 if (!hr_offset_determined) {
449 std::chrono::system_clock::time_point pre =
450 std::chrono::system_clock::now();
451 std::chrono::system_clock::time_point post;
456 post = std::chrono::system_clock::now();
457 }
while (pre == post);
461 std::chrono::high_resolution_clock::time_point high =
462 std::chrono::high_resolution_clock::now();
467 std::time_t high_secs =
468 std::chrono::duration_cast<std::chrono::seconds>(
469 high.time_since_epoch())
471 std::chrono::high_resolution_clock::time_point
472 fractional_high_secs = high - std::chrono::seconds(high_secs);
473 struct timeval high_time;
474 high_time.tv_sec =
static_cast<unsigned long>(high_secs);
475 high_time.tv_usec =
static_cast<unsigned long>(
476 std::chrono::duration_cast<std::chrono::microseconds>(
477 fractional_high_secs.time_since_epoch())
480 std::time_t post_secs =
481 std::chrono::duration_cast<std::chrono::seconds>(
482 post.time_since_epoch())
484 std::chrono::system_clock::time_point fractional_post_secs =
485 post - std::chrono::seconds(post_secs);
486 struct timeval post_time;
487 post_time.tv_sec =
static_cast<unsigned long>(post_secs);
488 post_time.tv_usec =
static_cast<unsigned long>(
489 std::chrono::duration_cast<std::chrono::microseconds>(
490 fractional_post_secs.time_since_epoch())
496 hr_offset_determined =
true;
498 hr_offset_semaphore.
v();
511 struct timezone *timeZone =
reinterpret_cast<struct timezone *
>(tzp);
515 std::chrono::high_resolution_clock::time_point now =
516 std::chrono::high_resolution_clock::now();
518 std::chrono::duration_cast<std::chrono::seconds>(now.time_since_epoch())
523 std::chrono::high_resolution_clock::time_point fractional_secs =
524 now - std::chrono::seconds(secs);
529 struct timeval hi_res_time;
530 hi_res_time.tv_sec =
static_cast<unsigned long>(secs);
531 hi_res_time.tv_usec =
static_cast<unsigned long>(
532 std::chrono::duration_cast<std::chrono::microseconds>(
533 fractional_secs.time_since_epoch())
535 *tp = high_resolution_time_to_system_time(hi_res_time);
538 if (timeZone != NULL) {
539 timeZone->tz_minuteswest = 0;
540 timeZone->tz_dsttime = 0;
562#ifndef VRPN_UNSAFE_WINDOWS_CLOCK
564#if defined(_WIN32) && !defined(__CYGWIN__)
567#pragma optimize("", on)
570void get_time_using_GetLocalTime(
unsigned long &sec,
unsigned long &usec)
576 GetLocalTime(&stime);
577 SystemTimeToFileTime(&stime, &ftime);
580 tics.HighPart = ftime.dwHighDateTime;
581 tics.LowPart = ftime.dwLowDateTime;
587 tics.QuadPart -= 11644473600000000ULL;
590 sec = (
unsigned long)(tics.QuadPart / 1000000UL);
591 usec = (
unsigned long)(tics.QuadPart % 1000000UL);
605 struct timezone *timeZone =
reinterpret_cast<struct timezone *
>(tzp);
609 unsigned long sec, usec;
610 get_time_using_GetLocalTime(sec, usec);
617 tp->tv_usec = (long)t.millitm * 1000;
621 TIME_ZONE_INFORMATION tz;
622 GetTimeZoneInformation(&tz);
623 timeZone->tz_minuteswest = tz.Bias;
624 timeZone->tz_dsttime = (tz.StandardBias != tz.Bias);
638#if defined(_WIN32) && !defined(__CYGWIN__)
648static __int64 VRPN_CLOCK_FREQ = 200000000;
659 _asm _emit 0x0f _asm _emit 0x31 _asm mov li.LowPart, \
660 eax _asm mov li.HighPart, edx \
666#ifndef VRPN_WINDOWS_CLOCK_V2
667#pragma optimize("", off)
668static int vrpn_AdjustFrequency(
void)
671 const int tPerLoop = 500;
672 fprintf(stderr,
"vrpn vrpn_gettimeofday: determining clock frequency...");
674 LARGE_INTEGER startperf, endperf;
675 LARGE_INTEGER perffreq;
680 if (QueryPerformanceFrequency(&perffreq) == 0) {
686 volatile LARGE_INTEGER liStart, liEnd;
688 DWORD dwPriorityClass = GetPriorityClass(GetCurrentProcess());
689 int iThreadPriority = GetThreadPriority(GetCurrentThread());
690 SetPriorityClass(GetCurrentProcess(), REALTIME_PRIORITY_CLASS);
691 SetThreadPriority(GetCurrentThread(), THREAD_PRIORITY_TIME_CRITICAL);
696 QueryPerformanceCounter(&startperf);
699 QueryPerformanceCounter(&endperf);
701 double freq = perffreq.QuadPart * (liEnd.QuadPart - liStart.QuadPart) /
702 ((
double)(endperf.QuadPart - startperf.QuadPart));
704 if (fabs(perffreq.QuadPart - freq) < 0.05 * freq) {
705 VRPN_CLOCK_FREQ = (__int64)perffreq.QuadPart;
706 fprintf(stderr,
"\nvrpn vrpn_gettimeofday: perf clock is tsc -- using "
707 "perf clock freq ( %lf MHz)\n",
708 perffreq.QuadPart / 1e6);
709 SetPriorityClass(GetCurrentProcess(), dwPriorityClass);
710 SetThreadPriority(GetCurrentThread(), iThreadPriority);
718 fprintf(stderr,
" (this will take %lf seconds)...\n",
719 loops * tPerLoop / 1000.0);
721 for (
int j = 0; j < loops; j++) {
723 QueryPerformanceCounter(&startperf);
726 QueryPerformanceCounter(&endperf);
736 sum += perffreq.QuadPart * (liEnd.QuadPart - liStart.QuadPart) /
737 ((
double)(endperf.QuadPart - startperf.QuadPart));
740 SetPriorityClass(GetCurrentProcess(), dwPriorityClass);
741 SetThreadPriority(GetCurrentThread(), iThreadPriority);
744 freq = (sum / loops);
758 if (fabs(perffreq.QuadPart - freq) < 0.05 * freq) {
759 VRPN_CLOCK_FREQ = perffreq.QuadPart;
760 fprintf(stderr,
"vrpn vrpn_gettimeofday: perf clock is tsc -- using "
761 "perf clock freq ( %lf MHz)\n",
762 perffreq.QuadPart / 1e6);
765 fprintf(stderr,
"vrpn vrpn_gettimeofday: adjusted clock freq to "
766 "measured freq ( %lf MHz )\n",
769 VRPN_CLOCK_FREQ = (__int64)freq;
772#pragma optimize("", on)
794#ifndef VRPN_WINDOWS_CLOCK_V2
797 struct timezone *timeZone =
reinterpret_cast<struct timezone *
>(tzp);
798 static int fFirst = 1;
799 static int fHasPerfCounter = 1;
800 static struct _timeb tbInit;
801 static LARGE_INTEGER liInit;
802 static LARGE_INTEGER liNow;
803 static LARGE_INTEGER liDiff;
806 if (!fHasPerfCounter) {
808 tp->tv_sec = tbInit.time;
809 tp->tv_usec = tbInit.millitm * 1000;
814 LARGE_INTEGER liTemp;
827 memset(&osvi, 0,
sizeof(OSVERSIONINFO));
828 osvi.dwOSVersionInfoSize =
sizeof(OSVERSIONINFO);
831 if (osvi.dwPlatformId != VER_PLATFORM_WIN32_NT) {
833 "\nvrpn_gettimeofday: disabling hi performance clock "
835 "Defaulting to _ftime (~6 ms resolution) ...\n");
843 if (!(fHasPerfCounter = QueryPerformanceFrequency(&liTemp))) {
845 "\nvrpn_gettimeofday: no hi performance clock available. "
846 "Defaulting to _ftime (~6 ms resolution) ...\n");
852 if (vrpn_AdjustFrequency() < 0) {
854 "\nvrpn_gettimeofday: can't verify clock frequency. "
855 "Defaulting to _ftime (~6 ms resolution) ...\n");
874 liDiff.QuadPart = liNow.QuadPart - liInit.QuadPart;
876 tvDiff.tv_sec = (long)(liDiff.QuadPart / VRPN_CLOCK_FREQ);
878 (long)(1e6 * ((liDiff.QuadPart - VRPN_CLOCK_FREQ * tvDiff.tv_sec) /
879 (
double)VRPN_CLOCK_FREQ));
882 tp->tv_sec = tbInit.time + tvDiff.tv_sec;
883 tp->tv_usec = tbInit.millitm * 1000 + tvDiff.tv_usec;
884 while (tp->tv_usec >= 1000000) {
886 tp->tv_usec -= 1000000;
893void get_time_using_GetLocalTime(
unsigned long &sec,
unsigned long &usec)
895 static LARGE_INTEGER first_count = {0, 0};
896 static unsigned long first_sec, first_usec;
897 static LARGE_INTEGER perf_freq;
901 LARGE_INTEGER perf_counter;
906 if (first_count.QuadPart == 0) {
907 QueryPerformanceCounter(&first_count);
911 QueryPerformanceFrequency(&perf_freq);
914 GetLocalTime(&stime);
915 SystemTimeToFileTime(&stime, &ftime);
919 tics.HighPart = ftime.dwHighDateTime;
920 tics.LowPart = ftime.dwLowDateTime;
924 sec = (long)(tics.QuadPart / 10000000L);
925 usec = (long)((tics.QuadPart - (((LONGLONG)(sec)) * 10000000L)) / 10);
930 QueryPerformanceCounter(&perf_counter);
931 if (perf_counter.QuadPart >= first_count.QuadPart) {
932 perf_counter.QuadPart =
933 perf_counter.QuadPart - first_count.QuadPart;
937 perf_counter.QuadPart = 0x7fffffffffffffffLL -
938 first_count.QuadPart +
939 perf_counter.QuadPart;
946 sec = (long)(perf_counter.QuadPart / perf_freq.QuadPart);
947 perf_counter.QuadPart -= perf_freq.QuadPart * sec;
948 perf_counter.QuadPart *= 1000000L;
949 usec = first_usec + (long)(perf_counter.QuadPart / perf_freq.QuadPart);
956 if (usec > 1000000L) {
970 struct timezone *timeZone =
reinterpret_cast<struct timezone *
>(tzp);
971 unsigned long sec, usec;
972 get_time_using_GetLocalTime(sec, usec);
976 TIME_ZONE_INFORMATION tz;
977 GetTimeZoneInformation(&tz);
978 timeZone->tz_minuteswest = tz.Bias;
979 timeZone->tz_dsttime = (tz.StandardBias != tz.Bias);
1002 vrpn_float64 dbuffer[256];
1005 vrpn_float64 in_float64 = 42.1;
1006 vrpn_int32 in_int32 = 17;
1007 vrpn_uint16 in_uint16 = 397;
1008 vrpn_uint8 in_uint8 = 1;
1010 vrpn_float64 out_float64;
1011 vrpn_int32 out_int32;
1012 vrpn_uint16 out_uint16;
1013 vrpn_uint8 out_uint8;
1017 char *bufptr = (
char *)dbuffer;
1018 buflen =
sizeof(dbuffer);
1021 "vrpn_test_pack_unpack(): Could not buffer little endian\n");
1026 "vrpn_test_pack_unpack(): Could not buffer little endian\n");
1031 "vrpn_test_pack_unpack(): Could not buffer little endian\n");
1036 "vrpn_test_pack_unpack(): Could not buffer little endian\n");
1041 bufptr = (
char *)dbuffer;
1044 vrpn_unbuffer_from_little_endian<vrpn_float64>(bufptr))) {
1046 "vrpn_test_pack_unpack(): Could not unbuffer little endian\n");
1050 (out_int32 = vrpn_unbuffer_from_little_endian<vrpn_int32>(bufptr))) {
1052 "vrpn_test_pack_unpack(): Could not unbuffer little endian\n");
1056 (out_uint16 = vrpn_unbuffer_from_little_endian<vrpn_uint16>(bufptr))) {
1058 "vrpn_test_pack_unpack(): Could not unbuffer little endian\n");
1062 (out_uint8 = vrpn_unbuffer_from_little_endian<vrpn_uint8>(bufptr))) {
1064 "vrpn_test_pack_unpack(): Could not unbuffer little endian\n");
1069 bufptr = (
char *)dbuffer;
1070 buflen =
sizeof(dbuffer);
1071 if (
vrpn_buffer(&bufptr, &buflen, in_float64) != 0) {
1073 "vrpn_test_pack_unpack(): Could not buffer big endian\n");
1076 if (
vrpn_buffer(&bufptr, &buflen, in_int32) != 0) {
1078 "vrpn_test_pack_unpack(): Could not buffer big endian\n");
1081 if (
vrpn_buffer(&bufptr, &buflen, in_uint16) != 0) {
1083 "vrpn_test_pack_unpack(): Could not buffer big endian\n");
1086 if (
vrpn_buffer(&bufptr, &buflen, in_uint8) != 0) {
1088 "vrpn_test_pack_unpack(): Could not buffer big endian\n");
1093 bufptr = (
char *)dbuffer;
1096 "vrpn_test_pack_unpack(): Could not unbuffer big endian\n");
1101 "vrpn_test_pack_unpack(): Could not unbuffer big endian\n");
1106 "vrpn_test_pack_unpack(): Could not unbuffer big endian\n");
1111 "vrpn_test_pack_unpack(): Could not unbuffer big endian\n");
1119 bufptr = (
char *)dbuffer;
1120 buflen =
sizeof(dbuffer);
1123 "vrpn_test_pack_unpack(): Could not buffer little endian\n");
1126 bufptr = (
char *)dbuffer;
1130 "vrpn_test_pack_unpack(): Cross-packing produced same result\n");
1142 if ((v0.
size() != 0) || (v0.
data() != 0)) {
1143 fprintf(stderr,
"vrpn_test_vrpn_vector(): Default constructor failed\n");
1151 vrpn_uint32 count = 19;
1153 if (v1.
size() != count) {
1154 fprintf(stderr,
"vrpn_test_vrpn_vector(): Sized constructor size failed\n");
1157 for (vrpn_uint32 i = 0; i < v1.
size(); i++) {
1161 if (v2.
size() != count) {
1162 fprintf(stderr,
"vrpn_test_vrpn_vector(): Copy constructor size failed\n");
1165 for (vrpn_uint32 i = 0; i < v2.
size(); i++) {
1167 fprintf(stderr,
"vrpn_test_vrpn_vector(): Copy constructor data failed\n");
1175 vrpn_uint32 count = 19;
1177 for (vrpn_uint32 i = 0; i < v1.
size(); i++) {
1181 if (v2.
size() != 9) {
1182 fprintf(stderr,
"vrpn_test_vrpn_vector(): Range constructor size failed\n");
1185 for (vrpn_uint32 i = 0; i < v2.
size(); i++) {
1187 fprintf(stderr,
"vrpn_test_vrpn_vector(): Range constructor data failed\n");
1197 fprintf(stderr,
"vrpn_test_vrpn_vector(): Empty failed when empty\n");
1202 fprintf(stderr,
"vrpn_test_vrpn_vector(): Empty failed when not empty\n");
1205 if (v1.
data()[0] != 1) {
1206 fprintf(stderr,
"vrpn_test_vrpn_vector(): data() failed on push_back\n");
1217 if (v1.
size() != 2) {
1218 fprintf(stderr,
"vrpn_test_vrpn_vector(): resize failed on do nothing\n");
1221 if ((v1[0] != 1) || (v1[1] != 2)) {
1222 fprintf(stderr,
"vrpn_test_vrpn_vector(): resize data failed on do nothing\n");
1226 if (v1.
size() != 1) {
1227 fprintf(stderr,
"vrpn_test_vrpn_vector(): resize failed on shrink\n");
1231 fprintf(stderr,
"vrpn_test_vrpn_vector(): resize data failed on shrink\n");
1235 if (v1.
size() != 10) {
1236 fprintf(stderr,
"vrpn_test_vrpn_vector(): resize failed on grow\n");
1240 fprintf(stderr,
"vrpn_test_vrpn_vector(): resize data failed on grow\n");
1250 if (v1.
front() != 1) {
1251 fprintf(stderr,
"vrpn_test_vrpn_vector(): front failed\n");
1254 if (v1.
back() != 2) {
1255 fprintf(stderr,
"vrpn_test_vrpn_vector(): back failed\n");
1259 vrpn_uint32 count = 2;
1261 if ((v2[0] != 7) || (v2[1] != 7)) {
1262 fprintf(stderr,
"vrpn_test_vrpn_vector(): assign value failed\n");
1265 v2.
assign(&v1[0], &v1[2]);
1266 if ((v2[0] != 1) || (v2[1] != 2)) {
1267 fprintf(stderr,
"vrpn_test_vrpn_vector(): assign iterators failed\n");
1271 if (v1.
size() != 0) {
1272 fprintf(stderr,
"vrpn_test_vrpn_vector(): clear failed\n");
1280 if ((v0.
begin() != 0) || (v0.
end() != 0)) {
1281 fprintf(stderr,
"vrpn_test_vrpn_vector(): empty begin/end failed\n");
1285 fprintf(stderr,
"vrpn_test_vrpn_vector(): begin/end failed\n");
1297 if ((v1[1] != 2) || (v0[0] != 1)) {
1298 fprintf(stderr,
"vrpn_test_vrpn_vector(): operator = failed (%d, %d)\n", v0[0], v1[1]);
int v()
Release of resource. ("up")
int p()
Blocking acquire of resource. ("down")
void push_back(const T &val)
void assign(size_type count, const T &value)
VRPN_API int vrpn_unbuffer(const char **buffer, timeval *t)
Utility routine for taking a struct timeval from a buffer that was sent as a message.
unsigned long vrpn_TimevalDuration(struct timeval endT, struct timeval startT)
Return number of microseconds between startT and endT.
bool vrpn_test_pack_unpack(void)
bool vrpn_test_vrpn_vector(void)
double vrpn_TimevalDurationSeconds(struct timeval endT, struct timeval startT)
Return the number of seconds between startT and endT as a floating-point value.
bool vrpn_TimevalGreater(const timeval &tv1, const timeval &tv2)
timeval vrpn_TimevalScale(const timeval &tv, double scale)
VRPN_API int vrpn_buffer(char **insertPt, vrpn_int32 *buflen, const timeval t)
Utility routine for placing a timeval struct into a buffer that is to be sent as a message.
vrpn_float64 vrpn_ntohd(vrpn_float64 d)
vrpn_float64 vrpn_htond(vrpn_float64 d)
double vrpn_TimevalMsecs(const timeval &tv)
timeval vrpn_TimevalDiff(const timeval &tv1, const timeval &tv2)
timeval vrpn_TimevalNormalize(const timeval &in_tv)
bool vrpn_TimevalEqual(const timeval &tv1, const timeval &tv2)
void vrpn_SleepMsecs(double dMilliSecs)
timeval vrpn_MsecsTimeval(const double dMsecs)
timeval vrpn_TimevalSum(const timeval &tv1, const timeval &tv2)
#define vrpn_gettimeofday
int vrpn_buffer_to_little_endian(ByteT **insertPt, vrpn_int32 *buflen, const T inVal)
Function template to buffer values to a buffer stored in little- endian order. Specify the type to bu...
char * vrpn_strncpynull(char *dst, const char *src, size_t size)
Version of strncpy that ensures the resulting string is alyways NULL terminated. It also only writes ...