src/timer/riscos/SDL_systimer.c
author Sam Lantinga <slouken@libsdl.org>
Fri, 10 Feb 2006 06:48:43 +0000
changeset 1358 c71e05b4dc2e
parent 1312 c9b51268668f
child 1361 19418e4422cb
permissions -rw-r--r--
More header massaging... works great on Windows. ;-)
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@630
    22
slouken@630
    23
#include <stdio.h>
slouken@630
    24
#include <time.h>
slouken@630
    25
#include <sys/time.h>
slouken@630
    26
#include <unistd.h>
slouken@630
    27
#include <string.h>
slouken@630
    28
#include <errno.h>
slouken@630
    29
slouken@630
    30
#include "SDL_timer.h"
slouken@630
    31
#include "SDL_timer_c.h"
slouken@630
    32
slouken@955
    33
#ifdef DISABLE_THREADS
slouken@630
    34
/* Timer start/reset time */
slouken@630
    35
static Uint32 timerStart;
slouken@630
    36
/* Timer running function */
slouken@630
    37
void RISCOS_CheckTimer();
slouken@955
    38
#else
slouken@955
    39
#include <pthread.h>
slouken@955
    40
extern Uint32 riscos_main_thread;
slouken@955
    41
extern int riscos_using_threads;
slouken@955
    42
extern Uint32 SDL_ThreadID();
slouken@955
    43
extern Uint32 SDL_EventThreadID(void);
slouken@955
    44
#endif
slouken@955
    45
slouken@630
    46
slouken@630
    47
extern void RISCOS_BackgroundTasks(void);
slouken@630
    48
slouken@630
    49
/* The first ticks value of the application */
slouken@630
    50
clock_t start;
slouken@630
    51
slouken@630
    52
void SDL_StartTicks(void)
slouken@630
    53
{
slouken@630
    54
	/* Set first ticks value */
slouken@630
    55
	start = clock();
slouken@630
    56
}
slouken@630
    57
slouken@630
    58
Uint32 SDL_GetTicks (void)
slouken@630
    59
{
slouken@630
    60
	clock_t ticks;
slouken@630
    61
slouken@630
    62
	ticks=clock()-start;
slouken@630
    63
slouken@630
    64
slouken@630
    65
#if CLOCKS_PER_SEC == 1000
slouken@630
    66
slouken@630
    67
	return(ticks);
slouken@630
    68
slouken@630
    69
#elif CLOCKS_PER_SEC == 100
slouken@630
    70
slouken@630
    71
	return (ticks * 10);
slouken@630
    72
slouken@630
    73
#else
slouken@630
    74
slouken@630
    75
	return ticks*(1000/CLOCKS_PER_SEC);
slouken@630
    76
slouken@630
    77
#endif
slouken@630
    78
slouken@630
    79
}
slouken@630
    80
slouken@630
    81
void SDL_Delay (Uint32 ms)
slouken@630
    82
{
slouken@630
    83
    Uint32 now,then,elapsed;
slouken@955
    84
#ifndef DISABLE_THREADS
slouken@955
    85
    int is_event_thread;
slouken@955
    86
    if (riscos_using_threads)
slouken@955
    87
    {
slouken@955
    88
       is_event_thread = 0;
slouken@955
    89
       if (SDL_EventThreadID())
slouken@955
    90
       {
slouken@955
    91
          if (SDL_EventThreadID() == SDL_ThreadID()) is_event_thread = 1;
slouken@955
    92
       } else if (SDL_ThreadID() == riscos_main_thread) is_event_thread = 1;
slouken@955
    93
    } else is_event_thread = 1;
slouken@955
    94
#endif
slouken@955
    95
slouken@1035
    96
        /*TODO: Next version of Unixlib may allow us to use usleep here */
slouken@1035
    97
        /*      for non event threads */
slouken@630
    98
slouken@630
    99
	/* Set the timeout interval - Linux only needs to do this once */
slouken@630
   100
	then = SDL_GetTicks();
slouken@630
   101
slouken@630
   102
	do {
slouken@630
   103
		/* Do background tasks required while sleeping as we are not multithreaded */
slouken@955
   104
#ifdef DISABLE_THREADS
slouken@630
   105
		RISCOS_BackgroundTasks();
slouken@955
   106
#else
slouken@955
   107
		/* For threaded build only run background tasks in event thread */
slouken@955
   108
		if (is_event_thread) RISCOS_BackgroundTasks();
slouken@955
   109
#endif
slouken@955
   110
slouken@630
   111
		/* Calculate the time interval left (in case of interrupt) */
slouken@630
   112
		now = SDL_GetTicks();
slouken@630
   113
		elapsed = (now-then);
slouken@630
   114
		then = now;
slouken@630
   115
		if ( elapsed >= ms ) {
slouken@630
   116
			break;
slouken@630
   117
		}
slouken@630
   118
		ms -= elapsed;
slouken@955
   119
#ifndef DISABLE_THREADS
slouken@955
   120
            /* Need to yield to let other threads have a go */
slouken@955
   121
            if (riscos_using_threads) pthread_yield();
slouken@955
   122
#endif
slouken@630
   123
slouken@630
   124
	} while ( 1 );
slouken@630
   125
}
slouken@630
   126
slouken@955
   127
#ifdef DISABLE_THREADS
slouken@955
   128
slouken@955
   129
/* Non-threaded version of timer */
slouken@955
   130
slouken@630
   131
int SDL_SYS_TimerInit(void)
slouken@630
   132
{
slouken@630
   133
	return(0);
slouken@630
   134
}
slouken@630
   135
slouken@630
   136
void SDL_SYS_TimerQuit(void)
slouken@630
   137
{
slouken@630
   138
	SDL_SetTimer(0, NULL);
slouken@630
   139
}
slouken@630
   140
slouken@630
   141
int SDL_SYS_StartTimer(void)
slouken@630
   142
{
slouken@630
   143
	timerStart = SDL_GetTicks();
slouken@630
   144
slouken@630
   145
	return(0);
slouken@630
   146
}
slouken@630
   147
slouken@630
   148
void SDL_SYS_StopTimer(void)
slouken@630
   149
{
slouken@630
   150
	/* Don't need to do anything as we use SDL_timer_running
slouken@630
   151
	   to detect if we need to check the timer */
slouken@630
   152
}
slouken@630
   153
slouken@630
   154
slouken@630
   155
void RISCOS_CheckTimer()
slouken@630
   156
{
slouken@630
   157
	if (SDL_timer_running && SDL_GetTicks() - timerStart >= SDL_alarm_interval)
slouken@630
   158
	{
slouken@630
   159
		Uint32 ms;
slouken@630
   160
slouken@630
   161
		ms = SDL_alarm_callback(SDL_alarm_interval);
slouken@630
   162
		if ( ms != SDL_alarm_interval )
slouken@630
   163
		{
slouken@630
   164
			if ( ms )
slouken@630
   165
			{
slouken@630
   166
				SDL_alarm_interval = ROUND_RESOLUTION(ms);
slouken@630
   167
			} else
slouken@630
   168
			{
slouken@630
   169
				SDL_alarm_interval = 0;
slouken@630
   170
				SDL_timer_running = 0;
slouken@630
   171
			}
slouken@630
   172
		}
slouken@630
   173
		if (SDL_alarm_interval) timerStart = SDL_GetTicks();
slouken@630
   174
	}
slouken@630
   175
}
slouken@955
   176
slouken@955
   177
#else
slouken@955
   178
slouken@955
   179
/* Threaded version of timer - based on code for linux */
slouken@955
   180
slouken@955
   181
#include "SDL_thread.h"
slouken@955
   182
slouken@955
   183
/* Data to handle a single periodic alarm */
slouken@955
   184
static int timer_alive = 0;
slouken@955
   185
static SDL_Thread *timer = NULL;
slouken@955
   186
slouken@955
   187
static int RunTimer(void *unused)
slouken@955
   188
{
slouken@955
   189
	while ( timer_alive ) {
slouken@955
   190
		if ( SDL_timer_running ) {
slouken@955
   191
			SDL_ThreadedTimerCheck();
slouken@955
   192
		}
slouken@955
   193
		SDL_Delay(1);
slouken@955
   194
	}
slouken@955
   195
	return(0);
slouken@955
   196
}
slouken@955
   197
slouken@955
   198
/* This is only called if the event thread is not running */
slouken@955
   199
int SDL_SYS_TimerInit(void)
slouken@955
   200
{
slouken@955
   201
	timer_alive = 1;
slouken@955
   202
	timer = SDL_CreateThread(RunTimer, NULL);
slouken@955
   203
	if ( timer == NULL )
slouken@955
   204
		return(-1);
slouken@955
   205
	return(SDL_SetTimerThreaded(1));
slouken@955
   206
}
slouken@955
   207
slouken@955
   208
void SDL_SYS_TimerQuit(void)
slouken@955
   209
{
slouken@955
   210
	timer_alive = 0;
slouken@955
   211
	if ( timer ) {
slouken@955
   212
		SDL_WaitThread(timer, NULL);
slouken@955
   213
		timer = NULL;
slouken@955
   214
	}
slouken@955
   215
}
slouken@955
   216
slouken@955
   217
int SDL_SYS_StartTimer(void)
slouken@955
   218
{
slouken@1035
   219
	SDL_SetError("Internal logic error: RISC OS uses threaded timer");
slouken@955
   220
	return(-1);
slouken@955
   221
}
slouken@955
   222
slouken@955
   223
void SDL_SYS_StopTimer(void)
slouken@955
   224
{
slouken@955
   225
	return;
slouken@955
   226
}
slouken@955
   227
slouken@955
   228
#endif /* DISABLE_THREADS */