Created
December 3, 2013 13:12
-
-
Save wandernauta/7768928 to your computer and use it in GitHub Desktop.
pithread.c
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// Includes | |
#include <math.h> // for pow | |
#include <pthread.h> | |
#include <stdio.h> | |
#include <stdlib.h> | |
#include <time.h> | |
#include <unistd.h> | |
// Useful macro's | |
#define lock pthread_mutex_lock(&job->mutex); | |
#define unlock pthread_mutex_unlock(&job->mutex); | |
#define sync(code) { lock; code; unlock; } | |
// Compile-time settings | |
#ifndef print_interval | |
#define print_interval 100000 | |
#endif | |
// Structures | |
typedef struct { | |
int maxiter; // The maximum iteration count. Runtime constant. | |
int maxtime; // The maximum seconds to run. Runtime constant. | |
time_t start; // The time_t the program was started. RT const. | |
int done; // Whether we're done yet (1 or 0). Flag. | |
long double current; // The current result. | |
pthread_mutex_t mutex; // The mutex protecting this job struct. | |
} job_t; | |
// pow1: returns (-1)^v | |
inline int pow1(int v) { | |
return (v % 2 == 0) ? 1 : -1; | |
} | |
// printpi: prints a long double value | |
void printpi(long double pi) { | |
printf("pi = %.62Lf\n", pi); | |
} | |
// Run the given Pi calculation job (hmm, pie) | |
void* leibniz(void* jobdata) { | |
job_t* job = (job_t*)jobdata; | |
for (int i = 0; i < job->maxiter; i++) { | |
// While we have iterations left... | |
if ((time(NULL) - job->start) < job->maxtime) { | |
// Synchronously leibnizise the current result. | |
sync(job->current += (pow1(i))/((2.0l*i)+1)); | |
} else { | |
// Out of time! Break out of the loop. | |
break; | |
} | |
} | |
// Job's done! | |
sync(job->done = 1); | |
return jobdata; | |
} | |
// Entry point. | |
int main(int argc, char** argv) { | |
if (argc < 3) { | |
// We didn't get enough arguments, print some usage info and bail | |
fprintf(stderr, "\n"); | |
fprintf(stderr, " Usage: pithread <iterations> <seconds>\n"); | |
fprintf(stderr, " i.e.: pithread 10000000 10\n"); | |
fprintf(stderr, "\n"); | |
return 1; | |
} | |
// Set up job | |
job_t* job = malloc(sizeof(job_t)); | |
job->maxiter = atoi(argv[1]); | |
job->maxtime = atoi(argv[2]); | |
job->done = 0; | |
job->start = time(NULL); | |
job->current = 0; | |
pthread_mutex_init(&job->mutex, NULL); | |
// Start thread | |
pthread_t thread; | |
pthread_create(&thread, NULL, &leibniz, job); | |
// Monitor loop | |
for (;;) { | |
usleep(print_interval); | |
lock; | |
if (job->done) break; | |
long double pi = job->current * 4; | |
unlock; | |
printpi(pi); | |
} | |
// The job said it was done... join it and print the final result | |
pthread_join(thread, NULL); | |
printpi(job->current * 4); | |
// Clean up job | |
pthread_mutex_destroy(&job->mutex); | |
free(job); | |
return EXIT_SUCCESS; | |
} | |
// vim: sw=2:ai:et:sts=2:ts=2: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment