Atlas - testrwlock.c
Home / ext / SDL / test Lines: 1 | Size: 5551 bytes [Download] [Show on GitHub] [Search similar files] [Raw] [Raw (proxy)][FILE BEGIN]1/* 2 Copyright (C) 1997-2025 Sam Lantinga <[email protected]> 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 SDL_free(threads); 170 171 SDL_Log("Reader threads have terminated, quitting!"); 172 SDL_DestroyRWLock(rwlock); 173 SDL_Quit(); 174 SDLTest_CommonDestroyState(state); 175 176 return 0; 177} 178[FILE END](C) 2025 0x4248 (C) 2025 4248 Media and 4248 Systems, All part of 0x4248 See LICENCE files for more information. Not all files are by 0x4248 always check Licencing.