test/testlock.c
author Sam Lantinga <slouken@libsdl.org>
Thu, 07 Dec 2017 16:08:09 -0800
changeset 11730 ac6c607e065c
parent 10737 3406a0f8b041
child 11811 5d94cb6b24d3
permissions -rw-r--r--
Enable building the Metal renderer by default, and weak link the Metal framework so the SDL library is safe to use on older Macs
Also generate iOS versions of the Metal shaders
slouken@5535
     1
/*
slouken@10737
     2
  Copyright (C) 1997-2017 Sam Lantinga <slouken@libsdl.org>
slouken@5535
     3
slouken@5535
     4
  This software is provided 'as-is', without any express or implied
slouken@5535
     5
  warranty.  In no event will the authors be held liable for any damages
slouken@5535
     6
  arising from the use of this software.
slouken@5535
     7
slouken@5535
     8
  Permission is granted to anyone to use this software for any purpose,
slouken@5535
     9
  including commercial applications, and to alter it and redistribute it
slouken@5535
    10
  freely.
slouken@5535
    11
*/
slouken@0
    12
slouken@7191
    13
/* Test the thread and mutex locking functions
slouken@0
    14
   Also exercises the system's signal/thread interaction
slouken@0
    15
*/
slouken@0
    16
slouken@0
    17
#include <signal.h>
slouken@0
    18
#include <stdio.h>
philipp@7442
    19
#include <stdlib.h> /* for atexit() */
slouken@0
    20
slouken@0
    21
#include "SDL.h"
slouken@0
    22
slouken@0
    23
static SDL_mutex *mutex = NULL;
slouken@3578
    24
static SDL_threadID mainthread;
slouken@0
    25
static SDL_Thread *threads[6];
icculus@10003
    26
static SDL_atomic_t doterminate;
slouken@0
    27
icculus@1151
    28
/*
icculus@1151
    29
 * SDL_Quit() shouldn't be used with atexit() directly because
icculus@1151
    30
 *  calling conventions may differ...
icculus@1151
    31
 */
slouken@1895
    32
static void
slouken@1895
    33
SDL_Quit_Wrapper(void)
slouken@1895
    34
{
slouken@1895
    35
    SDL_Quit();
slouken@1895
    36
}
slouken@1895
    37
slouken@1895
    38
void
slouken@1895
    39
printid(void)
slouken@1895
    40
{
aschiffler@7639
    41
    SDL_Log("Process %lu:  exiting\n", SDL_ThreadID());
slouken@1895
    42
}
slouken@1895
    43
slouken@1895
    44
void
slouken@1895
    45
terminate(int sig)
icculus@1151
    46
{
slouken@1895
    47
    signal(SIGINT, terminate);
icculus@10003
    48
    SDL_AtomicSet(&doterminate, 1);
slouken@1895
    49
}
slouken@1895
    50
slouken@1895
    51
void
slouken@1895
    52
closemutex(int sig)
slouken@1895
    53
{
slouken@3578
    54
    SDL_threadID id = SDL_ThreadID();
slouken@1895
    55
    int i;
aschiffler@7639
    56
    SDL_Log("Process %lu:  Cleaning up...\n", id == mainthread ? 0 : id);
icculus@10003
    57
    SDL_AtomicSet(&doterminate, 1);
slouken@1895
    58
    for (i = 0; i < 6; ++i)
slouken@2779
    59
        SDL_WaitThread(threads[i], NULL);
slouken@1895
    60
    SDL_DestroyMutex(mutex);
slouken@1895
    61
    exit(sig);
icculus@1151
    62
}
icculus@1151
    63
slouken@1895
    64
int SDLCALL
slouken@1895
    65
Run(void *data)
slouken@0
    66
{
slouken@1895
    67
    if (SDL_ThreadID() == mainthread)
slouken@1895
    68
        signal(SIGTERM, closemutex);
icculus@10003
    69
    while (!SDL_AtomicGet(&doterminate)) {
aschiffler@7639
    70
        SDL_Log("Process %lu ready to work\n", SDL_ThreadID());
slouken@6977
    71
        if (SDL_LockMutex(mutex) < 0) {
aschiffler@7639
    72
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError());
slouken@1895
    73
            exit(1);
slouken@1895
    74
        }
aschiffler@7639
    75
        SDL_Log("Process %lu, working!\n", SDL_ThreadID());
slouken@1895
    76
        SDL_Delay(1 * 1000);
aschiffler@7639
    77
        SDL_Log("Process %lu, done!\n", SDL_ThreadID());
slouken@6977
    78
        if (SDL_UnlockMutex(mutex) < 0) {
aschiffler@7639
    79
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't unlock mutex: %s", SDL_GetError());
slouken@1895
    80
            exit(1);
slouken@1895
    81
        }
slouken@1895
    82
        /* If this sleep isn't done, then threads may starve */
slouken@1895
    83
        SDL_Delay(10);
slouken@2779
    84
    }
icculus@10003
    85
    if (SDL_ThreadID() == mainthread && SDL_AtomicGet(&doterminate)) {
aschiffler@7639
    86
        SDL_Log("Process %lu:  raising SIGTERM\n", SDL_ThreadID());
slouken@2779
    87
        raise(SIGTERM);
slouken@1895
    88
    }
slouken@1895
    89
    return (0);
slouken@0
    90
}
slouken@0
    91
slouken@1895
    92
int
slouken@1895
    93
main(int argc, char *argv[])
slouken@0
    94
{
slouken@1895
    95
    int i;
slouken@1895
    96
    int maxproc = 6;
slouken@0
    97
philipp@9922
    98
    /* Enable standard application logging */
aschiffler@7639
    99
    SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO);
aschiffler@7639
   100
slouken@1895
   101
    /* Load the SDL library */
slouken@1895
   102
    if (SDL_Init(0) < 0) {
aschiffler@7639
   103
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s\n", SDL_GetError());
slouken@1895
   104
        exit(1);
slouken@1895
   105
    }
slouken@1895
   106
    atexit(SDL_Quit_Wrapper);
slouken@0
   107
icculus@10003
   108
    SDL_AtomicSet(&doterminate, 0);
icculus@10003
   109
slouken@1895
   110
    if ((mutex = SDL_CreateMutex()) == NULL) {
aschiffler@7639
   111
        SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create mutex: %s\n", SDL_GetError());
slouken@1895
   112
        exit(1);
slouken@1895
   113
    }
slouken@0
   114
slouken@1895
   115
    mainthread = SDL_ThreadID();
aschiffler@7639
   116
    SDL_Log("Main thread: %lu\n", mainthread);
slouken@1895
   117
    atexit(printid);
slouken@1895
   118
    for (i = 0; i < maxproc; ++i) {
icculus@5969
   119
        char name[64];
icculus@5969
   120
        SDL_snprintf(name, sizeof (name), "Worker%d", i);
icculus@5969
   121
        if ((threads[i] = SDL_CreateThread(Run, name, NULL)) == NULL)
aschiffler@7639
   122
            SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread!\n");
slouken@1895
   123
    }
slouken@1895
   124
    signal(SIGINT, terminate);
slouken@1895
   125
    Run(NULL);
slouken@0
   126
slouken@1895
   127
    return (0);                 /* Never reached */
slouken@0
   128
}