blob: e6ef266e86a1486809fae46d52c954be2747be0f [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andy McFadden581bed72009-10-15 11:24:54 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Fundamental synchronization mechanisms.
19 *
20 * The top part of the file has operations on "monitor" structs; the
21 * next part has the native calls on objects.
22 *
23 * The current implementation uses "thin locking" to avoid allocating
24 * an Object's full Monitor struct until absolutely necessary (i.e.,
25 * during contention or a call to wait()).
26 *
27 * TODO: make improvements to thin locking
28 * We may be able to improve performance and reduce memory requirements by:
29 * - reverting to a thin lock once the Monitor is no longer necessary
30 * - using a pool of monitor objects, with some sort of recycling scheme
31 *
32 * TODO: recycle native-level monitors when objects are garbage collected.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080033 */
34#include "Dalvik.h"
35
36#include <stdlib.h>
37#include <unistd.h>
38#include <pthread.h>
39#include <time.h>
40#include <sys/time.h>
41#include <errno.h>
42
43#define LOG_THIN LOGV
44
45#ifdef WITH_DEADLOCK_PREDICTION /* fwd */
46static const char* kStartBanner =
47 "<-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#";
48static const char* kEndBanner =
49 "#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#->";
50
51/*
52 * Unsorted, expanding list of objects.
53 *
54 * This is very similar to PointerSet (which came into existence after this),
55 * but these are unsorted, uniqueness is not enforced by the "add" function,
56 * and the base object isn't allocated on the heap.
57 */
58typedef struct ExpandingObjectList {
59 u2 alloc;
60 u2 count;
61 Object** list;
62} ExpandingObjectList;
63
64/* fwd */
65static void updateDeadlockPrediction(Thread* self, Object* obj);
66static void removeCollectedObject(Object* obj);
67static void expandObjClear(ExpandingObjectList* pList);
68#endif
69
70/*
71 * Every Object has a monitor associated with it, but not every Object is
72 * actually locked. Even the ones that are locked do not need a
73 * full-fledged monitor until a) there is actual contention or b) wait()
74 * is called on the Object.
75 *
76 * For Dalvik, we have implemented a scheme similar to the one described
77 * in Bacon et al.'s "Thin locks: featherweight synchronization for Java"
78 * (ACM 1998). Things are even easier for us, though, because we have
79 * a full 32 bits to work with.
80 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080081 * The two states of an Object's lock are referred to as "thin" and
82 * "fat". A lock may transition from the "thin" state to the "fat"
83 * state and this transition is referred to as inflation. Once a lock
84 * has been inflated it remains in the "fat" state indefinitely.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080085 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080086 * The lock value itself is stored in Object.lock. The LSB of the
87 * lock encodes its state. When cleared, the lock is in the "thin"
88 * state and its bits are formatted as follows:
Carl Shapiro71938022009-12-22 13:49:53 -080089 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080090 * [31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
91 * lock count thread id hash state 0
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080092 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080093 * When set, the lock is in the "fat" state and its bits are formatted
Carl Shapiro94338aa2009-12-21 11:42:59 -080094 * as follows:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080095 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080096 * [31 ---- 3] [2 ---- 1] [0]
97 * pointer hash state 1
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080098 *
99 * For an in-depth description of the mechanics of thin-vs-fat locking,
100 * read the paper referred to above.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800101 */
102
103/*
104 * Monitors provide:
105 * - mutually exclusive access to resources
106 * - a way for multiple threads to wait for notification
107 *
108 * In effect, they fill the role of both mutexes and condition variables.
109 *
110 * Only one thread can own the monitor at any time. There may be several
111 * threads waiting on it (the wait call unlocks it). One or more waiting
112 * threads may be getting interrupted or notified at any given time.
113 */
114struct Monitor {
115 Thread* owner; /* which thread currently owns the lock? */
116 int lockCount; /* owner's recursive lock depth */
117 Object* obj; /* what object are we part of [debug only] */
118
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800119 Thread* waitSet; /* threads currently waiting on this monitor */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800120
121 pthread_mutex_t lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800122
123 Monitor* next;
124
125#ifdef WITH_DEADLOCK_PREDICTION
126 /*
127 * Objects that have been locked immediately after this one in the
128 * past. We use an expanding flat array, allocated on first use, to
129 * minimize allocations. Deletions from the list, expected to be
130 * infrequent, are crunched down.
131 */
132 ExpandingObjectList historyChildren;
133
134 /*
135 * We also track parents. This isn't strictly necessary, but it makes
136 * the cleanup at GC time significantly faster.
137 */
138 ExpandingObjectList historyParents;
139
140 /* used during cycle detection */
141 bool historyMark;
142
143 /* stack trace, established the first time we locked the object */
144 int historyStackDepth;
145 int* historyRawStackTrace;
146#endif
147};
148
149
150/*
151 * Create and initialize a monitor.
152 */
153Monitor* dvmCreateMonitor(Object* obj)
154{
155 Monitor* mon;
156
157 mon = (Monitor*) calloc(1, sizeof(Monitor));
158 if (mon == NULL) {
159 LOGE("Unable to allocate monitor\n");
160 dvmAbort();
161 }
Carl Shapiro94338aa2009-12-21 11:42:59 -0800162 if (((u4)mon & 7) != 0) {
163 LOGE("Misaligned monitor: %p\n", mon);
164 dvmAbort();
165 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800166 mon->obj = obj;
167 dvmInitMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800168
169 /* replace the head of the list with the new monitor */
170 do {
171 mon->next = gDvm.monitorList;
172 } while (!ATOMIC_CMP_SWAP((int32_t*)(void*)&gDvm.monitorList,
173 (int32_t)mon->next, (int32_t)mon));
174
175 return mon;
176}
177
178/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800179 * Free the monitor list. Only used when shutting the VM down.
180 */
181void dvmFreeMonitorList(void)
182{
183 Monitor* mon;
184 Monitor* nextMon;
185
186 mon = gDvm.monitorList;
187 while (mon != NULL) {
188 nextMon = mon->next;
189
190#ifdef WITH_DEADLOCK_PREDICTION
191 expandObjClear(&mon->historyChildren);
192 expandObjClear(&mon->historyParents);
193 free(mon->historyRawStackTrace);
194#endif
195 free(mon);
196 mon = nextMon;
197 }
198}
199
200/*
201 * Log some info about our monitors.
202 */
203void dvmDumpMonitorInfo(const char* msg)
204{
205#if QUIET_ZYGOTE_MONITOR
206 if (gDvm.zygote) {
207 return;
208 }
209#endif
210
211 int totalCount;
212 int liveCount;
213
214 totalCount = liveCount = 0;
215 Monitor* mon = gDvm.monitorList;
216 while (mon != NULL) {
217 totalCount++;
218 if (mon->obj != NULL)
219 liveCount++;
220 mon = mon->next;
221 }
222
223 LOGD("%s: monitor list has %d entries (%d live)\n",
224 msg, totalCount, liveCount);
225}
226
227/*
228 * Get the object that a monitor is part of.
229 */
230Object* dvmGetMonitorObject(Monitor* mon)
231{
232 if (mon == NULL)
233 return NULL;
234 else
235 return mon->obj;
236}
237
238/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800239 * Returns the thread id of the thread owning the given lock.
240 */
241static u4 lockOwner(Object* obj)
242{
243 Thread *owner;
244 u4 lock;
245
246 assert(obj != NULL);
247 /*
248 * Since we're reading the lock value multiple times, latch it so
249 * that it doesn't change out from under us if we get preempted.
250 */
251 lock = obj->lock;
252 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
253 return LW_LOCK_OWNER(lock);
254 } else {
255 owner = LW_MONITOR(lock)->owner;
256 return owner ? owner->threadId : 0;
257 }
258}
259
260/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800261 * Checks whether the given thread holds the given
262 * objects's lock.
263 */
264bool dvmHoldsLock(Thread* thread, Object* obj)
265{
266 if (thread == NULL || obj == NULL) {
267 return false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800268 } else {
Carl Shapiro30aa9972010-01-13 22:07:50 -0800269 return thread->threadId == lockOwner(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800270 }
271}
272
273/*
274 * Free the monitor associated with an object and make the object's lock
275 * thin again. This is called during garbage collection.
276 */
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800277static void freeObjectMonitor(Object* obj)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800278{
279 Monitor *mon;
280
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800281 assert(LW_SHAPE(obj->lock) == LW_SHAPE_FAT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800282
283#ifdef WITH_DEADLOCK_PREDICTION
284 if (gDvm.deadlockPredictMode != kDPOff)
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800285 removeCollectedObject(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800286#endif
287
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800288 mon = LW_MONITOR(obj->lock);
289 obj->lock = DVM_LOCK_INITIAL_THIN_VALUE;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800290
291 /* This lock is associated with an object
292 * that's being swept. The only possible way
293 * anyone could be holding this lock would be
294 * if some JNI code locked but didn't unlock
295 * the object, in which case we've got some bad
296 * native code somewhere.
297 */
298 assert(pthread_mutex_trylock(&mon->lock) == 0);
299 pthread_mutex_destroy(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800300#ifdef WITH_DEADLOCK_PREDICTION
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800301 expandObjClear(&mon->historyChildren);
302 expandObjClear(&mon->historyParents);
303 free(mon->historyRawStackTrace);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800304#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800305 free(mon);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800306}
307
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800308/*
309 * Frees monitor objects belonging to unmarked objects.
310 */
311void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
312{
313 Monitor handle;
314 Monitor *prev, *curr;
315 Object *obj;
316
317 assert(mon != NULL);
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800318 assert(isUnmarkedObject != NULL);
319 prev = &handle;
320 prev->next = curr = *mon;
321 while (curr != NULL) {
322 obj = curr->obj;
323 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
324 prev->next = curr = curr->next;
325 freeObjectMonitor(obj);
326 } else {
327 prev = curr;
328 curr = curr->next;
329 }
330 }
331 *mon = handle.next;
332}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800333
334/*
335 * Lock a monitor.
336 */
337static void lockMonitor(Thread* self, Monitor* mon)
338{
339 int cc;
340
341 if (mon->owner == self) {
342 mon->lockCount++;
343 } else {
344 ThreadStatus oldStatus;
345
346 if (pthread_mutex_trylock(&mon->lock) != 0) {
347 /* mutex is locked, switch to wait status and sleep on it */
348 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
349 cc = pthread_mutex_lock(&mon->lock);
350 assert(cc == 0);
351 dvmChangeStatus(self, oldStatus);
352 }
353
354 mon->owner = self;
355 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800356 }
357}
358
359/*
360 * Try to lock a monitor.
361 *
362 * Returns "true" on success.
363 */
364static bool tryLockMonitor(Thread* self, Monitor* mon)
365{
366 int cc;
367
368 if (mon->owner == self) {
369 mon->lockCount++;
370 return true;
371 } else {
372 cc = pthread_mutex_trylock(&mon->lock);
373 if (cc == 0) {
374 mon->owner = self;
375 assert(mon->lockCount == 0);
376 return true;
377 } else {
378 return false;
379 }
380 }
381}
382
383
384/*
385 * Unlock a monitor.
386 *
387 * Returns true if the unlock succeeded.
388 * If the unlock failed, an exception will be pending.
389 */
390static bool unlockMonitor(Thread* self, Monitor* mon)
391{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800392 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800393 assert(mon != NULL); // can this happen?
394
395 if (mon->owner == self) {
396 /*
397 * We own the monitor, so nobody else can be in here.
398 */
399 if (mon->lockCount == 0) {
400 int cc;
401 mon->owner = NULL;
402 cc = pthread_mutex_unlock(&mon->lock);
403 assert(cc == 0);
404 } else {
405 mon->lockCount--;
406 }
407 } else {
408 /*
409 * We don't own this, so we're not allowed to unlock it.
410 * The JNI spec says that we should throw IllegalMonitorStateException
411 * in this case.
412 */
Carl Shapiro91117572010-02-24 02:30:55 -0800413 dvmThrowExceptionFmt("Ljava/lang/IllegalMonitorStateException;",
414 "unlock of unowned monitor, self=%d owner=%d",
415 self->threadId,
416 mon->owner ? mon->owner->threadId : 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800417 return false;
418 }
419 return true;
420}
421
422/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800423 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800424 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800425 */
426static int waitSetCheck(Monitor *mon)
427{
428 Thread *fast, *slow;
429 size_t n;
430
431 assert(mon != NULL);
432 fast = slow = mon->waitSet;
433 n = 0;
434 for (;;) {
435 if (fast == NULL) return 0;
436 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800437 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800438 n += 2;
439 fast = fast->waitNext->waitNext;
440 slow = slow->waitNext;
441 }
442}
443
444/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800445 * Links a thread into a monitor's wait set. The monitor lock must be
446 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800447 */
448static void waitSetAppend(Monitor *mon, Thread *thread)
449{
450 Thread *elt;
451
452 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800453 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800454 assert(thread != NULL);
455 assert(thread->waitNext == NULL);
456 assert(waitSetCheck(mon) == 0);
457 if (mon->waitSet == NULL) {
458 mon->waitSet = thread;
459 return;
460 }
461 elt = mon->waitSet;
462 while (elt->waitNext != NULL) {
463 elt = elt->waitNext;
464 }
465 elt->waitNext = thread;
466}
467
468/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800469 * Unlinks a thread from a monitor's wait set. The monitor lock must
470 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800471 */
472static void waitSetRemove(Monitor *mon, Thread *thread)
473{
474 Thread *elt;
475
476 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800477 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800478 assert(thread != NULL);
479 assert(waitSetCheck(mon) == 0);
480 if (mon->waitSet == NULL) {
481 return;
482 }
483 if (mon->waitSet == thread) {
484 mon->waitSet = thread->waitNext;
485 thread->waitNext = NULL;
486 return;
487 }
488 elt = mon->waitSet;
489 while (elt->waitNext != NULL) {
490 if (elt->waitNext == thread) {
491 elt->waitNext = thread->waitNext;
492 thread->waitNext = NULL;
493 return;
494 }
495 elt = elt->waitNext;
496 }
497}
498
Carl Shapirob4539192010-01-04 16:50:00 -0800499/*
500 * Converts the given relative waiting time into an absolute time.
501 */
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800502void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800503{
504 s8 endSec;
505
506#ifdef HAVE_TIMEDWAIT_MONOTONIC
507 clock_gettime(CLOCK_MONOTONIC, ts);
508#else
509 {
510 struct timeval tv;
511 gettimeofday(&tv, NULL);
512 ts->tv_sec = tv.tv_sec;
513 ts->tv_nsec = tv.tv_usec * 1000;
514 }
515#endif
516 endSec = ts->tv_sec + msec / 1000;
517 if (endSec >= 0x7fffffff) {
518 LOGV("NOTE: end time exceeds epoch\n");
519 endSec = 0x7ffffffe;
520 }
521 ts->tv_sec = endSec;
522 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
523
524 /* catch rollover */
525 if (ts->tv_nsec >= 1000000000L) {
526 ts->tv_sec++;
527 ts->tv_nsec -= 1000000000L;
528 }
529}
530
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800531int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
532 s8 msec, s4 nsec)
533{
534 int ret;
535 struct timespec ts;
536 absoluteTime(msec, nsec, &ts);
537#if defined(HAVE_TIMEDWAIT_MONOTONIC)
538 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
539#else
540 ret = pthread_cond_timedwait(cond, mutex, &ts);
541#endif
542 assert(ret == 0 || ret == ETIMEDOUT);
543 return ret;
544}
545
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800546/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800547 * Wait on a monitor until timeout, interrupt, or notification. Used for
548 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
549 *
550 * If another thread calls Thread.interrupt(), we throw InterruptedException
551 * and return immediately if one of the following are true:
552 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
553 * - blocked in join(), join(long), or join(long, int) methods of Thread
554 * - blocked in sleep(long), or sleep(long, int) methods of Thread
555 * Otherwise, we set the "interrupted" flag.
556 *
557 * Checks to make sure that "nsec" is in the range 0-999999
558 * (i.e. fractions of a millisecond) and throws the appropriate
559 * exception if it isn't.
560 *
561 * The spec allows "spurious wakeups", and recommends that all code using
562 * Object.wait() do so in a loop. This appears to derive from concerns
563 * about pthread_cond_wait() on multiprocessor systems. Some commentary
564 * on the web casts doubt on whether these can/should occur.
565 *
566 * Since we're allowed to wake up "early", we clamp extremely long durations
567 * to return at the end of the 32-bit time epoch.
568 */
569static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
570 bool interruptShouldThrow)
571{
572 struct timespec ts;
573 bool wasInterrupted = false;
574 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800575 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800576
Carl Shapiro71938022009-12-22 13:49:53 -0800577 assert(self != NULL);
578 assert(mon != NULL);
579
Carl Shapiro94338aa2009-12-21 11:42:59 -0800580 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800581 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800582 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
583 "object not locked by thread before wait()");
584 return;
585 }
586
587 /*
588 * Enforce the timeout range.
589 */
590 if (msec < 0 || nsec < 0 || nsec > 999999) {
591 dvmThrowException("Ljava/lang/IllegalArgumentException;",
592 "timeout arguments out of range");
593 return;
594 }
595
596 /*
597 * Compute absolute wakeup time, if necessary.
598 */
599 if (msec == 0 && nsec == 0) {
600 timed = false;
601 } else {
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800602 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800603 timed = true;
604 }
605
606 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800607 * Add ourselves to the set of threads waiting on this monitor, and
608 * release our hold. We need to let it go even if we're a few levels
609 * deep in a recursive lock, and we need to restore that later.
610 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800611 * We append to the wait set ahead of clearing the count and owner
612 * fields so the subroutine can check that the calling thread owns
613 * the monitor. Aside from that, the order of member updates is
614 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800615 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800616 waitSetAppend(mon, self);
617 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800618 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800619 mon->owner = NULL;
620
621 /*
622 * Update thread status. If the GC wakes up, it'll ignore us, knowing
623 * that we won't touch any references in this state, and we'll check
624 * our suspend mode before we transition out.
625 */
626 if (timed)
627 dvmChangeStatus(self, THREAD_TIMED_WAIT);
628 else
629 dvmChangeStatus(self, THREAD_WAIT);
630
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800631 ret = pthread_mutex_lock(&self->waitMutex);
632 assert(ret == 0);
633
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800634 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800635 * Set waitMonitor to the monitor object we will be waiting on.
636 * When waitMonitor is non-NULL a notifying or interrupting thread
637 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800638 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800639 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800640 self->waitMonitor = mon;
641
642 /*
643 * Handle the case where the thread was interrupted before we called
644 * wait().
645 */
646 if (self->interrupted) {
647 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800648 self->waitMonitor = NULL;
649 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800650 goto done;
651 }
652
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800653 /*
654 * Release the monitor lock and wait for a notification or
655 * a timeout to occur.
656 */
657 pthread_mutex_unlock(&mon->lock);
658
659 if (!timed) {
660 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
661 assert(ret == 0);
662 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800663#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800664 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800665#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800666 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800667#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800668 assert(ret == 0 || ret == ETIMEDOUT);
669 }
670 if (self->interrupted) {
671 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800672 }
673
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800674 self->interrupted = false;
675 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800676
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800677 pthread_mutex_unlock(&self->waitMutex);
678
Carl Shapiro30aa9972010-01-13 22:07:50 -0800679 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800680 lockMonitor(self, mon);
681
Carl Shapiro142ef272010-01-25 12:51:31 -0800682done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800683 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800684 * We remove our thread from wait set after restoring the count
685 * and owner fields so the subroutine can check that the calling
686 * thread owns the monitor. Aside from that, the order of member
687 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800688 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800689 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800690 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800691 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800692
693 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
694 dvmChangeStatus(self, THREAD_RUNNING);
695
696 if (wasInterrupted) {
697 /*
698 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800699 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800700 *
701 * The doc sayeth: "The interrupted status of the current thread is
702 * cleared when this exception is thrown."
703 */
704 self->interrupted = false;
705 if (interruptShouldThrow)
706 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
707 }
708}
709
710/*
711 * Notify one thread waiting on this monitor.
712 */
713static void notifyMonitor(Thread* self, Monitor* mon)
714{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800715 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800716
Carl Shapiro71938022009-12-22 13:49:53 -0800717 assert(self != NULL);
718 assert(mon != NULL);
719
Carl Shapiro94338aa2009-12-21 11:42:59 -0800720 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800721 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800722 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
723 "object not locked by thread before notify()");
724 return;
725 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800726 /* Signal the first waiting thread in the wait set. */
727 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800728 thread = mon->waitSet;
729 mon->waitSet = thread->waitNext;
730 thread->waitNext = NULL;
731 pthread_mutex_lock(&thread->waitMutex);
732 /* Check to see if the thread is still waiting. */
733 if (thread->waitMonitor != NULL) {
734 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800735 pthread_mutex_unlock(&thread->waitMutex);
736 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800737 }
738 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800739 }
740}
741
742/*
743 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800744 */
745static void notifyAllMonitor(Thread* self, Monitor* mon)
746{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800747 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800748
Carl Shapiro71938022009-12-22 13:49:53 -0800749 assert(self != NULL);
750 assert(mon != NULL);
751
Carl Shapiro94338aa2009-12-21 11:42:59 -0800752 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800753 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800754 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
755 "object not locked by thread before notifyAll()");
756 return;
757 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800758 /* Signal all threads in the wait set. */
759 while (mon->waitSet != NULL) {
760 thread = mon->waitSet;
761 mon->waitSet = thread->waitNext;
762 thread->waitNext = NULL;
763 pthread_mutex_lock(&thread->waitMutex);
764 /* Check to see if the thread is still waiting. */
765 if (thread->waitMonitor != NULL) {
766 pthread_cond_signal(&thread->waitCond);
767 }
768 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800769 }
770}
771
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800772/*
773 * Implements monitorenter for "synchronized" stuff.
774 *
775 * This does not fail or throw an exception (unless deadlock prediction
776 * is enabled and set to "err" mode).
777 */
778void dvmLockObject(Thread* self, Object *obj)
779{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800780 volatile u4 *thinp = &obj->lock;
781 u4 hashState;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800782 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800783 u4 threadId = self->threadId;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800784 Monitor *mon;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800785
786 /* First, try to grab the lock as if it's thin;
787 * this is the common case and will usually succeed.
788 */
Carl Shapiro30aa9972010-01-13 22:07:50 -0800789 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800790 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800791 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800792 if (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800793 hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800794 (int32_t)thin)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800795 /* The lock is either a thin lock held by someone (possibly 'self'),
796 * or a fat lock.
797 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800798 if (LW_LOCK_OWNER(*thinp) == threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800799 /* 'self' is already holding the thin lock; we can just
800 * bump the count. Atomic operations are not necessary
801 * because only the thread holding the lock is allowed
802 * to modify the Lock field.
803 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800804 *thinp += 1 << LW_LOCK_COUNT_SHIFT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800805 } else {
806 /* If this is a thin lock we need to spin on it, if it's fat
807 * we need to acquire the monitor.
808 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800809 if (LW_SHAPE(*thinp) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800810 ThreadStatus oldStatus;
811 static const unsigned long maxSleepDelay = 1 * 1024 * 1024;
812 unsigned long sleepDelay;
813
814 LOG_THIN("(%d) spin on lock 0x%08x: 0x%08x (0x%08x) 0x%08x\n",
815 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800816 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800817
818 /* The lock is still thin, but some other thread is
819 * holding it. Let the VM know that we're about
820 * to wait on another thread.
821 */
822 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
823
824 /* Spin until the other thread lets go.
825 */
826 sleepDelay = 0;
827 do {
828 /* In addition to looking for an unlock,
829 * we need to watch out for some other thread
830 * fattening the lock behind our back.
831 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800832 while (LW_LOCK_OWNER(*thinp) != 0) {
833 if (LW_SHAPE(*thinp) == LW_SHAPE_FAT) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800834 /* The lock has been fattened already.
835 */
836 LOG_THIN("(%d) lock 0x%08x surprise-fattened\n",
837 threadId, (uint)&obj->lock);
838 dvmChangeStatus(self, oldStatus);
839 goto fat_lock;
840 }
841
842 if (sleepDelay == 0) {
843 sched_yield();
844 sleepDelay = 1 * 1000;
845 } else {
846 usleep(sleepDelay);
847 if (sleepDelay < maxSleepDelay / 2) {
848 sleepDelay *= 2;
849 }
850 }
851 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800852 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800853 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800854 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800855 } while (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800856 (int32_t)hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800857 (int32_t)thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800858 LOG_THIN("(%d) spin on lock done 0x%08x: "
859 "0x%08x (0x%08x) 0x%08x\n",
860 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800861 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800862
863 /* We've got the thin lock; let the VM know that we're
864 * done waiting.
865 */
866 dvmChangeStatus(self, oldStatus);
867
868 /* Fatten the lock. Note this relinquishes ownership.
869 * We could also create the monitor in an "owned" state
870 * to avoid "re-locking" it in fat_lock.
871 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800872 mon = dvmCreateMonitor(obj);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800873 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
874 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800875 LOG_THIN("(%d) lock 0x%08x fattened\n",
876 threadId, (uint)&obj->lock);
877
878 /* Fall through to acquire the newly fat lock.
879 */
880 }
881
882 /* The lock is already fat, which means
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800883 * that obj->lock is a regular (Monitor *).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800884 */
885 fat_lock:
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800886 assert(LW_MONITOR(obj->lock) != NULL);
887 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800888 }
889 }
890 // else, the lock was acquired with the ATOMIC_CMP_SWAP().
891
892#ifdef WITH_DEADLOCK_PREDICTION
893 /*
894 * See if we were allowed to grab the lock at this time. We do it
895 * *after* acquiring the lock, rather than before, so that we can
896 * freely update the Monitor struct. This seems counter-intuitive,
897 * but our goal is deadlock *prediction* not deadlock *prevention*.
898 * (If we actually deadlock, the situation is easy to diagnose from
899 * a thread dump, so there's no point making a special effort to do
900 * the checks before the lock is held.)
901 *
902 * This needs to happen before we add the object to the thread's
903 * monitor list, so we can tell the difference between first-lock and
904 * re-lock.
905 *
906 * It's also important that we do this while in THREAD_RUNNING, so
907 * that we don't interfere with cleanup operations in the GC.
908 */
909 if (gDvm.deadlockPredictMode != kDPOff) {
910 if (self->status != THREAD_RUNNING) {
911 LOGE("Bad thread status (%d) in DP\n", self->status);
912 dvmDumpThread(self, false);
913 dvmAbort();
914 }
915 assert(!dvmCheckException(self));
916 updateDeadlockPrediction(self, obj);
917 if (dvmCheckException(self)) {
918 /*
919 * If we're throwing an exception here, we need to free the
920 * lock. We add the object to the thread's monitor list so the
921 * "unlock" code can remove it.
922 */
923 dvmAddToMonitorList(self, obj, false);
924 dvmUnlockObject(self, obj);
925 LOGV("--- unlocked, pending is '%s'\n",
926 dvmGetException(self)->clazz->descriptor);
927 }
928 }
929
930 /*
931 * Add the locked object, and the current stack trace, to the list
932 * held by the Thread object. If deadlock prediction isn't on,
933 * don't capture the stack trace.
934 */
935 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
936#elif defined(WITH_MONITOR_TRACKING)
937 /*
938 * Add the locked object to the list held by the Thread object.
939 */
940 dvmAddToMonitorList(self, obj, false);
941#endif
942}
943
944/*
945 * Implements monitorexit for "synchronized" stuff.
946 *
947 * On failure, throws an exception and returns "false".
948 */
949bool dvmUnlockObject(Thread* self, Object *obj)
950{
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800951 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800952 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800953
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800954 assert(self != NULL);
955 assert(self->status == THREAD_RUNNING);
956 assert(obj != NULL);
957
958 thinp = &obj->lock;
959 /*
960 * Cache the lock word as its value can change while we are
961 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800962 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800963 thin = *thinp;
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800964 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
965 /*
966 * The lock is thin. We must ensure that the lock is owned
967 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800968 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800969 if (LW_LOCK_OWNER(thin) == self->threadId) {
970 /*
971 * We are the lock owner. It is safe to update the lock
972 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800973 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800974 if (LW_LOCK_COUNT(thin) == 0) {
975 /*
976 * The lock was not recursively acquired, the common
977 * case. Unlock by clearing all bits except for the
978 * hash state.
979 */
980 *thinp &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
981 } else {
982 /*
983 * The object was recursively acquired. Decrement the
984 * lock recursion count field.
985 */
986 *thinp -= 1 << LW_LOCK_COUNT_SHIFT;
987 }
988 } else {
989 /*
990 * We do not own the lock. The JVM spec requires that we
991 * throw an exception in this case.
992 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800993 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800994 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800995 return false;
996 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800997 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800998 /*
999 * The lock is fat. We must check to see if unlockMonitor has
1000 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001001 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001002 assert(LW_MONITOR(obj->lock) != NULL);
1003 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001004 /*
1005 * An exception has been raised. Do not fall through.
1006 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001007 return false;
1008 }
1009 }
1010
1011#ifdef WITH_MONITOR_TRACKING
1012 /*
1013 * Remove the object from the Thread's list.
1014 */
1015 dvmRemoveFromMonitorList(self, obj);
1016#endif
1017
1018 return true;
1019}
1020
1021/*
1022 * Object.wait(). Also called for class init.
1023 */
1024void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1025 bool interruptShouldThrow)
1026{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001027 Monitor* mon = LW_MONITOR(obj->lock);
1028 u4 hashState;
1029 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001030
1031 /* If the lock is still thin, we need to fatten it.
1032 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001033 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001034 /* Make sure that 'self' holds the lock.
1035 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001036 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001037 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1038 "object not locked by thread before wait()");
1039 return;
1040 }
1041
1042 /* This thread holds the lock. We need to fatten the lock
1043 * so 'self' can block on it. Don't update the object lock
1044 * field yet, because 'self' needs to acquire the lock before
1045 * any other thread gets a chance.
1046 */
1047 mon = dvmCreateMonitor(obj);
1048
1049 /* 'self' has actually locked the object one or more times;
1050 * make sure that the monitor reflects this.
1051 */
1052 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001053 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001054 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1055 self->threadId, (uint)&obj->lock, mon->lockCount);
1056
Andy McFadden581bed72009-10-15 11:24:54 -07001057
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001058 /* Make the monitor public now that it's in the right state.
1059 */
Andy McFadden581bed72009-10-15 11:24:54 -07001060 MEM_BARRIER();
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001061 hashState = LW_HASH_STATE(thin) << LW_HASH_STATE_SHIFT;
1062 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001063 }
1064
1065 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1066}
1067
1068/*
1069 * Object.notify().
1070 */
1071void dvmObjectNotify(Thread* self, Object *obj)
1072{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001073 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001074
1075 /* If the lock is still thin, there aren't any waiters;
1076 * waiting on an object forces lock fattening.
1077 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001078 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001079 /* Make sure that 'self' holds the lock.
1080 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001081 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001082 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1083 "object not locked by thread before notify()");
1084 return;
1085 }
1086
1087 /* no-op; there are no waiters to notify.
1088 */
1089 } else {
1090 /* It's a fat lock.
1091 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001092 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001093 }
1094}
1095
1096/*
1097 * Object.notifyAll().
1098 */
1099void dvmObjectNotifyAll(Thread* self, Object *obj)
1100{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001101 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001102
1103 /* If the lock is still thin, there aren't any waiters;
1104 * waiting on an object forces lock fattening.
1105 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001106 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001107 /* Make sure that 'self' holds the lock.
1108 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001109 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001110 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1111 "object not locked by thread before notifyAll()");
1112 return;
1113 }
1114
1115 /* no-op; there are no waiters to notify.
1116 */
1117 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001118 /* It's a fat lock.
1119 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001120 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001121 }
1122}
1123
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001124/*
1125 * This implements java.lang.Thread.sleep(long msec, int nsec).
1126 *
1127 * The sleep is interruptible by other threads, which means we can't just
1128 * plop into an OS sleep call. (We probably could if we wanted to send
1129 * signals around and rely on EINTR, but that's inefficient and relies
1130 * on native code respecting our signal mask.)
1131 *
1132 * We have to do all of this stuff for Object.wait() as well, so it's
1133 * easiest to just sleep on a private Monitor.
1134 *
1135 * It appears that we want sleep(0,0) to go through the motions of sleeping
1136 * for a very short duration, rather than just returning.
1137 */
1138void dvmThreadSleep(u8 msec, u4 nsec)
1139{
1140 Thread* self = dvmThreadSelf();
1141 Monitor* mon = gDvm.threadSleepMon;
1142
1143 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1144 if (msec == 0 && nsec == 0)
1145 nsec++;
1146
1147 lockMonitor(self, mon);
1148 waitMonitor(self, mon, msec, nsec, true);
1149 unlockMonitor(self, mon);
1150}
1151
1152/*
1153 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001154 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001155void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001156{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001157 assert(thread != NULL);
1158
1159 pthread_mutex_lock(&thread->waitMutex);
1160
1161 /*
1162 * If the interrupted flag is already set no additional action is
1163 * required.
1164 */
1165 if (thread->interrupted == true) {
1166 pthread_mutex_unlock(&thread->waitMutex);
1167 return;
1168 }
1169
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001170 /*
1171 * Raise the "interrupted" flag. This will cause it to bail early out
1172 * of the next wait() attempt, if it's not currently waiting on
1173 * something.
1174 */
1175 thread->interrupted = true;
1176 MEM_BARRIER();
1177
1178 /*
1179 * Is the thread waiting?
1180 *
1181 * Note that fat vs. thin doesn't matter here; waitMonitor
1182 * is only set when a thread actually waits on a monitor,
1183 * which implies that the monitor has already been fattened.
1184 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001185 if (thread->waitMonitor != NULL) {
1186 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001187 }
1188
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001189 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001190}
1191
Carl Shapiro30aa9972010-01-13 22:07:50 -08001192#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001193u4 dvmIdentityHashCode(Object *obj)
1194{
1195 return (u4)obj;
1196}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001197#else
1198static size_t arrayElementWidth(const ArrayObject *array)
1199{
1200 const char *descriptor;
1201
1202 if (dvmIsObjectArray(array)) {
1203 return sizeof(Object *);
1204 } else {
1205 descriptor = array->obj.clazz->descriptor;
1206 switch (descriptor[1]) {
1207 case 'B': return 1; /* byte */
1208 case 'C': return 2; /* char */
1209 case 'D': return 8; /* double */
1210 case 'F': return 4; /* float */
1211 case 'I': return 4; /* int */
1212 case 'J': return 8; /* long */
1213 case 'S': return 2; /* short */
1214 case 'Z': return 1; /* boolean */
1215 }
1216 }
1217 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1218 dvmDumpThread(dvmThreadSelf(), false);
1219 dvmAbort();
1220 return 0; /* Quiet the compiler. */
1221}
1222
1223static size_t arrayObjectLength(const ArrayObject *array)
1224{
1225 size_t length;
1226
1227 length = offsetof(ArrayObject, contents);
1228 length += array->length * arrayElementWidth(array);
1229 return length;
1230}
1231
1232/*
1233 * Returns the identity hash code of the given object.
1234 */
1235u4 dvmIdentityHashCode(Object *obj)
1236{
1237 Thread *self, *thread;
1238 volatile u4 *lw;
1239 size_t length;
1240 u4 lock, owner, hashState;
1241
1242 if (obj == NULL) {
1243 /*
1244 * Null is defined to have an identity hash code of 0.
1245 */
1246 return 0;
1247 }
1248 lw = &obj->lock;
1249retry:
1250 hashState = LW_HASH_STATE(*lw);
1251 if (hashState == LW_HASH_STATE_HASHED) {
1252 /*
1253 * The object has been hashed but has not had its hash code
1254 * relocated by the garbage collector. Use the raw object
1255 * address.
1256 */
1257 return (u4)obj >> 3;
1258 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1259 /*
1260 * The object has been hashed and its hash code has been
1261 * relocated by the collector. Use the value of the naturally
1262 * aligned word following the instance data.
1263 */
1264 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1265 length = arrayObjectLength((ArrayObject *)obj);
1266 length = (length + 3) & ~3;
1267 } else {
1268 length = obj->clazz->objectSize;
1269 }
1270 return *(u4 *)(((char *)obj) + length);
1271 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1272 /*
1273 * The object has never been hashed. Change the hash state to
1274 * hashed and use the raw object address.
1275 */
1276 self = dvmThreadSelf();
1277 if (self->threadId == lockOwner(obj)) {
1278 /*
1279 * We already own the lock so we can update the hash state
1280 * directly.
1281 */
1282 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1283 return (u4)obj >> 3;
1284 }
1285 /*
1286 * We do not own the lock. Try acquiring the lock. Should
1287 * this fail, we must suspend the owning thread.
1288 */
1289 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1290 /*
1291 * If the lock is thin assume it is unowned. We simulate
1292 * an acquire, update, and release with a single CAS.
1293 */
1294 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1295 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1296 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1297 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1298 (int32_t)lock)) {
1299 /*
1300 * A new lockword has been installed with a hash state
1301 * of hashed. Use the raw object address.
1302 */
1303 return (u4)obj >> 3;
1304 }
1305 } else {
1306 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1307 /*
1308 * The monitor lock has been acquired. Change the
1309 * hash state to hashed and use the raw object
1310 * address.
1311 */
1312 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1313 unlockMonitor(self, LW_MONITOR(*lw));
1314 return (u4)obj >> 3;
1315 }
1316 }
1317 /*
1318 * At this point we have failed to acquire the lock. We must
1319 * identify the owning thread and suspend it.
1320 */
1321 dvmLockThreadList(self);
1322 /*
1323 * Cache the lock word as its value can change between
1324 * determining its shape and retrieving its owner.
1325 */
1326 lock = *lw;
1327 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1328 /*
1329 * Find the thread with the corresponding thread id.
1330 */
1331 owner = LW_LOCK_OWNER(lock);
1332 assert(owner != self->threadId);
1333 /*
1334 * If the lock has no owner do not bother scanning the
1335 * thread list and fall through to the failure handler.
1336 */
1337 thread = owner ? gDvm.threadList : NULL;
1338 while (thread != NULL) {
1339 if (thread->threadId == owner) {
1340 break;
1341 }
1342 thread = thread->next;
1343 }
1344 } else {
1345 thread = LW_MONITOR(lock)->owner;
1346 }
1347 /*
1348 * If thread is NULL the object has been released since the
1349 * thread list lock was acquired. Try again.
1350 */
1351 if (thread == NULL) {
1352 dvmUnlockThreadList();
1353 goto retry;
1354 }
1355 /*
1356 * Wait for the owning thread to suspend.
1357 */
1358 dvmSuspendThread(thread);
1359 if (dvmHoldsLock(thread, obj)) {
1360 /*
1361 * The owning thread has been suspended. We can safely
1362 * change the hash state to hashed.
1363 */
1364 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1365 dvmResumeThread(thread);
1366 dvmUnlockThreadList();
1367 return (u4)obj >> 3;
1368 }
1369 /*
1370 * The wrong thread has been suspended. Try again.
1371 */
1372 dvmResumeThread(thread);
1373 dvmUnlockThreadList();
1374 goto retry;
1375 }
1376 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1377 dvmDumpThread(dvmThreadSelf(), false);
1378 dvmAbort();
1379 return 0; /* Quiet the compiler. */
1380}
1381#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001382
1383#ifdef WITH_DEADLOCK_PREDICTION
1384/*
1385 * ===========================================================================
1386 * Deadlock prediction
1387 * ===========================================================================
1388 */
1389/*
1390The idea is to predict the possibility of deadlock by recording the order
1391in which monitors are acquired. If we see an attempt to acquire a lock
1392out of order, we can identify the locks and offending code.
1393
1394To make this work, we need to keep track of the locks held by each thread,
1395and create history trees for each lock. When a thread tries to acquire
1396a new lock, we walk through the "history children" of the lock, looking
1397for a match with locks the thread already holds. If we find a match,
1398it means the thread has made a request that could result in a deadlock.
1399
1400To support recursive locks, we always allow re-locking a currently-held
1401lock, and maintain a recursion depth count.
1402
1403An ASCII-art example, where letters represent Objects:
1404
1405 A
1406 /|\
1407 / | \
1408 B | D
1409 \ |
1410 \|
1411 C
1412
1413The above is the tree we'd have after handling Object synchronization
1414sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1415a child of B. (The lines represent pointers between parent and child.
1416Every node can have multiple parents and multiple children.)
1417
1418If we hold AC, and want to lock B, we recursively search through B's
1419children to see if A or C appears. It does, so we reject the attempt.
1420(A straightforward way to implement it: add a link from C to B, then
1421determine whether the graph starting at B contains a cycle.)
1422
1423If we hold AC and want to lock D, we would succeed, creating a new link
1424from C to D.
1425
1426The lock history and a stack trace is attached to the Object's Monitor
1427struct, which means we need to fatten every Object we lock (thin locking
1428is effectively disabled). If we don't need the stack trace we can
1429avoid fattening the leaf nodes, only fattening objects that need to hold
1430history trees.
1431
1432Updates to Monitor structs are only allowed for the thread that holds
1433the Monitor, so we actually do most of our deadlock prediction work after
1434the lock has been acquired.
1435
1436When an object with a monitor is GCed, we need to remove it from the
1437history trees. There are two basic approaches:
1438 (1) For through the entire set of known monitors, search all child
1439 lists for the object in question. This is rather slow, resulting
1440 in GC passes that take upwards of 10 seconds to complete.
1441 (2) Maintain "parent" pointers in each node. Remove the entries as
1442 required. This requires additional storage and maintenance for
1443 every operation, but is significantly faster at GC time.
1444For each GCed object, we merge all of the object's children into each of
1445the object's parents.
1446*/
1447
1448#if !defined(WITH_MONITOR_TRACKING)
1449# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1450#endif
1451
1452/*
1453 * Clear out the contents of an ExpandingObjectList, freeing any
1454 * dynamic allocations.
1455 */
1456static void expandObjClear(ExpandingObjectList* pList)
1457{
1458 if (pList->list != NULL) {
1459 free(pList->list);
1460 pList->list = NULL;
1461 }
1462 pList->alloc = pList->count = 0;
1463}
1464
1465/*
1466 * Get the number of objects currently stored in the list.
1467 */
1468static inline int expandBufGetCount(const ExpandingObjectList* pList)
1469{
1470 return pList->count;
1471}
1472
1473/*
1474 * Get the Nth entry from the list.
1475 */
1476static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1477 int i)
1478{
1479 return pList->list[i];
1480}
1481
1482/*
1483 * Add a new entry to the list.
1484 *
1485 * We don't check for or try to enforce uniqueness. It's expected that
1486 * the higher-level code does this for us.
1487 */
1488static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1489{
1490 if (pList->count == pList->alloc) {
1491 /* time to expand */
1492 Object** newList;
1493
1494 if (pList->alloc == 0)
1495 pList->alloc = 4;
1496 else
1497 pList->alloc *= 2;
1498 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1499 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1500 if (newList == NULL) {
1501 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1502 dvmAbort();
1503 }
1504 pList->list = newList;
1505 }
1506
1507 pList->list[pList->count++] = obj;
1508}
1509
1510/*
1511 * Returns "true" if the element was successfully removed.
1512 */
1513static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1514{
1515 int i;
1516
1517 for (i = pList->count-1; i >= 0; i--) {
1518 if (pList->list[i] == obj)
1519 break;
1520 }
1521 if (i < 0)
1522 return false;
1523
1524 if (i != pList->count-1) {
1525 /*
1526 * The order of elements is not important, so we just copy the
1527 * last entry into the new slot.
1528 */
1529 //memmove(&pList->list[i], &pList->list[i+1],
1530 // (pList->count-1 - i) * sizeof(pList->list[0]));
1531 pList->list[i] = pList->list[pList->count-1];
1532 }
1533
1534 pList->count--;
1535 pList->list[pList->count] = (Object*) 0xdecadead;
1536 return true;
1537}
1538
1539/*
1540 * Returns "true" if "obj" appears in the list.
1541 */
1542static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1543{
1544 int i;
1545
1546 for (i = 0; i < pList->count; i++) {
1547 if (pList->list[i] == obj)
1548 return true;
1549 }
1550 return false;
1551}
1552
1553/*
1554 * Print the list contents to stdout. For debugging.
1555 */
1556static void expandObjDump(const ExpandingObjectList* pList)
1557{
1558 int i;
1559 for (i = 0; i < pList->count; i++)
1560 printf(" %p", pList->list[i]);
1561}
1562
1563/*
1564 * Check for duplicate entries. Returns the index of the first instance
1565 * of the duplicated value, or -1 if no duplicates were found.
1566 */
1567static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1568{
1569 int i, j;
1570 for (i = 0; i < pList->count-1; i++) {
1571 for (j = i + 1; j < pList->count; j++) {
1572 if (pList->list[i] == pList->list[j]) {
1573 return i;
1574 }
1575 }
1576 }
1577
1578 return -1;
1579}
1580
1581
1582/*
1583 * Determine whether "child" appears in the list of objects associated
1584 * with the Monitor in "parent". If "parent" is a thin lock, we return
1585 * false immediately.
1586 */
1587static bool objectInChildList(const Object* parent, Object* child)
1588{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001589 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001590 if (!IS_LOCK_FAT(&lock)) {
1591 //LOGI("on thin\n");
1592 return false;
1593 }
1594
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001595 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001596}
1597
1598/*
1599 * Print the child list.
1600 */
1601static void dumpKids(Object* parent)
1602{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001603 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001604
1605 printf("Children of %p:", parent);
1606 expandObjDump(&mon->historyChildren);
1607 printf("\n");
1608}
1609
1610/*
1611 * Add "child" to the list of children in "parent", and add "parent" to
1612 * the list of parents in "child".
1613 */
1614static void linkParentToChild(Object* parent, Object* child)
1615{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001616 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001617 assert(IS_LOCK_FAT(&parent->lock));
1618 assert(IS_LOCK_FAT(&child->lock));
1619 assert(parent != child);
1620 Monitor* mon;
1621
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001622 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001623 assert(!expandObjHas(&mon->historyChildren, child));
1624 expandObjAddEntry(&mon->historyChildren, child);
1625
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001626 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001627 assert(!expandObjHas(&mon->historyParents, parent));
1628 expandObjAddEntry(&mon->historyParents, parent);
1629}
1630
1631
1632/*
1633 * Remove "child" from the list of children in "parent".
1634 */
1635static void unlinkParentFromChild(Object* parent, Object* child)
1636{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001637 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001638 assert(IS_LOCK_FAT(&parent->lock));
1639 assert(IS_LOCK_FAT(&child->lock));
1640 assert(parent != child);
1641 Monitor* mon;
1642
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001643 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001644 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1645 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1646 }
1647 assert(!expandObjHas(&mon->historyChildren, child));
1648 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1649
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001650 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001651 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1652 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1653 }
1654 assert(!expandObjHas(&mon->historyParents, parent));
1655 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1656}
1657
1658
1659/*
1660 * Log the monitors held by the current thread. This is done as part of
1661 * flagging an error.
1662 */
1663static void logHeldMonitors(Thread* self)
1664{
1665 char* name = NULL;
1666
1667 name = dvmGetThreadName(self);
1668 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1669 self->threadId, name);
1670 LOGW("(most-recently-acquired on top):\n");
1671 free(name);
1672
1673 LockedObjectData* lod = self->pLockedObjects;
1674 while (lod != NULL) {
1675 LOGW("--- object %p[%d] (%s)\n",
1676 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1677 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1678
1679 lod = lod->next;
1680 }
1681}
1682
1683/*
1684 * Recursively traverse the object hierarchy starting at "obj". We mark
1685 * ourselves on entry and clear the mark on exit. If we ever encounter
1686 * a marked object, we have a cycle.
1687 *
1688 * Returns "true" if all is well, "false" if we found a cycle.
1689 */
1690static bool traverseTree(Thread* self, const Object* obj)
1691{
1692 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001693 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001694
1695 /*
1696 * Have we been here before?
1697 */
1698 if (mon->historyMark) {
1699 int* rawStackTrace;
1700 int stackDepth;
1701
1702 LOGW("%s\n", kStartBanner);
1703 LOGW("Illegal lock attempt:\n");
1704 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1705
1706 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1707 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1708 free(rawStackTrace);
1709
1710 LOGW(" ");
1711 logHeldMonitors(self);
1712
1713 LOGW(" ");
1714 LOGW("Earlier, the following lock order (from last to first) was\n");
1715 LOGW("established -- stack trace is from first successful lock):\n");
1716 return false;
1717 }
1718 mon->historyMark = true;
1719
1720 /*
1721 * Examine the children. We do NOT hold these locks, so they might
1722 * very well transition from thin to fat or change ownership while
1723 * we work.
1724 *
1725 * NOTE: we rely on the fact that they cannot revert from fat to thin
1726 * while we work. This is currently a safe assumption.
1727 *
1728 * We can safely ignore thin-locked children, because by definition
1729 * they have no history and are leaf nodes. In the current
1730 * implementation we always fatten the locks to provide a place to
1731 * hang the stack trace.
1732 */
1733 ExpandingObjectList* pList = &mon->historyChildren;
1734 int i;
1735 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1736 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001737 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001738 if (!IS_LOCK_FAT(&lock))
1739 continue;
1740 if (!traverseTree(self, child)) {
1741 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1742 dvmLogRawStackTrace(mon->historyRawStackTrace,
1743 mon->historyStackDepth);
1744 mon->historyMark = false;
1745 return false;
1746 }
1747 }
1748
1749 mon->historyMark = false;
1750
1751 return true;
1752}
1753
1754/*
1755 * Update the deadlock prediction tree, based on the current thread
1756 * acquiring "acqObj". This must be called before the object is added to
1757 * the thread's list of held monitors.
1758 *
1759 * If the thread already holds the lock (recursion), or this is a known
1760 * lock configuration, we return without doing anything. Otherwise, we add
1761 * a link from the most-recently-acquired lock in this thread to "acqObj"
1762 * after ensuring that the parent lock is "fat".
1763 *
1764 * This MUST NOT be called while a GC is in progress in another thread,
1765 * because we assume exclusive access to history trees in owned monitors.
1766 */
1767static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1768{
1769 LockedObjectData* lod;
1770 LockedObjectData* mrl;
1771
1772 /*
1773 * Quick check for recursive access.
1774 */
1775 lod = dvmFindInMonitorList(self, acqObj);
1776 if (lod != NULL) {
1777 LOGV("+++ DP: recursive %p\n", acqObj);
1778 return;
1779 }
1780
1781 /*
1782 * Make the newly-acquired object's monitor "fat". In some ways this
1783 * isn't strictly necessary, but we need the GC to tell us when
1784 * "interesting" objects go away, and right now the only way to make
1785 * an object look interesting is to give it a monitor.
1786 *
1787 * This also gives us a place to hang a stack trace.
1788 *
1789 * Our thread holds the lock, so we're allowed to rewrite the lock
1790 * without worrying that something will change out from under us.
1791 */
1792 if (!IS_LOCK_FAT(&acqObj->lock)) {
1793 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001794 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001795 Monitor* newMon = dvmCreateMonitor(acqObj);
1796 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001797 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1798 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1799 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001800 }
1801
1802 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001803 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1804 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001805 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1806 &mon->historyStackDepth);
1807 }
1808
1809 /*
1810 * We need to examine and perhaps modify the most-recently-locked
1811 * monitor. We own that, so there's no risk of another thread
1812 * stepping on us.
1813 *
1814 * Retrieve the most-recently-locked entry from our thread.
1815 */
1816 mrl = self->pLockedObjects;
1817 if (mrl == NULL)
1818 return; /* no other locks held */
1819
1820 /*
1821 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1822 * this without holding the global lock because of our assertion that
1823 * a GC is not running in parallel -- nobody except the GC can
1824 * modify a history list in a Monitor they don't own, and we own "mrl".
1825 * (There might be concurrent *reads*, but no concurrent *writes.)
1826 *
1827 * If we find it, this is a known good configuration, and we're done.
1828 */
1829 if (objectInChildList(mrl->obj, acqObj))
1830 return;
1831
1832 /*
1833 * "mrl" is going to need to have a history tree. If it's currently
1834 * a thin lock, we make it fat now. The thin lock might have a
1835 * nonzero recursive lock count, which we need to carry over.
1836 *
1837 * Our thread holds the lock, so we're allowed to rewrite the lock
1838 * without worrying that something will change out from under us.
1839 */
1840 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1841 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001842 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001843 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1844 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001845 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1846 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1847 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001848 }
1849
1850 /*
1851 * We haven't seen this configuration before. We need to scan down
1852 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1853 * appear. We grab a global lock before traversing or updating the
1854 * history list.
1855 *
1856 * If we find a match for any of our held locks, we know that the lock
1857 * has previously been acquired *after* acqObj, and we throw an error.
1858 *
1859 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1860 * and do a recursive traversal, marking nodes as we cross them. If
1861 * we cross one a second time, we have a cycle and can throw an error.
1862 * (We do the flag-clearing traversal before adding the new link, so
1863 * that we're guaranteed to terminate.)
1864 *
1865 * If "acqObj" is a thin lock, it has no history, and we can create a
1866 * link to it without additional checks. [ We now guarantee that it's
1867 * always fat. ]
1868 */
1869 bool failed = false;
1870 dvmLockMutex(&gDvm.deadlockHistoryLock);
1871 linkParentToChild(mrl->obj, acqObj);
1872 if (!traverseTree(self, acqObj)) {
1873 LOGW("%s\n", kEndBanner);
1874 failed = true;
1875
1876 /* remove the entry so we're still okay when in "warning" mode */
1877 unlinkParentFromChild(mrl->obj, acqObj);
1878 }
1879 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1880
1881 if (failed) {
1882 switch (gDvm.deadlockPredictMode) {
1883 case kDPErr:
1884 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1885 break;
1886 case kDPAbort:
1887 LOGE("Aborting due to potential deadlock\n");
1888 dvmAbort();
1889 break;
1890 default:
1891 /* warn only */
1892 break;
1893 }
1894 }
1895}
1896
1897/*
1898 * We're removing "child" from existence. We want to pull all of
1899 * child's children into "parent", filtering out duplicates. This is
1900 * called during the GC.
1901 *
1902 * This does not modify "child", which might have multiple parents.
1903 */
1904static void mergeChildren(Object* parent, const Object* child)
1905{
1906 Monitor* mon;
1907 int i;
1908
1909 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001910 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001911 ExpandingObjectList* pList = &mon->historyChildren;
1912
1913 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1914 Object* grandChild = expandBufGetEntry(pList, i);
1915
1916 if (!objectInChildList(parent, grandChild)) {
1917 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1918 linkParentToChild(parent, grandChild);
1919 } else {
1920 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1921 }
1922 }
1923}
1924
1925/*
1926 * An object with a fat lock is being collected during a GC pass. We
1927 * want to remove it from any lock history trees that it is a part of.
1928 *
1929 * This may require updating the history trees in several monitors. The
1930 * monitor semantics guarantee that no other thread will be accessing
1931 * the history trees at the same time.
1932 */
1933static void removeCollectedObject(Object* obj)
1934{
1935 Monitor* mon;
1936
1937 LOGVV("+++ collecting %p\n", obj);
1938
1939#if 0
1940 /*
1941 * We're currently running through the entire set of known monitors.
1942 * This can be somewhat slow. We may want to keep lists of parents
1943 * in each child to speed up GC.
1944 */
1945 mon = gDvm.monitorList;
1946 while (mon != NULL) {
1947 Object* parent = mon->obj;
1948 if (parent != NULL) { /* value nulled for deleted entries */
1949 if (objectInChildList(parent, obj)) {
1950 LOGVV("removing child %p from parent %p\n", obj, parent);
1951 unlinkParentFromChild(parent, obj);
1952 mergeChildren(parent, obj);
1953 }
1954 }
1955 mon = mon->next;
1956 }
1957#endif
1958
1959 /*
1960 * For every parent of this object:
1961 * - merge all of our children into the parent's child list (creates
1962 * a two-way link between parent and child)
1963 * - remove ourselves from the parent's child list
1964 */
1965 ExpandingObjectList* pList;
1966 int i;
1967
1968 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001969 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001970 pList = &mon->historyParents;
1971 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1972 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001973 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001974
1975 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
1976 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
1977 }
1978 assert(!expandObjHas(&parentMon->historyChildren, obj));
1979
1980 mergeChildren(parent, obj);
1981 }
1982
1983 /*
1984 * For every child of this object:
1985 * - remove ourselves from the child's parent list
1986 */
1987 pList = &mon->historyChildren;
1988 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1989 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001990 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001991
1992 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
1993 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
1994 }
1995 assert(!expandObjHas(&childMon->historyParents, obj));
1996 }
1997}
1998
1999#endif /*WITH_DEADLOCK_PREDICTION*/