This is the mail archive of the gcc-patches@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [Patch, libgfortran] PR 40190 DATE_AND_TIME not thread-safe


On Thu, May 21, 2009 at 10:32, FX <fxcoudert@gmail.com> wrote:
> Hi Janne,
>
> At least one supported target doesn't has neither localtime_r nor gmtime_r:
> mingw.

Figures..

However, on the positive side, some further research suggests that
localtime and gmtime are threadsafe on MINGW due to using thread-local
storage for the result. So a modified form of the original question,
do we have a target 1) where we support OpenMP  2) doesn't have
localtime_r and gmtime_r nor threadsafe localtime and gmtime ?

The attached patch adds fallback implementations for localtime_r and
gmtime_r that should work properly on MINGW and other targets where we
support OpenMP and that have threadsafe localtime and gmtime.

Ok for trunk?


-- 
Janne Blomqvist

Attachment: ChangeLog
Description: Binary data

diff --git a/libgfortran/configure.ac b/libgfortran/configure.ac
index c0709bb..b1e5d1e 100644
--- a/libgfortran/configure.ac
+++ b/libgfortran/configure.ac
@@ -226,6 +226,7 @@ AC_CHECK_FUNCS(chdir strerror getlogin gethostname kill link symlink perror)
 AC_CHECK_FUNCS(sleep time ttyname signal alarm ctime clock access fork execl)
 AC_CHECK_FUNCS(wait setmode execvp pipe dup2 close fdopen strcasestr getrlimit)
 AC_CHECK_FUNCS(gettimeofday stat fstat lstat getpwuid vsnprintf dup getcwd)
+AC_CHECK_FUNCS(localtime_r gmtime_r)
 
 # Check for glibc backtrace functions
 AC_CHECK_FUNCS(backtrace backtrace_symbols)
diff --git a/libgfortran/intrinsics/date_and_time.c b/libgfortran/intrinsics/date_and_time.c
index 9cfa9e8..be64626 100644
--- a/libgfortran/intrinsics/date_and_time.c
+++ b/libgfortran/intrinsics/date_and_time.c
@@ -48,6 +48,31 @@ see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see
 #define abs(x) ((x)>=0 ? (x) : -(x))
 #endif
 
+
+/* If the re-entrant versions of localtime and gmtime are not
+   available, provide fallback implementations.  On some targets where
+   the _r versions are not available, localtime and gmtime use
+   thread-local storage so they are threadsafe.  */
+
+#ifndef HAVE_LOCALTIME_R
+static struct tm *
+localtime_r (const time_t * timep, struct tm * result)
+{
+  *result = *localtime (timep);
+  return result;
+}
+#endif
+
+#ifndef HAVE_GMTIME_R
+static struct tm *
+gmtime_r (const time_t * timep, struct tm * result)
+{
+  *result = *gmtime (timep);
+  return result;
+}
+#endif
+
+
 /* DATE_AND_TIME ([DATE, TIME, ZONE, VALUES])
 
    Description: Returns data on the real-time clock and date in a form
@@ -166,8 +191,8 @@ date_and_time (char *__date, char *__time, char *__zone,
 
   if (lt != (time_t) -1)
     {
-      local_time = *localtime (&lt);
-      UTC_time = *gmtime (&lt);
+      localtime_r (&lt, &local_time);
+      gmtime_r (&lt, &UTC_time);
 
       /* All arguments can be derived from VALUES.  */
       values[0] = 1900 + local_time.tm_year;
@@ -361,7 +386,7 @@ itime0 (int x[3])
 
   if (lt != (time_t) -1)
     {
-      local_time = *localtime (&lt);
+      localtime_r (&lt, &local_time);
 
       x[0] = local_time.tm_hour;
       x[1] = local_time.tm_min;
@@ -443,7 +468,7 @@ idate0 (int x[3])
 
   if (lt != (time_t) -1)
     {
-      local_time = *localtime (&lt);
+      localtime_r (&lt, &local_time);
 
       x[0] = local_time.tm_mday;
       x[1] = 1 + local_time.tm_mon;
@@ -510,7 +535,7 @@ idate_i8 (gfc_array_i8 *__values)
 /* GMTIME(STIME, TARRAY) - Non-standard
 
    Description: Given a system time value STime, fills TArray with values
-   extracted from it appropriate to the GMT time zone using gmtime(3).
+   extracted from it appropriate to the GMT time zone using gmtime_r(3).
 
    The array elements are as follows:
 
@@ -530,7 +555,7 @@ gmtime_0 (const time_t * t, int x[9])
 {
   struct tm lt;
 
-  lt = *gmtime (t);
+  gmtime_r (t, &lt);
   x[0] = lt.tm_sec;
   x[1] = lt.tm_min;
   x[2] = lt.tm_hour;
@@ -602,7 +627,7 @@ gmtime_i8 (GFC_INTEGER_8 * t, gfc_array_i8 * tarray)
 /* LTIME(STIME, TARRAY) - Non-standard
 
    Description: Given a system time value STime, fills TArray with values
-   extracted from it appropriate to the local time zone using localtime(3).
+   extracted from it appropriate to the local time zone using localtime_r(3).
 
    The array elements are as follows:
 
@@ -622,7 +647,7 @@ ltime_0 (const time_t * t, int x[9])
 {
   struct tm lt;
 
-  lt = *localtime (t);
+  localtime_r (t, &lt);
   x[0] = lt.tm_sec;
   x[1] = lt.tm_min;
   x[2] = lt.tm_hour;

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]