Semaphore test: Put test into separate function.

This commit is contained in:
Joel Linn 2020-12-23 13:35:35 -08:00
parent 548cb90893
commit 95a6d4e848

View File

@ -21,25 +21,14 @@
#define NUM_THREADS 10 #define NUM_THREADS 10
static SDL_sem *sem; static SDL_sem *sem;
int alive = 1; int alive;
int SDLCALL typedef struct Thread_State {
ThreadFunc(void *data) SDL_Thread * thread;
{ int number;
int threadnum = (int) (uintptr_t) data; int loop_count;
while (alive) { int content_count;
SDL_SemWait(sem); } Thread_State;
SDL_Log("Thread number %d has got the semaphore (value = %d)!\n",
threadnum, SDL_SemValue(sem));
SDL_Delay(200);
SDL_SemPost(sem);
SDL_Log("Thread number %d has released the semaphore (value = %d)!\n",
threadnum, SDL_SemValue(sem));
SDL_Delay(1); /* For the scheduler */
}
SDL_Log("Thread number %d exiting.\n", threadnum);
return 0;
}
static void static void
killed(int sig) killed(int sig)
@ -47,6 +36,61 @@ killed(int sig)
alive = 0; alive = 0;
} }
static int SDLCALL
ThreadFuncRealWorld(void *data)
{
Thread_State *state = (Thread_State *) data;
while (alive) {
SDL_SemWait(sem);
SDL_Log("Thread number %d has got the semaphore (value = %d)!\n",
state->number, SDL_SemValue(sem));
SDL_Delay(200);
SDL_SemPost(sem);
SDL_Log("Thread number %d has released the semaphore (value = %d)!\n",
state->number, SDL_SemValue(sem));
++state->loop_count;
SDL_Delay(1); /* For the scheduler */
}
SDL_Log("Thread number %d exiting.\n", state->number);
return 0;
}
static void
TestRealWorld(int init_sem) {
Thread_State thread_states[NUM_THREADS];
int i;
int loop_count;
sem = SDL_CreateSemaphore(init_sem);
SDL_Log("Running %d threads, semaphore value = %d\n", NUM_THREADS,
init_sem);
alive = 1;
/* Create all the threads */
for (i = 0; i < NUM_THREADS; ++i) {
char name[64];
SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i);
thread_states[i].number = i;
thread_states[i].loop_count = 0;
thread_states[i].thread = SDL_CreateThread(ThreadFuncRealWorld, name, (void *) &thread_states[i]);
}
/* Wait 10 seconds */
SDL_Delay(10 * 1000);
/* Wait for all threads to finish */
SDL_Log("Waiting for threads to finish\n");
alive = 0;
loop_count = 0;
for (i = 0; i < NUM_THREADS; ++i) {
SDL_WaitThread(thread_states[i].thread, NULL);
loop_count += thread_states[i].loop_count;
}
SDL_Log("Finished waiting for threads, ran %d loops in total\n\n", loop_count);
SDL_DestroySemaphore(sem);
}
static void static void
TestWaitTimeout(void) TestWaitTimeout(void)
{ {
@ -65,21 +109,19 @@ TestWaitTimeout(void)
duration = end_ticks - start_ticks; duration = end_ticks - start_ticks;
/* Accept a little offset in the effective wait */ /* Accept a little offset in the effective wait */
if (duration > 1900 && duration < 2050) SDL_assert(duration > 1900 && duration < 2050);
SDL_Log("Wait done.\n"); SDL_Log("Wait took %d milliseconds\n\n", duration);
else
SDL_Log("Wait took %d milliseconds\n", duration);
/* Check to make sure the return value indicates timed out */ /* Check to make sure the return value indicates timed out */
if (retval != SDL_MUTEX_TIMEDOUT) if (retval != SDL_MUTEX_TIMEDOUT)
SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_SemWaitTimeout returned: %d; expected: %d\n", retval, SDL_MUTEX_TIMEDOUT); SDL_LogError(SDL_LOG_CATEGORY_APPLICATION, "SDL_SemWaitTimeout returned: %d; expected: %d\n\n", retval, SDL_MUTEX_TIMEDOUT);
SDL_DestroySemaphore(sem);
} }
int int
main(int argc, char **argv) main(int argc, char **argv)
{ {
SDL_Thread *threads[NUM_THREADS];
uintptr_t i;
int init_sem; int init_sem;
/* Enable standard application logging */ /* Enable standard application logging */
@ -99,30 +141,10 @@ main(int argc, char **argv)
signal(SIGINT, killed); signal(SIGINT, killed);
init_sem = atoi(argv[1]); init_sem = atoi(argv[1]);
sem = SDL_CreateSemaphore(init_sem); if (init_sem > 0) {
TestRealWorld(init_sem);
SDL_Log("Running %d threads, semaphore value = %d\n", NUM_THREADS,
init_sem);
/* Create all the threads */
for (i = 0; i < NUM_THREADS; ++i) {
char name[64];
SDL_snprintf(name, sizeof (name), "Thread%u", (unsigned int) i);
threads[i] = SDL_CreateThread(ThreadFunc, name, (void *) i);
} }
/* Wait 10 seconds */
SDL_Delay(10 * 1000);
/* Wait for all threads to finish */
SDL_Log("Waiting for threads to finish\n");
alive = 0;
for (i = 0; i < NUM_THREADS; ++i) {
SDL_WaitThread(threads[i], NULL);
}
SDL_Log("Finished waiting for threads\n");
SDL_DestroySemaphore(sem);
TestWaitTimeout(); TestWaitTimeout();
SDL_Quit(); SDL_Quit();