Refactoring time-related default port implementations (#4513)

In the non-Windows code paths:
- New approach to compute TZA without the need for GNU-specific
  `struct tm.tm_gmtoff`.
- Always using `usleep` to sleep. (No real need for `nanosleep` as
  port API has sleep granularity of milliseconds.)
- Not checking for "time.h" at build configuration time as that
  header is mandated by the C standard.
- Not checking for "unistd.h" at build configuration time as that
  header is mandated by the POSIX standard (the default port is
  targeting POSIX systems -- and Windows).
- Fixing some macro guards.

JerryScript-DCO-1.0-Signed-off-by: Akos Kiss akiss@inf.u-szeged.hu
This commit is contained in:
Akos Kiss 2021-01-29 10:45:46 +01:00 committed by GitHub
parent ba06d492a3
commit 87d30b8088
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 66 deletions

View File

@ -59,31 +59,6 @@ endif()
# (should only be necessary if we used compiler default libc but not checking that)
set(DEFINES_PORT_DEFAULT _BSD_SOURCE _DEFAULT_SOURCE)
INCLUDE (CheckStructHasMember)
# CHECK_STRUCT_HAS_MEMBER works by trying to compile some C code that accesses the
# given field of the given struct. However, our default compiler options break this
# C code, so turn a couple of them off for this.
if(USING_GCC OR USING_CLANG)
set(CMAKE_REQUIRED_FLAGS "-Wno-error=strict-prototypes -Wno-error=old-style-definition -Wno-error=unused-value")
endif()
# tm.tm_gmtoff is non-standard, so glibc doesn't expose it in c99 mode
# (our default). Define some macros to expose it anyway.
set(CMAKE_REQUIRED_DEFINITIONS "-D_BSD_SOURCE -D_DEFAULT_SOURCE")
CHECK_STRUCT_HAS_MEMBER ("struct tm" tm_gmtoff time.h HAVE_TM_GMTOFF)
if(HAVE_TM_GMTOFF)
set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_TM_GMTOFF)
endif()
# Sleep function availability check
INCLUDE (CheckIncludeFiles)
CHECK_INCLUDE_FILES (time.h HAVE_TIME_H)
CHECK_INCLUDE_FILES (unistd.h HAVE_UNISTD_H)
if(HAVE_TIME_H)
set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_TIME_H)
elseif(HAVE_UNISTD_H)
set(DEFINES_PORT_DEFAULT ${DEFINES_PORT_DEFAULT} HAVE_UNISTD_H)
endif()
# Default Jerry port implementation library
add_library(${JERRY_PORT_DEFAULT_NAME} ${SOURCE_PORT_DEFAULT})
target_include_directories(${JERRY_PORT_DEFAULT_NAME} PUBLIC ${INCLUDE_PORT_DEFAULT})

View File

@ -13,20 +13,17 @@
* limitations under the License.
*/
#ifdef HAVE_TM_GMTOFF
#include <time.h>
#endif /* HAVE_TM_GMTOFF */
#ifdef _WIN32
#include <windows.h>
#include <winbase.h>
#include <winnt.h>
#include <time.h>
#endif /* _WIN32 */
#ifdef __GNUC__
#if defined (__GNUC__) || defined (__clang__)
#include <sys/time.h>
#endif /* __GNUC__ */
#endif /* __GNUC__ || __clang__ */
#include "jerryscript-port.h"
#include "jerryscript-port-default.h"
@ -54,9 +51,7 @@ static double FileTimeToUnixTimeMs (FILETIME ft)
#endif /* _WIN32 */
/**
* Default implementation of jerry_port_get_local_time_zone_adjustment. Uses the 'tm_gmtoff' field
* of 'struct tm' (a GNU extension) filled by 'localtime_r' if available on the
* system, does nothing otherwise.
* Default implementation of jerry_port_get_local_time_zone_adjustment.
*
* @return offset between UTC and local time at the given unix timestamp, if
* available. Otherwise, returns 0, assuming UTC time.
@ -64,19 +59,6 @@ static double FileTimeToUnixTimeMs (FILETIME ft)
double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since unix epoch */
bool is_utc) /**< is the time above in UTC? */
{
#ifdef HAVE_TM_GMTOFF
struct tm tm;
time_t now = (time_t) (unix_ms / 1000);
localtime_r (&now, &tm);
if (!is_utc)
{
now -= tm.tm_gmtoff;
localtime_r (&now, &tm);
}
return ((double) tm.tm_gmtoff) * 1000;
#else /* !HAVE_TM_GMTOFF */
(void) unix_ms;
(void) is_utc;
#ifdef _WIN32
FILETIME fileTime, localFileTime;
SYSTEMTIME systemTime, localSystemTime;
@ -94,9 +76,39 @@ double jerry_port_get_local_time_zone_adjustment (double unix_ms, /**< ms since
localTime.HighPart = localFileTime.dwHighDateTime;
return (double) (((LONGLONG) localTime.QuadPart - (LONGLONG) time.QuadPart) / TicksPerMs);
}
#endif /* _WIN32 */
#elif defined (__GNUC__) || defined (__clang__)
time_t now_time = (time_t) (unix_ms / 1000);
double tza_s = 0.0;
while (true)
{
struct tm now_tm;
if (!gmtime_r (&now_time, &now_tm))
{
break;
}
now_tm.tm_isdst = -1; /* if not overridden, DST will not be taken into account */
time_t local_time = mktime (&now_tm);
if (local_time == (time_t) -1)
{
break;
}
tza_s = difftime (now_time, local_time);
if (is_utc)
{
break;
}
now_time -= (time_t) tza_s;
is_utc = true;
}
return tza_s * 1000;
#else /* !_WIN32 && !__GNUC__ && !__clang__ */
(void) unix_ms; /* unused */
(void) is_utc; /* unused */
return 0.0;
#endif /* HAVE_TM_GMTOFF */
#endif /* _WIN32 */
} /* jerry_port_get_local_time_zone_adjustment */
/**
@ -113,14 +125,15 @@ double jerry_port_get_current_time (void)
FILETIME ft;
GetSystemTimeAsFileTime (&ft);
return FileTimeToUnixTimeMs (ft);
#elif __GNUC__
#elif defined (__GNUC__) || defined (__clang__)
struct timeval tv;
if (gettimeofday (&tv, NULL) == 0)
{
return ((double) tv.tv_sec) * 1000.0 + ((double) tv.tv_usec) / 1000.0;
}
#endif /* _WIN32 */
return 0.0;
#else /* !_WIN32 && !__GNUC__ && !__clang__ */
return 0.0;
#endif /* _WIN32 */
} /* jerry_port_get_current_time */

View File

@ -21,9 +21,7 @@
#ifdef _WIN32
#include <windows.h>
#elif defined (HAVE_TIME_H)
#include <time.h>
#elif defined (HAVE_UNISTD_H)
#else /* !_WIN32 */
#include <unistd.h>
#endif /* _WIN32 */
@ -31,22 +29,14 @@
#include "jerryscript-port-default.h"
/**
* Default implementation of jerry_port_sleep. Uses 'nanosleep' or 'usleep' if
* available on the system, does nothing otherwise.
* Default implementation of jerry_port_sleep. Uses 'usleep' if available on the
* system, does nothing otherwise.
*/
void jerry_port_sleep (uint32_t sleep_time) /**< milliseconds to sleep */
{
#ifdef _WIN32
Sleep (sleep_time);
#elif defined (HAVE_TIME_H)
struct timespec sleep_timespec;
sleep_timespec.tv_sec = (time_t) sleep_time / 1000;
sleep_timespec.tv_nsec = ((long int) sleep_time % 1000) * 1000000L;
nanosleep (&sleep_timespec, NULL);
#elif defined (HAVE_UNISTD_H)
#else /* !_WIN32 */
usleep ((useconds_t) sleep_time * 1000);
#else
(void) sleep_time;
#endif /* HAVE_TIME_H */
#endif /* _WIN32 */
} /* jerry_port_sleep */