1 /* 2 * ptw32_relmillisecs.c 3 * 4 * Description: 5 * This translation unit implements miscellaneous thread functions. 6 * 7 * -------------------------------------------------------------------------- 8 * 9 * Pthreads-win32 - POSIX Threads Library for Win32 10 * Copyright(C) 1998 John E. Bossom 11 * Copyright(C) 1999,2005 Pthreads-win32 contributors 12 * 13 * Contact Email: rpj (at) callisto.canberra.edu.au 14 * 15 * The current list of contributors is contained 16 * in the file CONTRIBUTORS included with the source 17 * code distribution. The list can also be seen at the 18 * following World Wide Web location: 19 * http://sources.redhat.com/pthreads-win32/contributors.html 20 * 21 * This library is free software; you can redistribute it and/or 22 * modify it under the terms of the GNU Lesser General Public 23 * License as published by the Free Software Foundation; either 24 * version 2 of the License, or (at your option) any later version. 25 * 26 * This library is distributed in the hope that it will be useful, 27 * but WITHOUT ANY WARRANTY; without even the implied warranty of 28 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 29 * Lesser General Public License for more details. 30 * 31 * You should have received a copy of the GNU Lesser General Public 32 * License along with this library in the file COPYING.LIB; 33 * if not, write to the Free Software Foundation, Inc., 34 * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA 35 */ 36 37 #include "pthread.h" 38 #include "implement.h" 39 #if !defined(NEED_FTIME) 40 #include <sys/timeb.h> 41 #endif 42 43 44 #if defined(PTW32_BUILD_INLINED) 45 INLINE 46 #endif /* PTW32_BUILD_INLINED */ 47 DWORD 48 ptw32_relmillisecs (const struct timespec * abstime) 49 { 50 const int64_t NANOSEC_PER_MILLISEC = 1000000; 51 const int64_t MILLISEC_PER_SEC = 1000; 52 DWORD milliseconds; 53 int64_t tmpAbsMilliseconds; 54 int64_t tmpCurrMilliseconds; 55 #if defined(NEED_FTIME) 56 struct timespec currSysTime; 57 FILETIME ft; 58 SYSTEMTIME st; 59 #else /* ! NEED_FTIME */ 60 #if ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \ 61 ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 ) 62 struct __timeb64 currSysTime; 63 #else 64 struct _timeb currSysTime; 65 #endif 66 #endif /* NEED_FTIME */ 67 68 69 /* 70 * Calculate timeout as milliseconds from current system time. 71 */ 72 73 /* 74 * subtract current system time from abstime in a way that checks 75 * that abstime is never in the past, or is never equivalent to the 76 * defined INFINITE value (0xFFFFFFFF). 77 * 78 * Assume all integers are unsigned, i.e. cannot test if less than 0. 79 */ 80 tmpAbsMilliseconds = (int64_t)abstime->tv_sec * MILLISEC_PER_SEC; 81 tmpAbsMilliseconds += ((int64_t)abstime->tv_nsec + (NANOSEC_PER_MILLISEC/2)) / NANOSEC_PER_MILLISEC; 82 83 /* get current system time */ 84 85 #if defined(NEED_FTIME) 86 87 GetSystemTime(&st); 88 SystemTimeToFileTime(&st, &ft); 89 /* 90 * GetSystemTimeAsFileTime(&ft); would be faster, 91 * but it does not exist on WinCE 92 */ 93 94 ptw32_filetime_to_timespec(&ft, &currSysTime); 95 96 tmpCurrMilliseconds = (int64_t)currSysTime.tv_sec * MILLISEC_PER_SEC; 97 tmpCurrMilliseconds += ((int64_t)currSysTime.tv_nsec + (NANOSEC_PER_MILLISEC/2)) 98 / NANOSEC_PER_MILLISEC; 99 100 #else /* ! NEED_FTIME */ 101 102 #if defined(_MSC_VER) && _MSC_VER >= 1400 103 _ftime64_s(&currSysTime); 104 #elif ( defined(_MSC_VER) && _MSC_VER >= 1300 ) || \ 105 ( (defined(__MINGW64__) || defined(__MINGW32__)) && __MSVCRT_VERSION__ >= 0x0601 ) 106 _ftime64(&currSysTime); 107 #else 108 _ftime(&currSysTime); 109 #endif 110 111 tmpCurrMilliseconds = (int64_t) currSysTime.time * MILLISEC_PER_SEC; 112 tmpCurrMilliseconds += (int64_t) currSysTime.millitm; 113 114 #endif /* NEED_FTIME */ 115 116 if (tmpAbsMilliseconds > tmpCurrMilliseconds) 117 { 118 milliseconds = (DWORD) (tmpAbsMilliseconds - tmpCurrMilliseconds); 119 if (milliseconds == INFINITE) 120 { 121 /* Timeouts must be finite */ 122 milliseconds--; 123 } 124 } 125 else 126 { 127 /* The abstime given is in the past */ 128 milliseconds = 0; 129 } 130 131 return milliseconds; 132 } 133