Initial import to Tizen
[profile/ivi/sphinxbase.git] / src / libsphinxbase / util / profile.c
1 /* -*- c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ====================================================================
3  * Copyright (c) 1999-2001 Carnegie Mellon University.  All rights
4  * reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  *
10  * 1. Redistributions of source code must retain the above copyright
11  *    notice, this list of conditions and the following disclaimer. 
12  *
13  * 2. Redistributions in binary form must reproduce the above copyright
14  *    notice, this list of conditions and the following disclaimer in
15  *    the documentation and/or other materials provided with the
16  *    distribution.
17  *
18  * This work was supported in part by funding from the Defense Advanced 
19  * Research Projects Agency and the National Science Foundation of the 
20  * United States of America, and the CMU Sphinx Speech Consortium.
21  *
22  * THIS SOFTWARE IS PROVIDED BY CARNEGIE MELLON UNIVERSITY ``AS IS'' AND 
23  * ANY EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 
24  * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
25  * PURPOSE ARE DISCLAIMED.  IN NO EVENT SHALL CARNEGIE MELLON UNIVERSITY
26  * NOR ITS EMPLOYEES BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
27  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT 
28  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 
29  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 
30  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 
31  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE 
32  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
33  *
34  * ====================================================================
35  *
36  */
37 /*
38  * profile.c -- For timing and event counting.
39  *
40  * **********************************************
41  * CMU ARPA Speech Project
42  *
43  * Copyright (c) 1999 Carnegie Mellon University.
44  * ALL RIGHTS RESERVED.
45  * **********************************************
46  * 
47  * HISTORY
48  * $Log: profile.c,v $
49  * Revision 1.7  2005/06/22 03:10:59  arthchan2003
50  * 1, Fixed doxygen documentation, 2, Added  keyword.
51  *
52  * Revision 1.3  2005/03/30 01:22:48  archan
53  * Fixed mistakes in last updates. Add
54  *
55  * 
56  * 11-Mar-1999  M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
57  *              Added ptmr_init().
58  * 
59  * 19-Jun-97    M K Ravishankar (rkm@cs.cmu.edu) at Carnegie Mellon University
60  *              Created.
61  */
62
63 #include <config.h>
64
65 #include <stdio.h>
66 #include <stdlib.h>
67 #include <string.h>
68
69 #if defined(_WIN32) && !defined(__SYMBIAN32__)
70 # include <windows.h>
71 # ifndef _WIN32_WCE
72 #  include <time.h>
73 # endif
74 #elif defined(HAVE_UNISTD_H) /* I know this, this is Unix... */
75 # include <unistd.h>
76 # include <sys/time.h>
77 # include <sys/resource.h>
78 #endif
79
80 #ifdef _MSC_VER
81 #pragma warning (disable: 4996)
82 #endif
83
84 #include "sphinxbase/profile.h"
85 #include "sphinxbase/err.h"
86 #include "sphinxbase/ckd_alloc.h"
87
88 /* Silvio Moioli: updated to use Unicode */
89 #ifdef _WIN32_WCE
90 DWORD unlink(const char *filename)
91 {
92         WCHAR *wfilename;
93         DWORD rv;
94         size_t len;
95
96         len = mbstowcs(NULL, filename, 0);
97         wfilename = ckd_calloc(len+1, sizeof(*wfilename));
98         mbstowcs(wfilename, filename, len);
99         rv = DeleteFileW(wfilename);
100         ckd_free(wfilename);
101
102         return rv;
103 }
104 #endif
105
106 pctr_t *
107 pctr_new(char *nm)
108 {
109     pctr_t *pc;
110
111     pc = ckd_calloc(1, sizeof(pctr_t));
112     pc->name = ckd_salloc(nm);
113     pc->count = 0;
114
115     return pc;
116 }
117
118 void
119 pctr_reset(pctr_t * ctr)
120 {
121     ctr->count = 0;
122 }
123
124
125 void
126 pctr_increment(pctr_t * ctr, int32 inc)
127 {
128     ctr->count += inc;
129     /*   E_INFO("Name %s, Count %d, inc %d\n",ctr->name, ctr->count, inc); */
130 }
131
132 void
133 pctr_print(FILE * fp, pctr_t * ctr)
134 {
135     fprintf(fp, "CTR:");
136     fprintf(fp, "[%d %s]", ctr->count, ctr->name);
137 }
138
139 void
140 pctr_free(pctr_t * pc)
141 {
142     if (pc) {
143         if (pc->name)
144             ckd_free(pc->name);
145     }
146     ckd_free(pc);
147 }
148
149
150 #if defined(_WIN32) && !defined(GNUWINCE) && !defined(__SYMBIAN32__)
151
152 #define TM_LOWSCALE     1e-7
153 #define TM_HIGHSCALE    (4294967296.0 * TM_LOWSCALE);
154
155 static float64
156 make_sec(FILETIME * tm)
157 {
158     float64 dt;
159
160     dt = tm->dwLowDateTime * TM_LOWSCALE;
161     dt += tm->dwHighDateTime * TM_HIGHSCALE;
162
163     return (dt);
164 }
165
166 #else /* NOT WINDOWS */
167
168 static float64
169 make_sec(struct timeval *s)
170 {
171     return (s->tv_sec + s->tv_usec * 0.000001);
172 }
173
174 #endif
175
176
177 void
178 ptmr_start(ptmr_t * tm)
179 {
180 #if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
181     struct timeval e_start;     /* Elapsed time */
182
183 #if (! defined(_HPUX_SOURCE))  && (! defined(__SYMBIAN32__))
184     struct rusage start;        /* CPU time */
185
186     /* Unix but not HPUX */
187     getrusage(RUSAGE_SELF, &start);
188     tm->start_cpu = make_sec(&start.ru_utime) + make_sec(&start.ru_stime);
189 #endif
190     /* Unix + HP */
191     gettimeofday(&e_start, 0);
192     tm->start_elapsed = make_sec(&e_start);
193 #elif defined(_WIN32_WCE)
194     /* No GetProcessTimes() on WinCE.  (Note CPU time will be bogus) */
195     tm->start_cpu = GetTickCount() / 1000;
196     tm->start_elapsed = GetTickCount() / 1000;
197 #else
198     HANDLE pid;
199     FILETIME t_create, t_exit, kst, ust;
200
201     /* PC */
202     pid = GetCurrentProcess();
203     GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
204     tm->start_cpu = make_sec(&ust) + make_sec(&kst);
205
206     tm->start_elapsed = (float64) clock() / CLOCKS_PER_SEC;
207 #endif
208 }
209
210
211 void
212 ptmr_stop(ptmr_t * tm)
213 {
214     float64 dt_cpu, dt_elapsed;
215
216 #if (! defined(_WIN32)) || defined(GNUWINCE) || defined(__SYMBIAN32__)
217     struct timeval e_stop;      /* Elapsed time */
218
219 #if (! defined(_HPUX_SOURCE))  && (! defined(__SYMBIAN32__))
220     struct rusage stop;         /* CPU time */
221
222     /* Unix but not HPUX */
223     getrusage(RUSAGE_SELF, &stop);
224     dt_cpu =
225         make_sec(&stop.ru_utime) + make_sec(&stop.ru_stime) -
226         tm->start_cpu;
227 #else
228     dt_cpu = 0.0;
229 #endif
230     /* Unix + HP */
231     gettimeofday(&e_stop, 0);
232     dt_elapsed = (make_sec(&e_stop) - tm->start_elapsed);
233 #elif defined(_WIN32_WCE)
234         /* No GetProcessTimes() on WinCE.  (Note CPU time will be bogus) */
235         dt_cpu = GetTickCount() / 1000 - tm->start_cpu;
236         dt_elapsed = GetTickCount() / 1000 - tm->start_elapsed;
237 #else
238     HANDLE pid;
239     FILETIME t_create, t_exit, kst, ust;
240
241     /* PC */
242     pid = GetCurrentProcess();
243     GetProcessTimes(pid, &t_create, &t_exit, &kst, &ust);
244     dt_cpu = make_sec(&ust) + make_sec(&kst) - tm->start_cpu;
245     dt_elapsed = ((float64) clock() / CLOCKS_PER_SEC) - tm->start_elapsed;
246 #endif
247
248     tm->t_cpu += dt_cpu;
249     tm->t_elapsed += dt_elapsed;
250
251     tm->t_tot_cpu += dt_cpu;
252     tm->t_tot_elapsed += dt_elapsed;
253 }
254
255
256 void
257 ptmr_reset(ptmr_t * tm)
258 {
259     tm->t_cpu = 0.0;
260     tm->t_elapsed = 0.0;
261 }
262
263
264 void
265 ptmr_init(ptmr_t * tm)
266 {
267     tm->t_cpu = 0.0;
268     tm->t_elapsed = 0.0;
269     tm->t_tot_cpu = 0.0;
270     tm->t_tot_elapsed = 0.0;
271 }
272
273
274 void
275 ptmr_reset_all(ptmr_t * tm)
276 {
277     for (; tm->name; tm++)
278         ptmr_reset(tm);
279 }
280
281
282 void
283 ptmr_print_all(FILE * fp, ptmr_t * tm, float64 norm)
284 {
285     if (norm != 0.0) {
286         norm = 1.0 / norm;
287         for (; tm->name; tm++)
288             fprintf(fp, "  %6.2fx %s", tm->t_cpu * norm, tm->name);
289     }
290 }
291
292
293 int32
294 host_endian(void)
295 {
296     FILE *fp;
297     int32 BYTE_ORDER_MAGIC;
298     char *file;
299     char buf[8];
300     int32 k, endian;
301
302     file = "/tmp/__EnDiAn_TeSt__";
303
304     if ((fp = fopen(file, "wb")) == NULL) {
305         E_ERROR("Failed to open file '%s' for writing: %s\n", file, strerror(errno));
306         return -1;
307     }
308
309     BYTE_ORDER_MAGIC = (int32) 0x11223344;
310
311     k = (int32) BYTE_ORDER_MAGIC;
312     if (fwrite(&k, sizeof(int32), 1, fp) != 1) {
313         E_ERROR("Failed to write to file '%s'\n", file);
314         fclose(fp);
315         unlink(file);
316         return -1;
317     }
318
319     fclose(fp);
320     if ((fp = fopen(file, "rb")) == NULL) {
321         E_ERROR("Failed to open file '%s' for reading: %s\n", file, strerror(errno));
322         unlink(file);
323         return -1;
324     }
325     if (fread(buf, 1, sizeof(int32), fp) != sizeof(int32)) {
326         E_ERROR("Failed to read from file '%s'\n", file);
327         fclose(fp);
328         unlink(file);
329         return -1;
330     }
331     fclose(fp);
332     unlink(file);
333
334     /* If buf[0] == lsB of BYTE_ORDER_MAGIC, we are little-endian */
335     endian = (buf[0] == (BYTE_ORDER_MAGIC & 0x000000ff)) ? 1 : 0;
336
337     return (endian);
338 }