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