Skip to content

Instantly share code, notes, and snippets.

@wandernauta
Created December 3, 2013 13:12
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save wandernauta/7768928 to your computer and use it in GitHub Desktop.
Save wandernauta/7768928 to your computer and use it in GitHub Desktop.
pithread.c
// 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