1218885Sdim//===- RWMutex.cpp - Reader/Writer Mutual Exclusion Lock --------*- C++ -*-===// 2218885Sdim// 3218885Sdim// The LLVM Compiler Infrastructure 4218885Sdim// 5218885Sdim// This file is distributed under the University of Illinois Open Source 6218885Sdim// License. See LICENSE.TXT for details. 7218885Sdim// 8218885Sdim//===----------------------------------------------------------------------===// 9218885Sdim// 10218885Sdim// This file implements the llvm::sys::RWMutex class. 11218885Sdim// 12218885Sdim//===----------------------------------------------------------------------===// 13218885Sdim 14218885Sdim#include "llvm/Config/config.h" 15218885Sdim#include "llvm/Support/RWMutex.h" 16218885Sdim#include <cstring> 17218885Sdim 18218885Sdim//===----------------------------------------------------------------------===// 19218885Sdim//=== WARNING: Implementation here must contain only TRULY operating system 20218885Sdim//=== independent code. 21218885Sdim//===----------------------------------------------------------------------===// 22218885Sdim 23235633Sdim#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0 24218885Sdim// Define all methods as no-ops if threading is explicitly disabled 25218885Sdimnamespace llvm { 26218885Sdimusing namespace sys; 27218885SdimRWMutexImpl::RWMutexImpl() { } 28218885SdimRWMutexImpl::~RWMutexImpl() { } 29218885Sdimbool RWMutexImpl::reader_acquire() { return true; } 30218885Sdimbool RWMutexImpl::reader_release() { return true; } 31218885Sdimbool RWMutexImpl::writer_acquire() { return true; } 32218885Sdimbool RWMutexImpl::writer_release() { return true; } 33218885Sdim} 34218885Sdim#else 35218885Sdim 36218885Sdim#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_RWLOCK_INIT) 37218885Sdim 38218885Sdim#include <cassert> 39218885Sdim#include <pthread.h> 40218885Sdim#include <stdlib.h> 41218885Sdim 42218885Sdimnamespace llvm { 43218885Sdimusing namespace sys; 44218885Sdim 45218885Sdim// Construct a RWMutex using pthread calls 46218885SdimRWMutexImpl::RWMutexImpl() 47218885Sdim : data_(0) 48218885Sdim{ 49235633Sdim // Declare the pthread_rwlock data structures 50235633Sdim pthread_rwlock_t* rwlock = 51235633Sdim static_cast<pthread_rwlock_t*>(malloc(sizeof(pthread_rwlock_t))); 52218885Sdim 53218885Sdim#ifdef __APPLE__ 54235633Sdim // Workaround a bug/mis-feature in Darwin's pthread_rwlock_init. 55235633Sdim bzero(rwlock, sizeof(pthread_rwlock_t)); 56218885Sdim#endif 57218885Sdim 58235633Sdim // Initialize the rwlock 59235633Sdim int errorcode = pthread_rwlock_init(rwlock, NULL); 60235633Sdim (void)errorcode; 61235633Sdim assert(errorcode == 0); 62218885Sdim 63235633Sdim // Assign the data member 64235633Sdim data_ = rwlock; 65218885Sdim} 66218885Sdim 67218885Sdim// Destruct a RWMutex 68218885SdimRWMutexImpl::~RWMutexImpl() 69218885Sdim{ 70235633Sdim pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 71235633Sdim assert(rwlock != 0); 72235633Sdim pthread_rwlock_destroy(rwlock); 73235633Sdim free(rwlock); 74218885Sdim} 75218885Sdim 76218885Sdimbool 77218885SdimRWMutexImpl::reader_acquire() 78218885Sdim{ 79235633Sdim pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 80235633Sdim assert(rwlock != 0); 81218885Sdim 82235633Sdim int errorcode = pthread_rwlock_rdlock(rwlock); 83235633Sdim return errorcode == 0; 84218885Sdim} 85218885Sdim 86218885Sdimbool 87218885SdimRWMutexImpl::reader_release() 88218885Sdim{ 89235633Sdim pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 90235633Sdim assert(rwlock != 0); 91218885Sdim 92235633Sdim int errorcode = pthread_rwlock_unlock(rwlock); 93235633Sdim return errorcode == 0; 94218885Sdim} 95218885Sdim 96218885Sdimbool 97218885SdimRWMutexImpl::writer_acquire() 98218885Sdim{ 99235633Sdim pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 100235633Sdim assert(rwlock != 0); 101218885Sdim 102235633Sdim int errorcode = pthread_rwlock_wrlock(rwlock); 103235633Sdim return errorcode == 0; 104218885Sdim} 105218885Sdim 106218885Sdimbool 107218885SdimRWMutexImpl::writer_release() 108218885Sdim{ 109235633Sdim pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_); 110235633Sdim assert(rwlock != 0); 111218885Sdim 112235633Sdim int errorcode = pthread_rwlock_unlock(rwlock); 113235633Sdim return errorcode == 0; 114218885Sdim} 115218885Sdim 116218885Sdim} 117218885Sdim 118218885Sdim#elif defined(LLVM_ON_UNIX) 119218885Sdim#include "Unix/RWMutex.inc" 120218885Sdim#elif defined( LLVM_ON_WIN32) 121218885Sdim#include "Windows/RWMutex.inc" 122218885Sdim#else 123226890Sdim#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp 124218885Sdim#endif 125218885Sdim#endif 126