This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_systimer.c
164 lines (139 loc) · 3.67 KB
1
2
/*
SDL - Simple DirectMedia Layer
3
Copyright (C) 1997-2011 Sam Lantinga
4
5
This library is free software; you can redistribute it and/or
6
modify it under the terms of the GNU Lesser General Public
7
License as published by the Free Software Foundation; either
8
version 2.1 of the License, or (at your option) any later version.
9
10
11
12
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
Lesser General Public License for more details.
14
15
16
17
You should have received a copy of the GNU Lesser General Public
License along with this library; if not, write to the Free Software
Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18
19
Sam Lantinga
20
slouken@libsdl.org
21
*/
22
#include "SDL_config.h"
23
24
25
#ifdef SDL_TIMER_UNIX
26
27
28
29
30
#include <stdio.h>
#include <sys/time.h>
#include <unistd.h>
#include <errno.h>
31
32
#include "SDL_timer.h"
33
34
35
36
37
/* 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
*/
38
#if HAVE_NANOSLEEP || HAVE_CLOCK_GETTIME
39
40
41
#include <time.h>
#endif
42
/* The first ticks value of the application */
43
#ifdef HAVE_CLOCK_GETTIME
44
45
static struct timespec start;
#else
46
static struct timeval start;
47
#endif /* HAVE_CLOCK_GETTIME */
48
49
50
51
void
SDL_StartTicks(void)
52
{
53
/* Set first ticks value */
54
#if HAVE_CLOCK_GETTIME
55
clock_gettime(CLOCK_MONOTONIC, &start);
56
#else
57
gettimeofday(&start, NULL);
58
#endif
59
60
}
61
62
Uint32
SDL_GetTicks(void)
63
{
64
#if HAVE_CLOCK_GETTIME
65
66
Uint32 ticks;
struct timespec now;
67
68
69
70
71
72
clock_gettime(CLOCK_MONOTONIC, &now);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
start.tv_nsec) / 1000000;
return (ticks);
73
#else
74
75
Uint32 ticks;
struct timeval now;
76
77
78
79
80
81
gettimeofday(&now, NULL);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
start.tv_usec) / 1000;
return (ticks);
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
115
#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;
116
#endif
117
118
}
119
120
void
SDL_Delay(Uint32 ms)
121
{
122
int was_error;
123
124
#if HAVE_NANOSLEEP
125
struct timespec elapsed, tv;
126
#else
127
128
struct timeval tv;
Uint32 then, now, elapsed;
129
130
#endif
131
/* Set the timeout interval */
132
#if HAVE_NANOSLEEP
133
134
elapsed.tv_sec = ms / 1000;
elapsed.tv_nsec = (ms % 1000) * 1000000;
135
#else
136
then = SDL_GetTicks();
137
#endif
138
139
do {
errno = 0;
140
141
#if HAVE_NANOSLEEP
142
143
144
tv.tv_sec = elapsed.tv_sec;
tv.tv_nsec = elapsed.tv_nsec;
was_error = nanosleep(&tv, &elapsed);
145
#else
146
147
148
149
150
151
152
153
154
155
156
157
/* 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);
158
#endif /* HAVE_NANOSLEEP */
159
} while (was_error && (errno == EINTR));
160
161
}
162
#endif /* SDL_TIMER_UNIX */
163
164
/* vi: set ts=4 sw=4 expandtab: */