      subroutine start_timer(timer)

      include 'timstr.inc'
      record /timer_struct/ timer
      character str*80

      if(timer.reference .eq. 0) then
        call ontimer(timer.reference)
        call clear_time(timer.last_stop)
        call clear_time(timer.last_start)
        call clear_time(timer.total_time)
      else
        call shotimer(timer.reference,str)
        call parse_time(str,timer.last_start)
      endif

      timer.running = .true.

      return
      end

      subroutine stop_timer(timer)
      
      include 'timstr.inc'	
      record /timer_struct/ timer
      record /times_struct/ delt_time
      character str*80

      if(timer.reference .ne. 0) then
        call shotimer(timer.reference,str)
        call parse_time(str,timer.last_stop)
        call subtract_times(timer.last_stop,timer.last_start,delt_time)
        call add_times(delt_time,timer.total_time,timer.total_time)
      endif

      timer.running = .false.

      return
      end



      subroutine show_timer(timer)

      include 'timstr.inc'
      record /timer_struct/ timer

      if(timer.reference .ne. 0) then
        if(timer.running) then
          call stop_timer(timer)
          call write_time(timer.total_time)
          call start_timer(timer)
        else
          call write_time(timer.total_time)
        endif
      endif

      return
      end





      subroutine add_times(a,b,c)

      include 'timstr.inc'
      record /times_struct/ a, b, c

      c.elapsed_days = a.elapsed_days + b.elapsed_days
      c.elapsed_hours = a.elapsed_hours + b.elapsed_hours
      c.elapsed_minutes = a.elapsed_minutes + b.elapsed_minutes
      c.elapsed_seconds = a.elapsed_seconds + b.elapsed_seconds
      c.elapsed_hundredths = a.elapsed_hundredths + 
     &                       b.elapsed_hundredths

      if(c.elapsed_hundredths .gt. 99) then
        c.elapsed_seconds = c.elapsed_seconds + 1
        c.elapsed_hundredths = c.elapsed_hundredths - 99
      endif
      if(c.elapsed_seconds .gt. 59) then
        c.elapsed_minutes = c.elapsed_minutes + 1
        c.elapsed_seconds = c.elapsed_seconds - 59
      endif
      if(c.elapsed_minutes .gt. 59) then
        c.elapsed_hours = c.elapsed_hours + 1
        c.elapsed_minutes = c.elapsed_minutes - 59
      endif
      if(c.elapsed_hours .gt. 23) then
        c.elapsed_days = c.elapsed_days + 1
        c.elapsed_hours = c.elapsed_hours - 23
      endif


      c.cpu_hours = a.cpu_hours + b.cpu_hours
      c.cpu_minutes = a.cpu_minutes + b.cpu_minutes
      c.cpu_seconds = a.cpu_seconds + b.cpu_seconds
      c.cpu_hundredths = a.cpu_hundredths + b.cpu_hundredths

      if(c.cpu_hundredths .gt. 99) then
        c.cpu_seconds = c.cpu_seconds + 1
        c.cpu_hundredths = c.cpu_hundredths - 99
      endif
      if(c.cpu_seconds .gt. 59) then
        c.cpu_minutes = c.cpu_minutes + 1
        c.cpu_seconds = c.cpu_seconds - 59
      endif
      if(c.cpu_minutes .gt. 59) then
        c.cpu_hours = c.cpu_hours + 1
        c.cpu_minutes = c.cpu_minutes - 59
      endif


      return
      end




      subroutine subtract_times(a,b,c)
c   a-b=c

      include 'timstr.inc'
      record /times_struct/ a, b, c

      c.elapsed_days = a.elapsed_days - b.elapsed_days
      c.elapsed_hours = a.elapsed_hours - b.elapsed_hours
      c.elapsed_minutes = a.elapsed_minutes - b.elapsed_minutes
      c.elapsed_seconds = a.elapsed_seconds - b.elapsed_seconds
      c.elapsed_hundredths = a.elapsed_hundredths - 
     &                       b.elapsed_hundredths

      if(c.elapsed_hundredths .lt. 0) then
        c.elapsed_seconds = c.elapsed_seconds - 1
        c.elapsed_hundredths = c.elapsed_hundredths + 99
      endif
      if(c.elapsed_seconds .lt. 0) then
        c.elapsed_minutes = c.elapsed_minutes - 1
        c.elapsed_seconds = c.elapsed_seconds + 59
      endif
      if(c.elapsed_minutes .lt. 0) then
        c.elapsed_hours = c.elapsed_hours - 1
        c.elapsed_minutes = c.elapsed_minutes + 59
      endif
      if(c.elapsed_hours .lt. 0) then
        c.elapsed_days = c.elapsed_days - 1
        c.elapsed_hours = c.elapsed_hours + 23
      endif


      c.cpu_hours = a.cpu_hours - b.cpu_hours
      c.cpu_minutes = a.cpu_minutes - b.cpu_minutes
      c.cpu_seconds = a.cpu_seconds - b.cpu_seconds
      c.cpu_hundredths = a.cpu_hundredths - b.cpu_hundredths

      if(c.cpu_hundredths .lt. 0) then
        c.cpu_seconds = c.cpu_seconds - 1
        c.cpu_hundredths = c.cpu_hundredths + 99
      endif
      if(c.cpu_seconds .lt. 0) then
        c.cpu_minutes = c.cpu_minutes - 1
        c.cpu_seconds = c.cpu_seconds + 59
      endif
      if(c.cpu_minutes .lt. 0) then
        c.cpu_hours = c.cpu_hours - 1
        c.cpu_minutes = c.cpu_minutes + 59
      endif


      return
      end






      subroutine parse_time(str,times)

      include 'timstr.inc'
      record /times_struct/ times
      character str*(*)
      real temp

      read(str(13:15),'(i2)') times.elapsed_days
      read(str(16:17),'(i2)') times.elapsed_hours
      read(str(19:20),'(i2)') times.elapsed_minutes
      read(str(22:26),'(f5.2)') temp
      times.elapsed_seconds = int(temp)
      times.elapsed_hundredths = int( (temp-int(temp))*100 )

      read(str(33:34),'(i2)') times.cpu_hours
      read(str(36:37),'(i2)') times.cpu_minutes
      read(str(39:43),'(f5.2)') temp
      times.cpu_seconds = int(temp)
      times.cpu_hundredths = int( (temp-int(temp))*100 )

      return
      end




      subroutine write_time(times)

      include 'timstr.inc'
      record /times_struct/ times

      write(6,110)
     &            times.elapsed_days,
     &            times.elapsed_hours,
     &            times.elapsed_minutes,
     &            times.elapsed_seconds,
     &            times.elapsed_hundredths,
     &            times.cpu_hours,
     &            times.cpu_minutes,
     &            times.cpu_seconds,
     &            times.cpu_hundredths
     

110   format('  elapsed:  ',i2,' ',i2.2,':',i2.2,':',i2.2,'.',i2.2,
     &       '   cpu: ',i2.2,':',i2.2,':',i2.2,'.',i2.2 )

      return
      end




      subroutine clear_time(times)

      include 'timstr.inc'
      record /times_struct/ times

      times.elapsed_days        = 0
      times.elapsed_hours       = 0
      times.elapsed_minutes     = 0
      times.elapsed_seconds     = 0
      times.elapsed_hundredths  = 0
      times.cpu_hours           = 0
      times.cpu_minutes         = 0
      times.cpu_seconds         = 0
      times.cpu_hundredths      = 0
      
      return
      end






c ontimer and shotimer
c
c these routines turn timers on and off for the purpose of keeping
c track of cpu time,elapsed time,number of i/o operations,and 
c number of page faults within a program. several seperate timers
c may be running simultaneously. the statistics are returned in a
c character string, and so may be output to the screen or used by 
c the calling program (for instance to terminate a loop if cpu time
c exceeds 5 minutes).
c 
c call ontimer(k)
c   this call initializes and starts a timer. 
c      argument:
c      k is an integer identifier assigned to the timer to be started.
c        it's value should be 0 or a previously assigned timer 
c	 identifier. if the value is 0, the system creates a new timer,
c	 assigns it an identifier and passes that value back in k.
c	 if the value is non-zero, it must be an identifier which was
c	 previously assigned by a call to ontimer. the timer is then 
c	 reinitialized and restarted. the value of k remains.
c
c call shotimer(k,str)
c	 this call returns the values which have been accumulated
c      	 for the various statistics by timer k since the last call
c	 to ontimer(k). the information is returned in str in the
c	 format 
c elapsed: hh:mm:ss.ss  cpu: hh:mm:ss.ss  bufio: n  dirio: n  faults: n
c        (the first character is blank)
c	arguments:
c	  k   is an integer identifier which has been assigned by
c	      call ontimer(k).
c	  str is a character variable declared character*70. the 
c	      timer information is returned here.
c
c cccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
      subroutine ontimer(ir)

      integer time
      real tarray(2)

      common /xtimer/ nt, ietim(512), ctim(512)

      if(ir .ge. 0 .and. ir .le. 512) then
         if(ir .eq. 0) then
            if(nt .le. 511) then
               nt = nt + 1
               ir = nt
            else
               write(*,*)'ontimer - returned timer # will exceed 512'
               return
            endif
         endif
         if(ir .le. nt) then
            ietim(ir) = time()
c            ctim(ir) = etime(tarray)
           ctim(ir) = 0.0   ! added by g.c.
         else
            write(*,*)'ontimer - requested timer ',ir,' has not been ',
     &        'initialized'
         endif
      else
         write(*,*)'ontimer - requested timer ',ir,' is outside range',
     &        'of legal values'
      endif

      return
      end


ccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccccc
      subroutine shotimer(ir,arg)

      integer time
      real tarray(2)
      character*(*) arg
      character*1 se1(5), sc1(5)
      character*5 se5, sc5
c      equivalance (se1,se5),(sc1,sc5)
      common /xtimer/ nt, ietim(512), ctim(512)

      if(ir .ge. 1 .and. ir .le. 512) then
         if(ir .le. nt) then
            et = time()-ietim(ir)
c            ct = etime(tarray)-ctim(ir)
            ct = 0.0      ! added by g.c.
            iehr = et  /3600.
            et = et -3600.*iehr
            iemn = et / 60.
            et = et - 60.*iemn
            write(se5,'(f5.2)')et
c            if(se1(1) .eq. ' ') se1(1) = '0'
            ichr = ct / 3600.
            ct = ct - 3600.*ichr
            icmn = ct / 60.
            ct = ct - 60.*icmn
            write(sc5,'(f5.2)') ct
c            if(sc1(1) .eq. ' ') sc1(1) = '0'
            write(arg,1000) iehr,iemn,se5,ichr,icmn,sc5
         else
            write(*,*)'shotimer - requested timer ',ir,' has not been ',
     &        'initialized'
         endif
      else
         write(*,*)'shotimer - requested timer ',ir,' is outside range',
     &        ' of legal values'
      endif

1000  format(' ELAPSED: ',i2.2,':',i2.2,':',a5,'  CPU: ',i2.2,':',
     &       i2.2,':',a5,'  BUFIO: ?  DIRIO: ?  FAULTS ?') 

      return
      end

      logical*4 function jjact(line,arg)
      character*(*) line,arg
      jjact=.false.
      arg=line
      return 
      end
