Coverage Report

Created: 2026-10-28 07:26

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/graphicsmagick/magick/timer.c
Line
Count
Source
1
/*
2
% Copyright (C) 2003-2020 GraphicsMagick Group
3
% Copyright (C) 2002 ImageMagick Studio
4
% SPDX-License-Identifier: MIT
5
%
6
% This program is covered by multiple licenses, which are described in
7
% Copyright.txt. You should have received a copy of Copyright.txt with this
8
% package; otherwise see http://www.graphicsmagick.org/www/Copyright.html.
9
%
10
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
11
%                                                                             %
12
%                                                                             %
13
%                                                                             %
14
%                    TTTTT  IIIII  M   M  EEEEE  RRRR                         %
15
%                      T      I    MM MM  E      R   R                        %
16
%                      T      I    M M M  EEE    RRRR                         %
17
%                      T      I    M   M  E      R R                          %
18
%                      T    IIIII  M   M  EEEEE  R  R                         %
19
%                                                                             %
20
%                                                                             %
21
%                      GraphicsMagick Timing Methods                          %
22
%                                                                             %
23
%                                                                             %
24
%                             Software Design                                 %
25
%                               John Cristy                                   %
26
%                              January 1993                                   %
27
%                                                                             %
28
%                                                                             %
29
%                                                                             %
30
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
31
%
32
%  Contributed by Bill Radcliffe and Bob Friesenhahn.
33
%
34
*/
35

36
/*
37
  Include declarations.
38
*/
39
#include "magick/studio.h"
40

41
/*
42
  Define declarations.
43
*/
44
#if !defined(CLK_TCK)
45
31.5M
#  define CLK_TCK  sysconf(_SC_CLK_TCK)
46
#endif
47
#if defined(HAVE_CLOCK_GETTIME)
48
31.5M
#  define NANOSECONDS_PER_SECOND 1000000000.0
49
#  if defined(CLOCK_HIGHRES) /* Solaris */
50
#    define CLOCK_ID CLOCK_HIGHRES
51
#  elif defined(CLOCK_MONOTONIC_RAW) /* Linux */
52
31.5M
#    define CLOCK_ID CLOCK_MONOTONIC_RAW
53
#  elif defined(CLOCK_MONOTONIC_PRECISE) /* FreeBSD */
54
#    define CLOCK_ID CLOCK_MONOTONIC_PRECISE
55
#  elif defined(CLOCK_MONOTONIC) /* Linux & FreeBSD */
56
#    define CLOCK_ID CLOCK_MONOTONIC
57
#  else
58
#    define CLOCK_ID CLOCK_REALTIME /* Fallback */
59
#  endif
60
#endif
61

62
/*
63
  Forward declarations.
64
*/
65
static double
66
  UserTime(void);
67

68
/*
69
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
70
%                                                                             %
71
%                                                                             %
72
%                                                                             %
73
%   C o n t i n u e T i m e r                                                 %
74
%                                                                             %
75
%                                                                             %
76
%                                                                             %
77
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
78
%
79
%  Method ContinueTimer resumes a stopped stopwatch. The stopwatch continues
80
%  counting from the last StartTimer() onwards.
81
%
82
%  The format of the ContinueTimer method is:
83
%
84
%      unsigned int ContinueTimer(TimerInfo *time_info)
85
%
86
%  A description of each parameter follows.
87
%
88
%    o  time_info: Time statistics structure.
89
%
90
*/
91
MagickExport unsigned int ContinueTimer(TimerInfo *time_info)
92
13.6M
{
93
13.6M
  assert(time_info != (TimerInfo *) NULL);
94
13.6M
  assert(time_info->signature == MagickSignature);
95
13.6M
  if (time_info->state == UndefinedTimerState)
96
0
    return(False);
97
13.6M
  if (time_info->state == StoppedTimerState)
98
13.6M
    {
99
13.6M
      time_info->user.total-=time_info->user.stop-time_info->user.start;
100
13.6M
      time_info->elapsed.total-=
101
13.6M
        time_info->elapsed.stop-time_info->elapsed.start;
102
13.6M
    }
103
13.6M
  time_info->state=RunningTimerState;
104
13.6M
  return(True);
105
13.6M
}
106

107
/*
108
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
109
%                                                                             %
110
%                                                                             %
111
%                                                                             %
112
+   E l a p s e d T i m e                                                     %
113
%                                                                             %
114
%                                                                             %
115
%                                                                             %
116
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
117
%
118
%  Method ElapsedTime returns the elapsed time (in seconds) since the last
119
%  call to StartTimer().
120
%
121
%  The format of the ElapsedTime method is:
122
%
123
%      double ElapsedTime()
124
%
125
*/
126
static double ElapsedTime(void)
127
31.5M
{
128
31.5M
#if defined(HAVE_CLOCK_GETTIME)
129
31.5M
  struct timespec timer;
130
31.5M
  (void) clock_gettime(CLOCK_ID, &timer);
131
132
31.5M
  return((double) timer.tv_sec + timer.tv_nsec/NANOSECONDS_PER_SECOND);
133
#elif defined(HAVE_TIMES)
134
  struct tms
135
    timer;
136
137
  return((double) times(&timer)/CLK_TCK);
138
#else
139
#if defined(MSWINDOWS)
140
  return(NTElapsedTime());
141
#else
142
  return((double) clock()/CLK_TCK);
143
#endif
144
#endif
145
31.5M
}
146

147
/*
148
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
149
%                                                                             %
150
%                                                                             %
151
%                                                                             %
152
%   G e t E l a p s e d T i m e                                               %
153
%                                                                             %
154
%                                                                             %
155
%                                                                             %
156
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
157
%
158
%  Method GetElapsedTime returns the elapsed time (in seconds) passed between
159
%  the start and stop events. If the stopwatch is still running, it is stopped
160
%  first.
161
%
162
%  The format of the GetElapsedTime method is:
163
%
164
%      double GetElapsedTime(TimerInfo *time_info)
165
%
166
%  A description of each parameter follows.
167
%
168
%    o  time_info: Timer statistics structure.
169
%
170
*/
171
MagickExport double GetElapsedTime(TimerInfo *time_info)
172
13.6M
{
173
13.6M
  assert(time_info != (TimerInfo *) NULL);
174
13.6M
  assert(time_info->signature == MagickSignature);
175
13.6M
  if (time_info->state == UndefinedTimerState)
176
0
    return(0.0);
177
13.6M
  if (time_info->state == RunningTimerState)
178
13.6M
    StopTimer(time_info);
179
13.6M
  return(time_info->elapsed.total);
180
13.6M
}
181

182
/*
183
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
184
%                                                                             %
185
%                                                                             %
186
%                                                                             %
187
%   G e t T i m e r I n f o                                                   %
188
%                                                                             %
189
%                                                                             %
190
%                                                                             %
191
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
192
%
193
%  Method GetTimerInfo initializes the TimerInfo structure.
194
%
195
%  The format of the GetTimerInfo method is:
196
%
197
%      void GetTimerInfo(TimerInfo *time_info)
198
%
199
%  A description of each parameter follows.
200
%
201
%    o  time_info: Timer statistics structure.
202
%
203
*/
204
MagickExport void GetTimerInfo(TimerInfo *time_info)
205
17.1M
{
206
  /*
207
    Create a stopwatch and start it.
208
  */
209
17.1M
  assert(time_info != (TimerInfo *) NULL);
210
17.1M
  (void) memset(time_info,0,sizeof(TimerInfo));
211
17.1M
  time_info->state=UndefinedTimerState;
212
17.1M
  time_info->signature=MagickSignature;
213
17.1M
  StartTimer(time_info,True);
214
17.1M
}
215

216
/*
217
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
218
%                                                                             %
219
%                                                                             %
220
%                                                                             %
221
%   G e t T i m e r R e s o l u t i o n                                       %
222
%                                                                             %
223
%                                                                             %
224
%                                                                             %
225
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
226
%
227
%  Obtain the measurement resolution of the timer.
228
%
229
%  The format of the GetTimerResolution method is:
230
%
231
%      void GetTimerInfo(TimerInfo *time_info)
232
%
233
%  A description of each parameter follows.
234
%
235
%    o  time_info: Timer statistics structure.
236
%
237
*/
238
MagickExport double GetTimerResolution(void)
239
0
{
240
0
#if defined(HAVE_CLOCK_GETRES)
241
0
  struct timespec timer;
242
0
  (void) clock_getres(CLOCK_ID, &timer);
243
244
0
  return((double) timer.tv_sec + (double) timer.tv_nsec/NANOSECONDS_PER_SECOND);
245
#elif defined(MSWINDOWS)
246
  return (0.02);
247
#else
248
  return (1.0/CLK_TCK);
249
#endif
250
0
}
251

252
/*
253
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
254
%                                                                             %
255
%                                                                             %
256
%                                                                             %
257
%   G e t U s e r T i m e                                                     %
258
%                                                                             %
259
%                                                                             %
260
%                                                                             %
261
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
262
%
263
%  Method GetUserTime returns the User time (user and system) by the operating
264
%  system (in seconds) between the start and stop events. If the stopwatch is
265
%  still running, it is stopped first.
266
%
267
%  The format of the GetUserTime method is:
268
%
269
%      double GetUserTime(TimerInfo *time_info)
270
%
271
%  A description of each parameter follows.
272
%
273
%    o  time_info: Timer statistics structure.
274
%
275
*/
276
MagickExport double GetUserTime(TimerInfo *time_info)
277
13.6M
{
278
13.6M
  assert(time_info != (TimerInfo *) NULL);
279
13.6M
  assert(time_info->signature == MagickSignature);
280
13.6M
  if (time_info->state == UndefinedTimerState)
281
0
    return(0.0);
282
13.6M
  if (time_info->state == RunningTimerState)
283
0
    StopTimer(time_info);
284
13.6M
  return(time_info->user.total);
285
13.6M
}
286

287
/*
288
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
289
%                                                                             %
290
%                                                                             %
291
%                                                                             %
292
%   R e s e t T i m e r                                                       %
293
%                                                                             %
294
%                                                                             %
295
%                                                                             %
296
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
297
%
298
%  Method ResetTimer resets the stopwatch.
299
%
300
%  The format of the ResetTimer method is:
301
%
302
%      void ResetTimer(TimerInfo *time_info)
303
%
304
%  A description of each parameter follows.
305
%
306
%    o  time_info: Timer statistics structure.
307
%
308
*/
309
MagickExport void ResetTimer(TimerInfo *time_info)
310
0
{
311
0
  assert(time_info != (TimerInfo *) NULL);
312
0
  assert(time_info->signature == MagickSignature);
313
0
  StopTimer(time_info);
314
0
  time_info->elapsed.stop=0.0;
315
0
  time_info->user.stop=0.0;
316
0
}
317

318
/*
319
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
320
%                                                                             %
321
%                                                                             %
322
%                                                                             %
323
+   S t a r t T i m e r                                                       %
324
%                                                                             %
325
%                                                                             %
326
%                                                                             %
327
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
328
%
329
%  Method StartTimer starts the stopwatch.
330
%
331
%  The format of the StartTimer method is:
332
%
333
%      void StartTimer(TimerInfo *time_info,const unsigned int reset)
334
%
335
%  A description of each parameter follows.
336
%
337
%    o  time_info: Timer statistics structure.
338
%
339
%    o  reset: If reset is True, then the stopwatch is reset prior to starting.
340
%       If reset is False, then timing is continued without resetting the
341
%       stopwatch.
342
%
343
*/
344
MagickExport void StartTimer(TimerInfo *time_info,const unsigned int reset)
345
17.1M
{
346
17.1M
  assert(time_info != (TimerInfo *) NULL);
347
17.1M
  assert(time_info->signature == MagickSignature);
348
17.1M
  if (reset)
349
17.1M
    {
350
      /*
351
        Reset the stopwatch before starting it.
352
      */
353
17.1M
      time_info->user.total=0.0;
354
17.1M
      time_info->elapsed.total=0.0;
355
17.1M
    }
356
17.1M
  if (time_info->state != RunningTimerState)
357
17.1M
    {
358
17.1M
      time_info->elapsed.start=ElapsedTime();
359
17.1M
      time_info->user.start=UserTime();
360
17.1M
    }
361
17.1M
  time_info->state=RunningTimerState;
362
17.1M
}
363

364
/*
365
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
366
%                                                                             %
367
%                                                                             %
368
%                                                                             %
369
+   S t o p T i m e r                                                         %
370
%                                                                             %
371
%                                                                             %
372
%                                                                             %
373
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
374
%
375
%  Method StopTimer stops the stopwatch.
376
%
377
%  The format of the StopTimer method is:
378
%
379
%      void StopTimer(TimerInfo *time_info)
380
%
381
%  A description of each parameter follows.
382
%
383
%    o  time_info: Timer statistics structure.
384
%
385
*/
386
MagickExport void StopTimer(TimerInfo *time_info)
387
14.4M
{
388
14.4M
  assert(time_info != (TimerInfo *) NULL);
389
14.4M
  assert(time_info->signature == MagickSignature);
390
14.4M
  time_info->elapsed.stop=ElapsedTime();
391
14.4M
  time_info->user.stop=UserTime();
392
14.4M
  if (time_info->state == RunningTimerState)
393
14.4M
    {
394
14.4M
      time_info->user.total+=
395
14.4M
        time_info->user.stop-time_info->user.start+MagickEpsilon;
396
14.4M
      time_info->elapsed.total+=
397
14.4M
        time_info->elapsed.stop-time_info->elapsed.start+MagickEpsilon;
398
14.4M
    }
399
14.4M
  time_info->state=StoppedTimerState;
400
14.4M
}
401

402
/*
403
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
404
%                                                                             %
405
%                                                                             %
406
%                                                                             %
407
+   U s e r T i m e                                                           %
408
%                                                                             %
409
%                                                                             %
410
%                                                                             %
411
%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
412
%
413
%  Method UserTime returns the total time the process has been scheduled (in
414
%  seconds) since the last call to StartTimer().
415
%
416
%  The format of the UserTime method is:
417
%
418
%      double UserTime()
419
%
420
*/
421
static double UserTime(void)
422
31.5M
{
423
31.5M
#if defined(HAVE_TIMES)
424
31.5M
  struct tms
425
31.5M
    timer;
426
427
31.5M
  (void) times(&timer);
428
31.5M
  return((double) (timer.tms_utime+timer.tms_stime)/CLK_TCK);
429
#else
430
#if defined(MSWINDOWS)
431
  return(NTUserTime());
432
#else
433
  return((double) clock()/CLK_TCK);
434
#endif
435
#endif
436
31.5M
}