test/testlock.c
author Andreas Schiffler <aschiffler@ferzkopp.net>
Wed, 26 Dec 2012 22:26:44 -0800
changeset 6773 5ebc5a9e35b4
parent 5969 3a041d215edc
child 6977 b73d51026c68
permissions -rw-r--r--
Add surface test suite; minor improvements to render suite; refactor image saving into test lib compare function; fix for Haiku build
     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 /* Test the thread and mutex locking functions 
    14    Also exercises the system's signal/thread interaction
    15 */
    16 
    17 #include <signal.h>
    18 #include <stdio.h>
    19 
    20 #include "SDL.h"
    21 #include "SDL_mutex.h"
    22 #include "SDL_thread.h"
    23 
    24 static SDL_mutex *mutex = NULL;
    25 static SDL_threadID mainthread;
    26 static SDL_Thread *threads[6];
    27 static volatile int doterminate = 0;
    28 
    29 /*
    30  * SDL_Quit() shouldn't be used with atexit() directly because
    31  *  calling conventions may differ...
    32  */
    33 static void
    34 SDL_Quit_Wrapper(void)
    35 {
    36     SDL_Quit();
    37 }
    38 
    39 void
    40 printid(void)
    41 {
    42     printf("Process %lu:  exiting\n", SDL_ThreadID());
    43 }
    44 
    45 void
    46 terminate(int sig)
    47 {
    48     signal(SIGINT, terminate);
    49     doterminate = 1;
    50 }
    51 
    52 void
    53 closemutex(int sig)
    54 {
    55     SDL_threadID id = SDL_ThreadID();
    56     int i;
    57     printf("Process %lu:  Cleaning up...\n", id == mainthread ? 0 : id);
    58     doterminate = 1;
    59     for (i = 0; i < 6; ++i)
    60         SDL_WaitThread(threads[i], NULL);
    61     SDL_DestroyMutex(mutex);
    62     exit(sig);
    63 }
    64 
    65 int SDLCALL
    66 Run(void *data)
    67 {
    68     if (SDL_ThreadID() == mainthread)
    69         signal(SIGTERM, closemutex);
    70     while (!doterminate) {
    71         printf("Process %lu ready to work\n", SDL_ThreadID());
    72         if (SDL_mutexP(mutex) < 0) {
    73             fprintf(stderr, "Couldn't lock mutex: %s", SDL_GetError());
    74             exit(1);
    75         }
    76         printf("Process %lu, working!\n", SDL_ThreadID());
    77         SDL_Delay(1 * 1000);
    78         printf("Process %lu, done!\n", SDL_ThreadID());
    79         if (SDL_mutexV(mutex) < 0) {
    80             fprintf(stderr, "Couldn't unlock mutex: %s", SDL_GetError());
    81             exit(1);
    82         }
    83         /* If this sleep isn't done, then threads may starve */
    84         SDL_Delay(10);
    85     }
    86     if (SDL_ThreadID() == mainthread && doterminate) {
    87         printf("Process %lu:  raising SIGTERM\n", SDL_ThreadID());
    88         raise(SIGTERM);
    89     }
    90     return (0);
    91 }
    92 
    93 int
    94 main(int argc, char *argv[])
    95 {
    96     int i;
    97     int maxproc = 6;
    98 
    99     /* Load the SDL library */
   100     if (SDL_Init(0) < 0) {
   101         fprintf(stderr, "%s\n", SDL_GetError());
   102         exit(1);
   103     }
   104     atexit(SDL_Quit_Wrapper);
   105 
   106     if ((mutex = SDL_CreateMutex()) == NULL) {
   107         fprintf(stderr, "Couldn't create mutex: %s\n", SDL_GetError());
   108         exit(1);
   109     }
   110 
   111     mainthread = SDL_ThreadID();
   112     printf("Main thread: %lu\n", mainthread);
   113     atexit(printid);
   114     for (i = 0; i < maxproc; ++i) {
   115         char name[64];
   116         SDL_snprintf(name, sizeof (name), "Worker%d", i);
   117         if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL)
   118             fprintf(stderr, "Couldn't create thread!\n");
   119     }
   120     signal(SIGINT, terminate);
   121     Run(NULL);
   122 
   123     return (0);                 /* Never reached */
   124 }