12a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===// 22a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// 32a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// The LLVM Compiler Infrastructure 42a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// 52a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// This file is distributed under the University of Illinois Open Source 62a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// License. See LICENSE.TXT for details. 72a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// 82a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===// 92a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// 102a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// This file implements the llvm::sys::RWMutex class. 112a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// 122a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===// 132a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 142a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include "llvm/Config/config.h" 151f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "llvm/Support/RWMutex.h" 16107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson#include <cstring> 172a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 182a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===// 192a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//=== WARNING: Implementation here must contain only TRULY operating system 202a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//=== independent code. 212a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson//===----------------------------------------------------------------------===// 222a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 2308b73a30bbb6407c7b48a734a29f65f4c8ddd782Dylan Noblesmith#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 242a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// Define all methods as no-ops if threading is explicitly disabled 252a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonnamespace llvm { 262a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonusing namespace sys; 27b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::RWMutexImpl() { } 28b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::~RWMutexImpl() { } 29b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::reader_acquire() { return true; } 30b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::reader_release() { return true; } 31b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::writer_acquire() { return true; } 32b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen Andersonbool RWMutexImpl::writer_release() { return true; } 332a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 342a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#else 352a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 362a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT) 372a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 382a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include <cassert> 392a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include <pthread.h> 402a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include <stdlib.h> 412a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 422a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonnamespace llvm { 432a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonusing namespace sys; 442a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 452a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// Construct a RWMutex using pthread calls 46b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::RWMutexImpl() 472a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson : data_(0) 482a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{ 4949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie // Declare the pthread_rwlock data structures 5049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie pthread_rwlock_t* rwlock = 5149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t))); 52107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson 53107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson#ifdef __APPLE__ 5449c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init. 5549c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie bzero(rwlock, sizeof(pthread_rwlock_t)); 56107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson#endif 57107a537db1261c09f8c9639ef7827b12f0812125Owen Anderson 5849c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie // Initialize the rwlock 5949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie int errorcode = pthread_rwlock_init(rwlock, NULL); 6049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie (void)errorcode; 6149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie assert(errorcode == 0); 622a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 6349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie // Assign the data member 6449c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie data_ = rwlock; 652a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 662a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 672a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson// Destruct a RWMutex 68b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::~RWMutexImpl() 692a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{ 7049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 7149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie assert(rwlock != 0); 7249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie pthread_rwlock_destroy(rwlock); 7349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie free(rwlock); 742a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 752a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 762a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool 77b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::reader_acquire() 782a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{ 7949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 8049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie assert(rwlock != 0); 8149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie 8249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie int errorcode = pthread_rwlock_rdlock(rwlock); 8349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie return errorcode == 0; 842a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 852a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 862a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool 87b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::reader_release() 882a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{ 8949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 9049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie assert(rwlock != 0); 9149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie 9249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie int errorcode = pthread_rwlock_unlock(rwlock); 9349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie return errorcode == 0; 942a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 952a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 962a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool 97b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::writer_acquire() 982a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{ 9949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 10049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie assert(rwlock != 0); 10149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie 10249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie int errorcode = pthread_rwlock_wrlock(rwlock); 10349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie return errorcode == 0; 1042a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 1052a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 1062a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Andersonbool 107b65e9ed10677fe8944822c450b14d7e321f6e6f5Owen AndersonRWMutexImpl::writer_release() 1082a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson{ 10949c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 11049c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie assert(rwlock != 0); 11149c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie 11249c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie int errorcode = pthread_rwlock_unlock(rwlock); 11349c0a9ac989848844f0eb8894ef7ae6b8dde3495David Blaikie return errorcode == 0; 1142a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 1152a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 1162a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson} 1172a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson 1182a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#elif defined(LLVM_ON_UNIX) 1192a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#include "Unix/RWMutex.inc" 1202a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#elif defined( LLVM_ON_WIN32) 1211f6efa3996dd1929fbc129203ce5009b620e6969Michael J. Spencer#include "Windows/RWMutex.inc" 1222a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#else 1232c607b665dbeb52e2ade86f0e1f191695290da3bDaniel Dunbar#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp 1242a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#endif 1252a8cf9aadd39e507e6e09c25530a2f01ca27fe57Owen Anderson#endif 126