timercos.c

Go to the documentation of this file.
00001 /*                      T I M E R C O S . C
00002  * BRL-CAD
00003  *
00004  * Copyright (c) 2004-2006 United States Government as represented by
00005  * the U.S. Army Research Laboratory.
00006  *
00007  * This library is free software; you can redistribute it and/or
00008  * modify it under the terms of the GNU Lesser General Public License
00009  * as published by the Free Software Foundation; either version 2 of
00010  * the License, or (at your option) any later version.
00011  *
00012  * This library is distributed in the hope that it will be useful, but
00013  * WITHOUT ANY WARRANTY; without even the implied warranty of
00014  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015  * Library General Public License for more details.
00016  *
00017  * You should have received a copy of the GNU Lesser General Public
00018  * License along with this file; see the file named COPYING for more
00019  * information.
00020  */
00021 
00022 /** @addtogroup timer */
00023 /*@{*/
00024 /** @file timercos.c
00025  *      To provide timing information for RT.
00026  *      THIS VERSION FOR Cray COS "C"
00027  */
00028 #ifndef lint
00029 static const char RCScos[] = "@(#)$Header: /cvsroot/brlcad/brlcad/src/librt/timercos.c,v 14.10 2006/09/16 02:04:26 lbutler Exp $ (BRL)";
00030 #endif
00031 
00032 #include "common.h"
00033 
00034 #include <stdlib.h>
00035 #include <stdio.h>
00036 #include <sys.h>
00037 
00038 static float cpu0;
00039 
00040 extern long time();
00041 
00042 static long time0;
00043 static long ns0;
00044 
00045 
00046 /*
00047  *                      P R E P _ T I M E R
00048  */
00049 void
00050 rt_prep_timer()
00051 {
00052         (void)time(&time0);
00053         ns0 = clock();          /* Reset time to 0? */
00054         cpu0 = 0;
00055         x_sys(F_JTI, &cpu0 );
00056 }
00057 
00058 
00059 /*
00060  *                      R E A D _ T I M E R
00061  *
00062  */
00063 double
00064 rt_read_timer(str,len)
00065 char *str;
00066 {
00067         long now, ns;
00068         double realt;
00069         double usert;
00070         char line[132];
00071         float cpunow;
00072 
00073         /* Real time */
00074         (void)time(&now);
00075         realt = now-time0;
00076 
00077         /* CPU time */
00078         ns = clock();           /* seems to be wall clock! */
00079         realt = ((double)(ns-ns0)) / 1.0e9;
00080         cpunow = 0;
00081         x_sys(F_JTI, &cpunow);
00082         usert = cpunow-cpu0;
00083         if( usert < 0.00001 )  usert = 0.00001;
00084         if( realt < 0.00001 )  realt = usert;
00085         sprintf(line,"%g CPU secs in %g elapsed secs (%g%%)",
00086                 usert, realt,
00087                 usert/realt*100 );
00088         (void)strncpy( str, line, len );
00089         return( usert );
00090 }
00091 
00092 /* Because COS memset() zaps registers, wrap in insulating function */
00093 bzero( str, n )
00094 {
00095         memset( str, '\0', n );
00096 }
00097 
00098 /*
00099  * Routines that seem to be missing or broken under COS on the XMP.
00100  */
00101 perror(str)
00102 char *str;
00103 {
00104         fprintf(stderr,"%s:  file access failure\n");
00105 }
00106 chmod(str,val)
00107 char *str;
00108 {
00109         ;
00110 }
00111 char *sbrk(i)
00112 {
00113         return( (char *)0 );
00114 }
00115 
00116 /******* Needed only on broken versions of COS ********/
00117 /*
00118  *      ascii to floating (atof)
00119  */
00120 #include <ctype.h>
00121 /******#include <values.h>******/
00122 /* These values work with any binary representation of integers
00123  * where the high-order bit contains the sign. */
00124 
00125 /* a number used normally for size of a shift */
00126 #define BITSPERBYTE     8
00127 #define BITS(type)      (BITSPERBYTE * (int)sizeof(type))
00128 
00129 /* short, regular and long ints with only the high-order bit turned on */
00130 #define HIBITS  ((short)(1 << BITS(short) - 1))
00131 #define HIBITI  (1 << BITS(int) - 1)
00132 #define HIBITL  (1L << BITS(long) - 1)
00133 
00134 /* largest short, regular and long int */
00135 #define MAXSHORT        ((short)~HIBITS)
00136 #define MAXINT  (~HIBITI)
00137 #define MAXLONG (~HIBITL)
00138 
00139 /* various values that describe the binary floating-point representation
00140  * _EXPBASE     - the exponent base
00141  * DMAXEXP      - the maximum exponent of a double (as returned by frexp())
00142  * FMAXEXP      - the maximum exponent of a float  (as returned by frexp())
00143  * DMINEXP      - the minimum exponent of a double (as returned by frexp())
00144  * FMINEXP      - the minimum exponent of a float  (as returned by frexp())
00145  * MAXDOUBLE    - the largest double
00146                         ((_EXPBASE ** DMAXEXP) * (1 - (_EXPBASE ** -DSIGNIF)))
00147  * MAXFLOAT     - the largest float
00148                         ((_EXPBASE ** FMAXEXP) * (1 - (_EXPBASE ** -FSIGNIF)))
00149  * MINDOUBLE    - the smallest double (_EXPBASE ** (DMINEXP - 1))
00150  * MINFLOAT     - the smallest float (_EXPBASE ** (FMINEXP - 1))
00151  * DSIGNIF      - the number of significant bits in a double
00152  * FSIGNIF      - the number of significant bits in a float
00153  * DMAXPOWTWO   - the largest power of two exactly representable as a double
00154  * FMAXPOWTWO   - the largest power of two exactly representable as a float
00155  * _IEEE        - 1 if IEEE standard representation is used
00156  * _DEXPLEN     - the number of bits for the exponent of a double
00157  * _FEXPLEN     - the number of bits for the exponent of a float
00158  * _HIDDENBIT   - 1 if high-significance bit of mantissa is implicit
00159  * LN_MAXDOUBLE - the natural log of the largest double  -- log(MAXDOUBLE)
00160  * LN_MINDOUBLE - the natural log of the smallest double -- log(MINDOUBLE)
00161  */
00162 #define MAXDOUBLE       0.7237005577332262e+76
00163 #define MAXFLOAT        ((float)0.7237005145e+76)
00164 #define MINDOUBLE       5.3976053469342702e-79
00165 #define MINFLOAT        ((float)MINDOUBLE)
00166 #define _IEEE           0
00167 #define _DEXPLEN        15
00168 #define _HIDDENBIT      0
00169 #define DMINEXP (-(DMAXEXP + 1))
00170 #define FMINEXP (-(FMAXEXP + 1))
00171 
00172 #define _FEXPLEN        15
00173 #define DSIGNIF (BITS(double) - _DEXPLEN + _HIDDENBIT - 1)
00174 #define FSIGNIF (BITS(float)  - _FEXPLEN + _HIDDENBIT - 1)
00175 #define DMAXPOWTWO      ((double)(1L << BITS(long) - 2) * \
00176                                 (1L << DSIGNIF - BITS(long) + 1))
00177 #define FMAXPOWTWO      ((float)(1L << FSIGNIF - 1))
00178 #define DMAXEXP ((1 << _DEXPLEN - 1) - 1 + _IEEE)
00179 #define FMAXEXP ((1 << _FEXPLEN - 1) - 1 + _IEEE)
00180 #define LN_MAXDOUBLE    (M_LN2 * DMAXEXP)
00181 #define LN_MINDOUBLE    (M_LN2 * (DMINEXP - 1))
00182 #define H_PREC  (DSIGNIF % 2 ? (1L << DSIGNIF/2) * M_SQRT2 : 1L << DSIGNIF/2)
00183 #define X_EPS   (1.0/H_PREC)
00184 #define X_PLOSS ((double)(long)(M_PI * H_PREC))
00185 #define X_TLOSS (M_PI * DMAXPOWTWO)
00186 #define M_LN2   0.69314718055994530942
00187 #define M_PI    3.14159265358979323846
00188 #define M_SQRT2 1.41421356237309504880
00189 #define MAXBEXP DMAXEXP /* for backward compatibility */
00190 #define MINBEXP DMINEXP /* for backward compatibility */
00191 #define MAXPOWTWO       DMAXPOWTWO /* for backward compatibility */
00192 /******#include <values.h>******/
00193 
00194 extern double ldexp();
00195 
00196 #       define POW1_25LEN       7
00197 
00198 static double pow1_25[POW1_25LEN] = { 0.0 };
00199 
00200 #define STORE_PTR
00201 #define GOT_DIGIT
00202 #define RET_ZERO(val)   if (!val) return (0.0)
00203 
00204 double
00205 atof(p)
00206 register char *p;
00207 {
00208         register int c;
00209         int exp = 0, neg_val = 0;
00210         double fl_val;
00211 
00212         while (isspace(c = *p)) /* eat leading white space */
00213                 p++;
00214         switch (c) { /* process sign */
00215         case '-':
00216                 neg_val++;
00217         case '+': /* fall-through */
00218                 p++;
00219         }
00220         {       /* accumulate value */
00221                 register long high = 0, low = 0, scale = 1;
00222                 register int decpt = 0, nzeroes = 0;
00223 
00224                 while (isdigit(c = *p++) || c == '.' && !decpt++) {
00225                         if (c == '.')
00226                                 continue;
00227                         GOT_DIGIT;
00228                         if (decpt) { /* handle trailing zeroes specially */
00229                                 if (c == '0') { /* ignore zero for now */
00230                                         nzeroes++;
00231                                         continue;
00232                                 }
00233                                 while (nzeroes > 0) { /* put zeroes back in */
00234                                         exp--;
00235                                         if (high < MAXLONG/10) {
00236                                                 high *= 10;
00237                                         } else if (scale < MAXLONG/10) {
00238                                                 scale *= 10;
00239                                                 low *= 10;
00240                                         } else
00241                                                 exp++;
00242                                         nzeroes--;
00243                                 }
00244                                 exp--; /* decr exponent if decimal pt. seen */
00245                         }
00246                         if (high < MAXLONG/10) {
00247                                 high *= 10;
00248                                 high += c - '0';
00249                         } else if (scale < MAXLONG/10) {
00250                                 scale *= 10;
00251                                 low *= 10;
00252                                 low += c - '0';
00253                         } else
00254                                 exp++;
00255                 }
00256                 RET_ZERO(high);
00257                 fl_val = (double)high;
00258                 if (scale > 1)
00259                         fl_val = (double)scale * fl_val + (double)low;
00260         }
00261         STORE_PTR; /* in case there is no legitimate exponent */
00262         if (c == 'E' || c == 'e') { /* accumulate exponent */
00263                 register int e_exp = 0, neg_exp = 0;
00264 
00265                 switch (*p) { /* process sign */
00266                 case '-':
00267                         neg_exp++;
00268                 case '+': /* fall-through */
00269                 case ' ': /* many FORTRAN environments generate this! */
00270                         p++;
00271                 }
00272                 if (isdigit(c = *p)) { /* found a legitimate exponent */
00273                         do {
00274                                 /* limit outrageously large exponents */
00275                                 if (e_exp < DMAXEXP)
00276                                         e_exp = 10 * e_exp + c - '0';
00277                         } while (isdigit(c = *++p));
00278                         if (neg_exp)
00279                                 exp -= e_exp;
00280                         else
00281                                 exp += e_exp;
00282                         STORE_PTR;
00283                 }
00284         }
00285         /*
00286          * The following computation is done in two stages,
00287          * first accumulating powers of (10/8), then jamming powers of 8,
00288          * to avoid underflow in situations like the following (for
00289          * the DEC representation): 1.2345678901234567890e-37,
00290          * where exp would be about (-37 + -18) = -55, and the
00291          * value 10^(-55) can't be represented, but 1.25^(-55) can
00292          * be represented, and then 8^(-55) jammed via ldexp().
00293          */
00294         if (exp != 0) { /* apply exponent */
00295                 register double *powptr = pow1_25, fl_exp = fl_val;
00296 
00297                 if (*powptr == 0.0) { /* need to initialize table */
00298                         *powptr = 1.25;
00299                         for (; powptr < &pow1_25[POW1_25LEN - 1]; powptr++)
00300                                 powptr[1] = *powptr * *powptr;
00301                         powptr = pow1_25;
00302                 }
00303                 if ((c = exp) < 0) {
00304                         c = -c;
00305                         fl_exp = 1.0;
00306                 }
00307                 if (c > DMAXEXP/2) /* outrageously large exponents */
00308                         c = DMAXEXP/2; /* will be handled by ldexp */
00309                 for ( ; ; powptr++) {
00310                         /* binary representation of ints assumed; otherwise
00311                          * replace (& 01) by (% 2) and (>>= 1) by (/= 2) */
00312                         if (c & 01)
00313                                 fl_exp *= *powptr;
00314                         if ((c >>= 1) == 0)
00315                                 break;
00316                 }
00317                 fl_val = ldexp(exp < 0 ? fl_val/fl_exp : fl_exp, 3 * exp);
00318         }
00319         return (neg_val ? -fl_val : fl_val); /* apply sign */
00320 }
00321 
00322 /*@}*/
00323 /*
00324  * Local Variables:
00325  * mode: C
00326  * tab-width: 8
00327  * c-basic-offset: 4
00328  * indent-tabs-mode: t
00329  * End:
00330  * ex: shiftwidth=4 tabstop=8
00331  */

Generated on Mon Sep 18 01:24:57 2006 for BRL-CAD by  doxygen 1.4.6