1 /*
2   Copyright (C) 1997-2021 Sam Lantinga <slouken@libsdl.org>
3 
4   This software is provided 'as-is', without any express or implied
5   warranty.  In no event will the authors be held liable for any damages
6   arising from the use of this software.
7 
8   Permission is granted to anyone to use this software for any purpose,
9   including commercial applications, and to alter it and redistribute it
10   freely.
11 */
12 
13 /* Test program to check the resolution of the SDL timer on the current
14    platform
15 */
16 
17 #include <stdlib.h>
18 #include <stdio.h>
19 
20 #include "SDL.h"
21 
22 #define DEFAULT_RESOLUTION  1
23 
24 static int ticks = 0;
25 
26 static Uint32 SDLCALL
ticktock(Uint32 interval,void * param)27 ticktock(Uint32 interval, void *param)
28 {
29     ++ticks;
30     return (interval);
31 }
32 
33 static Uint32 SDLCALL
callback(Uint32 interval,void * param)34 callback(Uint32 interval, void *param)
35 {
36     SDL_Log("Timer %d : param = %d\n", interval, (int) (uintptr_t) param);
37     return interval;
38 }
39 
40 int
main(int argc,char * argv[])41 main(int argc, char *argv[])
42 {
43     int i, desired;
44     SDL_TimerID t1, t2, t3;
45     Uint64 start64, now64;
46     Uint32 start32, now32;
47     Uint64 start, now;
48 
49     /* Enable standard application logging */
50     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
51 
52     if (SDL_Init(SDL_INIT_TIMER) < 0) {
53         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
54         return (1);
55     }
56 
57     /* Verify SDL_GetTicks* acts monotonically increasing, and not erratic. */
58     SDL_Log("Sanity-checking GetTicks\n");
59     for (i = 0; i < 1000; ++i) {
60         start64 = SDL_GetTicks64();
61         start32 = SDL_GetTicks();
62         SDL_Delay(1);
63         now64 = SDL_GetTicks64() - start64;
64         now32 = SDL_GetTicks() - start32;
65         if (now32 > 100 || now64 > 100) {
66             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "testtimer.c: Delta time erratic at iter %d. Delay 1ms = %d ms in ticks, %d ms in ticks64\n", i, (int)now32, (int)now64);
67             SDL_Quit();
68             return 1;
69         }
70     }
71 
72     /* Start the timer */
73     desired = 0;
74     if (argv[1]) {
75         desired = SDL_atoi(argv[1]);
76     }
77     if (desired == 0) {
78         desired = DEFAULT_RESOLUTION;
79     }
80     t1 = SDL_AddTimer(desired, ticktock, NULL);
81 
82     /* Wait 10 seconds */
83     SDL_Log("Waiting 10 seconds\n");
84     SDL_Delay(10 * 1000);
85 
86     /* Stop the timer */
87     SDL_RemoveTimer(t1);
88 
89     /* Print the results */
90     if (ticks) {
91         SDL_Log("Timer resolution: desired = %d ms, actual = %f ms\n",
92                 desired, (double) (10 * 1000) / ticks);
93     }
94 
95     /* Test multiple timers */
96     SDL_Log("Testing multiple timers...\n");
97     t1 = SDL_AddTimer(100, callback, (void *) 1);
98     if (!t1)
99         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"Could not create timer 1: %s\n", SDL_GetError());
100     t2 = SDL_AddTimer(50, callback, (void *) 2);
101     if (!t2)
102         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"Could not create timer 2: %s\n", SDL_GetError());
103     t3 = SDL_AddTimer(233, callback, (void *) 3);
104     if (!t3)
105         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION,"Could not create timer 3: %s\n", SDL_GetError());
106 
107     /* Wait 10 seconds */
108     SDL_Log("Waiting 10 seconds\n");
109     SDL_Delay(10 * 1000);
110 
111     SDL_Log("Removing timer 1 and waiting 5 more seconds\n");
112     SDL_RemoveTimer(t1);
113 
114     SDL_Delay(5 * 1000);
115 
116     SDL_RemoveTimer(t2);
117     SDL_RemoveTimer(t3);
118 
119     start = SDL_GetPerformanceCounter();
120     for (i = 0; i < 1000000; ++i) {
121         ticktock(0, NULL);
122     }
123     now = SDL_GetPerformanceCounter();
124     SDL_Log("1 million iterations of ticktock took %f ms\n", (double)((now - start)*1000) / SDL_GetPerformanceFrequency());
125 
126     SDL_Log("Performance counter frequency: %"SDL_PRIu64"\n", SDL_GetPerformanceFrequency());
127     start64 = SDL_GetTicks64();
128     start32 = SDL_GetTicks();
129     start = SDL_GetPerformanceCounter();
130     SDL_Delay(1000);
131     now = SDL_GetPerformanceCounter();
132     now64 = SDL_GetTicks64();
133     now32 = SDL_GetTicks();
134     SDL_Log("Delay 1 second = %d ms in ticks, %d ms in ticks64, %f ms according to performance counter\n", (int) (now32-start32), (int) (now64-start64), (double)((now - start)*1000) / SDL_GetPerformanceFrequency());
135 
136     SDL_Quit();
137     return (0);
138 }
139 
140 /* vi: set ts=4 sw=4 expandtab: */
141