brintos

brintos / llvm-project-archived public Read only

0
0
Text · 5.1 KiB · 233daf8 Raw
146 lines · cpp
1//===-- Tests for pthread_spinlock ----------------------------------------===//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 "hdr/errno_macros.h"10#include "src/pthread/pthread_create.h"11#include "src/pthread/pthread_join.h"12#include "src/pthread/pthread_spin_destroy.h"13#include "src/pthread/pthread_spin_init.h"14#include "src/pthread/pthread_spin_lock.h"15#include "src/pthread/pthread_spin_trylock.h"16#include "src/pthread/pthread_spin_unlock.h"17#include "test/IntegrationTest/test.h"18#include <pthread.h>19 20namespace {21void smoke_test() {22  pthread_spinlock_t lock;23  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE),24            0);25  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_lock(&lock), 0);26  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&lock), 0);27  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);28}29 30void trylock_test() {31  pthread_spinlock_t lock;32  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE),33            0);34  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_trylock(&lock), 0);35  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_trylock(&lock), EBUSY);36  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&lock), 0);37  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_trylock(&lock), 0);38  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&lock), 0);39  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);40}41 42void destroy_held_lock_test() {43  pthread_spinlock_t lock;44  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE),45            0);46  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_lock(&lock), 0);47  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), EBUSY);48  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&lock), 0);49  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);50}51 52void use_after_destroy_test() {53  pthread_spinlock_t lock;54  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE),55            0);56  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);57  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&lock), EINVAL);58  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_lock(&lock), EINVAL);59  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_trylock(&lock), EINVAL);60  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), EINVAL);61}62 63void unlock_without_holding_test() {64  pthread_spinlock_t lock;65  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE),66            0);67  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&lock), EPERM);68  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);69}70 71void deadlock_test() {72  pthread_spinlock_t lock;73  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE),74            0);75  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_lock(&lock), 0);76  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_lock(&lock), EDEADLK);77  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&lock), 0);78  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);79}80 81void null_lock_test() {82  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(nullptr, 0), EINVAL);83  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_lock(nullptr), EINVAL);84  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_trylock(nullptr), EINVAL);85  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(nullptr), EINVAL);86  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(nullptr), EINVAL);87}88 89void pshared_attribute_test() {90  pthread_spinlock_t lock;91  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_SHARED),92            0);93  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);94 95  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, PTHREAD_PROCESS_PRIVATE),96            0);97  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&lock), 0);98 99  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&lock, -1), EINVAL);100}101 102void multi_thread_test() {103  struct shared_data {104    pthread_spinlock_t lock;105    int count = 0;106  } shared;107  pthread_t thread[10];108  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_init(&shared.lock, 0), 0);109  for (int i = 0; i < 10; ++i) {110    ASSERT_EQ(111        LIBC_NAMESPACE::pthread_create(112            &thread[i], nullptr,113            [](void *arg) -> void * {114              auto *data = static_cast<shared_data *>(arg);115              for (int j = 0; j < 1000; ++j) {116                ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_lock(&data->lock), 0);117                data->count += j;118                ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_unlock(&data->lock), 0);119              }120              return nullptr;121            },122            &shared),123        0);124  }125  for (int i = 0; i < 10; ++i) {126    ASSERT_EQ(LIBC_NAMESPACE::pthread_join(thread[i], nullptr), 0);127  }128  ASSERT_EQ(LIBC_NAMESPACE::pthread_spin_destroy(&shared.lock), 0);129  ASSERT_EQ(shared.count, 1000 * 999 * 5);130}131 132} // namespace133 134TEST_MAIN() {135  smoke_test();136  trylock_test();137  destroy_held_lock_test();138  use_after_destroy_test();139  unlock_without_holding_test();140  deadlock_test();141  multi_thread_test();142  null_lock_test();143  pshared_attribute_test();144  return 0;145}146