Parallel Programming - Finished pthreads
[matches/honours.git] / course / semester2 / pprog / assignment1 / single-thread / nbody.c
index e4b4bc7..ee510ed 100644 (file)
@@ -23,10 +23,12 @@ RUNSTATE runstate = RUN;
  * @param a - Body to print'
  * @param out - FILE* to print to
  */
-void Body_Print(Body * a, FILE * out)
+inline void Body_Print(Body * a, FILE * out)
 {
-       fprintf(out,"Body %p M=%f X=%f Y=%f Z=%f Fx=%f Fy=%f Fz=%f Vx=%f Vy=%f Vz=%f\n", 
-           (void*)a, a->mass, a->x[0], a->x[1], a->x[2], a->F[0], a->F[1], a->F[2], a->v[0], a->v[1], a->v[2]);
+       //fprintf(out,"Body %p M=%f X=%f Y=%f Z=%f Fx=%f Fy=%f Fz=%f Vx=%f Vy=%f Vz=%f\n", 
+           //(void*)a, a->mass, a->x[0], a->x[1], a->x[2], a->F[0], a->F[1], a->F[2], a->v[0], a->v[1], a->v[2]);
+       fprintf(out, "%f %f %f %f %f %f %f %f %f %f\n", 
+               a->mass, a->x[0], a->x[1], a->x[2], a->v[0], a->v[1], a->v[2], a->F[0], a->F[1], a->F[2]);
 }
 
 /**
@@ -35,7 +37,7 @@ void Body_Print(Body * a, FILE * out)
  * @param a - The Body
  * @param b - The System
  */
-void Body_Force(Body * a, System * s) 
+inline void Body_Force(Body * a, System * s) 
 {
        double distance;
        double con;
@@ -67,7 +69,7 @@ void Body_Force(Body * a, System * s)
  * @purpose Compute velocity of a body
  * @param a - The Body
  */
-void Body_Velocity(Body * a) 
+inline void Body_Velocity(Body * a) 
 {
        for (unsigned i = 0; i < DIMENSIONS; ++i)
                a->v[i] += a->F[i] / a->mass * DELTA_T;
@@ -78,7 +80,7 @@ void Body_Velocity(Body * a)
  * @purpose Compute position of a body
  * @param a - The Body
  */
-void Body_Position(Body * a) 
+inline void Body_Position(Body * a) 
 {
        for (unsigned i = 0; i < DIMENSIONS; ++i)
                a->x[i] += a->v[i] * DELTA_T;
@@ -89,7 +91,7 @@ void Body_Position(Body * a)
  * @purpose Compute forces and then positions for bodies in System
  * NOTE: Only used in the single threaded version of the program
  */
-void System_Compute(System * s)
+inline void System_Compute(System * s)
 {
        System_Forces(s, s);
        System_Positions(s);
@@ -103,7 +105,7 @@ void System_Compute(System * s)
  *      In multi threaded version, called with s2 == &universe, but s1 is constructed for each thread
  *             In nested multi-threaded version, s2 is constructed for the nested threads as well
  */
-void System_Forces(System * s1, System * s2) 
+inline void System_Forces(System * s1, System * s2) 
 {
        //printf("Compute forces for %p - %d bodies...\n", (void*)s1, s1->N);
        for (unsigned i = 0; i < s1->N; ++i)
@@ -119,13 +121,13 @@ void System_Forces(System * s1, System * s2)
  * @purpose Compute positions of all objects in System
  * @param s - The system
  */
-void System_Positions(System * s)
+inline void System_Positions(System * s)
 {
        //printf("Compute positions for %p - %d bodies...\n", (void*)s, s->N);
        for (unsigned i = 0; i < s->N; ++i)
                Body_Position(s->body+i);
        //printf("Compute positions for %p - Done!\n", (void*)s);
-       s->steps += 1;
+       
 }
 
 
@@ -137,7 +139,7 @@ void System_Positions(System * s)
  * @param s - The System
  * @param fileName - The input file
  */
-void System_Init(System * s, const char *fileName) 
+inline void System_Init(System * s, const char *fileName) 
 {
        char line[LINE_SIZE];
        char * token;
@@ -155,19 +157,23 @@ void System_Init(System * s, const char *fileName)
                if (fgets(line, LINE_SIZE, file) != NULL)
                {
                        Body * a = s->body+i;
-                       token = strtok(line, ",; ");
+                       token = strtok(line, ",; \t");
                        a->mass = atof(token);
                        
                        for (unsigned j = 0; j < DIMENSIONS; ++j)
                        {
-                               token = strtok(NULL, ",; ");
+                               token = strtok(NULL, ",; \t");
                                a->x[j] = atof(token);
                        }
                        for (unsigned j = 0; j < DIMENSIONS; ++j)
                        {
-                               token = strtok(NULL, ",; ");
+                               token = strtok(NULL, ",; \t");
                                a->v[j] = atof(token);
                        }
+
+                       // Ignore any additional tokens
+                       while (token != NULL)
+                               token = strtok(NULL, ",; \t");
                        //Body_Print(a);
                }
        }
@@ -182,19 +188,30 @@ void System_Init(System * s, const char *fileName)
  * @purpose Cleans up the universe by freeing all memory
  *      Also prints the bodies in the universe to a file specified in "options" if required.
  */
-void Universe_Cleanup()
+inline void Universe_Cleanup()
 {
+       //fprintf(stderr, "Called Universe_Cleanup()\n");
        if (options.output != NULL) // An output file was specified...
        {
-               FILE * save = fopen(options.output, "w");
+               FILE * save = NULL;
+               if (strcmp("stdout", options.output) == 0)
+                       save = stdout;
+               else if (strcmp("stderr", options.output) == 0)
+                       save = stderr;
+               else
+                       save = fopen(options.output, "w");
                if (save == NULL)
                        perror("Couldn't save universe to file.");
                else
                {
-                       fprintf(save, "# Final field:\n");
+                       // Print the output in the same format as the initial field file
+                       fprintf(save, "%u\n", universe.N);
+                               
                        for (unsigned i = 0; i < universe.N; ++i) // Print all bodies to the file
                        {
-                               Body_Print(universe.body+i, save);
+                               Body_Print(universe.body+i, save);                      
+                               
+                                                               
                        }
                        fclose(save);
                }
@@ -212,7 +229,7 @@ void Universe_Cleanup()
  *     - Clock cycles executed 
  *     - Equivelant time for a single thread to execute same number of clock cycles
  */
-void DisplayStatistics()
+inline void DisplayStatistics()
 {
        clock_t end = clock();
        struct timeval end_time;
@@ -232,11 +249,16 @@ void DisplayStatistics()
  * @purpose Helper to check whether the program is supposed to exit
  *     Does not check for user triggered quit
  *     Checks for either a timeout, or computation of the required number of steps
+ * 
+ * The reason timeouts are integers is because this function is called a lot in lots of threads
+ *     So using floats (and working out microseconds every time) is expensive
+ *
  */
-bool ExitCondition(void)
+inline bool ExitCondition(void)
 {
-       bool result = (runstate != RUN || (options.timeout > 0.00 && ((unsigned)(time(NULL) - options.start_time.tv_sec) >= options.timeout))
-               || (options.num_steps > 0 && universe.steps > options.num_steps));
-       //printf("runstate %d\n timeout %d\n steps %d\n", (int)(runstate != RUN), (int)(options.timeout > 0.00 && ((unsigned)(time(NULL) - options.start_time.tv_sec) >= options.timeout)), (int)(options.num_steps > 0 && universe.steps > options.num_steps));
+       bool result = (runstate != RUN || 
+                       (options.num_steps >= 0 && universe.steps >= options.num_steps) ||
+                       (options.timeout >= 0 && ((int)(time(NULL) - options.start_time.tv_sec) >= options.timeout)));
+       //fprintf(stderr,"runstate %d\n timeout %d\n steps %d\n", (int)(runstate != RUN), (int)(options.timeout > 0.00 && ((unsigned)(time(NULL) - options.start_time.tv_sec) >= options.timeout)), (int)(options.num_steps > 0 && universe.steps > options.num_steps));
        return result;
 }

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