/** Mutex locks and semaphores * Parallel version of estimating Pi. Based on randomly throwing darts at a 1x1 * square board with a circle of diameter 1. The distance from the centre (0,0) * to the dart is calculated using pythagorean theorem. If the distance to the * dart is < 1, then the dart is counted as a hit. * * This code should compile and run as is. * * Compilation: gcc -Wall -Wextra -Wpedantic -Wconversion -Wstrict-prototypes * -Wmissing-declarations -lpthread */ #include #include #include #include #include #include /** Global variables */ /** HINT: mutex locks and semaphores should be global variables */ /* the number of hits in the circle */ static long int circle_count = 0; /** Total number of concurrent threads. This represents a resource such as the * number of CPU cores available, for example 4 */ static long int num_concurrent_threads; /** Prototype for the thread that will be created */ void *worker(void *param); int main(int argc, const char *argv[]) { if (argc < 4) { fprintf(stderr, "Not enough arguements. "); fprintf(stderr, "Usage: %s ", argv[0]); exit(128); } /** Number of darts to throw, for example 50 000 000 */ long int num_darts; /** Total number of threads to start, for example 8 */ long int num_total_threads; num_darts = strtol(argv[1], NULL, 10); num_total_threads = strtol(argv[2], NULL, 10); num_concurrent_threads = strtol(argv[2], NULL, 10); /** Seed the random number generator */ srand((unsigned)time(NULL)); /** Calculate how many darts each thread will throw */ long int darts_per_thread = num_darts / num_total_threads; /** Start the worker threads and wait for them to finish. There are more * threads started than can run concurrently. */ pthread_t *workers; workers = (pthread_t *)calloc((unsigned long)num_total_threads, sizeof(pthread_t)); for (int i = 0; i < num_total_threads; i++) pthread_create(&workers[i], 0, worker, &darts_per_thread); for (int i = 0; i < num_total_threads; i++) pthread_join(workers[i], NULL); /** Estimate Pi */ double estimated_pi; estimated_pi = 4.0 * (double)circle_count / (double)num_darts; printf("Pi = %f ", estimated_pi); return 0; } void *worker(void *param) { int number_of_darts; number_of_darts = *((int *)param); int hit_count = 0; double x, y; for (int i = 0; i < number_of_darts; i++) { /** Determine if this thread can acquire resources to run */ /** --------------------------- */ /* generate random numbers between -1.0 and +1.0 (exclusive) */ x = (rand() / ((double)RAND_MAX + 1.0)) * 2.0 - 1.0; y = (rand() / ((double)RAND_MAX + 1.0)) * 2.0 - 1.0; /** Determine if dart landed in circle */ if (sqrt(x * x + y * y) < 1.0) { ++hit_count; } /** --------------------------- */ } circle_count += hit_count; pthread_exit(0); }