test/testsem.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 27 Jan 2011 00:34:12 -0800
changeset 5106 d547877e355e
parent 1895 c121d94672cb
child 5535 96594ac5fd1a
permissions -rw-r--r--
Colin Leroy 2011-01-26 04:24:20 PST

the pthread implementation of SDL_SemWaitTimeout() uses busy waiting, while
pthread's sem_timedwait() does work. Attached are patches that make use of it
     1 
     2 /* Simple test of the SDL semaphore code */
     3 
     4 #include <stdio.h>
     5 #include <stdlib.h>
     6 #include <signal.h>
     7 
     8 #include "SDL.h"
     9 #include "SDL_thread.h"
    10 
    11 #define NUM_THREADS 10
    12 
    13 static SDL_sem *sem;
    14 int alive = 1;
    15 
    16 int SDLCALL
    17 ThreadFunc(void *data)
    18 {
    19     int threadnum = (int) (uintptr_t) data;
    20     while (alive) {
    21         SDL_SemWait(sem);
    22         fprintf(stderr,
    23                 "Thread number %d has got the semaphore (value = %d)!\n",
    24                 threadnum, SDL_SemValue(sem));
    25         SDL_Delay(200);
    26         SDL_SemPost(sem);
    27         fprintf(stderr,
    28                 "Thread number %d has released the semaphore (value = %d)!\n",
    29                 threadnum, SDL_SemValue(sem));
    30         SDL_Delay(1);           /* For the scheduler */
    31     }
    32     printf("Thread number %d exiting.\n", threadnum);
    33     return 0;
    34 }
    35 
    36 static void
    37 killed(int sig)
    38 {
    39     alive = 0;
    40 }
    41 
    42 static void
    43 TestWaitTimeout(void)
    44 {
    45     Uint32 start_ticks;
    46     Uint32 end_ticks;
    47     Uint32 duration;
    48 
    49     sem = SDL_CreateSemaphore(0);
    50     printf("Waiting 2 seconds on semaphore\n");
    51 
    52     start_ticks = SDL_GetTicks();
    53     SDL_SemWaitTimeout(sem, 2000);
    54     end_ticks = SDL_GetTicks();
    55 
    56     duration = end_ticks - start_ticks;
    57 
    58     /* Accept a little offset in the effective wait */
    59     if (duration > 1900 && duration < 2050)
    60         printf("Wait done.\n");
    61     else
    62         fprintf(stderr, "Wait took %d milliseconds\n", duration);
    63 }
    64 
    65 int
    66 main(int argc, char **argv)
    67 {
    68     SDL_Thread *threads[NUM_THREADS];
    69     uintptr_t i;
    70     int init_sem;
    71 
    72     if (argc < 2) {
    73         fprintf(stderr, "Usage: %s init_value\n", argv[0]);
    74         return (1);
    75     }
    76 
    77     /* Load the SDL library */
    78     if (SDL_Init(0) < 0) {
    79         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
    80         return (1);
    81     }
    82     signal(SIGTERM, killed);
    83     signal(SIGINT, killed);
    84 
    85     init_sem = atoi(argv[1]);
    86     sem = SDL_CreateSemaphore(init_sem);
    87 
    88     printf("Running %d threads, semaphore value = %d\n", NUM_THREADS,
    89            init_sem);
    90     /* Create all the threads */
    91     for (i = 0; i < NUM_THREADS; ++i) {
    92         threads[i] = SDL_CreateThread(ThreadFunc, (void *) i);
    93     }
    94 
    95     /* Wait 10 seconds */
    96     SDL_Delay(10 * 1000);
    97 
    98     /* Wait for all threads to finish */
    99     printf("Waiting for threads to finish\n");
   100     alive = 0;
   101     for (i = 0; i < NUM_THREADS; ++i) {
   102         SDL_WaitThread(threads[i], NULL);
   103     }
   104     printf("Finished waiting for threads\n");
   105 
   106     SDL_DestroySemaphore(sem);
   107 
   108     TestWaitTimeout();
   109 
   110     SDL_Quit();
   111     return (0);
   112 }