mirror of
https://github.com/gcc-mirror/gcc.git
synced 2024-11-21 13:40:47 +00:00
5f2408712a
This patch corrects the C equivalent of m2 LONGINT parameters in wrapclock.cc and corrects the SysClock.mod module. wrapclock.cc uses a typedef long long int longint_t to match m2 LONGINT (rather than unsigned long). These fixes prevent calls to SysClock hanging spinning on an (incorrect) large day count from the epoch. gcc/m2/ChangeLog: * gm2-compiler/M2Quads.mod (EndBuildFor): Improve block comments. * gm2-libs-iso/SysClock.mod (ExtractDate): Replace testDays with yearOfDays. New local variable monthOfDays. libgm2/ChangeLog: * libm2iso/wrapclock.cc (longint_t): New declaration. (GetTimespec): Replace types for sec and nano with longint_t. (SetTimespec): Replace types for sec and nano with longint_t. Signed-off-by: Gaius Mulley <gaiusmod2@gmail.com>
342 lines
7.0 KiB
C++
342 lines
7.0 KiB
C++
/* wrapclock.cc provides access to time related system calls.
|
|
|
|
Copyright (C) 2009-2022 Free Software Foundation, Inc.
|
|
Contributed by Gaius Mulley <gaius.mulley@southwales.ac.uk>.
|
|
|
|
This file is part of GNU Modula-2.
|
|
|
|
GNU Modula-2 is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 3, or (at your option)
|
|
any later version.
|
|
|
|
GNU Modula-2 is distributed in the hope that it will be useful, but
|
|
WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
|
General Public License for more details.
|
|
|
|
Under Section 7 of GPL version 3, you are granted additional
|
|
permissions described in the GCC Runtime Library Exception, version
|
|
3.1, as published by the Free Software Foundation.
|
|
|
|
You should have received a copy of the GNU General Public License and
|
|
a copy of the GCC Runtime Library Exception along with this program;
|
|
see the files COPYING3 and COPYING.RUNTIME respectively. If not, see
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
#include "config.h"
|
|
#include <m2rts.h>
|
|
|
|
#define EXPORT(FUNC) m2iso ## _wrapclock_ ## FUNC
|
|
#define M2EXPORT(FUNC) m2iso ## _M2_wrapclock_ ## FUNC
|
|
#define M2LIBNAME "m2iso"
|
|
|
|
#if defined(HAVE_STDLIB_H)
|
|
#include "stdlib.h"
|
|
#endif
|
|
|
|
#if defined(HAVE_UNISTD_H)
|
|
#include "unistd.h"
|
|
#endif
|
|
|
|
#if defined(HAVE_SYS_TYPES_H)
|
|
#include "sys/types.h"
|
|
#endif
|
|
|
|
#if defined(HAVE_SYS_TIME_H)
|
|
#include "sys/time.h"
|
|
#endif
|
|
|
|
#if defined(HAVE_TIME_H)
|
|
#include "time.h"
|
|
#endif
|
|
|
|
// Conditional inclusion of sys/time.h for gettimeofday
|
|
#if !defined(_GLIBCXX_USE_CLOCK_MONOTONIC) && \
|
|
!defined(_GLIBCXX_USE_CLOCK_REALTIME) && \
|
|
defined(_GLIBCXX_USE_GETTIMEOFDAY)
|
|
#include <sys/time.h>
|
|
#endif
|
|
|
|
#if defined(_GLIBCXX_USE_CLOCK_GETTIME_SYSCALL)
|
|
#include <unistd.h>
|
|
#include <sys/syscall.h>
|
|
#endif
|
|
|
|
#if defined(HAVE_MALLOC_H)
|
|
#include "malloc.h"
|
|
#endif
|
|
|
|
#if defined(HAVE_LIMITS_H)
|
|
#include "limits.h"
|
|
#endif
|
|
|
|
#if !defined(NULL)
|
|
#define NULL (void *)0
|
|
#endif
|
|
|
|
typedef long long int longint_t;
|
|
|
|
|
|
/* GetTimeRealtime performs return gettime (CLOCK_REALTIME, ts).
|
|
gettime returns 0 on success and -1 on failure. If the underlying
|
|
system does not have gettime then GetTimeRealtime returns 1. */
|
|
|
|
#if defined(HAVE_STRUCT_TIMESPEC) && defined(_GLIBCXX_USE_CLOCK_REALTIME)
|
|
extern "C" int
|
|
EXPORT(GetTimeRealtime) (struct timespec *ts)
|
|
{
|
|
timespec tp;
|
|
#if defined(_GLIBCXX_USE_CLOCK_GETTIME_SYSCALL)
|
|
return syscall (SYS_clock_gettime, CLOCK_REALTIME, ts);
|
|
#else
|
|
return clock_gettime (CLOCK_REALTIME, ts);
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
|
|
extern "C" int
|
|
EXPORT(GetTimeRealtime) (void *ts)
|
|
{
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
/* SetTimeRealtime performs return settime (CLOCK_REALTIME, ts).
|
|
gettime returns 0 on success and -1 on failure. If the underlying
|
|
system does not have gettime then GetTimeRealtime returns 1. */
|
|
|
|
#if defined(HAVE_STRUCT_TIMESPEC) && defined(_GLIBCXX_USE_CLOCK_REALTIME)
|
|
extern "C" int
|
|
EXPORT(SetTimeRealtime) (struct timespec *ts)
|
|
{
|
|
#if defined(_GLIBCXX_USE_CLOCK_SETTIME_SYSCALL)
|
|
return syscall (SYS_clock_settime, CLOCK_REALTIME, ts);
|
|
#elif defined(HAVE_CLOCK_SETTIME)
|
|
return clock_settime (CLOCK_REALTIME, ts);
|
|
#else
|
|
return 1;
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
|
|
extern "C" int
|
|
EXPORT(SetTimeRealtime) (void *ts)
|
|
{
|
|
return 1;
|
|
}
|
|
#endif
|
|
|
|
/* InitTimespec returns a newly created opaque type. */
|
|
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
extern "C" struct timespec *
|
|
EXPORT(InitTimespec) (void)
|
|
{
|
|
#if defined(HAVE_STRUCT_TIMESPEC) && defined(HAVE_MALLOC_H)
|
|
return (struct timespec *)malloc (sizeof (struct timespec));
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
|
|
extern "C" void *
|
|
EXPORT(InitTimespec) (void)
|
|
{
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
/* KillTimeval deallocates the memory associated with an opaque type. */
|
|
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
extern "C" struct timespec *
|
|
EXPORT(KillTimespec) (void *ts)
|
|
{
|
|
#if defined(HAVE_MALLOC_H)
|
|
free (ts);
|
|
#endif
|
|
return NULL;
|
|
}
|
|
|
|
#else
|
|
|
|
extern "C" void *
|
|
EXPORT(KillTimespec) (void *ts)
|
|
{
|
|
return NULL;
|
|
}
|
|
#endif
|
|
|
|
/* GetTimespec retrieves the number of seconds and nanoseconds from the
|
|
timespec. 1 is returned if successful and 0 otherwise. */
|
|
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
extern "C" int
|
|
EXPORT(GetTimespec) (timespec *ts, longint_t *sec, longint_t *nano)
|
|
{
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
*sec = ts->tv_sec;
|
|
*nano = ts->tv_nsec;
|
|
return 1;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
extern "C" int
|
|
EXPORT(GetTimespec) (void *ts, longint_t *sec, longint_t *nano)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
/* SetTimespec sets the number of seconds and nanoseconds into timespec.
|
|
1 is returned if successful and 0 otherwise. */
|
|
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
extern "C" int
|
|
EXPORT(SetTimespec) (timespec *ts, longint_t sec, longint_t nano)
|
|
{
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
ts->tv_sec = sec;
|
|
ts->tv_nsec = nano;
|
|
return 1;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
#else
|
|
|
|
extern "C" int
|
|
EXPORT(SetTimespec) (void *ts, longint_t sec, longint_t nano)
|
|
{
|
|
return 0;
|
|
}
|
|
#endif
|
|
|
|
extern "C" longint_t
|
|
EXPORT(timezone) (void)
|
|
{
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
struct tm result;
|
|
struct timespec ts;
|
|
|
|
#if defined(HAVE_TM_TM_GMTOFF)
|
|
if (EXPORT(GetTimeRealtime) (&ts) == 0)
|
|
{
|
|
time_t time = ts.tv_sec;
|
|
localtime_r (&time, &result);
|
|
return result.tm_gmtoff;
|
|
}
|
|
else
|
|
#endif
|
|
#endif
|
|
{
|
|
#if defined(HAVE_TIMEZONE)
|
|
return timezone;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
}
|
|
|
|
/* istimezone returns 1 if timezone in wrapclock.cc can resolve the
|
|
timezone value using the timezone C library call or by using
|
|
clock_gettime, localtime_r and tm_gmtoff. */
|
|
|
|
extern "C" int
|
|
EXPORT(istimezone) (void)
|
|
{
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
#if defined(HAVE_TM_TM_GMTOFF)
|
|
#if defined(_GLIBCXX_USE_CLOCK_REALTIME)
|
|
return 1;
|
|
#endif
|
|
#endif
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
extern "C" int
|
|
EXPORT(daylight) (void)
|
|
{
|
|
#if defined(HAVE_DAYLIGHT)
|
|
return daylight;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
/* isdst returns 1 if daylight saving time is currently in effect and
|
|
returns 0 if it is not. */
|
|
|
|
extern "C" int
|
|
EXPORT(isdst) (void)
|
|
{
|
|
#if defined(HAVE_STRUCT_TIMESPEC)
|
|
struct tm result;
|
|
struct timespec ts;
|
|
|
|
if (EXPORT(GetTimeRealtime) (&ts) == 0)
|
|
{
|
|
time_t time = ts.tv_sec;
|
|
localtime_r (&time, &result);
|
|
return result.tm_isdst;
|
|
}
|
|
else
|
|
return 0;
|
|
#else
|
|
return 0;
|
|
#endif
|
|
}
|
|
|
|
/* tzname returns the string associated with the local timezone.
|
|
The daylight value is 0 or 1. The value 0 returns the non
|
|
daylight saving timezone string and the value of 1 returns the
|
|
daylight saving timezone string. It returns NULL if tzname is
|
|
unavailable. */
|
|
|
|
extern "C" char *
|
|
EXPORT(tzname) (int daylight)
|
|
{
|
|
#if defined(HAVE_TZNAME)
|
|
return tzname[daylight];
|
|
#else
|
|
return NULL;
|
|
#endif
|
|
}
|
|
|
|
/* init - init/finish functions for the module */
|
|
|
|
/* GNU Modula-2 linking hooks. */
|
|
|
|
extern "C" void
|
|
M2EXPORT(init) (int, char **, char **)
|
|
{
|
|
}
|
|
|
|
extern "C" void
|
|
M2EXPORT(fini) (int, char **, char **)
|
|
{
|
|
}
|
|
|
|
extern "C" void
|
|
M2EXPORT(dep) (void)
|
|
{
|
|
}
|
|
|
|
extern "C" void __attribute__((__constructor__))
|
|
M2EXPORT(ctor) (void)
|
|
{
|
|
m2iso_M2RTS_RegisterModule ("wrapclock", M2LIBNAME,
|
|
M2EXPORT(init), M2EXPORT(fini),
|
|
M2EXPORT(dep));
|
|
}
|