Home | History | Annotate | Download | only in Support
      1 //===- Mutex.cpp - 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::Mutex class.
     11 //
     12 //===----------------------------------------------------------------------===//
     13 
     14 #include "llvm/Support/Mutex.h"
     15 #include "llvm/Config/config.h"
     16 #include "llvm/Support/ErrorHandling.h"
     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 MutexImpl::MutexImpl( bool recursive) { }
     28 MutexImpl::~MutexImpl() { }
     29 bool MutexImpl::acquire() { return true; }
     30 bool MutexImpl::release() { return true; }
     31 bool MutexImpl::tryacquire() { return true; }
     32 }
     33 #else
     34 
     35 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
     36 
     37 #include <cassert>
     38 #include <pthread.h>
     39 #include <stdlib.h>
     40 
     41 namespace llvm {
     42 using namespace sys;
     43 
     44 // Construct a Mutex using pthread calls
     45 MutexImpl::MutexImpl( bool recursive)
     46   : data_(nullptr)
     47 {
     48   // Declare the pthread_mutex data structures
     49   pthread_mutex_t* mutex =
     50     static_cast<pthread_mutex_t*>(safe_malloc(sizeof(pthread_mutex_t)));
     51 
     52   pthread_mutexattr_t attr;
     53 
     54   // Initialize the mutex attributes
     55   int errorcode = pthread_mutexattr_init(&attr);
     56   assert(errorcode == 0); (void)errorcode;
     57 
     58   // Initialize the mutex as a recursive mutex, if requested, or normal
     59   // otherwise.
     60   int kind = ( recursive  ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
     61   errorcode = pthread_mutexattr_settype(&attr, kind);
     62   assert(errorcode == 0);
     63 
     64   // Initialize the mutex
     65   errorcode = pthread_mutex_init(mutex, &attr);
     66   assert(errorcode == 0);
     67 
     68   // Destroy the attributes
     69   errorcode = pthread_mutexattr_destroy(&attr);
     70   assert(errorcode == 0);
     71 
     72   // Assign the data member
     73   data_ = mutex;
     74 }
     75 
     76 // Destruct a Mutex
     77 MutexImpl::~MutexImpl()
     78 {
     79   pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
     80   assert(mutex != nullptr);
     81   pthread_mutex_destroy(mutex);
     82   free(mutex);
     83 }
     84 
     85 bool
     86 MutexImpl::acquire()
     87 {
     88   pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
     89   assert(mutex != nullptr);
     90 
     91   int errorcode = pthread_mutex_lock(mutex);
     92   return errorcode == 0;
     93 }
     94 
     95 bool
     96 MutexImpl::release()
     97 {
     98   pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
     99   assert(mutex != nullptr);
    100 
    101   int errorcode = pthread_mutex_unlock(mutex);
    102   return errorcode == 0;
    103 }
    104 
    105 bool
    106 MutexImpl::tryacquire()
    107 {
    108   pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
    109   assert(mutex != nullptr);
    110 
    111   int errorcode = pthread_mutex_trylock(mutex);
    112   return errorcode == 0;
    113 }
    114 
    115 }
    116 
    117 #elif defined(LLVM_ON_UNIX)
    118 #include "Unix/Mutex.inc"
    119 #elif defined( _WIN32)
    120 #include "Windows/Mutex.inc"
    121 #else
    122 #warning Neither LLVM_ON_UNIX nor _WIN32 was set in Support/Mutex.cpp
    123 #endif
    124 #endif
    125