// Copyright 2015 The Emscripten Authors. All rights reserved. // Emscripten is available under two separate licenses, the MIT license and the // University of Illinois/NCSA Open Source License. Both these licenses can be // found in the LICENSE file. // This file tests pthread barrier usage. #include #include #include #include #define N 100 #define THREADS 8 int matrix[N][N] = {}; int intermediate[N] = {}; // Barrier variable pthread_barrier_t barr; // Sums a single row of a matrix. int sum_row(long r) { int sum = 0; for(int i = 0; i < N; ++i) sum += matrix[r][i]; return sum; } void *thread_main(void *arg) { // Each thread sums individual rows. long id = (long)arg; for(long i = id; i < N; i += THREADS) intermediate[i] = sum_row(i); // Synchronization point int rc = pthread_barrier_wait(&barr); if (rc != 0 && rc != PTHREAD_BARRIER_SERIAL_THREAD) { printf("Could not wait on barrier\n"); exit(-1); } // Then each thread sums the one intermediate vector. intptr_t totalSum = 0; for(int i = 0; i < N; ++i) totalSum += intermediate[i]; pthread_exit((void*)totalSum); } int main(int argc, char **argv) { pthread_t thr[THREADS]; // Create the matrix and compute the expected result. int expectedTotalSum = 0; for(int i = 0; i < N; ++i) for(int j = 0; j < N; ++j) { matrix[i][j] = rand(); expectedTotalSum += matrix[i][j]; } printf("The sum of the matrix is %d.\n", expectedTotalSum); // Barrier initialization int ret = pthread_barrier_init(&barr, NULL, THREADS); assert(ret == 0); for(intptr_t i = 0; i < THREADS; ++i) { pthread_create(&thr[i], NULL, &thread_main, (void*)i); } for(int i = 0; i < THREADS; ++i) { int totalSum = 0; pthread_join(thr[i], (void**)&totalSum); assert(totalSum == expectedTotalSum); } return 0; }