monitor.cc revision fc86162ce2a3467acb690e18cc8bd9b3daafc606
15f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 25f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Copyright (C) 2008 The Android Open Source Project 35f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 45f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Licensed under the Apache License, Version 2.0 (the "License"); 55f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * you may not use this file except in compliance with the License. 65f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * You may obtain a copy of the License at 75f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 85f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * http://www.apache.org/licenses/LICENSE-2.0 95f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Unless required by applicable law or agreed to in writing, software 115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * distributed under the License is distributed on an "AS IS" BASIS, 125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * See the License for the specific language governing permissions and 145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * limitations under the License. 155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1754e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#include "monitor.h" 185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include <errno.h> 205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include <fcntl.h> 215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include <pthread.h> 225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include <stdlib.h> 235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include <sys/time.h> 245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include <time.h> 255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include <unistd.h> 265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include "mutex.h" 285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include "object.h" 29c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes#include "stl_util.h" 305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include "thread.h" 318e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes#include "thread_list.h" 325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesnamespace art { 345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Every Object has a monitor associated with it, but not every Object is 375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * actually locked. Even the ones that are locked do not need a 385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * full-fledged monitor until a) there is actual contention or b) wait() 395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * is called on the Object. 405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * For Android, we have implemented a scheme similar to the one described 425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * in Bacon et al.'s "Thin locks: featherweight synchronization for Java" 435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * (ACM 1998). Things are even easier for us, though, because we have 445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * a full 32 bits to work with. 455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The two states of an Object's lock are referred to as "thin" and 475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * "fat". A lock may transition from the "thin" state to the "fat" 485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * state and this transition is referred to as inflation. Once a lock 495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * has been inflated it remains in the "fat" state indefinitely. 505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The lock value itself is stored in Object.lock. The LSB of the 525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * lock encodes its state. When cleared, the lock is in the "thin" 535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * state and its bits are formatted as follows: 545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * [31 ---- 19] [18 ---- 3] [2 ---- 1] [0] 565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * lock count thread id hash state 0 575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * When set, the lock is in the "fat" state and its bits are formatted 595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * as follows: 605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * [31 ---- 3] [2 ---- 1] [0] 625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * pointer hash state 1 635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * For an in-depth description of the mechanics of thin-vs-fat locking, 655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * read the paper referred to above. 6654e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * 675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Monitors provide: 685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * - mutually exclusive access to resources 695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * - a way for multiple threads to wait for notification 705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * In effect, they fill the role of both mutexes and condition variables. 725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Only one thread can own the monitor at any time. There may be several 745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * threads waiting on it (the wait call unlocks it). One or more waiting 755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * threads may be getting interrupted or notified at any given time. 765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * TODO: the various members of monitor are not SMP-safe. 785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 7954e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes 8054e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes 8154e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes/* 8254e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * Monitor accessor. Extracts a monitor structure pointer from a fat 8354e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * lock. Performs no error checking. 8454e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes */ 8554e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_MONITOR(x) \ 8654e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes ((Monitor*)((x) & ~((LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT) | LW_SHAPE_MASK))) 8754e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes 8854e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes/* 8954e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * Lock recursion count field. Contains a count of the number of times 9054e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * a lock has been recursively acquired. 9154e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes */ 9254e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_LOCK_COUNT_MASK 0x1fff 9354e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_LOCK_COUNT_SHIFT 19 9454e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_LOCK_COUNT(x) (((x) >> LW_LOCK_COUNT_SHIFT) & LW_LOCK_COUNT_MASK) 9554e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes 96fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughesbool (*Monitor::is_sensitive_thread_hook_)() = NULL; 9732d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughesbool Monitor::is_verbose_ = false; 98fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughesuint32_t Monitor::lock_profiling_threshold_ = 0; 9932d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes 100c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughesbool Monitor::IsVerbose() { 101c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes return is_verbose_; 102c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes} 103c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes 104fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughesbool Monitor::IsSensitiveThread() { 105fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes if (is_sensitive_thread_hook_ != NULL) { 106fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes return (*is_sensitive_thread_hook_)(); 107fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } 108fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes return false; 109fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes} 110fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 111fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughesvoid Monitor::Init(bool is_verbose, uint32_t lock_profiling_threshold, bool (*is_sensitive_thread_hook)()) { 11232d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes is_verbose_ = is_verbose; 113fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes lock_profiling_threshold_ = lock_profiling_threshold; 114fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes is_sensitive_thread_hook_ = is_sensitive_thread_hook; 11532d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes} 11632d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes 1175f79133a435ebcb20000370d56046fe01201dd80Elliott HughesMonitor::Monitor(Object* obj) 1185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes : owner_(NULL), 1195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_count_(0), 1205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes obj_(obj), 1215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes wait_set_(NULL), 1225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_("a monitor lock"), 1235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_filename_(NULL), 1245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_line_number_(0) { 1255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 1265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1275f79133a435ebcb20000370d56046fe01201dd80Elliott HughesMonitor::~Monitor() { 1285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(obj_ != NULL); 1295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK_EQ(LW_SHAPE(*obj_->GetRawLockWordAddress()), LW_SHAPE_FAT); 1305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#ifndef NDEBUG 1325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* This lock is associated with an object 1335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * that's being swept. The only possible way 1345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * anyone could be holding this lock would be 1355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * if some JNI code locked but didn't unlock 1365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * the object, in which case we've got some bad 1375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * native code somewhere. 1385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 1395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(lock_.TryLock()); 1405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_.Unlock(); 1415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#endif 1425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 1435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 1455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Links a thread into a monitor's wait set. The monitor lock must be 1465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * held by the caller of this routine. 1475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 1485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::AppendToWaitSet(Thread* thread) { 1495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(owner_ == Thread::Current()); 1505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(thread != NULL); 151dc33ad5db2dc6ed9b76d5219888626a604debbe1Elliott Hughes DCHECK(thread->wait_next_ == NULL) << thread->wait_next_; 1525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (wait_set_ == NULL) { 1535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes wait_set_ = thread; 1545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 1555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 1565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // push_back. 1585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread* t = wait_set_; 1595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes while (t->wait_next_ != NULL) { 1605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes t = t->wait_next_; 1615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 1625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes t->wait_next_ = thread; 1635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 1645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 1665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Unlinks a thread from a monitor's wait set. The monitor lock must 1675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * be held by the caller of this routine. 1685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 1695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::RemoveFromWaitSet(Thread *thread) { 1705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(owner_ == Thread::Current()); 1715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(thread != NULL); 1725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (wait_set_ == NULL) { 1735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 1745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 1755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (wait_set_ == thread) { 1765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes wait_set_ = thread->wait_next_; 1775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thread->wait_next_ = NULL; 1785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 1795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 1805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread* t = wait_set_; 1825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes while (t->wait_next_ != NULL) { 1835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (t->wait_next_ == thread) { 1845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes t->wait_next_ = thread->wait_next_; 1855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thread->wait_next_ = NULL; 1865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 1875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 1885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes t = t->wait_next_; 1895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 1905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 1915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 192c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott HughesObject* Monitor::GetObject() { 193c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes return obj_; 1945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 1955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 1965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Lock(Thread* self) { 1975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (owner_ == self) { 1985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_count_++; 1995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 2005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 201fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 202fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes uint64_t waitStart, waitEnd; 2035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (!lock_.TryLock()) { 204fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes uint32_t wait_threshold = lock_profiling_threshold_; 205fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes const char* current_owner_filename = NULL; 206fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes uint32_t current_owner_line_number = -1; 2075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes { 2085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ScopedThreadStateChange tsc(self, Thread::kBlocked); 209fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes if (wait_threshold != 0) { 210fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes waitStart = NanoTime() / 1000; 211fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } 212fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes current_owner_filename = owner_filename_; 213fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes current_owner_line_number = owner_line_number_; 2145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_.Lock(); 216fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes if (wait_threshold != 0) { 217fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes waitEnd = NanoTime() / 1000; 218fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } 219fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } 220fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes 221fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes if (wait_threshold != 0) { 222fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes uint64_t wait_ms = (waitEnd - waitStart) / 1000; 223fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes uint32_t sample_percent; 224fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes if (wait_ms >= wait_threshold) { 225fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes sample_percent = 100; 226fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } else { 227fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes sample_percent = 100 * wait_ms / wait_threshold; 228fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } 229fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes if (sample_percent != 0 && (static_cast<uint32_t>(rand() % 100) < sample_percent)) { 230fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes LogContentionEvent(self, wait_ms, sample_percent, current_owner_filename, current_owner_line_number); 231fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } 2325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_ = self; 2355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK_EQ(lock_count_, 0); 2365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // When debugging, save the current monitor holder for future 2385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // acquisition failures to use in sampled logging. 239fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes if (lock_profiling_threshold_ != 0) { 240fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes self->GetCurrentLocation(owner_filename_, owner_line_number_); 241fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes } 2425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 2435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid ThrowIllegalMonitorStateException(const char* msg) { 2455cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes Thread::Current()->ThrowNewException("Ljava/lang/IllegalMonitorStateException;", msg); 2465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 2475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesbool Monitor::Unlock(Thread* self) { 2495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(self != NULL); 2505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (owner_ == self) { 2515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // We own the monitor, so nobody else can be in here. 2525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (lock_count_ == 0) { 2535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_ = NULL; 2545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_filename_ = "unlocked"; 2555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_line_number_ = 0; 2565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_.Unlock(); 2575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 2585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes --lock_count_; 2595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 2615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // We don't own this, so we're not allowed to unlock it. 2625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The JNI spec says that we should throw IllegalMonitorStateException 2635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // in this case. 2645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("unlock of unowned monitor"); 2655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return false; 2665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return true; 2685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 2695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 2715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Converts the given relative waiting time into an absolute time. 2725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 2735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid ToAbsoluteTime(int64_t ms, int32_t ns, struct timespec *ts) { 2745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes int64_t endSec; 2755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#ifdef HAVE_TIMEDWAIT_MONOTONIC 2775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes clock_gettime(CLOCK_MONOTONIC, ts); 2785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#else 2795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes { 2805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes struct timeval tv; 2815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes gettimeofday(&tv, NULL); 2825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ts->tv_sec = tv.tv_sec; 2835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ts->tv_nsec = tv.tv_usec * 1000; 2845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#endif 2865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes endSec = ts->tv_sec + ms / 1000; 2875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (endSec >= 0x7fffffff) { 2885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes LOG(INFO) << "Note: end time exceeds epoch"; 2895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes endSec = 0x7ffffffe; 2905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ts->tv_sec = endSec; 2925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ts->tv_nsec = (ts->tv_nsec + (ms % 1000) * 1000000) + ns; 2935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 2945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Catch rollover. 2955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (ts->tv_nsec >= 1000000000L) { 2965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ts->tv_sec++; 2975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ts->tv_nsec -= 1000000000L; 2985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 2995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 3005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesint dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex, int64_t ms, int32_t ns) { 3025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes struct timespec ts; 3035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ToAbsoluteTime(ms, ns, &ts); 3045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#if defined(HAVE_TIMEDWAIT_MONOTONIC) 3055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes int rc = pthread_cond_timedwait_monotonic(cond, mutex, &ts); 3065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#else 3075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes int rc = pthread_cond_timedwait(cond, mutex, &ts); 3085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#endif 3095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(rc == 0 || rc == ETIMEDOUT); 3105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return rc; 3115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 3125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 3145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Wait on a monitor until timeout, interrupt, or notification. Used for 3155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join(). 3165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 3175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * If another thread calls Thread.interrupt(), we throw InterruptedException 3185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * and return immediately if one of the following are true: 3195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * - blocked in wait(), wait(long), or wait(long, int) methods of Object 3205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * - blocked in join(), join(long), or join(long, int) methods of Thread 3215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * - blocked in sleep(long), or sleep(long, int) methods of Thread 3225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Otherwise, we set the "interrupted" flag. 3235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 3245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Checks to make sure that "ns" is in the range 0-999999 3255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * (i.e. fractions of a millisecond) and throws the appropriate 3265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * exception if it isn't. 3275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 3285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The spec allows "spurious wakeups", and recommends that all code using 3295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Object.wait() do so in a loop. This appears to derive from concerns 3305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * about pthread_cond_wait() on multiprocessor systems. Some commentary 3315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * on the web casts doubt on whether these can/should occur. 3325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 3335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Since we're allowed to wake up "early", we clamp extremely long durations 3345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * to return at the end of the 32-bit time epoch. 3355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 3365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Wait(Thread* self, int64_t ms, int32_t ns, bool interruptShouldThrow) { 3375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(self != NULL); 3385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Make sure that we hold the lock. 3405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (owner_ != self) { 3415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("object not locked by thread before wait()"); 3425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 3435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 3445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Enforce the timeout range. 3465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (ms < 0 || ns < 0 || ns > 999999) { 3475cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;", 3485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes "timeout arguments out of range: ms=%lld ns=%d", ms, ns); 3495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 3505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 3515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Compute absolute wakeup time, if necessary. 3535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes struct timespec ts; 3545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes bool timed = false; 3555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (ms != 0 || ns != 0) { 3565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ToAbsoluteTime(ms, ns, &ts); 3575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes timed = true; 3585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 3595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 3615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Add ourselves to the set of threads waiting on this monitor, and 3625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * release our hold. We need to let it go even if we're a few levels 3635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * deep in a recursive lock, and we need to restore that later. 3645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 3655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * We append to the wait set ahead of clearing the count and owner 3665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * fields so the subroutine can check that the calling thread owns 3675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * the monitor. Aside from that, the order of member updates is 3685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * not order sensitive as we hold the pthread mutex. 3695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 3705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes AppendToWaitSet(self); 3715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes int prevLockCount = lock_count_; 3725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_count_ = 0; 3735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_ = NULL; 3745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes const char* savedFileName = owner_filename_; 3755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_filename_ = NULL; 3765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes uint32_t savedLineNumber = owner_line_number_; 3775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_line_number_ = 0; 3785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 3805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Update thread status. If the GC wakes up, it'll ignore us, knowing 3815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * that we won't touch any references in this state, and we'll check 3825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * our suspend mode before we transition out. 3835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 3845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (timed) { 3855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->SetState(Thread::kTimedWaiting); 3865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 3875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->SetState(Thread::kWaiting); 3885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 3895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 39085d1545e985ac689db4bad7849880e843707c862Elliott Hughes self->wait_mutex_->Lock(); 3915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 3925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 3935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Set wait_monitor_ to the monitor object we will be waiting on. 3945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * When wait_monitor_ is non-NULL a notifying or interrupting thread 3955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * must signal the thread's wait_cond_ to wake it up. 3965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 3975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(self->wait_monitor_ == NULL); 3985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->wait_monitor_ = this; 3995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 4015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Handle the case where the thread was interrupted before we called 4025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * wait(). 4035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 4045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes bool wasInterrupted = false; 4055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (self->interrupted_) { 4065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes wasInterrupted = true; 4075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->wait_monitor_ = NULL; 40885d1545e985ac689db4bad7849880e843707c862Elliott Hughes self->wait_mutex_->Unlock(); 4095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes goto done; 4105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 4135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Release the monitor lock and wait for a notification or 4145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * a timeout to occur. 4155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 4165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_.Unlock(); 4175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (!timed) { 41985d1545e985ac689db4bad7849880e843707c862Elliott Hughes self->wait_cond_->Wait(*self->wait_mutex_); 4205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 42185d1545e985ac689db4bad7849880e843707c862Elliott Hughes self->wait_cond_->TimedWait(*self->wait_mutex_, ts); 4225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (self->interrupted_) { 4245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes wasInterrupted = true; 4255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->interrupted_ = false; 4285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->wait_monitor_ = NULL; 42985d1545e985ac689db4bad7849880e843707c862Elliott Hughes self->wait_mutex_->Unlock(); 4305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Reacquire the monitor lock. 4325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Lock(self); 4335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesdone: 4355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 4365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * We remove our thread from wait set after restoring the count 4375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * and owner fields so the subroutine can check that the calling 4385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * thread owns the monitor. Aside from that, the order of member 4395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * updates is not order sensitive as we hold the pthread mutex. 4405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 4415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_ = self; 4425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes lock_count_ = prevLockCount; 4435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_filename_ = savedFileName; 4445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes owner_line_number_ = savedLineNumber; 4455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes RemoveFromWaitSet(self); 4465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* set self->status back to Thread::kRunnable, and self-suspend if needed */ 4485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->SetState(Thread::kRunnable); 4495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (wasInterrupted) { 4515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 4525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * We were interrupted while waiting, or somebody interrupted an 4535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * un-interruptible thread earlier and we're bailing out immediately. 4545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * 4555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The doc sayeth: "The interrupted status of the current thread is 4565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * cleared when this exception is thrown." 4575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 4585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->interrupted_ = false; 4595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (interruptShouldThrow) { 4605cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes Thread::Current()->ThrowNewException("Ljava/lang/InterruptedException;", NULL); 4615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 4645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Notify(Thread* self) { 4665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(self != NULL); 4675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Make sure that we hold the lock. 4695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (owner_ != self) { 4705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("object not locked by thread before notify()"); 4715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 4725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Signal the first waiting thread in the wait set. 4745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes while (wait_set_ != NULL) { 4755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread* thread = wait_set_; 4765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes wait_set_ = thread->wait_next_; 4775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thread->wait_next_ = NULL; 4785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Check to see if the thread is still waiting. 48085d1545e985ac689db4bad7849880e843707c862Elliott Hughes MutexLock mu(*thread->wait_mutex_); 4815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (thread->wait_monitor_ != NULL) { 48285d1545e985ac689db4bad7849880e843707c862Elliott Hughes thread->wait_cond_->Signal(); 4835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 4845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 4875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::NotifyAll(Thread* self) { 4895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(self != NULL); 4905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 4915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Make sure that we hold the lock. 4925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (owner_ != self) { 4935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("object not locked by thread before notifyAll()"); 4945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 4955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 4965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Signal all threads in the wait set. 4975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes while (wait_set_ != NULL) { 4985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread* thread = wait_set_; 4995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes wait_set_ = thread->wait_next_; 5005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thread->wait_next_ = NULL; 5015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thread->Notify(); 5025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 5035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 5045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 5055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 5065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Changes the shape of a monitor from thin to fat, preserving the 5075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * internal lock state. The calling thread must own the lock. 5085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 5095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Inflate(Thread* self, Object* obj) { 5105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(self != NULL); 5115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(obj != NULL); 5125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK_EQ(LW_SHAPE(*obj->GetRawLockWordAddress()), LW_SHAPE_THIN); 513f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes DCHECK_EQ(LW_LOCK_OWNER(*obj->GetRawLockWordAddress()), static_cast<int32_t>(self->GetThinLockId())); 5145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 5155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Allocate and acquire a new monitor. 5165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Monitor* m = new Monitor(obj); 51732d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes if (is_verbose_) { 518f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes LOG(INFO) << "monitor: thread " << self->GetThinLockId() 519f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes << " created monitor " << m << " for object " << obj; 52032d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes } 521c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes Runtime::Current()->GetMonitorList()->Add(m); 5225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes m->Lock(self); 5235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Propagate the lock state. 5245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes uint32_t thin = *obj->GetRawLockWordAddress(); 5255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes m->lock_count_ = LW_LOCK_COUNT(thin); 5265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT; 5275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thin |= reinterpret_cast<uint32_t>(m) | LW_SHAPE_FAT; 5285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Publish the updated lock word. 5295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes android_atomic_release_store(thin, obj->GetRawLockWordAddress()); 5305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 5315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 5325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::MonitorEnter(Thread* self, Object* obj) { 5335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes volatile int32_t* thinp = obj->GetRawLockWordAddress(); 5345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes struct timespec tm; 5355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes long sleepDelayNs; 5365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes long minSleepDelayNs = 1000000; /* 1 millisecond */ 5375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes long maxSleepDelayNs = 1000000000; /* 1 second */ 538f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes uint32_t thin, newThin; 5395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 5404681c809ba35d50fab92c592ce8d2c7f8b2731f7Elliott Hughes DCHECK(self != NULL); 5414681c809ba35d50fab92c592ce8d2c7f8b2731f7Elliott Hughes DCHECK(obj != NULL); 542f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes uint32_t threadId = self->GetThinLockId(); 5435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesretry: 5445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thin = *thinp; 5455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_SHAPE(thin) == LW_SHAPE_THIN) { 5465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 5475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The lock is a thin lock. The owner field is used to 5485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * determine the acquire method, ordered by cost. 5495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 5505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_LOCK_OWNER(thin) == threadId) { 5515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 5525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The calling thread owns the lock. Increment the 5535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * value of the recursion count field. 5545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 5555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *thinp += 1 << LW_LOCK_COUNT_SHIFT; 5565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_LOCK_COUNT(*thinp) == LW_LOCK_COUNT_MASK) { 5575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 5585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The reacquisition limit has been reached. Inflate 5595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * the lock so the next acquire will not overflow the 5605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * recursion count field. 5615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 5625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Inflate(self, obj); 5635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 5645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else if (LW_LOCK_OWNER(thin) == 0) { 5655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 5665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The lock is unowned. Install the thread id of the 5675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * calling thread into the owner field. This is the 5685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * common case. In performance critical code the JIT 5695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * will have tried this before calling out to the VM. 5705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 5715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT); 5725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (android_atomic_acquire_cas(thin, newThin, thinp) != 0) { 5735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The acquire failed. Try again. 5745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes goto retry; 5755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 5765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 57732d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes if (is_verbose_) { 578f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes LOG(INFO) << StringPrintf("monitor: thread %d spin on lock %p (a %s) owned by %d", 579f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes threadId, thinp, PrettyTypeOf(obj).c_str(), LW_LOCK_OWNER(thin)); 58032d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes } 5815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The lock is owned by another thread. Notify the VM that we are about to wait. 5828e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes self->monitor_enter_object_ = obj; 5835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread::State oldStatus = self->SetState(Thread::kBlocked); 5845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Spin until the thin lock is released or inflated. 5855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes sleepDelayNs = 0; 5865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes for (;;) { 5875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thin = *thinp; 5885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Check the shape of the lock word. Another thread 5895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // may have inflated the lock while we were waiting. 5905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_SHAPE(thin) == LW_SHAPE_THIN) { 5915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_LOCK_OWNER(thin) == 0) { 5925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The lock has been released. Install the thread id of the 5935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // calling thread into the owner field. 5945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT); 5955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (android_atomic_acquire_cas(thin, newThin, thinp) == 0) { 5965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The acquire succeed. Break out of the loop and proceed to inflate the lock. 5975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes break; 5985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 5995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The lock has not been released. Yield so the owning thread can run. 6015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (sleepDelayNs == 0) { 6025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes sched_yield(); 6035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes sleepDelayNs = minSleepDelayNs; 6045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes tm.tv_sec = 0; 6065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes tm.tv_nsec = sleepDelayNs; 6075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes nanosleep(&tm, NULL); 6085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Prepare the next delay value. Wrap to avoid once a second polls for eternity. 6095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (sleepDelayNs < maxSleepDelayNs / 2) { 6105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes sleepDelayNs *= 2; 6115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes sleepDelayNs = minSleepDelayNs; 6135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The thin lock was inflated by another thread. Let the VM know we are no longer 6185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // waiting and try again. 61932d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes if (is_verbose_) { 620f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes LOG(INFO) << "monitor: thread " << threadId 621f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes << " found lock " << (void*) thinp << " surprise-fattened by another thread"; 62232d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes } 6238e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes self->monitor_enter_object_ = NULL; 6245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->SetState(oldStatus); 6255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes goto retry; 6265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 62832d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes if (is_verbose_) { 629f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes LOG(INFO) << StringPrintf("monitor: thread %d spin on lock %p done", threadId, thinp); 63032d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes } 6315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // We have acquired the thin lock. Let the VM know that we are no longer waiting. 6328e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes self->monitor_enter_object_ = NULL; 6335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes self->SetState(oldStatus); 6345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Fatten the lock. 6355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Inflate(self, obj); 63632d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes if (is_verbose_) { 637f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes LOG(INFO) << StringPrintf("monitor: thread %d fattened lock %p", threadId, thinp); 63832d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes } 6395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // The lock is a fat lock. 64232d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes if (is_verbose_) { 643f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes LOG(INFO) << StringPrintf("monitor: thread %d locking fat lock %p (%p) %p on a %s", 644f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes threadId, thinp, LW_MONITOR(*thinp), (void*)*thinp, PrettyTypeOf(obj).c_str()); 64532d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes } 6465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(LW_MONITOR(*thinp) != NULL); 6475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes LW_MONITOR(*thinp)->Lock(self); 6485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 6505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 6515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesbool Monitor::MonitorExit(Thread* self, Object* obj) { 6525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes volatile int32_t* thinp = obj->GetRawLockWordAddress(); 6535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 6545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(self != NULL); 6554681c809ba35d50fab92c592ce8d2c7f8b2731f7Elliott Hughes //DCHECK_EQ(self->GetState(), Thread::kRunnable); 6565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(obj != NULL); 6575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 6585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 6595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Cache the lock word as its value can change while we are 6605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * examining its state. 6615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 6625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes uint32_t thin = *thinp; 6635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_SHAPE(thin) == LW_SHAPE_THIN) { 6645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 6655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The lock is thin. We must ensure that the lock is owned 6665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * by the given thread before unlocking it. 6675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 668f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes if (LW_LOCK_OWNER(thin) == self->GetThinLockId()) { 6695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 6705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * We are the lock owner. It is safe to update the lock 6715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * without CAS as lock ownership guards the lock itself. 6725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 6735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_LOCK_COUNT(thin) == 0) { 6745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 6755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The lock was not recursively acquired, the common 6765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * case. Unlock by clearing all bits except for the 6775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * hash state. 6785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 6795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes thin &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT); 6805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes android_atomic_release_store(thin, thinp); 6815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 6835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The object was recursively acquired. Decrement the 6845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * lock recursion count field. 6855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 6865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *thinp -= 1 << LW_LOCK_COUNT_SHIFT; 6875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 6905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * We do not own the lock. The JVM spec requires that we 6915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * throw an exception in this case. 6925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 6935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("unlock of unowned monitor"); 6945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return false; 6955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 6965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 6975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* 6985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The lock is fat. We must check to see if Unlock has 6995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * raised any exceptions before continuing. 7005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 7015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes DCHECK(LW_MONITOR(*thinp) != NULL); 7025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (!LW_MONITOR(*thinp)->Unlock(self)) { 7035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // An exception has been raised. Do not fall through. 7045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return false; 7055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return true; 7085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 7095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/* 7115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Object.wait(). Also called for class init. 7125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 7135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Wait(Thread* self, Object *obj, int64_t ms, int32_t ns, bool interruptShouldThrow) { 7145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes volatile int32_t* thinp = obj->GetRawLockWordAddress(); 7155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // If the lock is still thin, we need to fatten it. 7175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes uint32_t thin = *thinp; 7185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_SHAPE(thin) == LW_SHAPE_THIN) { 7195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Make sure that 'self' holds the lock. 720f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes if (LW_LOCK_OWNER(thin) != self->GetThinLockId()) { 7215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("object not locked by thread before wait()"); 7225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 7235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes /* This thread holds the lock. We need to fatten the lock 7265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * so 'self' can block on it. Don't update the object lock 7275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * field yet, because 'self' needs to acquire the lock before 7285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * any other thread gets a chance. 7295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */ 7305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Inflate(self, obj); 73132d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes if (is_verbose_) { 732f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes LOG(INFO) << StringPrintf("monitor: thread %d fattened lock %p by wait()", self->GetThinLockId(), thinp); 73332d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes } 7345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes LW_MONITOR(*thinp)->Wait(self, ms, ns, interruptShouldThrow); 7365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 7375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Notify(Thread* self, Object *obj) { 7395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes uint32_t thin = *obj->GetRawLockWordAddress(); 7405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // If the lock is still thin, there aren't any waiters; 7425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // waiting on an object forces lock fattening. 7435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_SHAPE(thin) == LW_SHAPE_THIN) { 7445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Make sure that 'self' holds the lock. 745f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes if (LW_LOCK_OWNER(thin) != self->GetThinLockId()) { 7465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("object not locked by thread before notify()"); 7475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 7485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // no-op; there are no waiters to notify. 7505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 7515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // It's a fat lock. 7525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes LW_MONITOR(thin)->Notify(self); 7535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 7555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::NotifyAll(Thread* self, Object *obj) { 7575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes uint32_t thin = *obj->GetRawLockWordAddress(); 7585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // If the lock is still thin, there aren't any waiters; 7605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // waiting on an object forces lock fattening. 7615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_SHAPE(thin) == LW_SHAPE_THIN) { 7625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // Make sure that 'self' holds the lock. 763f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes if (LW_LOCK_OWNER(thin) != self->GetThinLockId()) { 7645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes ThrowIllegalMonitorStateException("object not locked by thread before notifyAll()"); 7655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return; 7665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // no-op; there are no waiters to notify. 7685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 7695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes // It's a fat lock. 7705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes LW_MONITOR(thin)->NotifyAll(self); 7715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 7735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 77424a3c2e9924e8765c4a9b4d383cb8f3b922f9c9fBrian Carlstromuint32_t Monitor::GetThinLockId(uint32_t raw_lock_word) { 7755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes if (LW_SHAPE(raw_lock_word) == LW_SHAPE_THIN) { 7765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return LW_LOCK_OWNER(raw_lock_word); 7775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } else { 7785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes Thread* owner = LW_MONITOR(raw_lock_word)->owner_; 7795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes return owner ? owner->GetThinLockId() : 0; 7805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes } 7815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} 7825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes 7838e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughesvoid Monitor::DescribeWait(std::ostream& os, const Thread* thread) { 7848e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes Thread::State state = thread->GetState(); 7858e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 7868e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes Object* object = NULL; 7878e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes uint32_t lock_owner = ThreadList::kInvalidId; 7888e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes if (state == Thread::kWaiting || state == Thread::kTimedWaiting) { 7898e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes os << " - waiting on "; 7908e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes Monitor* monitor = thread->wait_monitor_; 7918e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes if (monitor != NULL) { 7928e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes object = monitor->obj_; 7938e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes } 7948e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes lock_owner = Thread::LockOwnerFromThreadLock(object); 7958e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes } else if (state == Thread::kBlocked) { 7968e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes os << " - waiting to lock "; 7978e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes object = thread->monitor_enter_object_; 7988e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes if (object != NULL) { 79924a3c2e9924e8765c4a9b4d383cb8f3b922f9c9fBrian Carlstrom lock_owner = object->GetThinLockId(); 8008e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes } 8018e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes } else { 8028e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // We're not waiting on anything. 8038e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes return; 8048e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes } 8058e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes os << "<" << object << ">"; 8068e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 8078e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // - waiting on <0x613f83d8> (a java.lang.ThreadLock) held by thread 5 8088e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes // - waiting on <0x6008c468> (a java.lang.Class<java.lang.ref.ReferenceQueue>) 8098e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes os << " (a " << PrettyTypeOf(object) << ")"; 8108e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 8118e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes if (lock_owner != ThreadList::kInvalidId) { 8128e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes os << " held by thread " << lock_owner; 8138e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes } 8148e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 8158e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes os << "\n"; 8168e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes} 8178e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes 818c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott HughesMonitorList::MonitorList() : lock_("MonitorList lock") { 819c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes} 820c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes 821c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott HughesMonitorList::~MonitorList() { 822c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes MutexLock mu(lock_); 823c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes STLDeleteElements(&list_); 824c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes} 825c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes 826c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughesvoid MonitorList::Add(Monitor* m) { 827c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes MutexLock mu(lock_); 828c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes list_.push_front(m); 829c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes} 830c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes 831c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughesvoid MonitorList::SweepMonitorList(Heap::IsMarkedTester is_marked, void* arg) { 832c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes MutexLock mu(lock_); 833c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes typedef std::list<Monitor*>::iterator It; // TODO: C++0x auto 834c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes It it = list_.begin(); 835c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes while (it != list_.end()) { 836c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes Monitor* m = *it; 837c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes if (!is_marked(m->GetObject(), arg)) { 838c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes if (Monitor::IsVerbose()) { 839c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes LOG(INFO) << "freeing monitor " << m << " belonging to unmarked object " << m->GetObject(); 840c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes } 841c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes delete m; 842c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes it = list_.erase(it); 843c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes } else { 844c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes ++it; 845c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes } 846c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes } 847c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes} 848c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes 8495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes} // namespace art 850