#include <windows.h>
#define hwport_uintmax_t ULONGLONG
int __hwport_get_absolute_time_msec(hwport_uintmax_t *s_msec_ptr)
{
LARGE_INTEGER s_performance_frequency;
LARGE_INTEGER s_performance_count;
if(QueryPerformanceFrequency((LARGE_INTEGER *)(&s_performance_frequency)) != TRUE) {
return(-1);
}
if(s_performance_frequency.QuadPart == ((LONGLONG)0)) {
return(-1);
}
if(QueryPerformanceCounter((LARGE_INTEGER *)(&s_performance_count)) != TRUE) {
return(-1);
}
*s_msec_ptr = ((((hwport_uintmax_t)s_performance_count.QuadPart) * ((hwport_uintmax_t)1000u)) / ((hwport_uintmax_t)s_performance_frequency.QuadPart));
return(0);
}
#if defined(__MACH__)
# include <mach/mach.h>
# include <mach/mach_time.h>
#define hwport_uintmax_t unsigned long long
int __hwport_get_absolute_time_msec(hwport_uintmax_t *s_msec_ptr)
{
mach_timebase_info_data_t s_timebase;
/* mach kernel */
mach_timebase_info(&s_timebase);
if(s_timebase.denom == 0) {
return(-1);
}
*s_msec_ptr = (((hwport_uintmax_t)mach_absolute_time()) * ((hwport_uintmax_t)s_timebase.numer)) / (((hwport_uintmax_t)s_timebase.denom) * ((hwport_uintmax_t)1000000));
return(0);
}
#endif
#if defined(__linux__)
/* need define _GNU_SOURCE */
#if !defined(_GNU_SOURCE)
# define _GNU_SOURCE (1L)
#endif
# include <unistd.h>
# include <sys/syscall.h>
# ifndef CLOCK_MONOTONIC
# warning "Old glibc (< 2.3.4) does not provide this constant. We use syscall directly so this definition is safe."
# define CLOCK_MONOTONIC 1
# endif
# if !defined(SYS_clock_gettime)
# define SYS_clock_gettime __NR_clock_gettime
# endif
#define hwport_uintmax_t unsigned long long
int __hwport_get_absolute_time_msec(hwport_uintmax_t *s_msec_ptr)
{
struct timespec s_timespec;
/* libc has incredibly messy way of doing this, typically requiring -lrt. We just skip all this mess */
if(syscall(SYS_clock_gettime /* __NR_clock_gettime */, (int)CLOCK_MONOTONIC, (void *)(&s_timespec)) != 0) {
return(-1);
}
*s_msec_ptr = (((hwport_uintmax_t)s_timespec.tv_sec) * ((hwport_uintmax_t)1000u)) + (((hwport_uintmax_t)s_timespec.tv_nsec) / ((hwport_uintmax_t)1000000u));
return(0);
}
#endif
#include <unistd.h>
#include <time.h>
#if (defined(_POSIX_VERSION) && (_POSIX_VERSION >= 199309L)) || (defined(_POSIX_C_SOURCE) && (_POSIX_C_SOURCE >= 199309L))
/*
clock_getres, clock_gettime, clock_settime 함수는 개발환경에 따라서 다르지만 적어도
_POSIX_VERSION (또는 _POSIX_C_SOURCE) define값이 199309L(POSIX 1003.1b = IEEE 1003.1b-1993) 이상이 되어야 정상적인 활용이 가능합니다.
또한 rt library를 링크해야 하는 경우가 필요할수 있습니다. ( Link with -lrt )
*/
#define hwport_uintmax_t unsigned long long
int __hwport_get_absolute_time_msec(hwport_uintmax_t *s_msec_ptr)
{
struct timespec s_timespec;
/* maybe requiring -lrt */ /* SUSv2, POSIX.1-2001 */
if(clock_gettime((clockid_t)CLOCK_MONOTONIC, (struct timespec *)(&s_timespec)) != 0) {
return(-1);
}
*s_msec_ptr = (((hwport_uintmax_t)s_timespec.tv_sec) * ((hwport_uintmax_t)1000u)) + (((hwport_uintmax_t)s_timespec.tv_nsec) / ((hwport_uintmax_t)1000000u));
return(0);
}
#endif
/* See also: https://docs.oracle.com/cd/E23824_01/html/821-1465/gethrtime-3c.html */
#if defined(__hpux) || defined(__sun) || defined(__SVR4)
# include <sys/time.h>
# define hwport_uintmax_t unsigned long long
int __hwport_get_absolute_time_msec(hwport_uintmax_t *s_msec_ptr)
{
*s_msec_ptr = ((hwport_uintmax_t)gethrtime() /* nano seconds */) / ((hwport_uintmax_t)1000000u);
return(0);
}
#endif
-1135, -1134, 1133, 1132, 1131, 1130, .., 1, 0, 1, 2, 3, 4, ... 와 같은식으로 발생합니다. 그리 좋은 Overflow 방식은 아닌듯 싶습니다.
UTC 와 표기법, 그리고 ISO 8601, RFC 3339 표준
(https://ohgyun.com/416)