This repository has been archived by the owner on Feb 11, 2021. It is now read-only.
/
SDL_systimer.c
128 lines (109 loc) · 3.13 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
67
68
69
70
71
Uint32 ticks;
struct timespec now;
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
75
76
77
78
79
Uint32 ticks;
struct timeval now;
gettimeofday(&now, NULL);
ticks =
(now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
start.tv_usec) / 1000;
return (ticks);
80
#endif
81
82
}
83
84
void
SDL_Delay(Uint32 ms)
85
{
86
int was_error;
87
88
#if HAVE_NANOSLEEP
89
struct timespec elapsed, tv;
90
#else
91
92
struct timeval tv;
Uint32 then, now, elapsed;
93
94
#endif
95
/* Set the timeout interval */
96
#if HAVE_NANOSLEEP
97
98
elapsed.tv_sec = ms / 1000;
elapsed.tv_nsec = (ms % 1000) * 1000000;
99
#else
100
then = SDL_GetTicks();
101
#endif
102
103
do {
errno = 0;
104
105
#if HAVE_NANOSLEEP
106
107
108
tv.tv_sec = elapsed.tv_sec;
tv.tv_nsec = elapsed.tv_nsec;
was_error = nanosleep(&tv, &elapsed);
109
#else
110
111
112
113
114
115
116
117
118
119
120
121
/* 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);
122
#endif /* HAVE_NANOSLEEP */
123
} while (was_error && (errno == EINTR));
124
125
}
126
#endif /* SDL_TIMER_UNIX */
127
128
/* vi: set ts=4 sw=4 expandtab: */