]> granicus.if.org Git - imagemagick/blob - MagickCore/timer.c
(no commit message)
[imagemagick] / MagickCore / timer.c
1 /*
2 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
3 %                                                                             %
4 %                                                                             %
5 %                                                                             %
6 %                    TTTTT  IIIII  M   M  EEEEE  RRRR                         %
7 %                      T      I    MM MM  E      R   R                        %
8 %                      T      I    M M M  EEE    RRRR                         %
9 %                      T      I    M   M  E      R R                          %
10 %                      T    IIIII  M   M  EEEEE  R  R                         %
11 %                                                                             %
12 %                                                                             %
13 %                         MagickCore Timing Methods                           %
14 %                                                                             %
15 %                             Software Design                                 %
16 %                                  Cristy                                     %
17 %                              January 1993                                   %
18 %                                                                             %
19 %                                                                             %
20 %  Copyright 1999-2014 ImageMagick Studio LLC, a non-profit organization      %
21 %  dedicated to making software imaging solutions freely available.           %
22 %                                                                             %
23 %  You may not use this file except in compliance with the License.  You may  %
24 %  obtain a copy of the License at                                            %
25 %                                                                             %
26 %    http://www.imagemagick.org/script/license.php                            %
27 %                                                                             %
28 %  Unless required by applicable law or agreed to in writing, software        %
29 %  distributed under the License is distributed on an "AS IS" BASIS,          %
30 %  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.   %
31 %  See the License for the specific language governing permissions and        %
32 %  limitations under the License.                                             %
33 %                                                                             %
34 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
35 %
36 %  Contributed by Bill Radcliffe and Bob Friesenhahn.
37 %
38 */
39 \f
40 /*
41   Include declarations.
42 */
43 #include "MagickCore/studio.h"
44 #include "MagickCore/exception.h"
45 #include "MagickCore/exception-private.h"
46 #include "MagickCore/log.h"
47 #include "MagickCore/memory_.h"
48 #include "MagickCore/nt-base-private.h"
49 #include "MagickCore/timer.h"
50 \f
51 /*
52   Define declarations.
53 */
54 #if !defined(CLOCKS_PER_SEC)
55 #define CLOCKS_PER_SEC  100
56 #endif
57 \f
58 /*
59   Forward declarations.
60 */
61 static double
62   UserTime(void);
63
64 static void
65   StopTimer(TimerInfo *);
66 \f
67 /*
68 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
69 %                                                                             %
70 %                                                                             %
71 %                                                                             %
72 %   A c q u i r e T i m e r I n f o                                           %
73 %                                                                             %
74 %                                                                             %
75 %                                                                             %
76 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
77 %
78 %  AcquireTimerInfo() initializes the TimerInfo structure.  It effectively
79 %  creates a stopwatch and starts it.
80 %
81 %  The format of the AcquireTimerInfo method is:
82 %
83 %      TimerInfo *AcquireTimerInfo(void)
84 %
85 */
86 MagickExport TimerInfo *AcquireTimerInfo(void)
87 {
88   TimerInfo
89     *timer_info;
90
91   timer_info=(TimerInfo *) AcquireMagickMemory(sizeof(*timer_info));
92   if (timer_info == (TimerInfo *) NULL)
93     ThrowFatalException(ResourceLimitFatalError,"UnableToAcquireString");
94   (void) ResetMagickMemory(timer_info,0,sizeof(*timer_info));
95   timer_info->signature=MagickSignature;
96   GetTimerInfo(timer_info);
97   return(timer_info);
98 }
99 \f
100 /*
101 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
102 %                                                                             %
103 %                                                                             %
104 %                                                                             %
105 %   C o n t i n u e T i m e r                                                 %
106 %                                                                             %
107 %                                                                             %
108 %                                                                             %
109 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
110 %
111 %  ContinueTimer() resumes a stopped stopwatch. The stopwatch continues
112 %  counting from the last StartTimer() onwards.
113 %
114 %  The format of the ContinueTimer method is:
115 %
116 %      MagickBooleanType ContinueTimer(TimerInfo *time_info)
117 %
118 %  A description of each parameter follows.
119 %
120 %    o  time_info: Time statistics structure.
121 %
122 */
123 MagickExport MagickBooleanType ContinueTimer(TimerInfo *time_info)
124 {
125   assert(time_info != (TimerInfo *) NULL);
126   assert(time_info->signature == MagickSignature);
127   if (time_info->state == UndefinedTimerState)
128     return(MagickFalse);
129   if (time_info->state == StoppedTimerState)
130     {
131       time_info->user.total-=time_info->user.stop-time_info->user.start;
132       time_info->elapsed.total-=time_info->elapsed.stop-
133         time_info->elapsed.start;
134     }
135   time_info->state=RunningTimerState;
136   return(MagickTrue);
137 }
138 \f
139 /*
140 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
141 %                                                                             %
142 %                                                                             %
143 %                                                                             %
144 %   D e s t r o y T i m e r I n f o                                           %
145 %                                                                             %
146 %                                                                             %
147 %                                                                             %
148 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149 %
150 %  DestroyTimerInfo() zeros memory associated with the TimerInfo structure.
151 %
152 %  The format of the DestroyTimerInfo method is:
153 %
154 %      TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
155 %
156 %  A description of each parameter follows:
157 %
158 %    o timer_info: The cipher context.
159 %
160 */
161 MagickExport TimerInfo *DestroyTimerInfo(TimerInfo *timer_info)
162 {
163   assert(timer_info != (TimerInfo *) NULL);
164   assert(timer_info->signature == MagickSignature);
165   timer_info->signature=(~MagickSignature);
166   timer_info=(TimerInfo *) RelinquishMagickMemory(timer_info);
167   return(timer_info);
168 }
169 \f
170 /*
171 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
172 %                                                                             %
173 %                                                                             %
174 %                                                                             %
175 +   E l a p s e d T i m e                                                     %
176 %                                                                             %
177 %                                                                             %
178 %                                                                             %
179 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
180 %
181 %  ElapsedTime() returns the elapsed time (in seconds) since the last call to
182 %  StartTimer().
183 %
184 %  The format of the ElapsedTime method is:
185 %
186 %      double ElapsedTime()
187 %
188 */
189 static double ElapsedTime(void)
190 {
191 #if defined(MAGICKCORE_HAVE_TIMES)
192   struct tms
193     timer;
194
195   return((double) times(&timer)/CLOCKS_PER_SEC);
196 #else
197 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
198   return(NTElapsedTime());
199 #else
200   return((double) clock()/CLOCKS_PER_SEC);
201 #endif
202 #endif
203 }
204 \f
205 /*
206 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
207 %                                                                             %
208 %                                                                             %
209 %                                                                             %
210 %   G e t E l a p s e d T i m e                                               %
211 %                                                                             %
212 %                                                                             %
213 %                                                                             %
214 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
215 %
216 %  GetElapsedTime() returns the elapsed time (in seconds) passed between the
217 %  start and stop events. If the stopwatch is still running, it is stopped
218 %  first.
219 %
220 %  The format of the GetElapsedTime method is:
221 %
222 %      double GetElapsedTime(TimerInfo *time_info)
223 %
224 %  A description of each parameter follows.
225 %
226 %    o  time_info: Timer statistics structure.
227 %
228 */
229 MagickExport double GetElapsedTime(TimerInfo *time_info)
230 {
231   assert(time_info != (TimerInfo *) NULL);
232   assert(time_info->signature == MagickSignature);
233   if (time_info->state == UndefinedTimerState)
234     return(0.0);
235   if (time_info->state == RunningTimerState)
236     StopTimer(time_info);
237   return(time_info->elapsed.total);
238 }
239 \f
240 /*
241 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
242 %                                                                             %
243 %                                                                             %
244 %                                                                             %
245 +   G e t T i m e r I n f o                                                   %
246 %                                                                             %
247 %                                                                             %
248 %                                                                             %
249 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
250 %
251 %  GetTimerInfo() initializes the TimerInfo structure.
252 %
253 %  The format of the GetTimerInfo method is:
254 %
255 %      void GetTimerInfo(TimerInfo *time_info)
256 %
257 %  A description of each parameter follows.
258 %
259 %    o  time_info: Timer statistics structure.
260 %
261 */
262 MagickExport void GetTimerInfo(TimerInfo *time_info)
263 {
264   /*
265     Create a stopwatch and start it.
266   */
267   assert(time_info != (TimerInfo *) NULL);
268   (void) ResetMagickMemory(time_info,0,sizeof(*time_info));
269   time_info->state=UndefinedTimerState;
270   time_info->signature=MagickSignature;
271   StartTimer(time_info,MagickTrue);
272 }
273 \f
274 /*
275 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
276 %                                                                             %
277 %                                                                             %
278 %                                                                             %
279 %   G e t U s e r T i m e                                                     %
280 %                                                                             %
281 %                                                                             %
282 %                                                                             %
283 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
284 %
285 %  GetUserTime() returns the User time (user and system) by the operating
286 %  system (in seconds) between the start and stop events. If the stopwatch is
287 %  still running, it is stopped first.
288 %
289 %  The format of the GetUserTime method is:
290 %
291 %      double GetUserTime(TimerInfo *time_info)
292 %
293 %  A description of each parameter follows.
294 %
295 %    o  time_info: Timer statistics structure.
296 %
297 */
298 MagickExport double GetUserTime(TimerInfo *time_info)
299 {
300   assert(time_info != (TimerInfo *) NULL);
301   assert(time_info->signature == MagickSignature);
302   if (time_info->state == UndefinedTimerState)
303     return(0.0);
304   if (time_info->state == RunningTimerState)
305     StopTimer(time_info);
306   return(time_info->user.total);
307 }
308 \f
309 /*
310 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
311 %                                                                             %
312 %                                                                             %
313 %                                                                             %
314 %   R e s e t T i m e r                                                       %
315 %                                                                             %
316 %                                                                             %
317 %                                                                             %
318 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
319 %
320 %  ResetTimer() resets the stopwatch.
321 %
322 %  The format of the ResetTimer method is:
323 %
324 %      void ResetTimer(TimerInfo *time_info)
325 %
326 %  A description of each parameter follows.
327 %
328 %    o  time_info: Timer statistics structure.
329 %
330 */
331 MagickExport void ResetTimer(TimerInfo *time_info)
332 {
333   assert(time_info != (TimerInfo *) NULL);
334   assert(time_info->signature == MagickSignature);
335   StopTimer(time_info);
336   time_info->elapsed.stop=0.0;
337   time_info->user.stop=0.0;
338 }
339 \f
340 /*
341 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
342 %                                                                             %
343 %                                                                             %
344 %                                                                             %
345 +   S t a r t T i m e r                                                       %
346 %                                                                             %
347 %                                                                             %
348 %                                                                             %
349 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
350 %
351 %  StartTimer() starts the stopwatch.
352 %
353 %  The format of the StartTimer method is:
354 %
355 %      void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
356 %
357 %  A description of each parameter follows.
358 %
359 %    o  time_info: Timer statistics structure.
360 %
361 %    o  reset: If reset is MagickTrue, then the stopwatch is reset prior to
362 %       starting.  If reset is MagickFalse, then timing is continued without
363 %       resetting the stopwatch.
364 %
365 */
366 MagickExport void StartTimer(TimerInfo *time_info,const MagickBooleanType reset)
367 {
368   assert(time_info != (TimerInfo *) NULL);
369   assert(time_info->signature == MagickSignature);
370   if (reset != MagickFalse)
371     {
372       /*
373         Reset the stopwatch before starting it.
374       */
375       time_info->user.total=0.0;
376       time_info->elapsed.total=0.0;
377     }
378   if (time_info->state != RunningTimerState)
379     {
380       time_info->elapsed.start=ElapsedTime();
381       time_info->user.start=UserTime();
382     }
383   time_info->state=RunningTimerState;
384 }
385 \f
386 /*
387 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
388 %                                                                             %
389 %                                                                             %
390 %                                                                             %
391 +   S t o p T i m e r                                                         %
392 %                                                                             %
393 %                                                                             %
394 %                                                                             %
395 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
396 %
397 %  StopTimer() stops the stopwatch.
398 %
399 %  The format of the StopTimer method is:
400 %
401 %      void StopTimer(TimerInfo *time_info)
402 %
403 %  A description of each parameter follows.
404 %
405 %    o  time_info: Timer statistics structure.
406 %
407 */
408 static void StopTimer(TimerInfo *time_info)
409 {
410   assert(time_info != (TimerInfo *) NULL);
411   assert(time_info->signature == MagickSignature);
412   time_info->elapsed.stop=ElapsedTime();
413   time_info->user.stop=UserTime();
414   if (time_info->state == RunningTimerState)
415     {
416       time_info->user.total+=time_info->user.stop-
417         time_info->user.start+MagickEpsilon;
418       time_info->elapsed.total+=time_info->elapsed.stop-
419         time_info->elapsed.start+MagickEpsilon;
420     }
421   time_info->state=StoppedTimerState;
422 }
423 \f
424 /*
425 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
426 %                                                                             %
427 %                                                                             %
428 %                                                                             %
429 +   U s e r T i m e                                                           %
430 %                                                                             %
431 %                                                                             %
432 %                                                                             %
433 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
434 %
435 %  UserTime() returns the total time the process has been scheduled (in
436 %  seconds) since the last call to StartTimer().
437 %
438 %  The format of the UserTime method is:
439 %
440 %      double UserTime()
441 %
442 */
443 static double UserTime(void)
444 {
445 #if defined(MAGICKCORE_HAVE_TIMES)
446   struct tms
447     timer;
448
449   (void) times(&timer);
450   return((double) (timer.tms_utime+timer.tms_stime)/CLOCKS_PER_SEC);
451 #else
452 #if defined(MAGICKCORE_WINDOWS_SUPPORT)
453   return(NTUserTime());
454 #else
455   return((double) clock()/CLOCKS_PER_SEC);
456 #endif
457 #endif
458 }