1139749Simp//===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
2119853Scg//
355639Scg//                     The LLVM Compiler Infrastructure
455639Scg//
555639Scg// This file is distributed under the University of Illinois Open Source
655639Scg// License. See LICENSE.TXT for details.
755639Scg//
855639Scg//===----------------------------------------------------------------------===//
955639Scg//
1055639Scg// This file implements the llvm::sys::Mutex class.
1155639Scg//
1255639Scg//===----------------------------------------------------------------------===//
1355639Scg
1455639Scg#include "llvm/Config/config.h"
1555639Scg#include "llvm/Support/Mutex.h"
1655639Scg
1755639Scg//===----------------------------------------------------------------------===//
1855639Scg//=== WARNING: Implementation here must contain only TRULY operating system
1955639Scg//===          independent code.
2055639Scg//===----------------------------------------------------------------------===//
2155639Scg
2255639Scg#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
2355639Scg// Define all methods as no-ops if threading is explicitly disabled
2455639Scgnamespace llvm {
2555639Scgusing namespace sys;
2655639ScgMutexImpl::MutexImpl( bool recursive) { }
2755639ScgMutexImpl::~MutexImpl() { }
2855639Scgbool MutexImpl::acquire() { return true; }
2955639Scgbool MutexImpl::release() { return true; }
3055639Scgbool MutexImpl::tryacquire() { return true; }
3155639Scg}
3255639Scg#else
33124617Sphk
3455639Scg#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
3555639Scg
3655639Scg#include <cassert>
3755639Scg#include <pthread.h>
3855639Scg#include <stdlib.h>
3955639Scg
4055639Scgnamespace llvm {
4155639Scgusing namespace sys;
4255639Scg
4355639Scg// Construct a Mutex using pthread calls
4455639ScgMutexImpl::MutexImpl( bool recursive)
4555639Scg  : data_(0)
4655639Scg{
4755639Scg  // Declare the pthread_mutex data structures
4855639Scg  pthread_mutex_t* mutex =
4955639Scg    static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
5055639Scg  pthread_mutexattr_t attr;
5155639Scg
5255639Scg  // Initialize the mutex attributes
5355639Scg  int errorcode = pthread_mutexattr_init(&attr);
5455639Scg  assert(errorcode == 0); (void)errorcode;
5555639Scg
5655639Scg  // Initialize the mutex as a recursive mutex, if requested, or normal
5755639Scg  // otherwise.
5855639Scg  int kind = ( recursive  ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
5955639Scg  errorcode = pthread_mutexattr_settype(&attr, kind);
6055639Scg  assert(errorcode == 0);
6155639Scg
6255639Scg#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \
6355639Scg    !defined(__DragonFly__) && !defined(__Bitrig__)
6455639Scg  // Make it a process local mutex
6555639Scg  errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
6655639Scg  assert(errorcode == 0);
6755639Scg#endif
6855639Scg
6955639Scg  // Initialize the mutex
7055639Scg  errorcode = pthread_mutex_init(mutex, &attr);
7155639Scg  assert(errorcode == 0);
7255639Scg
7355639Scg  // Destroy the attributes
7455639Scg  errorcode = pthread_mutexattr_destroy(&attr);
7555639Scg  assert(errorcode == 0);
7655639Scg
7755639Scg  // Assign the data member
7855639Scg  data_ = mutex;
7955639Scg}
8055639Scg
8155639Scg// Destruct a Mutex
8255639ScgMutexImpl::~MutexImpl()
8355639Scg{
8455639Scg  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
8555639Scg  assert(mutex != 0);
8655639Scg  pthread_mutex_destroy(mutex);
8755639Scg  free(mutex);
8855639Scg}
8955639Scg
9055639Scgbool
9155639ScgMutexImpl::acquire()
9255639Scg{
9355639Scg  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
9455639Scg  assert(mutex != 0);
9555639Scg
9655639Scg  int errorcode = pthread_mutex_lock(mutex);
9755639Scg  return errorcode == 0;
9855639Scg}
9955639Scg
10055639Scgbool
10155639ScgMutexImpl::release()
10255639Scg{
10355639Scg  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
10455639Scg  assert(mutex != 0);
10555639Scg
10655639Scg  int errorcode = pthread_mutex_unlock(mutex);
10755639Scg  return errorcode == 0;
10855639Scg}
10955639Scg
11055639Scgbool
11155639ScgMutexImpl::tryacquire()
11255639Scg{
11355639Scg  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
11455639Scg  assert(mutex != 0);
11555639Scg
11655639Scg  int errorcode = pthread_mutex_trylock(mutex);
11755639Scg  return errorcode == 0;
11855639Scg}
11955639Scg
12055639Scg}
12155639Scg
12255639Scg#elif defined(LLVM_ON_UNIX)
12355639Scg#include "Unix/Mutex.inc"
12455639Scg#elif defined( LLVM_ON_WIN32)
12555639Scg#include "Windows/Mutex.inc"
12655639Scg#else
12755639Scg#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
12855639Scg#endif
12955639Scg#endif
13055639Scg