test/torturethread.c
author Ryan C. Gordon <icculus@icculus.org>
Tue, 26 May 2015 21:13:27 -0400
changeset 9648 e6bf740c92f8
parent 9619 b94b6d0bff0f
child 9649 d7762e30ba24
permissions -rw-r--r--
Added a hint to specify new thread stack size (thanks, Gabriel!).

Fixes Bugzilla #2019.

(we'll do a better fix when we break the API in SDL 2.1.)
     1 /*
     2   Copyright (C) 1997-2015 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 threading code */
    14 
    15 #include <stdio.h>
    16 #include <stdlib.h>
    17 #include <signal.h>
    18 #include <string.h>
    19 
    20 #include "SDL.h"
    21 
    22 #define NUMTHREADS 10
    23 
    24 static char volatile time_for_threads_to_die[NUMTHREADS];
    25 
    26 /* Call this instead of exit(), so we can clean up SDL: atexit() is evil. */
    27 static void
    28 quit(int rc)
    29 {
    30     SDL_Quit();
    31     exit(rc);
    32 }
    33 
    34 int SDLCALL
    35 SubThreadFunc(void *data)
    36 {
    37     while (!*(int volatile *) data) {
    38         ;                       /* SDL_Delay(10); *//* do nothing */
    39     }
    40     return 0;
    41 }
    42 
    43 int SDLCALL
    44 ThreadFunc(void *data)
    45 {
    46     SDL_Thread *sub_threads[NUMTHREADS];
    47     int flags[NUMTHREADS];
    48     int i;
    49     int tid = (int) (uintptr_t) data;
    50 
    51     SDL_Log("Creating Thread %d\n", tid);
    52 
    53     for (i = 0; i < NUMTHREADS; i++) {
    54         char name[64];
    55         SDL_snprintf(name, sizeof (name), "Child%d_%d", tid, i);
    56         flags[i] = 0;
    57         sub_threads[i] = SDL_CreateThread(SubThreadFunc, name, &flags[i]);
    58     }
    59 
    60     SDL_Log("Thread '%d' waiting for signal\n", tid);
    61     while (time_for_threads_to_die[tid] != 1) {
    62         ;                       /* do nothing */
    63     }
    64 
    65     SDL_Log("Thread '%d' sending signals to subthreads\n", tid);
    66     for (i = 0; i < NUMTHREADS; i++) {
    67         flags[i] = 1;
    68         SDL_WaitThread(sub_threads[i], NULL);
    69     }
    70 
    71     SDL_Log("Thread '%d' exiting!\n", tid);
    72 
    73     return 0;
    74 }
    75 
    76 int
    77 main(int argc, char *argv[])
    78 {
    79     SDL_Thread *threads[NUMTHREADS];
    80     int i;
    81 
    82 	/* Enable standard application logging */
    83     SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
    84 
    85     /* Load the SDL library */
    86     if (SDL_Init(0) < 0) {
    87         SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't initialize SDL: %s\n", SDL_GetError());
    88         return (1);
    89     }
    90     
    91     SDL_SetHintWithPriority(SDL_HINT_THREAD_STACK_SIZE, SDL_getenv(SDL_HINT_THREAD_STACK_SIZE), SDL_HINT_OVERRIDE);
    92 
    93     signal(SIGSEGV, SIG_DFL);
    94     for (i = 0; i < NUMTHREADS; i++) {
    95         char name[64];
    96         SDL_snprintf(name, sizeof (name), "Parent%d", i);
    97         time_for_threads_to_die[i] = 0;
    98         threads[i] = SDL_CreateThread(ThreadFunc, name, (void*) (uintptr_t) i);
    99 
   100         if (threads[i] == NULL) {
   101             SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread: %s\n", SDL_GetError());
   102             quit(1);
   103         }
   104     }
   105 
   106     for (i = 0; i < NUMTHREADS; i++) {
   107         time_for_threads_to_die[i] = 1;
   108     }
   109 
   110     for (i = 0; i < NUMTHREADS; i++) {
   111         SDL_WaitThread(threads[i], NULL);
   112     }
   113     SDL_Quit();
   114     return (0);
   115 }