1 //===-- Linux implementation of the pthread_rwlock_init function ----------===// 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-exception 6 // 7 //===----------------------------------------------------------------------===// 8 9 #include "src/pthread/pthread_rwlock_init.h" 10 11 #include "src/__support/CPP/new.h" 12 #include "src/__support/common.h" 13 #include "src/__support/libc_assert.h" 14 #include "src/__support/macros/config.h" 15 #include "src/__support/threads/linux/rwlock.h" 16 17 #include <pthread.h> 18 19 namespace LIBC_NAMESPACE_DECL { 20 21 static_assert( 22 sizeof(RwLock) == sizeof(pthread_rwlock_t) && 23 alignof(RwLock) == alignof(pthread_rwlock_t), 24 "The public pthread_rwlock_t type must be of the same size and alignment " 25 "as the internal rwlock type."); 26 27 LLVM_LIBC_FUNCTION(int, pthread_rwlock_init, 28 (pthread_rwlock_t * rwlock, 29 const pthread_rwlockattr_t *__restrict attr)) { 30 pthread_rwlockattr_t rwlockattr{ 31 /*pshared=*/PTHREAD_PROCESS_PRIVATE, 32 /*pref*/ PTHREAD_RWLOCK_PREFER_READER_NP, 33 }; 34 // POSIX does not specify this check, so we add an assertion to catch it. 35 LIBC_ASSERT(rwlock && "rwlock is null"); 36 if (attr) 37 rwlockattr = *attr; 38 39 // PTHREAD_RWLOCK_PREFER_WRITER_NP is not supported. 40 rwlock::Role preference; 41 switch (rwlockattr.pref) { 42 case PTHREAD_RWLOCK_PREFER_READER_NP: 43 preference = rwlock::Role::Reader; 44 break; 45 case PTHREAD_RWLOCK_PREFER_WRITER_NONRECURSIVE_NP: 46 preference = rwlock::Role::Writer; 47 break; 48 default: 49 return EINVAL; 50 } 51 bool is_pshared; 52 switch (rwlockattr.pshared) { 53 case PTHREAD_PROCESS_PRIVATE: 54 is_pshared = false; 55 break; 56 case PTHREAD_PROCESS_SHARED: 57 is_pshared = true; 58 break; 59 default: 60 return EINVAL; 61 } 62 63 new (rwlock) RwLock(preference, is_pshared); 64 return 0; 65 } 66 67 } // namespace LIBC_NAMESPACE_DECL 68