ObjectLock<mirror::Class> lock(self, klass);
art/runtime/object_lock.cc
template <typename T>
ObjectLock<T>::ObjectLock(Thread* self, Handle<T> object) : self_(self), obj_(object) {
CHECK(object != nullptr);
obj_->MonitorEnter(self_);
}
template <typename T>
ObjectLock<T>::~ObjectLock() {
obj_->MonitorExit(self_);
}
art/runtime/mirror/object-inl.h
inline mirror::Object* Object::MonitorEnter(Thread* self) {
return Monitor::MonitorEnter(self, this, /*trylock*/false);
}
art/runtime/monitor.cc
mirror::Object* Monitor::MonitorEnter(Thread* self, mirror::Object* obj, bool trylock) {
StackHandleScope<1> hs(self);
Handle<mirror::Object> h_obj(hs.NewHandle(obj));
while (true) {
// We initially read the lockword with ordinary Java/relaxed semantics. When stronger
// semantics are needed, we address it below. Since GetLockWord bottoms out to a relaxed load,
// we can fix it later, in an infrequently executed case, with a fence.
LockWord lock_word = h_obj->GetLockWord(false);
switch (lock_word.GetState()) {
case LockWord::kUnlocked: {
// No ordering required for preceding lockword read, since we retest.
LockWord thin_locked(LockWord::FromThinLockId(thread_id, 0, lock_word.GCState()));
if (h_obj->CasLockWordWeakAcquire(lock_word, thin_locked)) {
AtraceMonitorLock(self, h_obj.Get(), false /* is_wait */);
return h_obj.Get(); // Success!
}
continue; // Go again.
}
case LockWord::kThinLocked: {
case LockWord::kFatLocked: {
art/runtime/lock_word.h
enum LockState {
kUnlocked, // No lock owners.
kThinLocked, // Single uncontended owner.
kFatLocked, // See associated monitor.
kHashCode, // Lock word contains an identity hash.
kForwardingAddress, // Lock word contains the forwarding address of an object.
};
prebuilts/gcc/linux-x86/host/x86_64-linux-glibc2.15-4.8/x86_64-linux/include/c++/4.8/mutex
/// @brief Scoped lock idiom.
// Acquire the mutex here with a constructor call, then release with
// the destructor call in accordance with RAII style.
template<typename _Mutex>
class lock_guard
{
public:
typedef _Mutex mutex_type;
explicit lock_guard(mutex_type& __m) : _M_device(__m)
{ _M_device.lock(); }
lock_guard(mutex_type& __m, adopt_lock_t) : _M_device(__m)
{ } // calling thread owns mutex
~lock_guard()
{ _M_device.unlock(); }
lock_guard(const lock_guard&) = delete;
lock_guard& operator=(const lock_guard&) = delete;
private:
mutex_type& _M_device;
};