13 const struct Vertices *vertices;
14 Computation *separately;
19 ForAllThreads *allthreads;
25 static void *routine(void *thread_v) {
26 PerThread *t= thread_v;
29 inparallel_barrier(); /* wait for work to do */
30 ForAllThreads *a= t->allthreads;
31 a->separately(a->vertices, t->section, t->secdata, a->gendata);
32 inparallel_barrier(); /* synchronise for completion */
38 static int threads_started;
39 static pthread_barrier_t threads_barrier;
40 static PerThread threads[NSECTIONS-1];
42 void inparallel(const struct Vertices *vertices,
43 Computation *separately,
45 size_t secdatasz, void *gendata) {
46 typedef struct { unsigned char secdata[secdatasz]; } SecData;
48 ForAllThreads allthreads;
49 SecData secdatas[nsections];
51 allthreads.vertices= vertices;
52 allthreads.separately= separately;
53 allthreads.gendata= gendata;
57 if (NSECTIONS>1 && !threads_started) {
58 r= pthread_barrier_init(&threads_barrier, 0, NSECTIONS);
59 if (r) { errno=r; diee("pthread_barrier_init"); }
61 for (s=0; s<NSECTIONS-1; s++) {
62 r= pthread_create(&threads[s].thread,0,routine,&threads[s]);
63 if (r) { errno=r; diee("pthread_create"); }
68 for (s=0; s<NSECTIONS-1; s++) {
69 threads[s].allthreads= &allthreads;
70 threads[s].section= s;
71 threads[s].secdata= secdatas[s].secdata;
74 inparallel_barrier(); /* announce more work to do */
76 separately(vertices, NSECTIONS-1, &secdatas[NSECTIONS-1], gendata);
78 inparallel_barrier(); /* synchronise for completion */
80 for (s=0; s<nsections; s++)
81 combine(vertices, s, &secdatas[s].secdata, gendata);
84 void inparallel_barrier(void) {
87 r= pthread_barrier_wait(&threads_barrier);
88 if (r && r!=PTHREAD_BARRIER_SERIAL_THREAD)
89 { errno=r; diee("pthread_barrier_wait"); }