X-Git-Url: https://git.ucc.asn.au/?a=blobdiff_plain;f=course%2Fsemester2%2Fpprog%2Fassignment1%2Fmthread%2Fnbody.c;h=42b97cf45acd0d45e305e35c5fe024a6c5fd18d7;hb=f012817dee17e24eee2e8951d138dab40b808ad3;hp=afd1d607dbd54b89edb9ca8166ea4fcbdebd21b1;hpb=a6366978284ba7c3762518e684e16561797053a5;p=matches%2Fhonours.git diff --git a/course/semester2/pprog/assignment1/mthread/nbody.c b/course/semester2/pprog/assignment1/mthread/nbody.c index afd1d607..42b97cf4 100644 --- a/course/semester2/pprog/assignment1/mthread/nbody.c +++ b/course/semester2/pprog/assignment1/mthread/nbody.c @@ -7,6 +7,8 @@ #include "nbody.h" // Declarations #include "../single-thread/nbody.c" // Include all functions from the single threaded version +#include "graphics.h" // For declaration of Graphics_Run only + // --- Variable declarations --- // pthread_t compute_thread; // The thread responsible for computations; it spawns worker threads @@ -86,19 +88,16 @@ void * Compute_Thread(void * arg) while (true) { - if (runstate != RUN) pthread_exit(NULL); //Check whether the main thread wants to exit + if (runstate != RUN) pthread_exit(NULL); //Check whether the thread needs to exit //Check whether the program should quit due to steps being computed, or a timeout - if (options.timeout > 0.0) + if (ExitCondition()) { - if ((unsigned)(time(NULL) - options.start_time.tv_sec) >= options.timeout) - QuitProgram(false); - } - - if (options.num_steps > 0 && universe.steps > options.num_steps) QuitProgram(false); + continue; // The check at the start of the next loop will stop the thread + } if (options.draw_graphics == false && options.verbosity != 0 && universe.steps % options.verbosity == 1) @@ -217,7 +216,8 @@ void * Position_Thread(void * s) */ void QuitProgram(bool error) { - + if (runstate == QUIT || runstate == QUIT_ERROR) + return; //Don't do anything if already quitting pthread_mutex_lock(&mutex_runstate); // aquire mutex if (error) // set the runstate runstate = QUIT_ERROR; @@ -247,29 +247,24 @@ void Thread_Cleanup(void) * @function Simulation_Run * @purpose Initialise and start the simulation. Will be called in the main thread. * Replaces the single-threaded macro that does nothing, and sets up the compute thread + * @param argc - Number of arguments - Passed to Graphics_Run if needed + * @param argv - Argument strings - Passed to Graphics_Run if needed */ -void Simulation_Run() +void Simulation_Run(int argc, char ** argv) { atexit(Thread_Cleanup); - if (options.draw_graphics == false) - { - Compute_Thread((void*)(&universe)); - - // If there are no graphics, run the computation loop in the main thread - // The call to pthread_exit(NULL) in the computation loop ends the main thread - - // This means the main function never calls the Graphics_Run function - // Without this condition here, Graphics_Display would essentially be running a busy loop in the main thread - - fprintf(stderr,"Should not see this\n"); - exit(EXIT_FAILURE); - } - - // Create a thread to handle computation loop - if (pthread_create(&compute_thread, NULL, Compute_Thread, (void*)&universe) != 0) + if (options.draw_graphics) { - perror("Error creating compute thread"); - exit(EXIT_FAILURE); + // The graphics are enabled, so create a thread to do computations + // Graphics are done in the main loop + if (pthread_create(&compute_thread, NULL, Compute_Thread, (void*)&universe) != 0) + { + perror("Error creating compute thread"); + exit(EXIT_FAILURE); + } + Graphics_Run(argc, argv); } + else + Compute_Thread((void*)(&universe)); // Graphics are disabled, so do computations in the main thread }