Skip to content
Snippets Groups Projects
psum_test.c 2.74 KiB
Newer Older
  • Learn to ignore specific revisions
  • spruett3's avatar
    spruett3 committed
    /*
     * 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);
    
    spruett3's avatar
    spruett3 committed
        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;
    }