1218885Sdim//===- Mutex.cpp - 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::Mutex class.
11218885Sdim//
12218885Sdim//===----------------------------------------------------------------------===//
13218885Sdim
14218885Sdim#include "llvm/Config/config.h"
15218885Sdim#include "llvm/Support/Mutex.h"
16218885Sdim
17218885Sdim//===----------------------------------------------------------------------===//
18218885Sdim//=== WARNING: Implementation here must contain only TRULY operating system
19218885Sdim//===          independent code.
20218885Sdim//===----------------------------------------------------------------------===//
21218885Sdim
22234353Sdim#if !defined(LLVM_ENABLE_THREADS) || LLVM_ENABLE_THREADS == 0
23218885Sdim// Define all methods as no-ops if threading is explicitly disabled
24218885Sdimnamespace llvm {
25218885Sdimusing namespace sys;
26218885SdimMutexImpl::MutexImpl( bool recursive) { }
27218885SdimMutexImpl::~MutexImpl() { }
28218885Sdimbool MutexImpl::acquire() { return true; }
29218885Sdimbool MutexImpl::release() { return true; }
30218885Sdimbool MutexImpl::tryacquire() { return true; }
31218885Sdim}
32218885Sdim#else
33218885Sdim
34218885Sdim#if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
35218885Sdim
36218885Sdim#include <cassert>
37218885Sdim#include <pthread.h>
38218885Sdim#include <stdlib.h>
39218885Sdim
40218885Sdimnamespace llvm {
41218885Sdimusing namespace sys;
42218885Sdim
43218885Sdim// Construct a Mutex using pthread calls
44218885SdimMutexImpl::MutexImpl( bool recursive)
45218885Sdim  : data_(0)
46218885Sdim{
47234353Sdim  // Declare the pthread_mutex data structures
48234353Sdim  pthread_mutex_t* mutex =
49234353Sdim    static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
50234353Sdim  pthread_mutexattr_t attr;
51218885Sdim
52234353Sdim  // Initialize the mutex attributes
53234353Sdim  int errorcode = pthread_mutexattr_init(&attr);
54234353Sdim  assert(errorcode == 0); (void)errorcode;
55218885Sdim
56234353Sdim  // Initialize the mutex as a recursive mutex, if requested, or normal
57234353Sdim  // otherwise.
58234353Sdim  int kind = ( recursive  ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
59234353Sdim  errorcode = pthread_mutexattr_settype(&attr, kind);
60234353Sdim  assert(errorcode == 0);
61218885Sdim
62239462Sdim#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && \
63239462Sdim    !defined(__DragonFly__) && !defined(__Bitrig__)
64234353Sdim  // Make it a process local mutex
65234353Sdim  errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
66234353Sdim  assert(errorcode == 0);
67218885Sdim#endif
68218885Sdim
69234353Sdim  // Initialize the mutex
70234353Sdim  errorcode = pthread_mutex_init(mutex, &attr);
71234353Sdim  assert(errorcode == 0);
72218885Sdim
73234353Sdim  // Destroy the attributes
74234353Sdim  errorcode = pthread_mutexattr_destroy(&attr);
75234353Sdim  assert(errorcode == 0);
76218885Sdim
77234353Sdim  // Assign the data member
78234353Sdim  data_ = mutex;
79218885Sdim}
80218885Sdim
81218885Sdim// Destruct a Mutex
82218885SdimMutexImpl::~MutexImpl()
83218885Sdim{
84234353Sdim  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
85234353Sdim  assert(mutex != 0);
86234353Sdim  pthread_mutex_destroy(mutex);
87234353Sdim  free(mutex);
88218885Sdim}
89218885Sdim
90218885Sdimbool
91218885SdimMutexImpl::acquire()
92218885Sdim{
93234353Sdim  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
94234353Sdim  assert(mutex != 0);
95218885Sdim
96234353Sdim  int errorcode = pthread_mutex_lock(mutex);
97234353Sdim  return errorcode == 0;
98218885Sdim}
99218885Sdim
100218885Sdimbool
101218885SdimMutexImpl::release()
102218885Sdim{
103234353Sdim  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
104234353Sdim  assert(mutex != 0);
105218885Sdim
106234353Sdim  int errorcode = pthread_mutex_unlock(mutex);
107234353Sdim  return errorcode == 0;
108218885Sdim}
109218885Sdim
110218885Sdimbool
111218885SdimMutexImpl::tryacquire()
112218885Sdim{
113234353Sdim  pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
114234353Sdim  assert(mutex != 0);
115218885Sdim
116234353Sdim  int errorcode = pthread_mutex_trylock(mutex);
117234353Sdim  return errorcode == 0;
118218885Sdim}
119218885Sdim
120218885Sdim}
121218885Sdim
122218885Sdim#elif defined(LLVM_ON_UNIX)
123218885Sdim#include "Unix/Mutex.inc"
124218885Sdim#elif defined( LLVM_ON_WIN32)
125218885Sdim#include "Windows/Mutex.inc"
126218885Sdim#else
127226633Sdim#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
128218885Sdim#endif
129218885Sdim#endif
130