Bug 23380 - [mingw32] cpu_time intrinsic malfunction
Summary: [mingw32] cpu_time intrinsic malfunction
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: libfortran (show other bugs)
Version: 4.1.0
: P2 normal
Target Milestone: 4.0.3
Assignee: Francois-Xavier Coudert
URL: http://gcc.gnu.org/ml/gcc-patches/200...
Keywords: patch
Depends on:
Blocks:
 
Reported: 2005-08-13 21:48 UTC by Edmund J Dunlop
Modified: 2005-09-29 12:29 UTC (History)
2 users (show)

See Also:
Host:
Target: i686-pc-mingw32
Build:
Known to work:
Known to fail:
Last reconfirmed: 2005-09-24 08:40:58


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description Edmund J Dunlop 2005-08-13 21:48:29 UTC
The gfortran intrinsic function cpu_time(x) does not measure cpu time - it 
always produces 0.0 (zero) as the result.

I am using "Native Windows build: download the latest installer (2005-08-06)" 
from http://gcc.gnu.org/wiki/GFortranBinaries, and am running under Windows XP 
Professional.
Comment 1 Andrew Pinski 2005-08-13 21:55:29 UTC
This is a mingw32 specific issue.

The implemention for mingw32 is not complete.
intrinsics/cpu_time.c is where it is implemented,
we only check for HAVE_GETRUSAGE and HAVE_TIMES.
Comment 2 kargls 2005-08-14 01:33:56 UTC
(In reply to comment #1)
> This is a mingw32 specific issue.
> 
> The implemention for mingw32 is not complete.
> intrinsics/cpu_time.c is where it is implemented,
> we only check for HAVE_GETRUSAGE and HAVE_TIMES.

This isn't exactly correct.  If neither HAVE_GETRUSAGE nor HAVE_TIMES
is defined, cpu_time can and does return -1. It appears that MingW
claims to have a HAVE_TIMES, when in fact it is broken.  This is not
a gfortran problem.  Please contact the MingW developers.
Comment 3 Danny Smith 2005-08-14 07:29:50 UTC
I don't know why you say that "MingW claims to have a HAVE_TIMES".  It doesn't. 

To get process times on mingw we need to use the win32api function 
GetProcessTimes.  This is available on NT4 and later but not on  win9x.

Would an ifdef _WIN32 clause be acceptable in cpu_time.c.  If so, I will submit 
a patch.

Danny
Comment 4 Edmund J Dunlop 2005-08-14 09:41:33 UTC
Subject: RE:  [mingw32] cpu_time intrinsic malfunction

Danny

I would consider your suggestion very acceptable - it is obviously not 100%
but would sort the problem for many users, including myself. Thank you to
all who replied re this problem.

Edmund.

Comment 5 kargls 2005-08-14 16:48:52 UTC
(In reply to comment #3)
> I don't know why you say that "MingW claims to have a HAVE_TIMES".
> It doesn't. 
>

Read the code for __cpu_time_1.  The only way that cpu_time can return
zero is if HAVE_TIMES is defined or if MingW has getrusage() and
getrusage is broken.

> Would an ifdef _WIN32 clause be acceptable in cpu_time.c.

IMO, no.  There are no other _WIN32 clauses in gfortran.  As soon as
you add the first one, there will be a proliferation of OS specific
clauses in gfortran.

What we need to understand is why cpu_time isn't returning -1, which 
is standard conforming.   So, does config.h contain HAVE_GETRUSAGE
or HAVE_TIMES defined?


Comment 6 Danny Smith 2005-08-14 20:56:15 UTC
From my libgfortran/config.h, configured with --host=mingw32 --target=mingw32
and mingw runtime as distributed by mingw.org

/* Define to 1 if you have the `getrusage' function. */
/* #undef HAVE_GETRUSAGE */

and

/* Define to 1 if you have the `times' function. */
/* #undef HAVE_TIMES */


So maybe you should query the source of your binaries.



FWIW, here is how to get cpu time on NT

#define WIN32_LEAN_AND_MEAN
#include <windows.h>

static void
__winnt_cpu_time (long *sec, long *usec)
{
  union {
    FILETIME ft;
    unsigned long long ulltime;
  } kernel_time,  user_time;

  FILETIME unused1, unused2;
  unsigned long long total_time;

  /* No support for Win9x.  The high order bit of the DWORD
     returned by GetVersion is 0 for NT and higher. */
  if (GetVersion () >= 0x80000000)
    {
      *sec = -1;
      *usec = 0;
      return;
    }

  /* The FILETIME structs filled in by GetProcessTimes represent
     time in 100 nanosecond units. */
  GetProcessTimes (GetCurrentProcess (), &unused1, &unused2,
              	   &kernel_time.ft, &user_time.ft);
      
  total_time = (kernel_time.ulltime + user_time.ulltime)/10; 
  *sec = total_time / 1000000;
  *usec = total_time % 1000000;
}
Comment 7 Francois-Xavier Coudert 2005-09-06 17:21:57 UTC
Well, I don't know what went wrong here, but: it works for me, with the
2005-08-05 binaries (downloaded the installer, etc.) Moreover, as the source of
the binaries, I checked my config.h file, and it is indeed correct.

$ cat cputime.f90 
  real x
  call cpu_time (x)
  print *, x
  end
$ ./bin/gfortran.exe cputime.f90 && a
  -1.000000    


Well, perhaps "nothing's wrong" is a bit too optimistic since cpu_time does
conform to the standard but is still not fully... satisfactory. Keeping this PR
open to track the new issue (correct by Danny's win32 code).
Comment 8 GCC Commits 2005-09-24 08:39:48 UTC
Subject: Bug 23380

CVSROOT:	/cvs/gcc
Module name:	gcc
Changes by:	fxcoudert@gcc.gnu.org	2005-09-24 08:39:35

Modified files:
	libgfortran    : ChangeLog 
	libgfortran/intrinsics: cpu_time.c 

Log message:
	PR libfortran/23380
	* intrinsics/cpu_time.c (__cpu_time_1): Provide a MS Windows
	version.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/ChangeLog.diff?cvsroot=gcc&r1=1.304&r2=1.305
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/cpu_time.c.diff?cvsroot=gcc&r1=1.6&r2=1.7

Comment 9 GCC Commits 2005-09-29 12:29:15 UTC
Subject: Bug 23380

CVSROOT:	/cvs/gcc
Module name:	gcc
Branch: 	gcc-4_0-branch
Changes by:	fxcoudert@gcc.gnu.org	2005-09-29 12:28:52

Modified files:
	libgfortran    : ChangeLog 
	libgfortran/intrinsics: cpu_time.c getXid.c getlog.c hostnm.c 
	                        sleep.c 

Log message:
	Backport from mainline:
	PR libfortran/23380
	PR libfortran/23802
	PR libfortran/23803
	* intrinsics/getXid.c: Add getpid wrapper for MinGW.
	* intrinsics/getlog.c: Add getlogin wrapper for MinGW.
	* intrinsics/hostnm.c: Add gethostname wrapper for MinGW.
	* intrinsics/sleep.c: Add correct sleep macro for MinGW.
	* intrinsics/cpu_time.c (__cpu_time_1): Provide a MS Windows
	version.

Patches:
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/ChangeLog.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.163.2.92&r2=1.163.2.93
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/cpu_time.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.5&r2=1.5.12.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/getXid.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.3&r2=1.3.12.1
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/getlog.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1.2.2&r2=1.1.2.3
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/hostnm.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1.2.1&r2=1.1.2.2
http://gcc.gnu.org/cgi-bin/cvsweb.cgi/gcc/libgfortran/intrinsics/sleep.c.diff?cvsroot=gcc&only_with_tag=gcc-4_0-branch&r1=1.1.2.1&r2=1.1.2.2

Comment 10 Francois-Xavier Coudert 2005-09-29 12:29:59 UTC
Fixed.