/* * Thread pool test program. * Parallel sum. * C version of http://en.cppreference.com/w/cpp/thread/async * * Written by G. Back for CS3214 Fall 2014. */ #include <assert.h> #include <pthread.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include <stdint.h> #include <unistd.h> #include <sys/time.h> #include <sys/resource.h> #include <time.h> #include "threadpool.h" #include "threadpool_lib.h" /* Data to be passed to callable. */ struct problem_parameters { unsigned beg, end; int *v; }; #define GRANULARITY 100 static void * parallel_sum(struct thread_pool * pool, void * _data) { struct problem_parameters * p = _data; int i, len = p->end - p->beg; if (len < GRANULARITY) { uintptr_t sum = 0; int * v = p->v; for (i = p->beg; i < p->end; i++) sum += v[i]; return (void *) sum; } int mid = p->beg + len / 2; struct problem_parameters left_half = { .beg = p->beg, .end = mid, .v = p->v }; struct problem_parameters right_half = { .beg = mid, .end = p->end, .v = p->v }; struct future * f = thread_pool_submit(pool, parallel_sum, &right_half); uintptr_t lresult = (uintptr_t) parallel_sum(pool, &left_half); uintptr_t rresult = (uintptr_t) future_get(f); future_free(f); return (void *)(lresult + rresult); } static void usage(char *av0, int nthreads) { fprintf(stderr, "Usage: %s [-n <n>] <N>\n" " -n number of threads in pool, default %d\n" , av0, nthreads); exit(0); } int main(int ac, char *av[]) { int nthreads = 4; int c; while ((c = getopt(ac, av, "n:h")) != EOF) { switch (c) { case 'n': nthreads = atoi(optarg); break; case 'h': usage(av[0], nthreads); } } if (optind == ac) usage(av[0], nthreads); int len = atoi(av[optind]); struct thread_pool * pool = thread_pool_new(nthreads); int * v = malloc(sizeof(int) * len); struct problem_parameters roottask = { .beg = 0, .end = len, .v = v, }; unsigned long long realsum = 0; int i; for (i = 0; i < len; i++) { v[i] = i % 3; realsum += v[i]; } printf("starting...\n"); struct benchmark_data* bdata = start_benchmark(); struct future *f = thread_pool_submit(pool, parallel_sum, &roottask); unsigned long long sum = (unsigned long long) future_get(f); stop_benchmark(bdata); future_free(f); if (sum != realsum) { printf("result %lld should be %lld\n", sum, realsum); abort(); } else { printf("result ok.\n"); report_benchmark_results(bdata); } thread_pool_shutdown_and_destroy(pool); return 0; }