Newer
Older
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
/*
* 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);
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
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;
}