2a1519769134a4039d7aecec1148569f31113954
[oota-llvm.git] / lib / System / Mutex.cpp
1 //===- Mutex.cpp - Mutual Exclusion Lock ------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by Reid Spencer and is distributed under the
6 // University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file implements the llvm::sys::Mutex class.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "llvm/System/Mutex.h"
15 #include "llvm/Config/config.h"
16
17 namespace llvm {
18 using namespace sys;
19
20 //===----------------------------------------------------------------------===//
21 //=== WARNING: Implementation here must contain only TRULY operating system
22 //===          independent code.
23 //===----------------------------------------------------------------------===//
24
25 #if defined(HAVE_PTHREAD_H) && defined(HAVE_PTHREAD_MUTEX_LOCK)
26 #include <cassert>
27 #include <pthread.h>
28 #include <stdlib.h>
29
30 // This variable is useful for situations where the pthread library has been
31 // compiled with weak linkage for its interface symbols. This allows the 
32 // threading support to be turned off by simply not linking against -lpthread.
33 // In that situation, the value of pthread_mutex_init will be 0 and 
34 // consequently pthread_enabled will be false. In such situations, all the
35 // pthread operations become no-ops and the functions all return false. If
36 // pthread_mutex_init does have an address, then mutex support is enabled.
37 // Note: all LLVM tools will link against -lpthread if its available since it
38 //       is configured into the LIBS variable.
39 // Note: this line of code generates a warning if pthread_mutex_init is not
40 //       declared with weak linkage. Its safe to ignore the warning.
41 static const bool pthread_enabled = static_cast<bool>(pthread_mutex_init);
42
43 // Construct a Mutex using pthread calls
44 Mutex::Mutex( bool recursive)
45   : data_(0)
46 {
47   if (pthread_enabled)
48   {
49     // Declare the pthread_mutex data structures
50     pthread_mutex_t* mutex = 
51       static_cast<pthread_mutex_t*>(malloc(sizeof(pthread_mutex_t)));
52     pthread_mutexattr_t attr;
53
54     // Initialize the mutex attributes
55     int errorcode = pthread_mutexattr_init(&attr);
56     assert(errorcode == 0);
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     // Make it a process local mutex
65     errorcode = pthread_mutexattr_setpshared(&attr, PTHREAD_PROCESS_PRIVATE);
66
67     // Initialize the mutex
68     errorcode = pthread_mutex_init(mutex, &attr);
69     assert(errorcode == 0);
70
71     // Destroy the attributes
72     errorcode = pthread_mutexattr_destroy(&attr);
73     assert(errorcode == 0);
74
75     // Assign the data member
76     data_ = mutex;
77   }
78 }
79
80 // Destruct a Mutex
81 Mutex::~Mutex()
82 {
83   if (pthread_enabled)
84   {
85     pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
86     assert(mutex != 0);
87     int errorcode = pthread_mutex_destroy(mutex);
88     assert(mutex != 0);
89   }
90 }
91
92 bool 
93 Mutex::acquire()
94 {
95   if (pthread_enabled) 
96   {
97     pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
98     assert(mutex != 0);
99
100     int errorcode = pthread_mutex_lock(mutex);
101     return errorcode == 0;
102   }
103   return false;
104 }
105
106 bool 
107 Mutex::release()
108 {
109   if (pthread_enabled)
110   {
111     pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
112     assert(mutex != 0);
113
114     int errorcode = pthread_mutex_unlock(mutex);
115     return errorcode == 0;
116   }
117   return false;
118 }
119
120 bool 
121 Mutex::tryacquire()
122 {
123   if (pthread_enabled)
124   {
125     pthread_mutex_t* mutex = reinterpret_cast<pthread_mutex_t*>(data_);
126     assert(mutex != 0);
127
128     int errorcode = pthread_mutex_trylock(mutex);
129     return errorcode == 0;
130   }
131   return false;
132 }
133
134 }
135 #elif defined(LLVM_ON_UNIX)
136 #include "Unix/Mutex.inc"
137 #elif defined( LLVM_ON_WIN32)
138 #include "Win32/Mutex.inc"
139 #else
140 #warning Neither LLVM_ON_UNIX nor LLVM_ON_WIN32 was set in System/Mutex.cpp
141 #endif