Alex Ferguson writes:
> 
> Perry The Cynic gets bitten by ye olde rusage gotcha.  Firstly, let
> me second Jon Mountjoy's suggestions -- especially the first.
> For quite a while we had a mixture of Solaris 2.4 and 2.5 mechines
> here, and what a pain in the neck that was.  But failing these,
> before you go to the desparate lengths of .hc files (shudder):
> 
> > This also happens to the binary distribution for version 0.29.
> > I am using a fairly standard Solaris version 2.4.
> 

This should have been fixed a long time ago, but appears to have
fallen between the cracks after it was first reported with 0.29/2.01 -
sorry about that. Anyway, the enclosed patch will hopefully remedy the
problem for solaris2.4 platforms. (The patch is done wrt 2.04 sources,
but I'm fairly confident it could also be applied to 2.02 sources with
some success.)

Re: question of how to boot from .hc files, there's not that too much
to it - add the entry 'GhcWithHscBuiltViaC=YES' to your mk/build.mk
and proceed as usual. I've updated the docs - thanks for the report.

--Sigbjorn

*** ghc/runtime/storage/SMstats.lc.~1~  Mon Mar 17 17:21:32 1997
--- ghc/runtime/storage/SMstats.lc      Thu Jul 10 22:54:24 1997
***************
*** 54,59 ****
--- 54,77 ----
  #define HAVE_GETRUSAGE
  #endif
  
+ /*
+  getrusage() is not the preferred way of getting at process-specific
+  info under Solaris...at least it wasn't. It was supported via a BSD
+  compatibility library in 2.4, whereas 2.5 has it in libc.
+ 
+  The upshot of this change of heart is that we cannot rely on getrusage()
+  being available via libc, i.e., 2.5 binaries will not run under 2.4
+  without some extra work. Could use libucb under 2.5 as well, but
+  a simpler solution is simply to avoid the problem and stay away
+  from getrusage() for Solaris   -- SOF
+ */
+ #if solaris2_TARGET_OS
+ #undef __STRICT_ANSI__  /* oh, dear */
+ #include <sys/fcntl.h>
+ #include <sys/signal.h>
+ #include <sys/procfs.h>
+ #endif
+ 
  static StgDouble GC_start_time,  GC_tot_time = 0;  /* User GC Time */
  static StgDouble GCe_start_time, GCe_tot_time = 0; /* Elapsed GC time */
  
***************
*** 114,135 ****
  
  #else /* not stumped */
  
! /* "times" is the more standard, but we prefer "getrusage"
!     (because we are old worn-out BSD hackers)
! */
! # if defined(HAVE_GETRUSAGE) && ! irix_TARGET_OS
!     struct rusage t;
! 
!     getrusage(RUSAGE_SELF, &t);
!     return(t.ru_utime.tv_sec + 1e-6*t.ru_utime.tv_usec);
! 
! # else /* HAVE_TIMES */
      struct tms t;
  
      times(&t);
      return(((StgDouble)(t.tms_utime))/TicksPerSecond);
  
! # endif /* HAVE_TIMES */
  #endif /* not stumped */
  }
  
--- 132,150 ----
  
  #else /* not stumped */
  
! # if defined(HAVE_TIMES) 
      struct tms t;
  
      times(&t);
      return(((StgDouble)(t.tms_utime))/TicksPerSecond);
  
! #else /* HAVE_GETRUSAGE */
!     struct rusage t;
! 
!     getrusage(RUSAGE_SELF, &t);
!     return(t.ru_utime.tv_sec + 1e-6*t.ru_utime.tv_usec);
! 
! # endif /* HAVE_GETRUSAGE */
  #endif /* not stumped */
  }
  
***************
*** 206,223 ****
      InitElapsedTime = elapsedtime();
  }
  
  static I_
  pagefaults(STG_NO_ARGS)
  {
! #if !defined(HAVE_GETRUSAGE) || irix_TARGET_OS || cygwin32_TARGET_OS
!     return 0;
  #else
      struct rusage t;
  
      getrusage(RUSAGE_SELF, &t);
      return(t.ru_majflt);
! #endif
  }
  
  /* Called at the beginning of execution of the program */
  /* Writes the command line and inits stats header */
--- 221,285 ----
      InitElapsedTime = elapsedtime();
  }
  
+ #if defined(solaris2_TARGET_OS)
  static I_
  pagefaults(STG_NO_ARGS)
  {
!     int         fd, ret_val;
!     char        proc[30]; /* Will break when PIDs are repr. by more than 64bits */
!     prusage_t   prusage;
! 
!     /* Under Solaris, we get at the number of major page faults
!        via the process file descriptor and ioctl()ing with 
!        PIOCUSAGE to get the prusage_t structure.
!        (as per proc(4) man page and Solaris porting FAQ).
!     */
!     sprintf(proc,"/proc/%d", getpid()); /* ToDo: this string is static 
!                                          per process, optimise? */
! 
!     if ((fd = open(proc, O_RDONLY)) == -1) {
!       /* Silently return on error ... */
! #ifdef DEBUG
!       perror("pagefaults:open");
!         EXIT(EXIT_FAILURE);
! #else
!       return 0;
! #endif
!     }
!     if (ioctl(fd, PIOCUSAGE, &prusage) == -1 ) {
! #ifdef DEBUG
!          perror("pagefaults:ioctl");
!            EXIT(EXIT_FAILURE);
  #else
+          ret_val = 0;   
+ #endif
+     } else {
+          ret_val = prusage.pr_majf;
+     }
+     while ((close(fd)) != 0) {
+       if (errno != EINTR) {
+           fflush(stdout);
+           fprintf(stderr, "pagefaults: close failed\n");
+           EXIT(EXIT_FAILURE);
+       }       
+     }
+     return ret_val;
+ }
+ #else 
+ 
+ static I_
+ pagefaults(STG_NO_ARGS)
+ {
+ # if !defined(HAVE_GETRUSAGE) || irix_TARGET_OS || cygwin32_TARGET_OS
+     return 0;
+ # else
      struct rusage t;
  
      getrusage(RUSAGE_SELF, &t);
      return(t.ru_majflt);
! # endif
  }
+ #endif
  
  /* Called at the beginning of execution of the program */
  /* Writes the command line and inits stats header */

Reply via email to