| // 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 <emscripten/threading.h> |
| #include <pthread.h> |
| #include <stdlib.h> |
| #include <stdio.h> |
| #include <assert.h> |
| |
| #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(int 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. |
| int id = (int)arg; |
| for(int 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. |
| int 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; |
| srand(time(NULL)); |
| 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(int i = 0; i < THREADS; ++i) pthread_create(&thr[i], NULL, &thread_main, (void*)i); |
| if (emscripten_has_threading_support()) |
| { |
| for(int i = 0; i < THREADS; ++i) |
| { |
| int totalSum = 0; |
| pthread_join(thr[i], (void**)&totalSum); |
| assert(totalSum == expectedTotalSum); |
| } |
| } |
| |
| #ifdef REPORT_RESULT |
| REPORT_RESULT(0); |
| #endif |
| } |