brintos

brintos / llvm-project-archived public Read only

0
0
Text · 3.9 KiB · c8e1104 Raw
118 lines · cpp
1//===-- Tests for pthread_barrier_t ---------------------------------------===//2//3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.4// See https://llvm.org/LICENSE.txt for license information.5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception6//7//===----------------------------------------------------------------------===//8 9#include "src/pthread/pthread_barrier_destroy.h"10#include "src/pthread/pthread_barrier_init.h"11#include "src/pthread/pthread_barrier_wait.h"12 13#include "src/__support/CPP/atomic.h"14#include "src/pthread/pthread_create.h"15#include "src/pthread/pthread_join.h"16#include "src/pthread/pthread_mutex_destroy.h"17#include "src/pthread/pthread_mutex_init.h"18#include "src/pthread/pthread_mutex_lock.h"19#include "src/pthread/pthread_mutex_unlock.h"20#include "src/string/memset.h"21 22#include "test/IntegrationTest/test.h"23 24#include <pthread.h>25 26pthread_barrier_t barrier;27LIBC_NAMESPACE::cpp::Atomic<int> counter;28 29void *increment_counter_and_wait(void *args) {30  counter.fetch_add(1);31  return reinterpret_cast<void *>(32      LIBC_NAMESPACE::pthread_barrier_wait(&barrier));33}34 35void single_use_barrier_test(int num_threads) {36  counter.set(0);37  // create n - 1 ADDITIONAL threads since the current thread will also wait at38  // the barrier39  pthread_t threads[num_threads - 1];40  LIBC_NAMESPACE::memset(&barrier, 0, sizeof(pthread_barrier_t));41  ASSERT_EQ(42      LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, num_threads), 0);43 44  for (int i = 0; i < num_threads - 1; ++i)45    LIBC_NAMESPACE::pthread_create(&threads[i], nullptr,46                                   increment_counter_and_wait, nullptr);47 48  uintptr_t return_val_sum =49      reinterpret_cast<uintptr_t>(increment_counter_and_wait(nullptr));50  ASSERT_EQ(counter.load(), num_threads);51 52  // verify only one thread got the PTHREAD_BARRIER_SERIAL_THREAD return value53  for (int i = 0; i < num_threads - 1; ++i) {54    void *ret;55    LIBC_NAMESPACE::pthread_join(threads[i], &ret);56    if (reinterpret_cast<uintptr_t>(ret) ==57        static_cast<uintptr_t>(PTHREAD_BARRIER_SERIAL_THREAD)) {58      return_val_sum += reinterpret_cast<uintptr_t>(ret);59    } else {60      ASSERT_EQ(ret, 0);61    }62  }63  ASSERT_EQ(return_val_sum,64            static_cast<uintptr_t>(PTHREAD_BARRIER_SERIAL_THREAD));65 66  LIBC_NAMESPACE::pthread_barrier_destroy(&barrier);67}68 69void reused_barrier_test() {70  counter.set(0);71  const int NUM_THREADS = 30;72  const int REPEAT = 20;73  pthread_t threads[NUM_THREADS - 1]; // subtract 1 for main thread74  LIBC_NAMESPACE::memset(&barrier, 0, sizeof(pthread_barrier_t));75  ASSERT_EQ(76      LIBC_NAMESPACE::pthread_barrier_init(&barrier, nullptr, NUM_THREADS), 0);77 78  for (int i = 0; i < REPEAT; ++i) {79    for (int j = 0; j < NUM_THREADS - 1; ++j)80      LIBC_NAMESPACE::pthread_create(&threads[j], nullptr,81                                     increment_counter_and_wait, nullptr);82 83    uintptr_t return_val_sum =84        reinterpret_cast<uintptr_t>(increment_counter_and_wait(nullptr));85    ASSERT_EQ(counter.load(), NUM_THREADS * (i + 1));86 87    // verify only one thread got the PTHREAD_BARRIER_SERIAL_THREAD return value88    for (int i = 0; i < NUM_THREADS - 1; ++i) {89      void *ret;90      LIBC_NAMESPACE::pthread_join(threads[i], &ret);91      if (reinterpret_cast<uintptr_t>(ret) ==92          static_cast<uintptr_t>(PTHREAD_BARRIER_SERIAL_THREAD)) {93        return_val_sum += reinterpret_cast<uintptr_t>(ret);94      } else {95        ASSERT_EQ(ret, 0);96      }97    }98    ASSERT_EQ(return_val_sum,99              static_cast<uintptr_t>(PTHREAD_BARRIER_SERIAL_THREAD));100  }101 102  LIBC_NAMESPACE::pthread_barrier_destroy(&barrier);103}104 105void *barrier_wait(void *in) {106  return reinterpret_cast<void *>(107      LIBC_NAMESPACE::pthread_barrier_wait(&barrier));108}109 110TEST_MAIN() {111  // don't create any additional threads; only use main thread112  single_use_barrier_test(1);113 114  single_use_barrier_test(30);115  reused_barrier_test();116  return 0;117}118