== [wiki:GetAbsoluteTime Àý´ëÀû ¼ø¹æÇ⠽ð£ÀÚ¿ø ¾ò±â] == * ÀÛ¼ºÀÚ Á¶ÀçÇõ([mailto:minzkn@minzkn.com]) * °íÄ£°úÁ¤ 2014³â 12¿ù 2ÀÏ : óÀ½¾¸ [[TableOfContents]] === ½ÃÀÛÇϱâÀü¿¡ === ÇÁ·Î±×·¡¹ÖÀ» ÇÏ´Ù°¡ º¸¸é Àý´ëÀûÀ¸·Î ¼ø¹æÇâÀ¸·Î¸¸ Áõ°¡ÇÏ´Â ½Ã°£ÀÚ¿øÀÌ ÇÊ¿äÇÒ¶§°¡ ¸¹½À´Ï´Ù. ƯÁ¤ ½Ã°£ ±¸°£ÀÇ ¼Ò¿ä½Ã°£À» ÃøÁ¤ÇÑ´Ù´ø°¡ ƯÁ¤ Áֱ⸶´Ù ¾î¶² ½ÇÇàÀ» ±¸ÇöÇÏ·Á°í ÇÒ¶§ ÀϹÝÀûÀÎ ½Ã°èÀÚ¿øÀÇ °æ¿ì ½Ã°£µ¿±â°¡ Áß°£¿¡ ÀϾ¸é ½Ã°£ÀÌ ¿ª¹æÇ⠶Ǵ ¸¹Àº ½Ã°£À» °Ç³Ê¶Ù´Â »óÅ°¡ ¹ß»ýÇÒ ¼ö ÀÖ½À´Ï´Ù. ÀÌ·²¶§ ÃæºÐÈ÷ °í·ÁµÇÁö ¾ÊÀ¸¸é ÇÁ·Î±×·¥Àº ÀǵµµÇÁö ¾ÊÀº µ¿ÀÛÀ» ÀÏÀ¸Å°±â ¸Å¿ì ½±½À´Ï´Ù. ¿©±â¼­´Â ÃÖ´ëÇÑ ¸¹Àº Platform¿¡¼­ µ¿ÀÛ°¡´ÉÇÑ Àý´ëÀû ¼ø¹æÇ⠽ð£ÀÚ¿ø¿¡ ´ëÇÑ ±¸ÇöÀ» ´Ù·ç°íÀÚ ÇÕ´Ï´Ù. Àý´ëÀû ¼ø¹æÇ⠽ð£ÀÚ¿øÀÇ ±¸Çö¿¡ ÇʼöÀûÀÎ ¿ä±¸»çÇ×Àº ´ÙÀ½°ú °°½À´Ï´Ù. * ½Ã°£ÀÌ ¿ª¹æÇâÀ¸·Î È帣Áö ¾Ê´Â´Ù. (¾î¶°ÇÑ Á¶°Ç¿¡µµ °ú°Å½Ã°£À¸·Î µ¹¾Æ°¡Áö ¾Ê¾Æ¾ß ÇÑ´Ù.) * Overflow¿¡ ´ëÇÑ °í·Á°¡ µÇ¾î ÀÖÁö ¾Ê´Ù¸é ÃæºÐÈ÷ Å« °ªÀ¸·Î ´Ù·ê¼ö ÀÖ¾î¾ß ÇÑ´Ù. * ƯÁ¤ ½Ã°£ÀÌ È帥 »óÅ¿¡¼­ Á¤È®È÷ ±× Èê·¯°£ ½Ã°£ °£°ÝÀ» ÃøÁ¤ÇÒ¼ö ÀÖ¾î¾ß ÇÑ´Ù. * ¿ÜºÎ¿¡¼­ ÀÌ ½Ã°£ÀÚ¿øÀ» ÀÓÀÇ·Î Á¶ÀÛÇÒ¼ö ¾ø°Å³ª Á¶ÀÛÇÏ¿©µµ ¿µÇâÀ» ¹ÞÁö ¾Ê¾Æ¾ß ÇÑ´Ù. * Àû¾îµµ msec ´ÜÀ§ÀÇ ½Ã°£Çػ󵵸¦ Áö¿øÇÒ ¼ö ÀÖ¾î¾ß ÇÑ´Ù. (¸¸¾à RTOS°è¿­ÀÎ °æ¿ì usec ´ÜÀ§ Áö¿ø¿¡ ´ëÇÑ °í·Á¸¦ ÇÏ´Â°Ô ÁÁ´Ù.) * ÃÖ´ëÇÑ ¼º´É¿¡ ¿µÇâÀ» Àû°Ô ¹Þ´Â ¹æ¹ýÀ¸·Î ±¸ÇöµÇ¾î¾ß ÇÑ´Ù. === Windows ¿¡¼­ÀÇ ±¸Çö === {{{#!plain #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); } }}} === OS X ¿¡¼­ÀÇ ±¸Çö (Mach kernel ±â¹Ý) === {{{#!plain # include #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); } }}} === Linux(¶Ç´Â Android) ¿¡¼­ÀÇ ±¸Çö (librt.so ¸¦ Á÷Á¢ ¸µÅ©ÇÏÁö ¾Ê°í SystemCallÀ» Á÷Á¢ »ç¿ëÇÏ´Â ¹æ¹ý) === {{{#!plain /* need define _GNU_SOURCE */ # include # include # 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); } }}} === Unix/BSD/Linux °è¿­¿¡¼­ÀÇ ±¸Çö (SUv2 ¹× POSIX.1-2001 À» ¸¸Á·Çϴ ȯ°æ, rt library¸¦ ¸µÅ©ÇØ¾ß ÇÏ´Â °æ¿ì°¡ ÇÊ¿äÇÒ¼ö ÀÖÀ½) === {{{#!plain #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); } }}} === ±âŸȯ°æ¿¡¼­ÀÇ ±¸Çö === * times ÇÔ¼öÀÇ ¹Ýȯ°ªÀ» ÀÌ·¯ÇÑ ¿ëµµ·Î È°¿ëÇÒ¼ö ÀÖ´Â °æ¿ìµµ ÀÖ½À´Ï´Ù. ÇÏÁö¸¸ ÀÌ »çÇ×Àº Ä¿³ÎÀÇ ±¸Çö¹æ½ÄÀ» È®ÀÎÇÏ´Â°Ô ÇÊ¿äÇÏ¸ç °æ¿ì¿¡ µû¶ó¼­ ƯÁ¤ ½Ã°£ÀÌ Áö³ª¸é Overflow¿¡ ´ëÇÑ °í·Á°¡ ÀÖ¾î¾ß ÇÕ´Ï´Ù. (ÀÇ¿Ü·Î ÇÊÀÚÀÇ °æÇè»ó timesÀÇ ±¸ÇöÀº ¸Å¿ì È¥¶õ½º·¯¿î Overflow ´ëÀÀ°í·Á°¡ ÇÊ¿äÇÕ´Ï´Ù.) * ÀϺÎȯ°æ¿¡¼­´Â times ÇÔ¼öÀÇ ¹Ýȯ°ª clock() / HZ °¡ ºÎÆÃÁ÷ÈÄ 289ÃÊ Âë¿¡¼­ Overflow°¡ {{{-1135, -1134, 1133, 1132, 1131, 1130, .., 1, 0, 1, 2, 3, 4, ...}}} ¿Í °°Àº½ÄÀ¸·Î ¹ß»ýÇÕ´Ï´Ù. ±×¸® ÁÁÀº Overflow ¹æ½ÄÀº ¾Æ´Ñµí ½Í½À´Ï´Ù. * Timer IRQ¸¦ Á÷Á¢ »ç¿ëÇÒ¼ö ÀÖ´Â °æ¿ì Interrupt loss ¿¡ ´ëÇÑ loss count¸¦ ¹Ýµå½Ã °í·ÁÇÏ´Â°Ô ÇÊ¿äÇÕ´Ï´Ù. * ¸ðµç ±¸Çö»çÇ׿¡´Â Overflow µÇÁö ¾Ê´Â ÃæºÐÈ÷ Å« counter°ªÀ» »ç¿ëÇϰųª Overflow ¿¡ ´ëÀÀÇÏ´Â º¸Á¤ÀÌ ÇÊ¿äÇÕ´Ï´Ù.