Parallel Programming - Start OpenMP Version
[matches/honours.git] / course / semester2 / pprog / assignment1 / mthread / nbody.c
index afd1d60..42b97cf 100644 (file)
@@ -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
 }

UCC git Repository :: git.ucc.asn.au