Home | History | Annotate | Download | only in Support
      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
     25 namespace llvm {
     26 using namespace sys;
     27 RWMutexImpl::RWMutexImpl() { }
     28 RWMutexImpl::~RWMutexImpl() { }
     29 bool RWMutexImpl::reader_acquire() { return true; }
     30 bool RWMutexImpl::reader_release() { return true; }
     31 bool RWMutexImpl::writer_acquire() { return true; }
     32 bool 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 
     42 namespace llvm {
     43 using namespace sys;
     44 
     45 // Construct a RWMutex using pthread calls
     46 RWMutexImpl::RWMutexImpl()
     47   : data_(nullptr)
     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, nullptr);
     60   (void)errorcode;
     61   assert(errorcode == 0);
     62 
     63   // Assign the data member
     64   data_ = rwlock;
     65 }
     66 
     67 // Destruct a RWMutex
     68 RWMutexImpl::~RWMutexImpl()
     69 {
     70   pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
     71   assert(rwlock != nullptr);
     72   pthread_rwlock_destroy(rwlock);
     73   free(rwlock);
     74 }
     75 
     76 bool
     77 RWMutexImpl::reader_acquire()
     78 {
     79   pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
     80   assert(rwlock != nullptr);
     81 
     82   int errorcode = pthread_rwlock_rdlock(rwlock);
     83   return errorcode == 0;
     84 }
     85 
     86 bool
     87 RWMutexImpl::reader_release()
     88 {
     89   pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
     90   assert(rwlock != nullptr);
     91 
     92   int errorcode = pthread_rwlock_unlock(rwlock);
     93   return errorcode == 0;
     94 }
     95 
     96 bool
     97 RWMutexImpl::writer_acquire()
     98 {
     99   pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
    100   assert(rwlock != nullptr);
    101 
    102   int errorcode = pthread_rwlock_wrlock(rwlock);
    103   return errorcode == 0;
    104 }
    105 
    106 bool
    107 RWMutexImpl::writer_release()
    108 {
    109   pthread_rwlock_t* rwlock = static_cast<pthread_rwlock_t*>(data_);
    110   assert(rwlock != nullptr);
    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