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