test/testsem.c
author Ryan C. Gordon <icculus@icculus.org>
Sun, 02 Oct 2011 00:29:16 -0400
changeset 5969 3a041d215edc
parent 5535 96594ac5fd1a
child 6298 9110462bfc57
permissions -rw-r--r--
1.3 API CHANGE: Add support for naming threads.
     1 /*
     2   Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
     3 
     4   This software is provided 'as-is', without any express or implied
     5   warranty.  In no event will the authors be held liable for any damages
     6   arising from the use of this software.
     7 
     8   Permission is granted to anyone to use this software for any purpose,
     9   including commercial applications, and to alter it and redistribute it
    10   freely.
    11 */
    12 
    13 /* Simple test of the SDL semaphore code */
    14 
    15 #include <stdio.h>
    16 #include <stdlib.h>
    17 #include <signal.h>
    18 
    19 #include "SDL.h"
    20 #include "SDL_thread.h"
    21 
    22 #define NUM_THREADS 10
    23 
    24 static SDL_sem *sem;
    25 int alive = 1;
    26 
    27 int SDLCALL
    28 ThreadFunc(void *data)
    29 {
    30     int threadnum = (int) (uintptr_t) data;
    31     while (alive) {
    32         SDL_SemWait(sem);
    33         fprintf(stderr,
    34                 "Thread number %d has got the semaphore (value = %d)!\n",
    35                 threadnum, SDL_SemValue(sem));
    36         SDL_Delay(200);
    37         SDL_SemPost(sem);
    38         fprintf(stderr,
    39                 "Thread number %d has released the semaphore (value = %d)!\n",
    40                 threadnum, SDL_SemValue(sem));
    41         SDL_Delay(1);           /* For the scheduler */
    42     }
    43     printf("Thread number %d exiting.\n", threadnum);
    44     return 0;
    45 }
    46 
    47 static void
    48 killed(int sig)
    49 {
    50     alive = 0;
    51 }
    52 
    53 static void
    54 TestWaitTimeout(void)
    55 {
    56     Uint32 start_ticks;
    57     Uint32 end_ticks;
    58     Uint32 duration;
    59 
    60     sem = SDL_CreateSemaphore(0);
    61     printf("Waiting 2 seconds on semaphore\n");
    62 
    63     start_ticks = SDL_GetTicks();
    64     SDL_SemWaitTimeout(sem, 2000);
    65     end_ticks = SDL_GetTicks();
    66 
    67     duration = end_ticks - start_ticks;
    68 
    69     /* Accept a little offset in the effective wait */
    70     if (duration > 1900 && duration < 2050)
    71         printf("Wait done.\n");
    72     else
    73         fprintf(stderr, "Wait took %d milliseconds\n", duration);
    74 }
    75 
    76 int
    77 main(int argc, char **argv)
    78 {
    79     SDL_Thread *threads[NUM_THREADS];
    80     uintptr_t i;
    81     int init_sem;
    82 
    83     if (argc < 2) {
    84         fprintf(stderr, "Usage: %s init_value\n", argv[0]);
    85         return (1);
    86     }
    87 
    88     /* Load the SDL library */
    89     if (SDL_Init(0) < 0) {
    90         fprintf(stderr, "Couldn't initialize SDL: %s\n", SDL_GetError());
    91         return (1);
    92     }
    93     signal(SIGTERM, killed);
    94     signal(SIGINT, killed);
    95 
    96     init_sem = atoi(argv[1]);
    97     sem = SDL_CreateSemaphore(init_sem);
    98 
    99     printf("Running %d threads, semaphore value = %d\n", NUM_THREADS,
   100            init_sem);
   101     /* Create all the threads */
   102     for (i = 0; i < NUM_THREADS; ++i) {
   103         char name[64];
   104         SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i);
   105         threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i);
   106     }
   107 
   108     /* Wait 10 seconds */
   109     SDL_Delay(10 * 1000);
   110 
   111     /* Wait for all threads to finish */
   112     printf("Waiting for threads to finish\n");
   113     alive = 0;
   114     for (i = 0; i < NUM_THREADS; ++i) {
   115         SDL_WaitThread(threads[i], NULL);
   116     }
   117     printf("Finished waiting for threads\n");
   118 
   119     SDL_DestroySemaphore(sem);
   120 
   121     TestWaitTimeout();
   122 
   123     SDL_Quit();
   124     return (0);
   125 }