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