Serenity Operating System
at master 131 lines 3.1 kB view raw
1/* 2 * Copyright (c) 2021, Brian Gianforcaro <bgianf@serenityos.org> 3 * 4 * SPDX-License-Identifier: BSD-2-Clause 5 */ 6 7#include <LibTest/TestCase.h> 8#include <errno.h> 9#include <pthread.h> 10#include <unistd.h> 11 12TEST_CASE(spin_init_process_scope) 13{ 14 { 15 pthread_spinlock_t lock {}; 16 auto result = pthread_spin_init(&lock, PTHREAD_SCOPE_PROCESS); 17 EXPECT_EQ(0, result); 18 result = pthread_spin_destroy(&lock); 19 EXPECT_EQ(0, result); 20 } 21 22 { 23 pthread_spinlock_t garbage_lock { 0x1337 }; 24 auto result = pthread_spin_init(&garbage_lock, PTHREAD_SCOPE_PROCESS); 25 EXPECT_EQ(0, result); 26 result = pthread_spin_destroy(&garbage_lock); 27 EXPECT_EQ(0, result); 28 } 29} 30 31TEST_CASE(spin_init_system_scope) 32{ 33 pthread_spinlock_t lock {}; 34 auto result = pthread_spin_init(&lock, PTHREAD_SCOPE_SYSTEM); 35 EXPECT_EQ(0, result); 36 pthread_spinlock_t garbage_lock { 0x99999 }; 37 result = pthread_spin_init(&garbage_lock, PTHREAD_SCOPE_PROCESS); 38 EXPECT_EQ(0, result); 39} 40 41TEST_CASE(spin_lock) 42{ 43 pthread_spinlock_t lock {}; 44 auto result = pthread_spin_lock(&lock); 45 EXPECT_EQ(0, result); 46 47 // We should detect that this thread already holds this lock. 48 result = pthread_spin_lock(&lock); 49 EXPECT_EQ(EDEADLK, result); 50} 51 52TEST_CASE(spin_try_lock) 53{ 54 { 55 pthread_spinlock_t lock {}; 56 auto result = pthread_spin_trylock(&lock); 57 EXPECT_EQ(0, result); 58 59 result = pthread_spin_unlock(&lock); 60 EXPECT_EQ(0, result); 61 } 62 63 { 64 pthread_spinlock_t lock {}; 65 auto result = pthread_spin_trylock(&lock); 66 EXPECT_EQ(0, result); 67 68 // We should detect that this thread already holds the lock. 69 result = pthread_spin_trylock(&lock); 70 EXPECT_EQ(EBUSY, result); 71 } 72} 73 74static void lock_from_different_thread(pthread_spinlock_t* lock) 75{ 76 pthread_t thread_id {}; 77 auto result = pthread_create( 78 &thread_id, nullptr, [](void* param) -> void* { 79 auto lock = (pthread_spinlock_t*)param; 80 pthread_spin_lock(lock); 81 return nullptr; 82 }, 83 lock); 84 EXPECT_EQ(0, result); 85 86 result = pthread_join(thread_id, nullptr); 87 EXPECT_EQ(0, result); 88} 89 90TEST_CASE(spin_unlock) 91{ 92 { 93 pthread_spinlock_t lock {}; 94 auto result = pthread_spin_lock(&lock); 95 EXPECT_EQ(0, result); 96 97 result = pthread_spin_unlock(&lock); 98 EXPECT_EQ(0, result); 99 } 100 101 { 102 pthread_spinlock_t lock {}; 103 lock_from_different_thread(&lock); 104 105 auto result = pthread_spin_unlock(&lock); 106 EXPECT_EQ(EPERM, result); 107 } 108} 109 110TEST_CASE(spin_destroy) 111{ 112 { 113 pthread_spinlock_t lock {}; 114 auto result = pthread_spin_lock(&lock); 115 EXPECT_EQ(0, result); 116 117 result = pthread_spin_destroy(&lock); 118 EXPECT_EQ(EBUSY, result); 119 120 result = pthread_spin_unlock(&lock); 121 EXPECT_EQ(0, result); 122 } 123 124 { 125 pthread_spinlock_t lock {}; 126 lock_from_different_thread(&lock); 127 128 auto result = pthread_spin_destroy(&lock); 129 EXPECT_EQ(EBUSY, result); 130 } 131}