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