SphinxBase  0.6
src/libsphinxbase/util/profile.c
00001 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
00002 /* ====================================================================
00003  * Copyright (c) 1999-2001 Carnegie Mellon University.  All rights
00004  * reserved.
00005  *
00006  * Redistribution and use in source and binary forms, with or without
00007  * modification, are permitted provided that the following conditions
00008  * are met:
00009  *
00010  * 1. Redistributions of source code must retain the above copyright
00011  *    notice, this list of conditions and the following disclaimer. 
00012  *
00013  * 2. Redistributions in binary form must reproduce the above copyright
00014  *    notice, this list of conditions and the following disclaimer in
00015  *    the documentation and/or other materials provided with the
00016  *    distribution.
00017  *
00018  * This work was supported in part by funding from the Defense Advanced 
00019  * Research Projects Agency and the National Science Foundation of the 
00020  * United States of America, and the CMU Sphinx Speech Consortium.
00021  *
00022  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
00023  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
00024  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
00025  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
00026  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
00027  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
00028  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
00029  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
00030  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
00031  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
00032  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
00033  *
00034  * ====================================================================
00035  *
00036  */
00037 /*
00038  * profile.c -- For timing and event counting.
00039  *
00040  * **********************************************
00041  * CMU ARPA Speech Project
00042  *
00043  * Copyright (c) 1999 Carnegie Mellon University.
00044  * ALL RIGHTS RESERVED.
00045  * **********************************************
00046  * 
00047  * HISTORY
00048  * $Log: profile.c,v $
00049  * Revision 1.7  2005/06/22 03:10:59  arthchan2003
00050  * 1, Fixed doxygen documentation, 2, Added  keyword.
00051  *
00052  * Revision 1.3  2005/03/30 01:22:48  archan
00053  * Fixed mistakes in last updates. Add
00054  *
00055  * 
00056  * 11-Mar-1999  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
00057  *              Added ptmr_init().
00058  * 
00059  * 19-Jun-97    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
00060  *              Created.
00061  */
00062 
00063 #include <config.h>
00064 
00065 #include <stdio.h>
00066 #include <stdlib.h>
00067 #include <string.h>
00068 
00069 #if defined(_WIN32) && !defined(__SYMBIAN32__)
00070 # include <windows.h>
00071 # ifndef _WIN32_WCE
00072 #  include <time.h>
00073 # endif
00074 #elif defined(HAVE_UNISTD_H) /* I know this, this is Unix... */
00075 # include <unistd.h>
00076 # include <sys/time.h>
00077 # include <sys/resource.h>
00078 #endif
00079 
00080 #ifdef _MSC_VER
00081 #pragma warning (disable: 4996)
00082 #endif
00083 
00084 #include "sphinxbase/profile.h"
00085 #include "sphinxbase/err.h"
00086 #include "sphinxbase/ckd_alloc.h"
00087 
00088 /* Silvio Moioli: updated to use Unicode */
00089 #ifdef _WIN32_WCE
00090 DWORD unlink(const char *filename)
00091 {
00092         WCHAR *wfilename;
00093         DWORD rv;
00094         size_t len;
00095 
00096         len = mbstowcs(NULL, filename, 0);
00097         wfilename = ckd_calloc(len+1, sizeof(*wfilename));
00098         mbstowcs(wfilename, filename, len);
00099         rv = DeleteFileW(wfilename);
00100         ckd_free(wfilename);
00101 
00102         return rv;
00103 }
00104 #endif
00105 
00106 pctr_t *
00107 pctr_new(char *nm)
00108 {
00109     pctr_t *pc;
00110 
00111     pc = ckd_calloc(1, sizeof(pctr_t));
00112     pc->name = ckd_salloc(nm);
00113     pc->count = 0;
00114 
00115     return pc;
00116 }
00117 
00118 void
00119 pctr_reset(pctr_t * ctr)
00120 {
00121     ctr->count = 0;
00122 }
00123 
00124 
00125 void
00126 pctr_increment(pctr_t * ctr, int32 inc)
00127 {
00128     ctr->count += inc;
00129     /*   E_INFO("Name %s, Count %d, inc %d\n",ctr->name, ctr->count, inc); */
00130 }
00131 
00132 void
00133 pctr_print(FILE * fp, pctr_t * ctr)
00134 {
00135     fprintf(fp, "CTR:");
00136     fprintf(fp, "[%d %s]", ctr->count, ctr->name);
00137 }
00138 
00139 void
00140 pctr_free(pctr_t * pc)
00141 {
00142     if (pc) {
00143         if (pc->name)
00144             ckd_free(pc->name);
00145     }
00146     ckd_free(pc);
00147 }
00148 
00149 
00150 #if defined(_WIN32) && !defined(GNUWINCE) && !defined(__SYMBIAN32__)
00151 
00152 #define TM_LOWSCALE     1e-7
00153 #define TM_HIGHSCALE    (4294967296.0 * TM_LOWSCALE);
00154 
00155 static float64
00156 make_sec(FILETIME * tm)
00157 {
00158     float64 dt;
00159 
00160     dt = tm->dwLowDateTime * TM_LOWSCALE;
00161     dt += tm->dwHighDateTime * TM_HIGHSCALE;
00162 
00163     return (dt);
00164 }
00165 
00166 #else /* NOT WINDOWS */
00167 
00168 static float64
00169 make_sec(struct timeval *s)
00170 {
00171     return (s->tv_sec + s->tv_usec * 0.000001);
00172 }
00173 
00174 #endif
00175 
00176 
00177 void
00178 ptmr_start(ptmr_t * tm)
00179 {
00180 #if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
00181     struct timeval e_start;     /* Elapsed time */
00182 
00183 #if (! defined(_HPUX_SOURCE))  && (! defined(__SYMBIAN32__))
00184     struct rusage start;        /* CPU time */
00185 
00186     /* Unix but not HPUX */
00187     getrusage(RUSAGE_SELF, &start);
00188     tm->start_cpu = make_sec(&start.ru_utime) + make_sec(&start.ru_stime);
00189 #endif
00190     /* Unix + HP */
00191     gettimeofday(&e_start, 0);
00192     tm->start_elapsed = make_sec(&e_start);
00193 #elif defined(_WIN32_WCE)
00194     /* No GetProcessTimes() on WinCE.  (Note CPU time will be bogus) */
00195     tm->start_cpu = GetTickCount() / 1000;
00196     tm->start_elapsed = GetTickCount() / 1000;
00197 #else
00198     HANDLE pid;
00199     FILETIME t_create, t_exit, kst, ust;
00200 
00201     /* PC */
00202     pid = GetCurrentProcess();
00203     GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
00204     tm->start_cpu = make_sec(&ust) + make_sec(&kst);
00205 
00206     tm->start_elapsed = (float64) clock() / CLOCKS_PER_SEC;
00207 #endif
00208 }
00209 
00210 
00211 void
00212 ptmr_stop(ptmr_t * tm)
00213 {
00214     float64 dt_cpu, dt_elapsed;
00215 
00216 #if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
00217     struct timeval e_stop;      /* Elapsed time */
00218 
00219 #if (! defined(_HPUX_SOURCE))  && (! defined(__SYMBIAN32__))
00220     struct rusage stop;         /* CPU time */
00221 
00222     /* Unix but not HPUX */
00223     getrusage(RUSAGE_SELF, &stop);
00224     dt_cpu =
00225         make_sec(&stop.ru_utime) + make_sec(&stop.ru_stime) -
00226         tm->start_cpu;
00227 #else
00228     dt_cpu = 0.0;
00229 #endif
00230     /* Unix + HP */
00231     gettimeofday(&e_stop, 0);
00232     dt_elapsed = (make_sec(&e_stop) - tm->start_elapsed);
00233 #elif defined(_WIN32_WCE)
00234         /* No GetProcessTimes() on WinCE.  (Note CPU time will be bogus) */
00235         dt_cpu = GetTickCount() / 1000 - tm->start_cpu;
00236         dt_elapsed = GetTickCount() / 1000 - tm->start_elapsed;
00237 #else
00238     HANDLE pid;
00239     FILETIME t_create, t_exit, kst, ust;
00240 
00241     /* PC */
00242     pid = GetCurrentProcess();
00243     GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
00244     dt_cpu = make_sec(&ust) + make_sec(&kst) - tm->start_cpu;
00245     dt_elapsed = ((float64) clock() / CLOCKS_PER_SEC) - tm->start_elapsed;
00246 #endif
00247 
00248     tm->t_cpu += dt_cpu;
00249     tm->t_elapsed += dt_elapsed;
00250 
00251     tm->t_tot_cpu += dt_cpu;
00252     tm->t_tot_elapsed += dt_elapsed;
00253 }
00254 
00255 
00256 void
00257 ptmr_reset(ptmr_t * tm)
00258 {
00259     tm->t_cpu = 0.0;
00260     tm->t_elapsed = 0.0;
00261 }
00262 
00263 
00264 void
00265 ptmr_init(ptmr_t * tm)
00266 {
00267     tm->t_cpu = 0.0;
00268     tm->t_elapsed = 0.0;
00269     tm->t_tot_cpu = 0.0;
00270     tm->t_tot_elapsed = 0.0;
00271 }
00272 
00273 
00274 void
00275 ptmr_reset_all(ptmr_t * tm)
00276 {
00277     for (; tm->name; tm++)
00278         ptmr_reset(tm);
00279 }
00280 
00281 
00282 void
00283 ptmr_print_all(FILE * fp, ptmr_t * tm, float64 norm)
00284 {
00285     if (norm != 0.0) {
00286         norm = 1.0 / norm;
00287         for (; tm->name; tm++)
00288             fprintf(fp, "  %6.2fx %s", tm->t_cpu * norm, tm->name);
00289     }
00290 }
00291 
00292 
00293 int32
00294 host_endian(void)
00295 {
00296     FILE *fp;
00297     int32 BYTE_ORDER_MAGIC;
00298     char *file;
00299     char buf[8];
00300     int32 k, endian;
00301 
00302     file = "/tmp/__EnDiAn_TeSt__";
00303 
00304     if ((fp = fopen(file, "wb")) == NULL) {
00305         E_ERROR("Failed to open file '%s' for writing: %s\n", file, strerror(errno));
00306         return -1;
00307     }
00308 
00309     BYTE_ORDER_MAGIC = (int32) 0x11223344;
00310 
00311     k = (int32) BYTE_ORDER_MAGIC;
00312     if (fwrite(&k, sizeof(int32), 1, fp) != 1) {
00313         E_ERROR("Failed to write to file '%s'\n", file);
00314         fclose(fp);
00315         unlink(file);
00316         return -1;
00317     }
00318 
00319     fclose(fp);
00320     if ((fp = fopen(file, "rb")) == NULL) {
00321         E_ERROR("Failed to open file '%s' for reading: %s\n", file, strerror(errno));
00322         unlink(file);
00323         return -1;
00324     }
00325     if (fread(buf, 1, sizeof(int32), fp) != sizeof(int32)) {
00326         E_ERROR("Failed to read from file '%s'\n", file);
00327         fclose(fp);
00328         unlink(file);
00329         return -1;
00330     }
00331     fclose(fp);
00332     unlink(file);
00333 
00334     /* If buf[0] == lsB of BYTE_ORDER_MAGIC, we are little-endian */
00335     endian = (buf[0] == (BYTE_ORDER_MAGIC & 0x000000ff)) ? 1 : 0;
00336 
00337     return (endian);
00338 }