|
@@ -21,30 +21,74 @@
|
|
|
#define NUM_THREADS 10
|
|
|
|
|
|
static SDL_sem *sem;
|
|
|
-int alive = 1;
|
|
|
+int alive;
|
|
|
|
|
|
-int SDLCALL
|
|
|
-ThreadFunc(void *data)
|
|
|
+typedef struct Thread_State {
|
|
|
+ SDL_Thread * thread;
|
|
|
+ int number;
|
|
|
+ int loop_count;
|
|
|
+ int content_count;
|
|
|
+} Thread_State;
|
|
|
+
|
|
|
+static void
|
|
|
+killed(int sig)
|
|
|
+{
|
|
|
+ alive = 0;
|
|
|
+}
|
|
|
+
|
|
|
+static int SDLCALL
|
|
|
+ThreadFuncRealWorld(void *data)
|
|
|
{
|
|
|
- int threadnum = (int) (uintptr_t) data;
|
|
|
+ Thread_State *state = (Thread_State *) data;
|
|
|
while (alive) {
|
|
|
SDL_SemWait(sem);
|
|
|
SDL_Log("Thread number %d has got the semaphore (value = %d)!\n",
|
|
|
- threadnum, SDL_SemValue(sem));
|
|
|
+ state->number, 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));
|
|
|
+ state->number, SDL_SemValue(sem));
|
|
|
+ ++state->loop_count;
|
|
|
SDL_Delay(1); /* For the scheduler */
|
|
|
}
|
|
|
- SDL_Log("Thread number %d exiting.\n", threadnum);
|
|
|
+ SDL_Log("Thread number %d exiting.\n", state->number);
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
static void
|
|
|
-killed(int sig)
|
|
|
-{
|
|
|
+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
|
|
@@ -65,21 +109,19 @@ TestWaitTimeout(void)
|
|
|
duration = end_ticks - start_ticks;
|
|
|
|
|
|
/* Accept a little offset in the effective wait */
|
|
|
- if (duration > 1900 && duration < 2050)
|
|
|
- SDL_Log("Wait done.\n");
|
|
|
- else
|
|
|
- SDL_Log("Wait took %d milliseconds\n", duration);
|
|
|
+ SDL_assert(duration > 1900 && duration < 2050);
|
|
|
+ SDL_Log("Wait took %d milliseconds\n\n", duration);
|
|
|
|
|
|
/* Check to make sure the return value indicates timed out */
|
|
|
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
|
|
|
main(int argc, char **argv)
|
|
|
{
|
|
|
- SDL_Thread *threads[NUM_THREADS];
|
|
|
- uintptr_t i;
|
|
|
int init_sem;
|
|
|
|
|
|
/* Enable standard application logging */
|
|
@@ -99,29 +141,9 @@ main(int argc, char **argv)
|
|
|
signal(SIGINT, killed);
|
|
|
|
|
|
init_sem = atoi(argv[1]);
|
|
|
- sem = SDL_CreateSemaphore(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);
|
|
|
+ if (init_sem > 0) {
|
|
|
+ TestRealWorld(init_sem);
|
|
|
}
|
|
|
- SDL_Log("Finished waiting for threads\n");
|
|
|
-
|
|
|
- SDL_DestroySemaphore(sem);
|
|
|
|
|
|
TestWaitTimeout();
|
|
|
|