comparison src/timer/unix/SDL_systimer.c @ 1895:c121d94672cb

SDL 1.2 is moving to a branch, and SDL 1.3 is becoming the head.
author Sam Lantinga <slouken@libsdl.org>
date Mon, 10 Jul 2006 21:04:37 +0000
parents 92947e3a18db
children e27bdcc80744
comparison
equal deleted inserted replaced
1894:c69cee13dd76 1895:c121d94672cb
56 #else 56 #else
57 static struct timeval start; 57 static struct timeval start;
58 #endif /* HAVE_CLOCK_GETTIME */ 58 #endif /* HAVE_CLOCK_GETTIME */
59 59
60 60
61 void SDL_StartTicks(void) 61 void
62 { 62 SDL_StartTicks(void)
63 /* Set first ticks value */ 63 {
64 /* Set first ticks value */
64 #if HAVE_CLOCK_GETTIME 65 #if HAVE_CLOCK_GETTIME
65 clock_gettime(CLOCK_MONOTONIC,&start); 66 clock_gettime(CLOCK_MONOTONIC, &start);
66 #else 67 #else
67 gettimeofday(&start, NULL); 68 gettimeofday(&start, NULL);
68 #endif 69 #endif
69 } 70 }
70 71
71 Uint32 SDL_GetTicks (void) 72 Uint32
73 SDL_GetTicks(void)
72 { 74 {
73 #if HAVE_CLOCK_GETTIME 75 #if HAVE_CLOCK_GETTIME
74 Uint32 ticks; 76 Uint32 ticks;
75 struct timespec now; 77 struct timespec now;
76 clock_gettime(CLOCK_MONOTONIC,&now); 78 clock_gettime(CLOCK_MONOTONIC, &now);
77 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_nsec-start.tv_nsec)/1000000; 79 ticks =
78 return(ticks); 80 (now.tv_sec - start.tv_sec) * 1000 + (now.tv_nsec -
79 #else 81 start.tv_nsec) / 1000000;
80 Uint32 ticks; 82 return (ticks);
81 struct timeval now; 83 #else
82 gettimeofday(&now, NULL); 84 Uint32 ticks;
83 ticks=(now.tv_sec-start.tv_sec)*1000+(now.tv_usec-start.tv_usec)/1000; 85 struct timeval now;
84 return(ticks); 86 gettimeofday(&now, NULL);
85 #endif 87 ticks =
86 } 88 (now.tv_sec - start.tv_sec) * 1000 + (now.tv_usec -
87 89 start.tv_usec) / 1000;
88 void SDL_Delay (Uint32 ms) 90 return (ticks);
91 #endif
92 }
93
94 void
95 SDL_Delay(Uint32 ms)
89 { 96 {
90 #if SDL_THREAD_PTH 97 #if SDL_THREAD_PTH
91 pth_time_t tv; 98 pth_time_t tv;
92 tv.tv_sec = ms/1000; 99 tv.tv_sec = ms / 1000;
93 tv.tv_usec = (ms%1000)*1000; 100 tv.tv_usec = (ms % 1000) * 1000;
94 pth_nap(tv); 101 pth_nap(tv);
95 #else 102 #else
96 int was_error; 103 int was_error;
97 104
98 #if HAVE_NANOSLEEP 105 #if HAVE_NANOSLEEP
99 struct timespec elapsed, tv; 106 struct timespec elapsed, tv;
100 #else 107 #else
101 struct timeval tv; 108 struct timeval tv;
102 Uint32 then, now, elapsed; 109 Uint32 then, now, elapsed;
103 #endif 110 #endif
104 111
105 /* Set the timeout interval */ 112 /* Set the timeout interval */
106 #if HAVE_NANOSLEEP 113 #if HAVE_NANOSLEEP
107 elapsed.tv_sec = ms/1000; 114 elapsed.tv_sec = ms / 1000;
108 elapsed.tv_nsec = (ms%1000)*1000000; 115 elapsed.tv_nsec = (ms % 1000) * 1000000;
109 #else 116 #else
110 then = SDL_GetTicks(); 117 then = SDL_GetTicks();
111 #endif 118 #endif
112 do { 119 do {
113 errno = 0; 120 errno = 0;
114 121
115 #if HAVE_NANOSLEEP 122 #if HAVE_NANOSLEEP
116 tv.tv_sec = elapsed.tv_sec; 123 tv.tv_sec = elapsed.tv_sec;
117 tv.tv_nsec = elapsed.tv_nsec; 124 tv.tv_nsec = elapsed.tv_nsec;
118 was_error = nanosleep(&tv, &elapsed); 125 was_error = nanosleep(&tv, &elapsed);
119 #else 126 #else
120 /* Calculate the time interval left (in case of interrupt) */ 127 /* Calculate the time interval left (in case of interrupt) */
121 now = SDL_GetTicks(); 128 now = SDL_GetTicks();
122 elapsed = (now-then); 129 elapsed = (now - then);
123 then = now; 130 then = now;
124 if ( elapsed >= ms ) { 131 if (elapsed >= ms) {
125 break; 132 break;
126 } 133 }
127 ms -= elapsed; 134 ms -= elapsed;
128 tv.tv_sec = ms/1000; 135 tv.tv_sec = ms / 1000;
129 tv.tv_usec = (ms%1000)*1000; 136 tv.tv_usec = (ms % 1000) * 1000;
130 137
131 was_error = select(0, NULL, NULL, NULL, &tv); 138 was_error = select(0, NULL, NULL, NULL, &tv);
132 #endif /* HAVE_NANOSLEEP */ 139 #endif /* HAVE_NANOSLEEP */
133 } while ( was_error && (errno == EINTR) ); 140 }
141 while (was_error && (errno == EINTR));
134 #endif /* SDL_THREAD_PTH */ 142 #endif /* SDL_THREAD_PTH */
135 } 143 }
136 144
137 #ifdef USE_ITIMER 145 #ifdef USE_ITIMER
138 146
139 static void HandleAlarm(int sig) 147 static void
140 { 148 HandleAlarm(int sig)
141 Uint32 ms; 149 {
142 150 Uint32 ms;
143 if ( SDL_alarm_callback ) { 151
144 ms = (*SDL_alarm_callback)(SDL_alarm_interval); 152 if (SDL_alarm_callback) {
145 if ( ms != SDL_alarm_interval ) { 153 ms = (*SDL_alarm_callback) (SDL_alarm_interval);
146 SDL_SetTimer(ms, SDL_alarm_callback); 154 if (ms != SDL_alarm_interval) {
147 } 155 SDL_SetTimer(ms, SDL_alarm_callback);
148 } 156 }
149 } 157 }
150 158 }
151 int SDL_SYS_TimerInit(void) 159
152 { 160 int
153 struct sigaction action; 161 SDL_SYS_TimerInit(void)
154 162 {
155 /* Set the alarm handler (Linux specific) */ 163 struct sigaction action;
156 SDL_memset(&action, 0, sizeof(action)); 164
157 action.sa_handler = HandleAlarm; 165 /* Set the alarm handler (Linux specific) */
158 action.sa_flags = SA_RESTART; 166 SDL_memset(&action, 0, sizeof(action));
159 sigemptyset(&action.sa_mask); 167 action.sa_handler = HandleAlarm;
160 sigaction(SIGALRM, &action, NULL); 168 action.sa_flags = SA_RESTART;
161 return(0); 169 sigemptyset(&action.sa_mask);
162 } 170 sigaction(SIGALRM, &action, NULL);
163 171 return (0);
164 void SDL_SYS_TimerQuit(void) 172 }
165 { 173
166 SDL_SetTimer(0, NULL); 174 void
167 } 175 SDL_SYS_TimerQuit(void)
168 176 {
169 int SDL_SYS_StartTimer(void) 177 SDL_SetTimer(0, NULL);
170 { 178 }
171 struct itimerval timer; 179
172 180 int
173 timer.it_value.tv_sec = (SDL_alarm_interval/1000); 181 SDL_SYS_StartTimer(void)
174 timer.it_value.tv_usec = (SDL_alarm_interval%1000)*1000; 182 {
175 timer.it_interval.tv_sec = (SDL_alarm_interval/1000); 183 struct itimerval timer;
176 timer.it_interval.tv_usec = (SDL_alarm_interval%1000)*1000; 184
177 setitimer(ITIMER_REAL, &timer, NULL); 185 timer.it_value.tv_sec = (SDL_alarm_interval / 1000);
178 return(0); 186 timer.it_value.tv_usec = (SDL_alarm_interval % 1000) * 1000;
179 } 187 timer.it_interval.tv_sec = (SDL_alarm_interval / 1000);
180 188 timer.it_interval.tv_usec = (SDL_alarm_interval % 1000) * 1000;
181 void SDL_SYS_StopTimer(void) 189 setitimer(ITIMER_REAL, &timer, NULL);
182 { 190 return (0);
183 struct itimerval timer; 191 }
184 192
185 SDL_memset(&timer, 0, (sizeof timer)); 193 void
186 setitimer(ITIMER_REAL, &timer, NULL); 194 SDL_SYS_StopTimer(void)
195 {
196 struct itimerval timer;
197
198 SDL_memset(&timer, 0, (sizeof timer));
199 setitimer(ITIMER_REAL, &timer, NULL);
187 } 200 }
188 201
189 #else /* USE_ITIMER */ 202 #else /* USE_ITIMER */
190 203
191 #include "SDL_thread.h" 204 #include "SDL_thread.h"
192 205
193 /* Data to handle a single periodic alarm */ 206 /* Data to handle a single periodic alarm */
194 static int timer_alive = 0; 207 static int timer_alive = 0;
195 static SDL_Thread *timer = NULL; 208 static SDL_Thread *timer = NULL;
196 209
197 static int RunTimer(void *unused) 210 static int
198 { 211 RunTimer(void *unused)
199 while ( timer_alive ) { 212 {
200 if ( SDL_timer_running ) { 213 while (timer_alive) {
201 SDL_ThreadedTimerCheck(); 214 if (SDL_timer_running) {
202 } 215 SDL_ThreadedTimerCheck();
203 SDL_Delay(1); 216 }
204 } 217 SDL_Delay(1);
205 return(0); 218 }
219 return (0);
206 } 220 }
207 221
208 /* This is only called if the event thread is not running */ 222 /* This is only called if the event thread is not running */
209 int SDL_SYS_TimerInit(void) 223 int
210 { 224 SDL_SYS_TimerInit(void)
211 timer_alive = 1; 225 {
212 timer = SDL_CreateThread(RunTimer, NULL); 226 timer_alive = 1;
213 if ( timer == NULL ) 227 timer = SDL_CreateThread(RunTimer, NULL);
214 return(-1); 228 if (timer == NULL)
215 return(SDL_SetTimerThreaded(1)); 229 return (-1);
216 } 230 return (SDL_SetTimerThreaded(1));
217 231 }
218 void SDL_SYS_TimerQuit(void) 232
219 { 233 void
220 timer_alive = 0; 234 SDL_SYS_TimerQuit(void)
221 if ( timer ) { 235 {
222 SDL_WaitThread(timer, NULL); 236 timer_alive = 0;
223 timer = NULL; 237 if (timer) {
224 } 238 SDL_WaitThread(timer, NULL);
225 } 239 timer = NULL;
226 240 }
227 int SDL_SYS_StartTimer(void) 241 }
228 { 242
229 SDL_SetError("Internal logic error: Linux uses threaded timer"); 243 int
230 return(-1); 244 SDL_SYS_StartTimer(void)
231 } 245 {
232 246 SDL_SetError("Internal logic error: Linux uses threaded timer");
233 void SDL_SYS_StopTimer(void) 247 return (-1);
234 { 248 }
235 return; 249
250 void
251 SDL_SYS_StopTimer(void)
252 {
253 return;
236 } 254 }
237 255
238 #endif /* USE_ITIMER */ 256 #endif /* USE_ITIMER */
239 257
240 #endif /* SDL_TIMER_UNIX */ 258 #endif /* SDL_TIMER_UNIX */
259 /* vi: set ts=4 sw=4 expandtab: */