testsem.c (3378B)
1/* 2 Copyright (C) 1997-2014 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 24static SDL_sem *sem; 25int alive = 1; 26 27int SDLCALL 28ThreadFunc(void *data) 29{ 30 int threadnum = (int) (uintptr_t) data; 31 while (alive) { 32 SDL_SemWait(sem); 33 SDL_Log("Thread number %d has got the semaphore (value = %d)!\n", 34 threadnum, SDL_SemValue(sem)); 35 SDL_Delay(200); 36 SDL_SemPost(sem); 37 SDL_Log("Thread number %d has released the semaphore (value = %d)!\n", 38 threadnum, SDL_SemValue(sem)); 39 SDL_Delay(1); /* For the scheduler */ 40 } 41 SDL_Log("Thread number %d exiting.\n", threadnum); 42 return 0; 43} 44 45static void 46killed(int sig) 47{ 48 alive = 0; 49} 50 51static void 52TestWaitTimeout(void) 53{ 54 Uint32 start_ticks; 55 Uint32 end_ticks; 56 Uint32 duration; 57 int retval; 58 59 sem = SDL_CreateSemaphore(0); 60 SDL_Log("Waiting 2 seconds on semaphore\n"); 61 62 start_ticks = SDL_GetTicks(); 63 retval = SDL_SemWaitTimeout(sem, 2000); 64 end_ticks = SDL_GetTicks(); 65 66 duration = end_ticks - start_ticks; 67 68 /* Accept a little offset in the effective wait */ 69 if (duration > 1900 && duration < 2050) 70 SDL_Log("Wait done.\n"); 71 else 72 SDL_Log("Wait took %d milliseconds\n", duration); 73 74 /* Check to make sure the return value indicates timed out */ 75 if (retval != SDL_MUTEX_TIMEDOUT) 76 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_SemWaitTimeout returned: %d; expected: %d\n", retval, SDL_MUTEX_TIMEDOUT); 77} 78 79int 80main(int argc, char **argv) 81{ 82 SDL_Thread *threads[NUM_THREADS]; 83 uintptr_t i; 84 int init_sem; 85 86 /* Enable standard application logging */ 87 SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); 88 89 if (argc < 2) { 90 SDL_Log("Usage: %s init_value\n", argv[0]); 91 return (1); 92 } 93 94 /* Load the SDL library */ 95 if (SDL_Init(0) < 0) { 96 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError()); 97 return (1); 98 } 99 signal(SIGTERM, killed); 100 signal(SIGINT, killed); 101 102 init_sem = atoi(argv[1]); 103 sem = SDL_CreateSemaphore(init_sem); 104 105 SDL_Log("Running %d threads, semaphore value = %d\n", NUM_THREADS, 106 init_sem); 107 /* Create all the threads */ 108 for (i = 0; i < NUM_THREADS; ++i) { 109 char name[64]; 110 SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i); 111 threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i); 112 } 113 114 /* Wait 10 seconds */ 115 SDL_Delay(10 * 1000); 116 117 /* Wait for all threads to finish */ 118 SDL_Log("Waiting for threads to finish\n"); 119 alive = 0; 120 for (i = 0; i < NUM_THREADS; ++i) { 121 SDL_WaitThread(threads[i], NULL); 122 } 123 SDL_Log("Finished waiting for threads\n"); 124 125 SDL_DestroySemaphore(sem); 126 127 TestWaitTimeout(); 128 129 SDL_Quit(); 130 return (0); 131}