RWMutex.cpp revision 49c0a9ac989848844f0eb8894ef7ae6b8dde3495
1//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file implements the llvm::sys::RWMutex class. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/Config/config.h" 15#include "llvm/Support/RWMutex.h" 16#include <cstring> 17 18//===----------------------------------------------------------------------===// 19//=== WARNING: Implementation here must contain only TRULY operating system 20//=== independent code. 21//===----------------------------------------------------------------------===// 22 23#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 24// Define all methods as no-ops if threading is explicitly disabled 25namespace llvm { 26using namespace sys; 27RWMutexImpl::RWMutexImpl() { } 28RWMutexImpl::~RWMutexImpl() { } 29bool RWMutexImpl::reader_acquire() { return true; } 30bool RWMutexImpl::reader_release() { return true; } 31bool RWMutexImpl::writer_acquire() { return true; } 32bool RWMutexImpl::writer_release() { return true; } 33} 34#else 35 36#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT) 37 38#include <cassert> 39#include <pthread.h> 40#include <stdlib.h> 41 42namespace llvm { 43using namespace sys; 44 45// Construct a RWMutex using pthread calls 46RWMutexImpl::RWMutexImpl() 47 : data_(0) 48{ 49 // Declare the pthread_rwlock data structures 50 pthread_rwlock_t* rwlock = 51 static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t))); 52 53#ifdef __APPLE__ 54 // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init. 55 bzero(rwlock, sizeof(pthread_rwlock_t)); 56#endif 57 58 // Initialize the rwlock 59 int errorcode = pthread_rwlock_init(rwlock, NULL); 60 (void)errorcode; 61 assert(errorcode == 0); 62 63 // Assign the data member 64 data_ = rwlock; 65} 66 67// Destruct a RWMutex 68RWMutexImpl::~RWMutexImpl() 69{ 70 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 71 assert(rwlock != 0); 72 pthread_rwlock_destroy(rwlock); 73 free(rwlock); 74} 75 76bool 77RWMutexImpl::reader_acquire() 78{ 79 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 80 assert(rwlock != 0); 81 82 int errorcode = pthread_rwlock_rdlock(rwlock); 83 return errorcode == 0; 84} 85 86bool 87RWMutexImpl::reader_release() 88{ 89 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 90 assert(rwlock != 0); 91 92 int errorcode = pthread_rwlock_unlock(rwlock); 93 return errorcode == 0; 94} 95 96bool 97RWMutexImpl::writer_acquire() 98{ 99 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 100 assert(rwlock != 0); 101 102 int errorcode = pthread_rwlock_wrlock(rwlock); 103 return errorcode == 0; 104} 105 106bool 107RWMutexImpl::writer_release() 108{ 109 pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 110 assert(rwlock != 0); 111 112 int errorcode = pthread_rwlock_unlock(rwlock); 113 return errorcode == 0; 114} 115 116} 117 118#elif defined(LLVM_ON_UNIX) 119#include "Unix/RWMutex.inc" 120#elif defined( LLVM_ON_WIN32) 121#include "Windows/RWMutex.inc" 122#else 123#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp 124#endif 125#endif 126