- if (runstate == RUN) // If this is true, as far as child threads are concerned, the simulation is still running
- QuitProgram(false); // So call QuitProgram which will set runstate, and cause child threads to exit
- pthread_join(compute_thread, NULL);
- free(worker_thread);
- free(sub_system);
+
+
+ // Threads recheck the exit condition whenever they leave a barrier.
+ // These calls will stop any threads waiting forever in a barrier for threads that exited before getting to the barrier.
+ Barrier_ForceExit(&force_barrier);
+ Barrier_ForceExit(&position_barrier);
+
+
+ if (options.draw_graphics) // If the graphics are enabled...
+ {
+ // Then there is a computation thread, since graphics are done in the main thread
+ pthread_join(compute_thread, NULL);
+ }
+
+ #ifdef PERSISTENT_THREADS
+ for (unsigned i = 0; i < options.num_threads-1; ++i)
+ {
+ pthread_join(worker_thread[i], NULL);
+ }
+ #else
+ // All other worker threads (if they were spawned) are terminated in Compute_Thread
+ #endif //PERSISTENT_THREADS
+
+ // Scary memory management here.
+ if (worker_thread != NULL)
+ free(worker_thread);
+ if (sub_system != NULL)
+ free(sub_system);
+ worker_thread = NULL;
+ sub_system = NULL;
+