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