src/timer/riscos/SDL_systimer.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 14 Apr 2006 04:46:47 +0000
changeset 1635 92947e3a18db
parent 1402 d910939febfa
child 1662 782fd950bd46
child 1895 c121d94672cb
child 4159 a1b03ba2fcd0
permissions -rw-r--r--
Make sure code is only compiled if the appropriate subsystem is enabled
slouken@630
     1
/*
slouken@630
     2
    SDL - Simple DirectMedia Layer
slouken@1312
     3
    Copyright (C) 1997-2006 Sam Lantinga
slouken@630
     4
slouken@630
     5
    This library is free software; you can redistribute it and/or
slouken@1312
     6
    modify it under the terms of the GNU Lesser General Public
slouken@630
     7
    License as published by the Free Software Foundation; either
slouken@1312
     8
    version 2.1 of the License, or (at your option) any later version.
slouken@630
     9
slouken@630
    10
    This library is distributed in the hope that it will be useful,
slouken@630
    11
    but WITHOUT ANY WARRANTY; without even the implied warranty of
slouken@630
    12
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
slouken@1312
    13
    Lesser General Public License for more details.
slouken@630
    14
slouken@1312
    15
    You should have received a copy of the GNU Lesser General Public
slouken@1312
    16
    License along with this library; if not, write to the Free Software
slouken@1312
    17
    Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301  USA
slouken@630
    18
slouken@630
    19
    Sam Lantinga
slouken@1312
    20
    slouken@libsdl.org
slouken@630
    21
*/
slouken@1402
    22
#include "SDL_config.h"
slouken@630
    23
slouken@1635
    24
#ifdef SDL_TIMER_RISCOS
slouken@1635
    25
slouken@630
    26
#include <stdio.h>
slouken@630
    27
#include <time.h>
slouken@630
    28
#include <sys/time.h>
slouken@630
    29
#include <unistd.h>
slouken@630
    30
#include <string.h>
slouken@630
    31
#include <errno.h>
slouken@630
    32
slouken@630
    33
#include "SDL_timer.h"
slouken@1361
    34
#include "../SDL_timer_c.h"
slouken@630
    35
slouken@1361
    36
#if SDL_THREADS_DISABLED
slouken@1361
    37
/* Timer  SDL_arraysize(Timer ),start/reset time */
slouken@630
    38
static Uint32 timerStart;
slouken@630
    39
/* Timer running function */
slouken@630
    40
void RISCOS_CheckTimer();
slouken@955
    41
#else
slouken@955
    42
#include <pthread.h>
slouken@955
    43
extern Uint32 riscos_main_thread;
slouken@955
    44
extern int riscos_using_threads;
slouken@955
    45
extern Uint32 SDL_ThreadID();
slouken@955
    46
extern Uint32 SDL_EventThreadID(void);
slouken@955
    47
#endif
slouken@955
    48
slouken@630
    49
slouken@630
    50
extern void RISCOS_BackgroundTasks(void);
slouken@630
    51
slouken@630
    52
/* The first ticks value of the application */
slouken@630
    53
clock_t start;
slouken@630
    54
slouken@630
    55
void SDL_StartTicks(void)
slouken@630
    56
{
slouken@630
    57
	/* Set first ticks value */
slouken@630
    58
	start = clock();
slouken@630
    59
}
slouken@630
    60
slouken@630
    61
Uint32 SDL_GetTicks (void)
slouken@630
    62
{
slouken@630
    63
	clock_t ticks;
slouken@630
    64
slouken@630
    65
	ticks=clock()-start;
slouken@630
    66
slouken@630
    67
slouken@630
    68
#if CLOCKS_PER_SEC == 1000
slouken@630
    69
slouken@630
    70
	return(ticks);
slouken@630
    71
slouken@630
    72
#elif CLOCKS_PER_SEC == 100
slouken@630
    73
slouken@630
    74
	return (ticks * 10);
slouken@630
    75
slouken@630
    76
#else
slouken@630
    77
slouken@630
    78
	return ticks*(1000/CLOCKS_PER_SEC);
slouken@630
    79
slouken@630
    80
#endif
slouken@630
    81
slouken@630
    82
}
slouken@630
    83
slouken@630
    84
void SDL_Delay (Uint32 ms)
slouken@630
    85
{
slouken@630
    86
    Uint32 now,then,elapsed;
slouken@1361
    87
#if !SDL_THREADS_DISABLED
slouken@955
    88
    int is_event_thread;
slouken@955
    89
    if (riscos_using_threads)
slouken@955
    90
    {
slouken@955
    91
       is_event_thread = 0;
slouken@955
    92
       if (SDL_EventThreadID())
slouken@955
    93
       {
slouken@955
    94
          if (SDL_EventThreadID() == SDL_ThreadID()) is_event_thread = 1;
slouken@955
    95
       } else if (SDL_ThreadID() == riscos_main_thread) is_event_thread = 1;
slouken@955
    96
    } else is_event_thread = 1;
slouken@955
    97
#endif
slouken@955
    98
slouken@1035
    99
        /*TODO: Next version of Unixlib may allow us to use usleep here */
slouken@1035
   100
        /*      for non event threads */
slouken@630
   101
slouken@630
   102
	/* Set the timeout interval - Linux only needs to do this once */
slouken@630
   103
	then = SDL_GetTicks();
slouken@630
   104
slouken@630
   105
	do {
slouken@630
   106
		/* Do background tasks required while sleeping as we are not multithreaded */
slouken@1361
   107
#if SDL_THREADS_DISABLED
slouken@630
   108
		RISCOS_BackgroundTasks();
slouken@955
   109
#else
slouken@955
   110
		/* For threaded build only run background tasks in event thread */
slouken@955
   111
		if (is_event_thread) RISCOS_BackgroundTasks();
slouken@955
   112
#endif
slouken@955
   113
slouken@630
   114
		/* Calculate the time interval left (in case of interrupt) */
slouken@630
   115
		now = SDL_GetTicks();
slouken@630
   116
		elapsed = (now-then);
slouken@630
   117
		then = now;
slouken@630
   118
		if ( elapsed >= ms ) {
slouken@630
   119
			break;
slouken@630
   120
		}
slouken@630
   121
		ms -= elapsed;
slouken@1361
   122
#if !SDL_THREADS_DISABLED
slouken@955
   123
            /* Need to yield to let other threads have a go */
slouken@955
   124
            if (riscos_using_threads) pthread_yield();
slouken@955
   125
#endif
slouken@630
   126
slouken@630
   127
	} while ( 1 );
slouken@630
   128
}
slouken@630
   129
slouken@1361
   130
#if SDL_THREADS_DISABLED
slouken@955
   131
slouken@955
   132
/* Non-threaded version of timer */
slouken@955
   133
slouken@630
   134
int SDL_SYS_TimerInit(void)
slouken@630
   135
{
slouken@630
   136
	return(0);
slouken@630
   137
}
slouken@630
   138
slouken@630
   139
void SDL_SYS_TimerQuit(void)
slouken@630
   140
{
slouken@630
   141
	SDL_SetTimer(0, NULL);
slouken@630
   142
}
slouken@630
   143
slouken@630
   144
int SDL_SYS_StartTimer(void)
slouken@630
   145
{
slouken@630
   146
	timerStart = SDL_GetTicks();
slouken@630
   147
slouken@630
   148
	return(0);
slouken@630
   149
}
slouken@630
   150
slouken@630
   151
void SDL_SYS_StopTimer(void)
slouken@630
   152
{
slouken@630
   153
	/* Don't need to do anything as we use SDL_timer_running
slouken@630
   154
	   to detect if we need to check the timer */
slouken@630
   155
}
slouken@630
   156
slouken@630
   157
slouken@630
   158
void RISCOS_CheckTimer()
slouken@630
   159
{
slouken@630
   160
	if (SDL_timer_running && SDL_GetTicks() - timerStart >= SDL_alarm_interval)
slouken@630
   161
	{
slouken@630
   162
		Uint32 ms;
slouken@630
   163
slouken@630
   164
		ms = SDL_alarm_callback(SDL_alarm_interval);
slouken@630
   165
		if ( ms != SDL_alarm_interval )
slouken@630
   166
		{
slouken@630
   167
			if ( ms )
slouken@630
   168
			{
slouken@630
   169
				SDL_alarm_interval = ROUND_RESOLUTION(ms);
slouken@630
   170
			} else
slouken@630
   171
			{
slouken@630
   172
				SDL_alarm_interval = 0;
slouken@630
   173
				SDL_timer_running = 0;
slouken@630
   174
			}
slouken@630
   175
		}
slouken@630
   176
		if (SDL_alarm_interval) timerStart = SDL_GetTicks();
slouken@630
   177
	}
slouken@630
   178
}
slouken@955
   179
slouken@955
   180
#else
slouken@955
   181
slouken@955
   182
/* Threaded version of timer - based on code for linux */
slouken@955
   183
slouken@955
   184
#include "SDL_thread.h"
slouken@955
   185
slouken@955
   186
/* Data to handle a single periodic alarm */
slouken@955
   187
static int timer_alive = 0;
slouken@955
   188
static SDL_Thread *timer = NULL;
slouken@955
   189
slouken@955
   190
static int RunTimer(void *unused)
slouken@955
   191
{
slouken@955
   192
	while ( timer_alive ) {
slouken@955
   193
		if ( SDL_timer_running ) {
slouken@955
   194
			SDL_ThreadedTimerCheck();
slouken@955
   195
		}
slouken@955
   196
		SDL_Delay(1);
slouken@955
   197
	}
slouken@955
   198
	return(0);
slouken@955
   199
}
slouken@955
   200
slouken@955
   201
/* This is only called if the event thread is not running */
slouken@955
   202
int SDL_SYS_TimerInit(void)
slouken@955
   203
{
slouken@955
   204
	timer_alive = 1;
slouken@955
   205
	timer = SDL_CreateThread(RunTimer, NULL);
slouken@955
   206
	if ( timer == NULL )
slouken@955
   207
		return(-1);
slouken@955
   208
	return(SDL_SetTimerThreaded(1));
slouken@955
   209
}
slouken@955
   210
slouken@955
   211
void SDL_SYS_TimerQuit(void)
slouken@955
   212
{
slouken@955
   213
	timer_alive = 0;
slouken@955
   214
	if ( timer ) {
slouken@955
   215
		SDL_WaitThread(timer, NULL);
slouken@955
   216
		timer = NULL;
slouken@955
   217
	}
slouken@955
   218
}
slouken@955
   219
slouken@955
   220
int SDL_SYS_StartTimer(void)
slouken@955
   221
{
slouken@1035
   222
	SDL_SetError("Internal logic error: RISC OS uses threaded timer");
slouken@955
   223
	return(-1);
slouken@955
   224
}
slouken@955
   225
slouken@955
   226
void SDL_SYS_StopTimer(void)
slouken@955
   227
{
slouken@955
   228
	return;
slouken@955
   229
}
slouken@955
   230
slouken@1361
   231
#endif /* SDL_THREADS_DISABLED */
slouken@1635
   232
slouken@1635
   233
#endif /* SDL_TIMER_RISCOS */