Mutex.cpp revision 226633
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
22218885Sdim#if !defined(ENABLE_THREADS) || 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
44218885Sdim// This variable is useful for situations where the pthread library has been
45218885Sdim// compiled with weak linkage for its interface symbols. This allows the
46218885Sdim// threading support to be turned off by simply not linking against -lpthread.
47218885Sdim// In that situation, the value of pthread_mutex_init will be 0 and
48218885Sdim// consequently pthread_enabled will be false. In such situations, all the
49218885Sdim// pthread operations become no-ops and the functions all return false. If
50218885Sdim// pthread_mutex_init does have an address, then mutex support is enabled.
51218885Sdim// Note: all LLVM tools will link against -lpthread if its available since it
52218885Sdim//       is configured into the LIBS variable.
53218885Sdim// Note: this line of code generates a warning if pthread_mutex_init is not
54218885Sdim//       declared with weak linkage. It's safe to ignore the warning.
55218885Sdimstatic const bool pthread_enabled = true;
56218885Sdim
57218885Sdim// Construct a Mutex using pthread calls
58218885SdimMutexImpl::MutexImpl( bool recursive)
59218885Sdim  : data_(0)
60218885Sdim{
61218885Sdim  if (pthread_enabled)
62218885Sdim  {
63218885Sdim    // Declare the pthread_mutex data structures
64218885Sdim    pthread_mutex_t* mutex =
65218885Sdim      static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
66218885Sdim    pthread_mutexattr_t attr;
67218885Sdim
68218885Sdim    // Initialize the mutex attributes
69218885Sdim    int errorcode = pthread_mutexattr_init(&attr);
70218885Sdim    assert(errorcode == 0);
71218885Sdim
72218885Sdim    // Initialize the mutex as a recursive mutex, if requested, or normal
73218885Sdim    // otherwise.
74218885Sdim    int kind = ( recursive  ? PTHREAD_MUTEX_RECURSIVE : PTHREAD_MUTEX_NORMAL );
75218885Sdim    errorcode = pthread_mutexattr_settype(&attr, kind);
76218885Sdim    assert(errorcode == 0);
77218885Sdim
78218885Sdim#if !defined(__FreeBSD__) && !defined(__OpenBSD__) && !defined(__NetBSD__) && !defined(__DragonFly__)
79218885Sdim    // Make it a process local mutex
80218885Sdim    errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
81218885Sdim    assert(errorcode == 0);
82218885Sdim#endif
83218885Sdim
84218885Sdim    // Initialize the mutex
85218885Sdim    errorcode = pthread_mutex_init(mutex, &attr);
86218885Sdim    assert(errorcode == 0);
87218885Sdim
88218885Sdim    // Destroy the attributes
89218885Sdim    errorcode = pthread_mutexattr_destroy(&attr);
90218885Sdim    assert(errorcode == 0);
91218885Sdim
92218885Sdim    // Assign the data member
93218885Sdim    data_ = mutex;
94218885Sdim  }
95218885Sdim}
96218885Sdim
97218885Sdim// Destruct a Mutex
98218885SdimMutexImpl::~MutexImpl()
99218885Sdim{
100218885Sdim  if (pthread_enabled)
101218885Sdim  {
102218885Sdim    pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
103218885Sdim    assert(mutex != 0);
104218885Sdim    pthread_mutex_destroy(mutex);
105218885Sdim    free(mutex);
106218885Sdim  }
107218885Sdim}
108218885Sdim
109218885Sdimbool
110218885SdimMutexImpl::acquire()
111218885Sdim{
112218885Sdim  if (pthread_enabled)
113218885Sdim  {
114218885Sdim    pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
115218885Sdim    assert(mutex != 0);
116218885Sdim
117218885Sdim    int errorcode = pthread_mutex_lock(mutex);
118218885Sdim    return errorcode == 0;
119218885Sdim  } else return false;
120218885Sdim}
121218885Sdim
122218885Sdimbool
123218885SdimMutexImpl::release()
124218885Sdim{
125218885Sdim  if (pthread_enabled)
126218885Sdim  {
127218885Sdim    pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
128218885Sdim    assert(mutex != 0);
129218885Sdim
130218885Sdim    int errorcode = pthread_mutex_unlock(mutex);
131218885Sdim    return errorcode == 0;
132218885Sdim  } else return false;
133218885Sdim}
134218885Sdim
135218885Sdimbool
136218885SdimMutexImpl::tryacquire()
137218885Sdim{
138218885Sdim  if (pthread_enabled)
139218885Sdim  {
140218885Sdim    pthread_mutex_t* mutex = static_cast<pthread_mutex_t*>(data_);
141218885Sdim    assert(mutex != 0);
142218885Sdim
143218885Sdim    int errorcode = pthread_mutex_trylock(mutex);
144218885Sdim    return errorcode == 0;
145218885Sdim  } else return false;
146218885Sdim}
147218885Sdim
148218885Sdim}
149218885Sdim
150218885Sdim#elif defined(LLVM_ON_UNIX)
151218885Sdim#include "Unix/Mutex.inc"
152218885Sdim#elif defined( LLVM_ON_WIN32)
153218885Sdim#include "Windows/Mutex.inc"
154218885Sdim#else
155226633Sdim#warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in Support/Mutex.cpp
156218885Sdim#endif
157218885Sdim#endif
158