monitor.cc revision d423741f91526cada9d081c64ee295ec9863032d
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
2733dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao#include "class_linker.h"
285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include "mutex.h"
295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include "object.h"
306d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers#include "object_utils.h"
31c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes#include "stl_util.h"
325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#include "thread.h"
338e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes#include "thread_list.h"
345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesnamespace art {
365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/*
385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Every Object has a monitor associated with it, but not every Object is
395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * actually locked.  Even the ones that are locked do not need a
405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * full-fledged monitor until a) there is actual contention or b) wait()
415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * is called on the Object.
425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * For Android, we have implemented a scheme similar to the one described
445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * in Bacon et al.'s "Thin locks: featherweight synchronization for Java"
455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * (ACM 1998).  Things are even easier for us, though, because we have
465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * a full 32 bits to work with.
475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The two states of an Object's lock are referred to as "thin" and
495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * "fat".  A lock may transition from the "thin" state to the "fat"
505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * state and this transition is referred to as inflation.  Once a lock
515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * has been inflated it remains in the "fat" state indefinitely.
525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The lock value itself is stored in Object.lock.  The LSB of the
545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * lock encodes its state.  When cleared, the lock is in the "thin"
555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * state and its bits are formatted as follows:
565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *    [31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *     lock count   thread id  hash state  0
595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * When set, the lock is in the "fat" state and its bits are formatted
615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * as follows:
625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *    [31 ---- 3] [2 ---- 1] [0]
645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *      pointer   hash state  1
655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * For an in-depth description of the mechanics of thin-vs-fat locking,
675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * read the paper referred to above.
6854e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes *
695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Monitors provide:
705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *  - mutually exclusive access to resources
715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *  - a way for multiple threads to wait for notification
725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * In effect, they fill the role of both mutexes and condition variables.
745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Only one thread can own the monitor at any time.  There may be several
765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * threads waiting on it (the wait call unlocks it).  One or more waiting
775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * threads may be getting interrupted or notified at any given time.
785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * TODO: the various members of monitor are not SMP-safe.
805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */
8154e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes
8254e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes
8354e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes/*
8454e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * Monitor accessor.  Extracts a monitor structure pointer from a fat
8554e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * lock.  Performs no error checking.
8654e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes */
8754e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_MONITOR(x) \
8854e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes  ((Monitor*)((x) & ~((LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT) | LW_SHAPE_MASK)))
8954e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes
9054e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes/*
9154e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * Lock recursion count field.  Contains a count of the number of times
9254e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes * a lock has been recursively acquired.
9354e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes */
9454e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_LOCK_COUNT_MASK 0x1fff
9554e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_LOCK_COUNT_SHIFT 19
9654e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes#define LW_LOCK_COUNT(x) (((x) >> LW_LOCK_COUNT_SHIFT) & LW_LOCK_COUNT_MASK)
9754e7df1896a4066cbb9fe6f72249829f0b8c49c6Elliott Hughes
98fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughesbool (*Monitor::is_sensitive_thread_hook_)() = NULL;
99fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughesuint32_t Monitor::lock_profiling_threshold_ = 0;
10032d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes
101fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughesbool Monitor::IsSensitiveThread() {
102fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  if (is_sensitive_thread_hook_ != NULL) {
103fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes    return (*is_sensitive_thread_hook_)();
104fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  }
105fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  return false;
106fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes}
107fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes
1084dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughesvoid Monitor::Init(uint32_t lock_profiling_threshold, bool (*is_sensitive_thread_hook)()) {
109fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  lock_profiling_threshold_ = lock_profiling_threshold;
110fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  is_sensitive_thread_hook_ = is_sensitive_thread_hook;
11132d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes}
11232d6e1e5654433d7eadede89e1c770b2c839aee9Elliott Hughes
1135f79133a435ebcb20000370d56046fe01201dd80Elliott HughesMonitor::Monitor(Object* obj)
1145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    : owner_(NULL),
1155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      lock_count_(0),
1165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      obj_(obj),
1175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      wait_set_(NULL),
1185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      lock_("a monitor lock"),
11933dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao      locking_method_(NULL),
12033dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao      locking_pc_(0) {
1215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
1225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1235f79133a435ebcb20000370d56046fe01201dd80Elliott HughesMonitor::~Monitor() {
1245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(obj_ != NULL);
1255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK_EQ(LW_SHAPE(*obj_->GetRawLockWordAddress()), LW_SHAPE_FAT);
1265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
1275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/*
1295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Links a thread into a monitor's wait set.  The monitor lock must be
1305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * held by the caller of this routine.
1315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */
1325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::AppendToWaitSet(Thread* thread) {
1335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(owner_ == Thread::Current());
1345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(thread != NULL);
135dc33ad5db2dc6ed9b76d5219888626a604debbe1Elliott Hughes  DCHECK(thread->wait_next_ == NULL) << thread->wait_next_;
1365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (wait_set_ == NULL) {
1375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    wait_set_ = thread;
1385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
1395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
1405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // push_back.
1425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Thread* t = wait_set_;
1435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  while (t->wait_next_ != NULL) {
1445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    t = t->wait_next_;
1455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
1465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  t->wait_next_ = thread;
1475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
1485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/*
1505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Unlinks a thread from a monitor's wait set.  The monitor lock must
1515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * be held by the caller of this routine.
1525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */
1535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::RemoveFromWaitSet(Thread *thread) {
1545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(owner_ == Thread::Current());
1555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(thread != NULL);
1565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (wait_set_ == NULL) {
1575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
1585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
1595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (wait_set_ == thread) {
1605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    wait_set_ = thread->wait_next_;
1615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    thread->wait_next_ = NULL;
1625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
1635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
1645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Thread* t = wait_set_;
1665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  while (t->wait_next_ != NULL) {
1675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (t->wait_next_ == thread) {
1685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      t->wait_next_ = thread->wait_next_;
1695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      thread->wait_next_ = NULL;
1705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
1715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
1725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    t = t->wait_next_;
1735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
1745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
1755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
176c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott HughesObject* Monitor::GetObject() {
177c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  return obj_;
1785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
1795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Lock(Thread* self) {
1815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (owner_ == self) {
1825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    lock_count_++;
1835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
1845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
185fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes
186fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  uint64_t waitStart, waitEnd;
1875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (!lock_.TryLock()) {
188fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes    uint32_t wait_threshold = lock_profiling_threshold_;
18933dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao    const Method* current_locking_method = NULL;
190e65a6c99b0fd8908484b61c3c8f5a43cf0081f3cElliott Hughes    uintptr_t current_locking_pc = 0;
1915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    {
1925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      ScopedThreadStateChange tsc(self, Thread::kBlocked);
193fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      if (wait_threshold != 0) {
194fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes        waitStart = NanoTime() / 1000;
195fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      }
19633dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao      current_locking_method = locking_method_;
19733dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao      current_locking_pc = locking_pc_;
1985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
1995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      lock_.Lock();
200fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      if (wait_threshold != 0) {
201fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes        waitEnd = NanoTime() / 1000;
202fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      }
203fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes    }
204fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes
205fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes    if (wait_threshold != 0) {
206fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      uint64_t wait_ms = (waitEnd - waitStart) / 1000;
207fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      uint32_t sample_percent;
208fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      if (wait_ms >= wait_threshold) {
209fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes        sample_percent = 100;
210fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      } else {
211fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes        sample_percent = 100 * wait_ms / wait_threshold;
212fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      }
213fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      if (sample_percent != 0 && (static_cast<uint32_t>(rand() % 100) < sample_percent)) {
21433dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao        const char* current_locking_filename;
21533dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao        uint32_t current_locking_line_number;
21633dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao        TranslateLocation(current_locking_method, current_locking_pc,
21733dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao                          current_locking_filename, current_locking_line_number);
21833dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao        LogContentionEvent(self, wait_ms, sample_percent, current_locking_filename, current_locking_line_number);
219fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes      }
2205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
2215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
2225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  owner_ = self;
2235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK_EQ(lock_count_, 0);
2245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
2255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // When debugging, save the current monitor holder for future
2265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // acquisition failures to use in sampled logging.
227fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  if (lock_profiling_threshold_ != 0) {
228d07986fad0d08cdf05505cf9230714a2cf0dd9aeElliott Hughes    locking_method_ = self->GetCurrentMethod(&locking_pc_);
229fc86162ce2a3467acb690e18cc8bd9b3daafc606Elliott Hughes  }
2305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
2315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
2326d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogersstatic void ThrowIllegalMonitorStateExceptionF(const char* fmt, ...)
2336d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers                                              __attribute__((format(printf, 1, 2)));
2346d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
2356d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogersstatic void ThrowIllegalMonitorStateExceptionF(const char* fmt, ...) {
2366d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  va_list args;
2376d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  va_start(args, fmt);
2386d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  Thread::Current()->ThrowNewExceptionV("Ljava/lang/IllegalMonitorStateException;", fmt, args);
2396d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  va_end(args);
2406d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers}
2416d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers
242d423741f91526cada9d081c64ee295ec9863032dElliott Hughesstatic std::string ThreadToString(Thread* thread) {
243d423741f91526cada9d081c64ee295ec9863032dElliott Hughes  if (thread == NULL) {
244d423741f91526cada9d081c64ee295ec9863032dElliott Hughes    return "NULL";
245d423741f91526cada9d081c64ee295ec9863032dElliott Hughes  }
246d423741f91526cada9d081c64ee295ec9863032dElliott Hughes  std::ostringstream oss;
247d423741f91526cada9d081c64ee295ec9863032dElliott Hughes  // TODO: alternatively, we could just return the thread's name.
248d423741f91526cada9d081c64ee295ec9863032dElliott Hughes  oss << *thread;
249d423741f91526cada9d081c64ee295ec9863032dElliott Hughes  return oss.str();
250d423741f91526cada9d081c64ee295ec9863032dElliott Hughes}
251d423741f91526cada9d081c64ee295ec9863032dElliott Hughes
2526d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogersvoid Monitor::FailedUnlock(Object* obj, Thread* expected_owner, Thread* found_owner,
2536d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers                           Monitor* mon) {
2546d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Acquire thread list lock so threads won't disappear from under us
2556d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  ScopedThreadListLock tll;
2566d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  // Re-read owner now that we hold lock
2576d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  Thread* current_owner = mon != NULL ? mon->owner_ : NULL;
2586d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  if (current_owner == NULL) {
2596d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    if (found_owner == NULL) {
2606d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      ThrowIllegalMonitorStateExceptionF("unlock of unowned monitor on object of type '%s'"
2616d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers                                         " on thread '%s'",
262d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         PrettyTypeOf(obj).c_str(),
263d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         ThreadToString(expected_owner).c_str());
2646d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    } else {
2656d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      // Race: the original read found an owner but now there is none
2666d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      ThrowIllegalMonitorStateExceptionF("unlock of monitor owned by '%s' on object of type '%s'"
2676d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers                                         " (where now the monitor appears unowned) on thread '%s'",
268d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         ThreadToString(found_owner).c_str(),
269d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         PrettyTypeOf(obj).c_str(),
270d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         ThreadToString(expected_owner).c_str());
2716d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    }
2726d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  } else {
2736d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    if (found_owner == NULL) {
2746d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      // Race: originally there was no owner, there is now
2756d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      ThrowIllegalMonitorStateExceptionF("unlock of monitor owned by '%s' on object of type '%s'"
2766d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers                                         " (originally believed to be unowned) on thread '%s'",
277d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         ThreadToString(current_owner).c_str(),
278d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         PrettyTypeOf(obj).c_str(),
279d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                         ThreadToString(expected_owner).c_str());
2806d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    } else {
2816d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      if (found_owner != current_owner) {
2826d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers        // Race: originally found and current owner have changed
2836d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers        ThrowIllegalMonitorStateExceptionF("unlock of monitor originally owned by '%s' (now"
2846d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers                                           " owned by '%s') on object of type '%s' on thread '%s'",
285d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                           ThreadToString(found_owner).c_str(),
286d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                           ThreadToString(current_owner).c_str(),
287d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                           PrettyTypeOf(obj).c_str(),
288d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                           ThreadToString(expected_owner).c_str());
2896d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      } else {
2906d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers        ThrowIllegalMonitorStateExceptionF("unlock of monitor owned by '%s' on object of type '%s'"
2916d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers                                           " on thread '%s",
292d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                           ThreadToString(current_owner).c_str(),
293d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                           PrettyTypeOf(obj).c_str(),
294d423741f91526cada9d081c64ee295ec9863032dElliott Hughes                                           ThreadToString(expected_owner).c_str());
2956d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      }
2966d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    }
2976d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  }
2985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
2995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesbool Monitor::Unlock(Thread* self) {
3015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(self != NULL);
3026d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  Thread* owner = owner_;
3036d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers  if (owner == self) {
3045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // We own the monitor, so nobody else can be in here.
3055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (lock_count_ == 0) {
3065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      owner_ = NULL;
30733dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao      locking_method_ = NULL;
30833dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao      locking_pc_ = 0;
3095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      lock_.Unlock();
3105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    } else {
3115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      --lock_count_;
3125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
3135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
3145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // We don't own this, so we're not allowed to unlock it.
3155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // The JNI spec says that we should throw IllegalMonitorStateException
3165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // in this case.
3176d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    FailedUnlock(obj_, self, owner, this);
3185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return false;
3195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
3205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  return true;
3215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
3225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/*
3245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Converts the given relative waiting time into an absolute time.
3255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */
3265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid ToAbsoluteTime(int64_t ms, int32_t ns, struct timespec *ts) {
3275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  int64_t endSec;
3285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#ifdef HAVE_TIMEDWAIT_MONOTONIC
3305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  clock_gettime(CLOCK_MONOTONIC, ts);
3315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#else
3325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  {
3335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    struct timeval tv;
3345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    gettimeofday(&tv, NULL);
3355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    ts->tv_sec = tv.tv_sec;
3365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    ts->tv_nsec = tv.tv_usec * 1000;
3375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
3385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#endif
3395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  endSec = ts->tv_sec + ms / 1000;
3405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (endSec >= 0x7fffffff) {
3415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    LOG(INFO) << "Note: end time exceeds epoch";
3425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    endSec = 0x7ffffffe;
3435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
3445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  ts->tv_sec = endSec;
3455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  ts->tv_nsec = (ts->tv_nsec + (ms % 1000) * 1000000) + ns;
3465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Catch rollover.
3485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (ts->tv_nsec >= 1000000000L) {
3495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    ts->tv_sec++;
3505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    ts->tv_nsec -= 1000000000L;
3515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
3525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
3535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesint dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex, int64_t ms, int32_t ns) {
3555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  struct timespec ts;
3565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  ToAbsoluteTime(ms, ns, &ts);
3575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#if defined(HAVE_TIMEDWAIT_MONOTONIC)
3585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  int rc = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
3595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#else
3605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  int rc = pthread_cond_timedwait(cond, mutex, &ts);
3615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes#endif
3625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(rc == 0 || rc == ETIMEDOUT);
3635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  return rc;
3645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
3655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/*
3675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Wait on a monitor until timeout, interrupt, or notification.  Used for
3685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
3695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
3705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * If another thread calls Thread.interrupt(), we throw InterruptedException
3715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * and return immediately if one of the following are true:
3725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *  - blocked in wait(), wait(long), or wait(long, int) methods of Object
3735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *  - blocked in join(), join(long), or join(long, int) methods of Thread
3745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *  - blocked in sleep(long), or sleep(long, int) methods of Thread
3755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Otherwise, we set the "interrupted" flag.
3765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
3775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Checks to make sure that "ns" is in the range 0-999999
3785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * (i.e. fractions of a millisecond) and throws the appropriate
3795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * exception if it isn't.
3805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
3815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * The spec allows "spurious wakeups", and recommends that all code using
3825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Object.wait() do so in a loop.  This appears to derive from concerns
3835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * about pthread_cond_wait() on multiprocessor systems.  Some commentary
3845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * on the web casts doubt on whether these can/should occur.
3855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes *
3865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Since we're allowed to wake up "early", we clamp extremely long durations
3875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * to return at the end of the 32-bit time epoch.
3885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */
3895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Wait(Thread* self, int64_t ms, int32_t ns, bool interruptShouldThrow) {
3905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(self != NULL);
3915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Make sure that we hold the lock.
3935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (owner_ != self) {
3946d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    ThrowIllegalMonitorStateExceptionF("object not locked by thread before wait()");
3955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
3965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
3975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
3985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Enforce the timeout range.
3995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (ms < 0 || ns < 0 || ns > 999999) {
4005cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes    Thread::Current()->ThrowNewExceptionF("Ljava/lang/IllegalArgumentException;",
4015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        "timeout arguments out of range: ms=%lld ns=%d", ms, ns);
4025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
4035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Compute absolute wakeup time, if necessary.
4065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  struct timespec ts;
4075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  bool timed = false;
4085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (ms != 0 || ns != 0) {
4095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    ToAbsoluteTime(ms, ns, &ts);
4105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    timed = true;
4115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /*
4145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * Add ourselves to the set of threads waiting on this monitor, and
4155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * release our hold.  We need to let it go even if we're a few levels
4165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * deep in a recursive lock, and we need to restore that later.
4175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   *
4185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * We append to the wait set ahead of clearing the count and owner
4195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * fields so the subroutine can check that the calling thread owns
4205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * the monitor.  Aside from that, the order of member updates is
4215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * not order sensitive as we hold the pthread mutex.
4225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   */
4235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  AppendToWaitSet(self);
4245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  int prevLockCount = lock_count_;
4255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  lock_count_ = 0;
4265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  owner_ = NULL;
42733dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  const Method* savedMethod = locking_method_;
42833dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  locking_method_ = NULL;
429e65a6c99b0fd8908484b61c3c8f5a43cf0081f3cElliott Hughes  uintptr_t savedPc = locking_pc_;
43033dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  locking_pc_ = 0;
4315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /*
4335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * Update thread status.  If the GC wakes up, it'll ignore us, knowing
4345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * that we won't touch any references in this state, and we'll check
4355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * our suspend mode before we transition out.
4365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   */
4375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (timed) {
4385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    self->SetState(Thread::kTimedWaiting);
4395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
4405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    self->SetState(Thread::kWaiting);
4415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
44385d1545e985ac689db4bad7849880e843707c862Elliott Hughes  self->wait_mutex_->Lock();
4445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /*
4465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * Set wait_monitor_ to the monitor object we will be waiting on.
4475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * When wait_monitor_ is non-NULL a notifying or interrupting thread
4485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * must signal the thread's wait_cond_ to wake it up.
4495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   */
4505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(self->wait_monitor_ == NULL);
4515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  self->wait_monitor_ = this;
4525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /*
4545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * Handle the case where the thread was interrupted before we called
4555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * wait().
4565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   */
4575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  bool wasInterrupted = false;
4585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (self->interrupted_) {
4595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    wasInterrupted = true;
4605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    self->wait_monitor_ = NULL;
46185d1545e985ac689db4bad7849880e843707c862Elliott Hughes    self->wait_mutex_->Unlock();
4625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    goto done;
4635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /*
4665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * Release the monitor lock and wait for a notification or
4675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * a timeout to occur.
4685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   */
4695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  lock_.Unlock();
4705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (!timed) {
47285d1545e985ac689db4bad7849880e843707c862Elliott Hughes    self->wait_cond_->Wait(*self->wait_mutex_);
4735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
47485d1545e985ac689db4bad7849880e843707c862Elliott Hughes    self->wait_cond_->TimedWait(*self->wait_mutex_, ts);
4755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (self->interrupted_) {
4775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    wasInterrupted = true;
4785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
4795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  self->interrupted_ = false;
4815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  self->wait_monitor_ = NULL;
48285d1545e985ac689db4bad7849880e843707c862Elliott Hughes  self->wait_mutex_->Unlock();
4835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Reacquire the monitor lock.
4855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Lock(self);
4865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
4875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesdone:
4885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /*
4895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * We remove our thread from wait set after restoring the count
4905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * and owner fields so the subroutine can check that the calling
4915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * thread owns the monitor. Aside from that, the order of member
4925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * updates is not order sensitive as we hold the pthread mutex.
4935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   */
4945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  owner_ = self;
4955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  lock_count_ = prevLockCount;
49633dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  locking_method_ = savedMethod;
49733dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  locking_pc_ = savedPc;
4985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  RemoveFromWaitSet(self);
4995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /* set self->status back to Thread::kRunnable, and self-suspend if needed */
5015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  self->SetState(Thread::kRunnable);
5025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (wasInterrupted) {
5045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    /*
5055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * We were interrupted while waiting, or somebody interrupted an
5065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * un-interruptible thread earlier and we're bailing out immediately.
5075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     *
5085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * The doc sayeth: "The interrupted status of the current thread is
5095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * cleared when this exception is thrown."
5105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     */
5115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    self->interrupted_ = false;
5125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (interruptShouldThrow) {
5135cb5ad27944efb08d4556b3c0d362302e37e832bElliott Hughes      Thread::Current()->ThrowNewException("Ljava/lang/InterruptedException;", NULL);
5145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
5155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
5175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Notify(Thread* self) {
5195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(self != NULL);
5205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Make sure that we hold the lock.
5225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (owner_ != self) {
5236d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    ThrowIllegalMonitorStateExceptionF("object not locked by thread before notify()");
5245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
5255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Signal the first waiting thread in the wait set.
5275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  while (wait_set_ != NULL) {
5285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    Thread* thread = wait_set_;
5295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    wait_set_ = thread->wait_next_;
5305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    thread->wait_next_ = NULL;
5315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // Check to see if the thread is still waiting.
53385d1545e985ac689db4bad7849880e843707c862Elliott Hughes    MutexLock mu(*thread->wait_mutex_);
5345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (thread->wait_monitor_ != NULL) {
53585d1545e985ac689db4bad7849880e843707c862Elliott Hughes      thread->wait_cond_->Signal();
5365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
5375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
5385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
5405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::NotifyAll(Thread* self) {
5425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(self != NULL);
5435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Make sure that we hold the lock.
5455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (owner_ != self) {
5466d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers    ThrowIllegalMonitorStateExceptionF("object not locked by thread before notifyAll()");
5475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return;
5485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Signal all threads in the wait set.
5505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  while (wait_set_ != NULL) {
5515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    Thread* thread = wait_set_;
5525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    wait_set_ = thread->wait_next_;
5535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    thread->wait_next_ = NULL;
5545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    thread->Notify();
5555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
5565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
5575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/*
5595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Changes the shape of a monitor from thin to fat, preserving the
5605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * internal lock state. The calling thread must own the lock.
5615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */
5625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Inflate(Thread* self, Object* obj) {
5635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(self != NULL);
5645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(obj != NULL);
5655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK_EQ(LW_SHAPE(*obj->GetRawLockWordAddress()), LW_SHAPE_THIN);
566f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes  DCHECK_EQ(LW_LOCK_OWNER(*obj->GetRawLockWordAddress()), static_cast<int32_t>(self->GetThinLockId()));
5675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Allocate and acquire a new monitor.
5695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  Monitor* m = new Monitor(obj);
5704dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes  VLOG(monitor) << "monitor: thread " << self->GetThinLockId()
5714dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes                << " created monitor " << m << " for object " << obj;
572c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  Runtime::Current()->GetMonitorList()->Add(m);
5735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  m->Lock(self);
5745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Propagate the lock state.
5755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  uint32_t thin = *obj->GetRawLockWordAddress();
5765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  m->lock_count_ = LW_LOCK_COUNT(thin);
5775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
5785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  thin |= reinterpret_cast<uint32_t>(m) | LW_SHAPE_FAT;
5795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // Publish the updated lock word.
5805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  android_atomic_release_store(thin, obj->GetRawLockWordAddress());
5815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
5825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::MonitorEnter(Thread* self, Object* obj) {
5845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  volatile int32_t* thinp = obj->GetRawLockWordAddress();
5855f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  struct timespec tm;
5865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  long sleepDelayNs;
5875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  long minSleepDelayNs = 1000000;  /* 1 millisecond */
5885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  long maxSleepDelayNs = 1000000000;  /* 1 second */
589f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes  uint32_t thin, newThin;
5905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
5914681c809ba35d50fab92c592ce8d2c7f8b2731f7Elliott Hughes  DCHECK(self != NULL);
5924681c809ba35d50fab92c592ce8d2c7f8b2731f7Elliott Hughes  DCHECK(obj != NULL);
593f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes  uint32_t threadId = self->GetThinLockId();
5945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesretry:
5955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  thin = *thinp;
5965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
5975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    /*
5985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * The lock is a thin lock.  The owner field is used to
5995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * determine the acquire method, ordered by cost.
6005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     */
6015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (LW_LOCK_OWNER(thin) == threadId) {
6025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      /*
6035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * The calling thread owns the lock.  Increment the
6045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * value of the recursion count field.
6055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       */
6065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      *thinp += 1 << LW_LOCK_COUNT_SHIFT;
6075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      if (LW_LOCK_COUNT(*thinp) == LW_LOCK_COUNT_MASK) {
6085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        /*
6095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * The reacquisition limit has been reached.  Inflate
6105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * the lock so the next acquire will not overflow the
6115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * recursion count field.
6125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         */
6135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        Inflate(self, obj);
6145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      }
6155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    } else if (LW_LOCK_OWNER(thin) == 0) {
6165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      /*
6175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * The lock is unowned.  Install the thread id of the
6185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * calling thread into the owner field.  This is the
6195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * common case.  In performance critical code the JIT
6205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * will have tried this before calling out to the VM.
6215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       */
6225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
6235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      if (android_atomic_acquire_cas(thin, newThin, thinp) != 0) {
6245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        // The acquire failed. Try again.
6255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        goto retry;
6265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      }
6275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    } else {
6284dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes      VLOG(monitor) << StringPrintf("monitor: thread %d spin on lock %p (a %s) owned by %d",
6294dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes          threadId, thinp, PrettyTypeOf(obj).c_str(), LW_LOCK_OWNER(thin));
6305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      // The lock is owned by another thread. Notify the VM that we are about to wait.
6318e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes      self->monitor_enter_object_ = obj;
6325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      Thread::State oldStatus = self->SetState(Thread::kBlocked);
6335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      // Spin until the thin lock is released or inflated.
6345f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      sleepDelayNs = 0;
6355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      for (;;) {
6365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        thin = *thinp;
6375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        // Check the shape of the lock word. Another thread
6385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        // may have inflated the lock while we were waiting.
6395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
6405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes          if (LW_LOCK_OWNER(thin) == 0) {
6415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            // The lock has been released. Install the thread id of the
6425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            // calling thread into the owner field.
6435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
6445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            if (android_atomic_acquire_cas(thin, newThin, thinp) == 0) {
6455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              // The acquire succeed. Break out of the loop and proceed to inflate the lock.
6465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              break;
6475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            }
6485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes          } else {
6495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            // The lock has not been released. Yield so the owning thread can run.
6505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            if (sleepDelayNs == 0) {
6515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              sched_yield();
6525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              sleepDelayNs = minSleepDelayNs;
6535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            } else {
6545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              tm.tv_sec = 0;
6555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              tm.tv_nsec = sleepDelayNs;
6565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              nanosleep(&tm, NULL);
6575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              // Prepare the next delay value. Wrap to avoid once a second polls for eternity.
6585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              if (sleepDelayNs < maxSleepDelayNs / 2) {
6595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes                sleepDelayNs *= 2;
6605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              } else {
6615f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes                sleepDelayNs = minSleepDelayNs;
6625f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes              }
6635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes            }
6645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes          }
6655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        } else {
6665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes          // The thin lock was inflated by another thread. Let the VM know we are no longer
6675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes          // waiting and try again.
6684dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes          VLOG(monitor) << "monitor: thread " << threadId
6694dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes                        << " found lock " << (void*) thinp << " surprise-fattened by another thread";
6708e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes          self->monitor_enter_object_ = NULL;
6715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes          self->SetState(oldStatus);
6725f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes          goto retry;
6735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        }
6745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      }
6754dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes      VLOG(monitor) << StringPrintf("monitor: thread %d spin on lock %p done", threadId, thinp);
6765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      // We have acquired the thin lock. Let the VM know that we are no longer waiting.
6778e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes      self->monitor_enter_object_ = NULL;
6785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      self->SetState(oldStatus);
6795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      // Fatten the lock.
6805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      Inflate(self, obj);
6814dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes      VLOG(monitor) << StringPrintf("monitor: thread %d fattened lock %p", threadId, thinp);
6825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
6835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
6845f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // The lock is a fat lock.
6854dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(monitor) << StringPrintf("monitor: thread %d locking fat lock %p (%p) %p on a %s",
686f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes          threadId, thinp, LW_MONITOR(*thinp), (void*)*thinp, PrettyTypeOf(obj).c_str());
6875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    DCHECK(LW_MONITOR(*thinp) != NULL);
6885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    LW_MONITOR(*thinp)->Lock(self);
6895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
6905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
6915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
6925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesbool Monitor::MonitorExit(Thread* self, Object* obj) {
6935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  volatile int32_t* thinp = obj->GetRawLockWordAddress();
6945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
6955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(self != NULL);
6964681c809ba35d50fab92c592ce8d2c7f8b2731f7Elliott Hughes  //DCHECK_EQ(self->GetState(), Thread::kRunnable);
6975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  DCHECK(obj != NULL);
6985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
6995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  /*
7005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * Cache the lock word as its value can change while we are
7015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   * examining its state.
7025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes   */
7035f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  uint32_t thin = *thinp;
7045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
7055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    /*
7065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * The lock is thin.  We must ensure that the lock is owned
7075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * by the given thread before unlocking it.
7085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     */
709f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes    if (LW_LOCK_OWNER(thin) == self->GetThinLockId()) {
7105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      /*
7115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * We are the lock owner.  It is safe to update the lock
7125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * without CAS as lock ownership guards the lock itself.
7135f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       */
7145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      if (LW_LOCK_COUNT(thin) == 0) {
7155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        /*
7165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * The lock was not recursively acquired, the common
7175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * case.  Unlock by clearing all bits except for the
7185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * hash state.
7195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         */
7205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        thin &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
7215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        android_atomic_release_store(thin, thinp);
7225f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      } else {
7235f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        /*
7245f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * The object was recursively acquired.  Decrement the
7255f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         * lock recursion count field.
7265f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes         */
7275f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes        *thinp -= 1 << LW_LOCK_COUNT_SHIFT;
7285f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      }
7295f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    } else {
7305f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      /*
7315f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * We do not own the lock.  The JVM spec requires that we
7325f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       * throw an exception in this case.
7335f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes       */
7346d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      FailedUnlock(obj, self, NULL, NULL);
7355f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return false;
7365f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
7375f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
7385f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    /*
7395f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * The lock is fat.  We must check to see if Unlock has
7405f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * raised any exceptions before continuing.
7415f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     */
7425f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    DCHECK(LW_MONITOR(*thinp) != NULL);
7435f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    if (!LW_MONITOR(*thinp)->Unlock(self)) {
7445f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      // An exception has been raised.  Do not fall through.
7455f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return false;
7465f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
7475f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
7485f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  return true;
7495f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
7505f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7515f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes/*
7525f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes * Object.wait().  Also called for class init.
7535f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes */
7545f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Wait(Thread* self, Object *obj, int64_t ms, int32_t ns, bool interruptShouldThrow) {
7555f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  volatile int32_t* thinp = obj->GetRawLockWordAddress();
7565f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7575f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // If the lock is still thin, we need to fatten it.
7585f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  uint32_t thin = *thinp;
7595f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
7605f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // Make sure that 'self' holds the lock.
761f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes    if (LW_LOCK_OWNER(thin) != self->GetThinLockId()) {
7626d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      ThrowIllegalMonitorStateExceptionF("object not locked by thread before wait()");
7635f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
7645f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
7655f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7665f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    /* This thread holds the lock.  We need to fatten the lock
7675f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * so 'self' can block on it.  Don't update the object lock
7685f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * field yet, because 'self' needs to acquire the lock before
7695f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     * any other thread gets a chance.
7705f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes     */
7715f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    Inflate(self, obj);
7724dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes    VLOG(monitor) << StringPrintf("monitor: thread %d fattened lock %p by wait()", self->GetThinLockId(), thinp);
7735f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
7745f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  LW_MONITOR(*thinp)->Wait(self, ms, ns, interruptShouldThrow);
7755f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
7765f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7775f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::Notify(Thread* self, Object *obj) {
7785f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  uint32_t thin = *obj->GetRawLockWordAddress();
7795f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7805f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // If the lock is still thin, there aren't any waiters;
7815f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // waiting on an object forces lock fattening.
7825f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
7835f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // Make sure that 'self' holds the lock.
784f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes    if (LW_LOCK_OWNER(thin) != self->GetThinLockId()) {
7856d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      ThrowIllegalMonitorStateExceptionF("object not locked by thread before notify()");
7865f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
7875f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
7885f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // no-op;  there are no waiters to notify.
7895f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
7905f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // It's a fat lock.
7915f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    LW_MONITOR(thin)->Notify(self);
7925f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
7935f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
7945f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7955f79133a435ebcb20000370d56046fe01201dd80Elliott Hughesvoid Monitor::NotifyAll(Thread* self, Object *obj) {
7965f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  uint32_t thin = *obj->GetRawLockWordAddress();
7975f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
7985f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // If the lock is still thin, there aren't any waiters;
7995f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  // waiting on an object forces lock fattening.
8005f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
8015f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // Make sure that 'self' holds the lock.
802f8e012785ee61a3d2f43f74a249d66e1381bdb83Elliott Hughes    if (LW_LOCK_OWNER(thin) != self->GetThinLockId()) {
8036d0b13e931fb73d5e964d14b0a7ecd1f3f5db547Ian Rogers      ThrowIllegalMonitorStateExceptionF("object not locked by thread before notifyAll()");
8045f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes      return;
8055f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    }
8065f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // no-op;  there are no waiters to notify.
8075f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
8085f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    // It's a fat lock.
8095f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    LW_MONITOR(thin)->NotifyAll(self);
8105f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
8115f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
8125f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
81324a3c2e9924e8765c4a9b4d383cb8f3b922f9c9fBrian Carlstromuint32_t Monitor::GetThinLockId(uint32_t raw_lock_word) {
8145f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  if (LW_SHAPE(raw_lock_word) == LW_SHAPE_THIN) {
8155f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return LW_LOCK_OWNER(raw_lock_word);
8165f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  } else {
8175f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    Thread* owner = LW_MONITOR(raw_lock_word)->owner_;
8185f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes    return owner ? owner->GetThinLockId() : 0;
8195f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes  }
8205f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}
8215f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes
8228e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughesvoid Monitor::DescribeWait(std::ostream& os, const Thread* thread) {
8238e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  Thread::State state = thread->GetState();
8248e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
8258e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  Object* object = NULL;
8268e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  uint32_t lock_owner = ThreadList::kInvalidId;
8278e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  if (state == Thread::kWaiting || state == Thread::kTimedWaiting) {
8288e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    os << "  - waiting on ";
8298e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    Monitor* monitor = thread->wait_monitor_;
8308e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    if (monitor != NULL) {
8318e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes      object = monitor->obj_;
8328e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    }
8338e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    lock_owner = Thread::LockOwnerFromThreadLock(object);
8348e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  } else if (state == Thread::kBlocked) {
8358e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    os << "  - waiting to lock ";
8368e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    object = thread->monitor_enter_object_;
8378e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    if (object != NULL) {
83824a3c2e9924e8765c4a9b4d383cb8f3b922f9c9fBrian Carlstrom      lock_owner = object->GetThinLockId();
8398e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    }
8408e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  } else {
8418e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    // We're not waiting on anything.
8428e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    return;
8438e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  }
8448e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  os << "<" << object << ">";
8458e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
8468e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // - waiting on <0x613f83d8> (a java.lang.ThreadLock) held by thread 5
8478e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  // - waiting on <0x6008c468> (a java.lang.Class<java.lang.ref.ReferenceQueue>)
8488e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  os << " (a " << PrettyTypeOf(object) << ")";
8498e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
8508e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  if (lock_owner != ThreadList::kInvalidId) {
8518e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes    os << " held by thread " << lock_owner;
8528e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  }
8538e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
8548e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes  os << "\n";
8558e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes}
8568e4aac52962d54cb4be2078b9cd95685e067133aElliott Hughes
85733dc7717cd16592bcc825350bea6305be9eb2ea1jeffhaovoid Monitor::TranslateLocation(const Method* method, uint32_t pc,
85833dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao                                const char*& source_file, uint32_t& line_number) const {
85933dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  // If method is null, location is unknown
86033dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  if (method == NULL) {
86112c51e3e5a8b5655351539618f1cf2331f52d1abElliott Hughes    source_file = "";
86233dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao    line_number = 0;
86333dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao    return;
86433dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao  }
8656d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  MethodHelper mh(method);
8666d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  source_file = mh.GetDeclaringClassSourceFile();
86712c51e3e5a8b5655351539618f1cf2331f52d1abElliott Hughes  if (source_file == NULL) {
86812c51e3e5a8b5655351539618f1cf2331f52d1abElliott Hughes    source_file = "";
86912c51e3e5a8b5655351539618f1cf2331f52d1abElliott Hughes  }
8706d4d9fcb4f01e287ee29e81cd1c941ee5d11d379Ian Rogers  line_number = mh.GetLineNumFromNativePC(pc);
87133dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao}
87233dc7717cd16592bcc825350bea6305be9eb2ea1jeffhao
873c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott HughesMonitorList::MonitorList() : lock_("MonitorList lock") {
874c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes}
875c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes
876c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott HughesMonitorList::~MonitorList() {
877c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  MutexLock mu(lock_);
878c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  STLDeleteElements(&list_);
879c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes}
880c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes
881c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughesvoid MonitorList::Add(Monitor* m) {
882c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  MutexLock mu(lock_);
883c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  list_.push_front(m);
884c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes}
885c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes
886c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughesvoid MonitorList::SweepMonitorList(Heap::IsMarkedTester is_marked, void* arg) {
887c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  MutexLock mu(lock_);
888c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  typedef std::list<Monitor*>::iterator It; // TODO: C++0x auto
889c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  It it = list_.begin();
890c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  while (it != list_.end()) {
891c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes    Monitor* m = *it;
892c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes    if (!is_marked(m->GetObject(), arg)) {
8934dd9b4d95eec9db5338fb9bf132f9bb8facf6cf4Elliott Hughes      VLOG(monitor) << "freeing monitor " << m << " belonging to unmarked object " << m->GetObject();
894c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes      delete m;
895c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes      it = list_.erase(it);
896c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes    } else {
897c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes      ++it;
898c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes    }
899c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes  }
900c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes}
901c33a32bccc4c66ed82ce3a580b16636399385cb4Elliott Hughes
9025f79133a435ebcb20000370d56046fe01201dd80Elliott Hughes}  // namespace art
903