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