This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_systimer.c
163 lines (139 loc) · 3.74 KB
1
/*
2
3
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
4
5
6
7
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
8
9
10
11
Permission is granted to anyone to use this software for any purpose,
including commercial applications, and to alter it and redistribute it
freely, subject to the following restrictions:
12
13
14
15
16
17
18
19
1. The origin of this software must not be misrepresented; you must not
claim that you wrote the original software. If you use this software
in a product, an acknowledgment in the product documentation would be
appreciated but is not required.
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
20
*/
21
#include "SDL_config.h"
22
23
24
#ifdef SDL_TIMER_UNIX
25
26
27
28
29
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
30
31
#include "SDL_timer.h"
32
33
34
35
36
/* The clock_gettime provides monotonous time, so we should use it if
it's available. The clock_gettime function is behind ifdef
for __USE_POSIX199309
Tommi Kyntola (tommi.kyntola@ray.fi) 27/09/2005
*/
37
#if HAVE_NANOSLEEP || HAVE_CLOCK_GETTIME
38
39
40
#include <time.h>
#endif
41
/* The first ticks value of the application */
42
#ifdef HAVE_CLOCK_GETTIME
43
44
static struct timespec start;
#else
45
static struct timeval start;
46
#endif /* HAVE_CLOCK_GETTIME */
47
48
49
50
void
SDL_StartTicks(void)
51
{
52
/* Set first ticks value */
53
#if HAVE_CLOCK_GETTIME
54
clock_gettime(CLOCK_MONOTONIC, &start);
55
#else
56
gettimeofday(&start, NULL);
57
#endif
58
59
}
60
61
Uint32
SDL_GetTicks(void)
62
{
63
#if HAVE_CLOCK_GETTIME
64
65
Uint32 ticks;
struct timespec now;
66
67
68
69
70
71
clock_gettime(CLOCK_MONOTONIC, &now);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
start.tv_nsec) / 1000000;
return (ticks);
72
#else
73
74
Uint32 ticks;
struct timeval now;
75
76
77
78
79
80
gettimeofday(&now, NULL);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
start.tv_usec) / 1000;
return (ticks);
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
#endif
}
Uint64
SDL_GetPerformanceCounter(void)
{
#if HAVE_CLOCK_GETTIME
Uint64 ticks;
struct timespec now;
clock_gettime(CLOCK_MONOTONIC, &now);
ticks = now.tv_sec;
ticks *= 1000000000;
ticks += now.tv_nsec;
return (ticks);
#else
Uint64 ticks;
struct timeval now;
gettimeofday(&now, NULL);
ticks = now.tv_sec;
ticks *= 1000000;
ticks += now.tv_usec;
return (ticks);
#endif
}
Uint64
SDL_GetPerformanceFrequency(void)
{
#if HAVE_CLOCK_GETTIME
return 1000000000;
#else
return 1000000;
115
#endif
116
117
}
118
119
void
SDL_Delay(Uint32 ms)
120
{
121
int was_error;
122
123
#if HAVE_NANOSLEEP
124
struct timespec elapsed, tv;
125
#else
126
127
struct timeval tv;
Uint32 then, now, elapsed;
128
129
#endif
130
/* Set the timeout interval */
131
#if HAVE_NANOSLEEP
132
133
elapsed.tv_sec = ms / 1000;
elapsed.tv_nsec = (ms % 1000) * 1000000;
134
#else
135
then = SDL_GetTicks();
136
#endif
137
138
do {
errno = 0;
139
140
#if HAVE_NANOSLEEP
141
142
143
tv.tv_sec = elapsed.tv_sec;
tv.tv_nsec = elapsed.tv_nsec;
was_error = nanosleep(&tv, &elapsed);
144
#else
145
146
147
148
149
150
151
152
153
154
155
156
/* Calculate the time interval left (in case of interrupt) */
now = SDL_GetTicks();
elapsed = (now - then);
then = now;
if (elapsed >= ms) {
break;
}
ms -= elapsed;
tv.tv_sec = ms / 1000;
tv.tv_usec = (ms % 1000) * 1000;
was_error = select(0, NULL, NULL, NULL, &tv);
157
#endif /* HAVE_NANOSLEEP */
158
} while (was_error && (errno == EINTR));
159
160
}
161
#endif /* SDL_TIMER_UNIX */
162
163
/* vi: set ts=4 sw=4 expandtab: */