summaryrefslogtreecommitdiff
path: root/src/contrib/SDL-3.2.20/test/testrwlock.c
diff options
context:
space:
mode:
author3gg <3gg@shellblade.net>2025-08-30 16:53:58 -0700
committer3gg <3gg@shellblade.net>2025-08-30 16:53:58 -0700
commit6aaedb813fa11ba0679c3051bc2eb28646b9506c (patch)
tree34acbfc9840e02cb4753e6306ea7ce978bf8b58e /src/contrib/SDL-3.2.20/test/testrwlock.c
parent8f228ade99dd3d4c8da9b78ade1815c9adf85c8f (diff)
Update to SDL3
Diffstat (limited to 'src/contrib/SDL-3.2.20/test/testrwlock.c')
-rw-r--r--src/contrib/SDL-3.2.20/test/testrwlock.c176
1 files changed, 176 insertions, 0 deletions
diff --git a/src/contrib/SDL-3.2.20/test/testrwlock.c b/src/contrib/SDL-3.2.20/test/testrwlock.c
new file mode 100644
index 0000000..a80873c
--- /dev/null
+++ b/src/contrib/SDL-3.2.20/test/testrwlock.c
@@ -0,0 +1,176 @@
1/*
2 Copyright (C) 1997-2025 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 rwlock locking functions
14 Also exercises the system's signal/thread interaction
15*/
16
17#include <SDL3/SDL.h>
18#include <SDL3/SDL_main.h>
19#include <SDL3/SDL_test.h>
20
21static SDL_RWLock *rwlock = NULL;
22static SDL_ThreadID mainthread;
23static SDL_AtomicInt doterminate;
24static int nb_threads = 6;
25static SDL_Thread **threads;
26static int worktime = 1000;
27static int writerworktime = 100;
28static int timeout = 10000;
29static SDLTest_CommonState *state;
30
31static void DoWork(const int workticks) /* "Work" */
32{
33 const SDL_ThreadID tid = SDL_GetCurrentThreadID();
34 const bool is_reader = tid != mainthread;
35 const char *typestr = is_reader ? "Reader" : "Writer";
36
37 SDL_Log("%s Thread %" SDL_PRIu64 ": ready to work", typestr, tid);
38 if (is_reader) {
39 SDL_LockRWLockForReading(rwlock);
40 } else {
41 SDL_LockRWLockForWriting(rwlock);
42 }
43
44 SDL_Log("%s Thread %" SDL_PRIu64 ": start work!", typestr, tid);
45 SDL_Delay(workticks);
46 SDL_Log("%s Thread %" SDL_PRIu64 ": work done!", typestr, tid);
47 SDL_UnlockRWLock(rwlock);
48
49 /* If this sleep isn't done, then threads may starve */
50 SDL_Delay(10);
51}
52
53static int SDLCALL
54ReaderRun(void *data)
55{
56 SDL_Log("Reader Thread %" SDL_PRIu64 ": starting up", SDL_GetCurrentThreadID());
57 while (!SDL_GetAtomicInt(&doterminate)) {
58 DoWork(worktime);
59 }
60 SDL_Log("Reader Thread %" SDL_PRIu64 ": exiting!", SDL_GetCurrentThreadID());
61 return 0;
62}
63
64int main(int argc, char *argv[])
65{
66 int i;
67
68 /* Initialize test framework */
69 state = SDLTest_CommonCreateState(argv, 0);
70 if (!state) {
71 return 1;
72 }
73
74 SDL_SetAtomicInt(&doterminate, 0);
75
76 /* Parse commandline */
77 for (i = 1; i < argc;) {
78 int consumed;
79
80 consumed = SDLTest_CommonArg(state, i);
81 if (!consumed) {
82 if (SDL_strcmp(argv[i], "--nbthreads") == 0) {
83 if (argv[i + 1]) {
84 char *endptr;
85 nb_threads = SDL_strtol(argv[i + 1], &endptr, 0);
86 if (endptr != argv[i + 1] && *endptr == '\0' && nb_threads > 0) {
87 consumed = 2;
88 }
89 }
90 } else if (SDL_strcmp(argv[i], "--worktime") == 0) {
91 if (argv[i + 1]) {
92 char *endptr;
93 worktime = SDL_strtol(argv[i + 1], &endptr, 0);
94 if (endptr != argv[i + 1] && *endptr == '\0' && worktime > 0) {
95 consumed = 2;
96 }
97 }
98 } else if (SDL_strcmp(argv[i], "--writerworktime") == 0) {
99 if (argv[i + 1]) {
100 char *endptr;
101 writerworktime = SDL_strtol(argv[i + 1], &endptr, 0);
102 if (endptr != argv[i + 1] && *endptr == '\0' && writerworktime > 0) {
103 consumed = 2;
104 }
105 }
106 } else if (SDL_strcmp(argv[i], "--timeout") == 0) {
107 if (argv[i + 1]) {
108 char *endptr;
109 timeout = (Uint64) SDL_strtol(argv[i + 1], &endptr, 0);
110 if (endptr != argv[i + 1] && *endptr == '\0' && timeout > 0) {
111 consumed = 2;
112 }
113 }
114 }
115 }
116 if (consumed <= 0) {
117 static const char *options[] = {
118 "[--nbthreads NB]",
119 "[--worktime ms]",
120 "[--writerworktime ms]",
121 "[--timeout ms]",
122 NULL,
123 };
124 SDLTest_CommonLogUsage(state, argv[0], options);
125 return 1;
126 }
127
128 i += consumed;
129 }
130
131 threads = SDL_malloc(nb_threads * sizeof(SDL_Thread*));
132
133 /* Load the SDL library */
134 if (!SDL_Init(0)) {
135 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "%s", SDL_GetError());
136 return 1;
137 }
138
139 SDL_SetAtomicInt(&doterminate, 0);
140
141 rwlock = SDL_CreateRWLock();
142 if (!rwlock) {
143 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create rwlock: %s", SDL_GetError());
144 SDL_Quit();
145 SDLTest_CommonDestroyState(state);
146 return 1;
147 }
148
149 mainthread = SDL_GetCurrentThreadID();
150 SDL_Log("Writer thread: %" SDL_PRIu64, mainthread);
151 for (i = 0; i < nb_threads; ++i) {
152 char name[64];
153 (void)SDL_snprintf(name, sizeof(name), "Reader%d", i);
154 threads[i] = SDL_CreateThread(ReaderRun, name, NULL);
155 if (threads[i] == NULL) {
156 SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create reader thread! %s", SDL_GetError());
157 }
158 }
159
160 while (!SDL_GetAtomicInt(&doterminate) && (SDL_GetTicks() < ((Uint64) timeout))) {
161 DoWork(writerworktime);
162 }
163
164 SDL_SetAtomicInt(&doterminate, 1);
165 SDL_Log("Waiting on reader threads to terminate...");
166 for (i = 0; i < nb_threads; ++i) {
167 SDL_WaitThread(threads[i], NULL);
168 }
169
170 SDL_Log("Reader threads have terminated, quitting!");
171 SDL_DestroyRWLock(rwlock);
172 SDL_Quit();
173 SDLTest_CommonDestroyState(state);
174
175 return 0;
176}