From 64b739bc1e8ee19cc65a7e5105e15331a300054a Mon Sep 17 00:00:00 2001 From: Anonymous Maarten Date: Thu, 16 Mar 2023 16:56:16 +0100 Subject: [PATCH] testlock: parse arguments using SDLTest_CommonState + extra arguments --- test/testlock.c | 115 +++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 100 insertions(+), 15 deletions(-) diff --git a/test/testlock.c b/test/testlock.c index a4abc0bd3..a0189e4b2 100644 --- a/test/testlock.c +++ b/test/testlock.c @@ -19,11 +19,15 @@ #include #include +#include static SDL_mutex *mutex = NULL; static SDL_threadID mainthread; -static SDL_Thread *threads[6]; static SDL_AtomicInt doterminate; +static int nb_threads = 6; +static SDL_Thread **threads; +static int worktime = 1000; +static SDLTest_CommonState *state; /** * SDL_Quit() shouldn't be used with atexit() directly because @@ -33,11 +37,12 @@ static void SDL_Quit_Wrapper(void) { SDL_Quit(); + SDLTest_CommonDestroyState(state); } static void printid(void) { - SDL_Log("Process %lu: exiting\n", SDL_ThreadID()); + SDL_Log("Thread %lu: exiting\n", SDL_ThreadID()); } static void terminate(int sig) @@ -50,30 +55,35 @@ static void closemutex(int sig) { SDL_threadID id = SDL_ThreadID(); int i; - SDL_Log("Process %lu: Cleaning up...\n", id == mainthread ? 0 : id); + SDL_Log("Thread %lu: Cleaning up...\n", id == mainthread ? 0 : id); SDL_AtomicSet(&doterminate, 1); - for (i = 0; i < 6; ++i) { - SDL_WaitThread(threads[i], NULL); + if (threads) { + for (i = 0; i < nb_threads; ++i) { + SDL_WaitThread(threads[i], NULL); + } + SDL_free(threads); + threads = NULL; } SDL_DestroyMutex(mutex); exit(sig); } static int SDLCALL -Run(void *data) +DoWork(void *data) { if (SDL_ThreadID() == mainthread) { (void)signal(SIGTERM, closemutex); } + SDL_Log("Thread %lu: starting up", SDL_ThreadID()); while (!SDL_AtomicGet(&doterminate)) { - SDL_Log("Process %lu ready to work\n", SDL_ThreadID()); + SDL_Log("Thread %lu: ready to work\n", SDL_ThreadID()); if (SDL_LockMutex(mutex) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't lock mutex: %s", SDL_GetError()); exit(1); } - SDL_Log("Process %lu, working!\n", SDL_ThreadID()); - SDL_Delay(1 * 1000); - SDL_Log("Process %lu, done!\n", SDL_ThreadID()); + SDL_Log("Thread %lu: start work!\n", SDL_ThreadID()); + SDL_Delay(1 * worktime); + SDL_Log("Thread %lu: work done!\n", SDL_ThreadID()); if (SDL_UnlockMutex(mutex) < 0) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't unlock mutex: %s", SDL_GetError()); exit(1); @@ -82,19 +92,87 @@ Run(void *data) SDL_Delay(10); } if (SDL_ThreadID() == mainthread && SDL_AtomicGet(&doterminate)) { - SDL_Log("Process %lu: raising SIGTERM\n", SDL_ThreadID()); + SDL_Log("Thread %lu: raising SIGTERM\n", SDL_ThreadID()); (void)raise(SIGTERM); } + SDL_Log("Thread %lu: exiting!\n", SDL_ThreadID()); return 0; } +#if !defined(_WIN32) +Uint32 hit_timeout(Uint32 interval, void *param) { + SDL_Log("Hit timeout! Sending SIGINT!"); + kill(0, SIGINT); + return 0; +} +#endif + int main(int argc, char *argv[]) { int i; - int maxproc = 6; +#if !defined(_WIN32) + int timeout = 0; +#endif + + /* Initialize test framework */ + state = SDLTest_CommonCreateState(argv, 0); + if (state == NULL) { + return 1; + } /* Enable standard application logging */ SDL_LogSetPriority(SDL_LOG_CATEGORY_APPLICATION, SDL_LOG_PRIORITY_INFO); + /* Parse commandline */ + for (i = 1; i < argc;) { + int consumed; + + consumed = SDLTest_CommonArg(state, i); + if (!consumed) { + if (SDL_strcmp(argv[i], "--nbthreads") == 0) { + if (argv[i + 1]) { + char *endptr; + nb_threads = SDL_strtol(argv[i + 1], &endptr, 0); + if (endptr != argv[i + 1] && *endptr == '\0' && nb_threads > 0) { + consumed = 2; + } + } + } else if (SDL_strcmp(argv[i], "--worktime") == 0) { + if (argv[i + 1]) { + char *endptr; + nb_threads = SDL_strtol(argv[i + 1], &endptr, 0); + if (endptr != argv[i + 1] && *endptr == '\0' && nb_threads > 0) { + consumed = 2; + } + } +#if !defined(_WIN32) + } else if (SDL_strcmp(argv[i], "--timeout") == 0) { + if (argv[i + 1]) { + char *endptr; + timeout = SDL_strtol(argv[i + 1], &endptr, 0); + if (endptr != argv[i + 1] && *endptr == '\0' && timeout > 0) { + consumed = 2; + } + } +#endif + } + } + if (consumed <= 0) { + static const char *options[] = { + "[--nbthreads NB]", + "[--worktime ms]", +#if !defined(_WIN32) + "[--timeout ms]", +#endif + NULL, + }; + SDLTest_CommonLogUsage(state, argv[0], options); + exit(1); + } + + i += consumed; + } + + threads = SDL_malloc(nb_threads * sizeof(SDL_Thread*)); /* Load the SDL library */ if (SDL_Init(0) < 0) { @@ -114,16 +192,23 @@ int main(int argc, char *argv[]) mainthread = SDL_ThreadID(); SDL_Log("Main thread: %lu\n", mainthread); (void)atexit(printid); - for (i = 0; i < maxproc; ++i) { + for (i = 0; i < nb_threads; ++i) { char name[64]; (void)SDL_snprintf(name, sizeof(name), "Worker%d", i); - threads[i] = SDL_CreateThread(Run, name, NULL); + threads[i] = SDL_CreateThread(DoWork, name, &threads[i]); if (threads[i] == NULL) { SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "Couldn't create thread!\n"); } } + +#if !defined(_WIN32) + if (timeout) { + SDL_AddTimer(timeout, hit_timeout, NULL); + } +#endif + (void)signal(SIGINT, terminate); - Run(NULL); + DoWork(NULL); return 0; /* Never reached */ }