blob: 20d6dabca64f4cf4aabc110b0249804f4b53299d [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/*
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800773 * Changes the shape of a monitor from thin to fat, preserving the
774 * internal lock state. The calling thread must own the lock.
775 */
776static void inflateMonitor(Thread *self, Object *obj)
777{
778 Monitor *mon;
779 u4 thin;
780
781 assert(self != NULL);
782 assert(obj != NULL);
783 assert(LW_SHAPE(obj->lock) == LW_SHAPE_THIN);
784 assert(LW_LOCK_OWNER(obj->lock) == self->threadId);
785 /* Allocate and acquire a new monitor. */
786 mon = dvmCreateMonitor(obj);
787 lockMonitor(self, mon);
788 /* Propagate the lock state. */
789 thin = obj->lock;
790 mon->lockCount = LW_LOCK_COUNT(thin);
791 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
792 thin |= (u4)mon | LW_SHAPE_FAT;
793 /* Publish the updated lock word. */
794 MEM_BARRIER();
795 obj->lock = thin;
796}
797
798/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800799 * Implements monitorenter for "synchronized" stuff.
800 *
801 * This does not fail or throw an exception (unless deadlock prediction
802 * is enabled and set to "err" mode).
803 */
804void dvmLockObject(Thread* self, Object *obj)
805{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800806 volatile u4 *thinp;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800807 ThreadStatus oldStatus;
808 useconds_t sleepDelay;
809 const useconds_t maxSleepDelay = 1 << 20;
810 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800811
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800812 assert(self != NULL);
813 assert(obj != NULL);
814 threadId = self->threadId;
815 thinp = &obj->lock;
816retry:
817 thin = *thinp;
818 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
819 /*
820 * The lock is a thin lock. The owner field is used to
821 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800822 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800823 if (LW_LOCK_OWNER(thin) == threadId) {
824 /*
825 * The calling thread owns the lock. Increment the
826 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800827 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800828 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
829 } else if (LW_LOCK_OWNER(thin) == 0) {
830 /*
831 * The lock is unowned. Install the thread id of the
832 * calling thread into the owner field. This is the
833 * common case. In performance critical code the JIT
834 * will have tried this before calling out to the VM.
835 */
836 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
837 if (!ATOMIC_CMP_SWAP((int32_t *)thinp, thin, newThin)) {
838 /*
839 * The acquire failed. Try again.
840 */
841 goto retry;
842 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800843 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800844 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
845 threadId, &obj->lock, 0, *thinp, thin);
846 /*
847 * The lock is owned by another thread. Notify the VM
848 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800849 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800850 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
851 /*
852 * Spin until the thin lock is released or inflated.
853 */
854 sleepDelay = 0;
855 for (;;) {
856 thin = *thinp;
857 /*
858 * Check the shape of the lock word. Another thread
859 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800860 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800861 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
862 if (LW_LOCK_OWNER(thin) == 0) {
863 /*
864 * The lock has been released. Install the
865 * thread id of the calling thread into the
866 * owner field.
867 */
868 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
869 if (ATOMIC_CMP_SWAP((int32_t *)thinp,
870 thin, newThin)) {
871 /*
872 * The acquire succeed. Break out of the
873 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800874 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800875 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800876 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800877 } else {
878 /*
879 * The lock has not been released. Yield so
880 * the owning thread can run.
881 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800882 if (sleepDelay == 0) {
883 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800884 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800885 } else {
886 usleep(sleepDelay);
887 if (sleepDelay < maxSleepDelay / 2) {
888 sleepDelay *= 2;
889 }
890 }
891 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800892 } else {
893 /*
894 * The thin lock was inflated by another thread.
895 * Let the VM know we are no longer waiting and
896 * try again.
897 */
898 LOG_THIN("(%d) lock %p surprise-fattened",
899 threadId, &obj->lock);
900 dvmChangeStatus(self, oldStatus);
901 goto retry;
902 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800903 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800904 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
905 threadId, &obj->lock, 0, *thinp, thin);
906 /*
907 * We have acquired the thin lock. Let the VM know that
908 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800909 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800910 dvmChangeStatus(self, oldStatus);
911 /*
912 * Fatten the lock.
913 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800914 inflateMonitor(self, obj);
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800915 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800916 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800917 } else {
918 /*
919 * The lock is a fat lock.
920 */
921 assert(LW_MONITOR(obj->lock) != NULL);
922 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800923 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800924#ifdef WITH_DEADLOCK_PREDICTION
925 /*
926 * See if we were allowed to grab the lock at this time. We do it
927 * *after* acquiring the lock, rather than before, so that we can
928 * freely update the Monitor struct. This seems counter-intuitive,
929 * but our goal is deadlock *prediction* not deadlock *prevention*.
930 * (If we actually deadlock, the situation is easy to diagnose from
931 * a thread dump, so there's no point making a special effort to do
932 * the checks before the lock is held.)
933 *
934 * This needs to happen before we add the object to the thread's
935 * monitor list, so we can tell the difference between first-lock and
936 * re-lock.
937 *
938 * It's also important that we do this while in THREAD_RUNNING, so
939 * that we don't interfere with cleanup operations in the GC.
940 */
941 if (gDvm.deadlockPredictMode != kDPOff) {
942 if (self->status != THREAD_RUNNING) {
943 LOGE("Bad thread status (%d) in DP\n", self->status);
944 dvmDumpThread(self, false);
945 dvmAbort();
946 }
947 assert(!dvmCheckException(self));
948 updateDeadlockPrediction(self, obj);
949 if (dvmCheckException(self)) {
950 /*
951 * If we're throwing an exception here, we need to free the
952 * lock. We add the object to the thread's monitor list so the
953 * "unlock" code can remove it.
954 */
955 dvmAddToMonitorList(self, obj, false);
956 dvmUnlockObject(self, obj);
957 LOGV("--- unlocked, pending is '%s'\n",
958 dvmGetException(self)->clazz->descriptor);
959 }
960 }
961
962 /*
963 * Add the locked object, and the current stack trace, to the list
964 * held by the Thread object. If deadlock prediction isn't on,
965 * don't capture the stack trace.
966 */
967 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
968#elif defined(WITH_MONITOR_TRACKING)
969 /*
970 * Add the locked object to the list held by the Thread object.
971 */
972 dvmAddToMonitorList(self, obj, false);
973#endif
974}
975
976/*
977 * Implements monitorexit for "synchronized" stuff.
978 *
979 * On failure, throws an exception and returns "false".
980 */
981bool dvmUnlockObject(Thread* self, Object *obj)
982{
Carl Shapiro94338aa2009-12-21 11:42:59 -0800983 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800984
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800985 assert(self != NULL);
986 assert(self->status == THREAD_RUNNING);
987 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800988 /*
989 * Cache the lock word as its value can change while we are
990 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800991 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800992 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800993 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
994 /*
995 * The lock is thin. We must ensure that the lock is owned
996 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800997 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800998 if (LW_LOCK_OWNER(thin) == self->threadId) {
999 /*
1000 * We are the lock owner. It is safe to update the lock
1001 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001002 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001003 if (LW_LOCK_COUNT(thin) == 0) {
1004 /*
1005 * The lock was not recursively acquired, the common
1006 * case. Unlock by clearing all bits except for the
1007 * hash state.
1008 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001009 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001010 } else {
1011 /*
1012 * The object was recursively acquired. Decrement the
1013 * lock recursion count field.
1014 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001015 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001016 }
1017 } else {
1018 /*
1019 * We do not own the lock. The JVM spec requires that we
1020 * throw an exception in this case.
1021 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001022 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001023 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001024 return false;
1025 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001026 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001027 /*
1028 * The lock is fat. We must check to see if unlockMonitor has
1029 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001030 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001031 assert(LW_MONITOR(obj->lock) != NULL);
1032 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001033 /*
1034 * An exception has been raised. Do not fall through.
1035 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001036 return false;
1037 }
1038 }
1039
1040#ifdef WITH_MONITOR_TRACKING
1041 /*
1042 * Remove the object from the Thread's list.
1043 */
1044 dvmRemoveFromMonitorList(self, obj);
1045#endif
1046
1047 return true;
1048}
1049
1050/*
1051 * Object.wait(). Also called for class init.
1052 */
1053void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1054 bool interruptShouldThrow)
1055{
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001056 Monitor* mon;
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001057 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001058
1059 /* If the lock is still thin, we need to fatten it.
1060 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001061 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001062 /* Make sure that 'self' holds the lock.
1063 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001064 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001065 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1066 "object not locked by thread before wait()");
1067 return;
1068 }
1069
1070 /* This thread holds the lock. We need to fatten the lock
1071 * so 'self' can block on it. Don't update the object lock
1072 * field yet, because 'self' needs to acquire the lock before
1073 * any other thread gets a chance.
1074 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001075 inflateMonitor(self, obj);
1076 LOG_THIN("(%d) lock %p fattened by wait() to count %d",
1077 self->threadId, &obj->lock, mon->lockCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001078 }
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001079 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001080 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1081}
1082
1083/*
1084 * Object.notify().
1085 */
1086void dvmObjectNotify(Thread* self, Object *obj)
1087{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001088 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001089
1090 /* If the lock is still thin, there aren't any waiters;
1091 * waiting on an object forces lock fattening.
1092 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001093 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001094 /* Make sure that 'self' holds the lock.
1095 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001096 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001097 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1098 "object not locked by thread before notify()");
1099 return;
1100 }
1101
1102 /* no-op; there are no waiters to notify.
1103 */
1104 } else {
1105 /* It's a fat lock.
1106 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001107 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001108 }
1109}
1110
1111/*
1112 * Object.notifyAll().
1113 */
1114void dvmObjectNotifyAll(Thread* self, Object *obj)
1115{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001116 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001117
1118 /* If the lock is still thin, there aren't any waiters;
1119 * waiting on an object forces lock fattening.
1120 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001121 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001122 /* Make sure that 'self' holds the lock.
1123 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001124 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001125 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1126 "object not locked by thread before notifyAll()");
1127 return;
1128 }
1129
1130 /* no-op; there are no waiters to notify.
1131 */
1132 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001133 /* It's a fat lock.
1134 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001135 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001136 }
1137}
1138
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001139/*
1140 * This implements java.lang.Thread.sleep(long msec, int nsec).
1141 *
1142 * The sleep is interruptible by other threads, which means we can't just
1143 * plop into an OS sleep call. (We probably could if we wanted to send
1144 * signals around and rely on EINTR, but that's inefficient and relies
1145 * on native code respecting our signal mask.)
1146 *
1147 * We have to do all of this stuff for Object.wait() as well, so it's
1148 * easiest to just sleep on a private Monitor.
1149 *
1150 * It appears that we want sleep(0,0) to go through the motions of sleeping
1151 * for a very short duration, rather than just returning.
1152 */
1153void dvmThreadSleep(u8 msec, u4 nsec)
1154{
1155 Thread* self = dvmThreadSelf();
1156 Monitor* mon = gDvm.threadSleepMon;
1157
1158 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1159 if (msec == 0 && nsec == 0)
1160 nsec++;
1161
1162 lockMonitor(self, mon);
1163 waitMonitor(self, mon, msec, nsec, true);
1164 unlockMonitor(self, mon);
1165}
1166
1167/*
1168 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001169 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001170void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001171{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001172 assert(thread != NULL);
1173
1174 pthread_mutex_lock(&thread->waitMutex);
1175
1176 /*
1177 * If the interrupted flag is already set no additional action is
1178 * required.
1179 */
1180 if (thread->interrupted == true) {
1181 pthread_mutex_unlock(&thread->waitMutex);
1182 return;
1183 }
1184
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001185 /*
1186 * Raise the "interrupted" flag. This will cause it to bail early out
1187 * of the next wait() attempt, if it's not currently waiting on
1188 * something.
1189 */
1190 thread->interrupted = true;
1191 MEM_BARRIER();
1192
1193 /*
1194 * Is the thread waiting?
1195 *
1196 * Note that fat vs. thin doesn't matter here; waitMonitor
1197 * is only set when a thread actually waits on a monitor,
1198 * which implies that the monitor has already been fattened.
1199 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001200 if (thread->waitMonitor != NULL) {
1201 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001202 }
1203
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001204 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001205}
1206
Carl Shapiro30aa9972010-01-13 22:07:50 -08001207#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001208u4 dvmIdentityHashCode(Object *obj)
1209{
1210 return (u4)obj;
1211}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001212#else
1213static size_t arrayElementWidth(const ArrayObject *array)
1214{
1215 const char *descriptor;
1216
1217 if (dvmIsObjectArray(array)) {
1218 return sizeof(Object *);
1219 } else {
1220 descriptor = array->obj.clazz->descriptor;
1221 switch (descriptor[1]) {
1222 case 'B': return 1; /* byte */
1223 case 'C': return 2; /* char */
1224 case 'D': return 8; /* double */
1225 case 'F': return 4; /* float */
1226 case 'I': return 4; /* int */
1227 case 'J': return 8; /* long */
1228 case 'S': return 2; /* short */
1229 case 'Z': return 1; /* boolean */
1230 }
1231 }
1232 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1233 dvmDumpThread(dvmThreadSelf(), false);
1234 dvmAbort();
1235 return 0; /* Quiet the compiler. */
1236}
1237
1238static size_t arrayObjectLength(const ArrayObject *array)
1239{
1240 size_t length;
1241
1242 length = offsetof(ArrayObject, contents);
1243 length += array->length * arrayElementWidth(array);
1244 return length;
1245}
1246
1247/*
1248 * Returns the identity hash code of the given object.
1249 */
1250u4 dvmIdentityHashCode(Object *obj)
1251{
1252 Thread *self, *thread;
1253 volatile u4 *lw;
1254 size_t length;
1255 u4 lock, owner, hashState;
1256
1257 if (obj == NULL) {
1258 /*
1259 * Null is defined to have an identity hash code of 0.
1260 */
1261 return 0;
1262 }
1263 lw = &obj->lock;
1264retry:
1265 hashState = LW_HASH_STATE(*lw);
1266 if (hashState == LW_HASH_STATE_HASHED) {
1267 /*
1268 * The object has been hashed but has not had its hash code
1269 * relocated by the garbage collector. Use the raw object
1270 * address.
1271 */
1272 return (u4)obj >> 3;
1273 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1274 /*
1275 * The object has been hashed and its hash code has been
1276 * relocated by the collector. Use the value of the naturally
1277 * aligned word following the instance data.
1278 */
1279 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1280 length = arrayObjectLength((ArrayObject *)obj);
1281 length = (length + 3) & ~3;
1282 } else {
1283 length = obj->clazz->objectSize;
1284 }
1285 return *(u4 *)(((char *)obj) + length);
1286 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1287 /*
1288 * The object has never been hashed. Change the hash state to
1289 * hashed and use the raw object address.
1290 */
1291 self = dvmThreadSelf();
1292 if (self->threadId == lockOwner(obj)) {
1293 /*
1294 * We already own the lock so we can update the hash state
1295 * directly.
1296 */
1297 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1298 return (u4)obj >> 3;
1299 }
1300 /*
1301 * We do not own the lock. Try acquiring the lock. Should
1302 * this fail, we must suspend the owning thread.
1303 */
1304 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1305 /*
1306 * If the lock is thin assume it is unowned. We simulate
1307 * an acquire, update, and release with a single CAS.
1308 */
1309 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1310 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1311 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1312 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1313 (int32_t)lock)) {
1314 /*
1315 * A new lockword has been installed with a hash state
1316 * of hashed. Use the raw object address.
1317 */
1318 return (u4)obj >> 3;
1319 }
1320 } else {
1321 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1322 /*
1323 * The monitor lock has been acquired. Change the
1324 * hash state to hashed and use the raw object
1325 * address.
1326 */
1327 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1328 unlockMonitor(self, LW_MONITOR(*lw));
1329 return (u4)obj >> 3;
1330 }
1331 }
1332 /*
1333 * At this point we have failed to acquire the lock. We must
1334 * identify the owning thread and suspend it.
1335 */
1336 dvmLockThreadList(self);
1337 /*
1338 * Cache the lock word as its value can change between
1339 * determining its shape and retrieving its owner.
1340 */
1341 lock = *lw;
1342 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1343 /*
1344 * Find the thread with the corresponding thread id.
1345 */
1346 owner = LW_LOCK_OWNER(lock);
1347 assert(owner != self->threadId);
1348 /*
1349 * If the lock has no owner do not bother scanning the
1350 * thread list and fall through to the failure handler.
1351 */
1352 thread = owner ? gDvm.threadList : NULL;
1353 while (thread != NULL) {
1354 if (thread->threadId == owner) {
1355 break;
1356 }
1357 thread = thread->next;
1358 }
1359 } else {
1360 thread = LW_MONITOR(lock)->owner;
1361 }
1362 /*
1363 * If thread is NULL the object has been released since the
1364 * thread list lock was acquired. Try again.
1365 */
1366 if (thread == NULL) {
1367 dvmUnlockThreadList();
1368 goto retry;
1369 }
1370 /*
1371 * Wait for the owning thread to suspend.
1372 */
1373 dvmSuspendThread(thread);
1374 if (dvmHoldsLock(thread, obj)) {
1375 /*
1376 * The owning thread has been suspended. We can safely
1377 * change the hash state to hashed.
1378 */
1379 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1380 dvmResumeThread(thread);
1381 dvmUnlockThreadList();
1382 return (u4)obj >> 3;
1383 }
1384 /*
1385 * The wrong thread has been suspended. Try again.
1386 */
1387 dvmResumeThread(thread);
1388 dvmUnlockThreadList();
1389 goto retry;
1390 }
1391 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1392 dvmDumpThread(dvmThreadSelf(), false);
1393 dvmAbort();
1394 return 0; /* Quiet the compiler. */
1395}
1396#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001397
1398#ifdef WITH_DEADLOCK_PREDICTION
1399/*
1400 * ===========================================================================
1401 * Deadlock prediction
1402 * ===========================================================================
1403 */
1404/*
1405The idea is to predict the possibility of deadlock by recording the order
1406in which monitors are acquired. If we see an attempt to acquire a lock
1407out of order, we can identify the locks and offending code.
1408
1409To make this work, we need to keep track of the locks held by each thread,
1410and create history trees for each lock. When a thread tries to acquire
1411a new lock, we walk through the "history children" of the lock, looking
1412for a match with locks the thread already holds. If we find a match,
1413it means the thread has made a request that could result in a deadlock.
1414
1415To support recursive locks, we always allow re-locking a currently-held
1416lock, and maintain a recursion depth count.
1417
1418An ASCII-art example, where letters represent Objects:
1419
1420 A
1421 /|\
1422 / | \
1423 B | D
1424 \ |
1425 \|
1426 C
1427
1428The above is the tree we'd have after handling Object synchronization
1429sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1430a child of B. (The lines represent pointers between parent and child.
1431Every node can have multiple parents and multiple children.)
1432
1433If we hold AC, and want to lock B, we recursively search through B's
1434children to see if A or C appears. It does, so we reject the attempt.
1435(A straightforward way to implement it: add a link from C to B, then
1436determine whether the graph starting at B contains a cycle.)
1437
1438If we hold AC and want to lock D, we would succeed, creating a new link
1439from C to D.
1440
1441The lock history and a stack trace is attached to the Object's Monitor
1442struct, which means we need to fatten every Object we lock (thin locking
1443is effectively disabled). If we don't need the stack trace we can
1444avoid fattening the leaf nodes, only fattening objects that need to hold
1445history trees.
1446
1447Updates to Monitor structs are only allowed for the thread that holds
1448the Monitor, so we actually do most of our deadlock prediction work after
1449the lock has been acquired.
1450
1451When an object with a monitor is GCed, we need to remove it from the
1452history trees. There are two basic approaches:
1453 (1) For through the entire set of known monitors, search all child
1454 lists for the object in question. This is rather slow, resulting
1455 in GC passes that take upwards of 10 seconds to complete.
1456 (2) Maintain "parent" pointers in each node. Remove the entries as
1457 required. This requires additional storage and maintenance for
1458 every operation, but is significantly faster at GC time.
1459For each GCed object, we merge all of the object's children into each of
1460the object's parents.
1461*/
1462
1463#if !defined(WITH_MONITOR_TRACKING)
1464# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1465#endif
1466
1467/*
1468 * Clear out the contents of an ExpandingObjectList, freeing any
1469 * dynamic allocations.
1470 */
1471static void expandObjClear(ExpandingObjectList* pList)
1472{
1473 if (pList->list != NULL) {
1474 free(pList->list);
1475 pList->list = NULL;
1476 }
1477 pList->alloc = pList->count = 0;
1478}
1479
1480/*
1481 * Get the number of objects currently stored in the list.
1482 */
1483static inline int expandBufGetCount(const ExpandingObjectList* pList)
1484{
1485 return pList->count;
1486}
1487
1488/*
1489 * Get the Nth entry from the list.
1490 */
1491static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1492 int i)
1493{
1494 return pList->list[i];
1495}
1496
1497/*
1498 * Add a new entry to the list.
1499 *
1500 * We don't check for or try to enforce uniqueness. It's expected that
1501 * the higher-level code does this for us.
1502 */
1503static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1504{
1505 if (pList->count == pList->alloc) {
1506 /* time to expand */
1507 Object** newList;
1508
1509 if (pList->alloc == 0)
1510 pList->alloc = 4;
1511 else
1512 pList->alloc *= 2;
1513 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1514 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1515 if (newList == NULL) {
1516 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1517 dvmAbort();
1518 }
1519 pList->list = newList;
1520 }
1521
1522 pList->list[pList->count++] = obj;
1523}
1524
1525/*
1526 * Returns "true" if the element was successfully removed.
1527 */
1528static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1529{
1530 int i;
1531
1532 for (i = pList->count-1; i >= 0; i--) {
1533 if (pList->list[i] == obj)
1534 break;
1535 }
1536 if (i < 0)
1537 return false;
1538
1539 if (i != pList->count-1) {
1540 /*
1541 * The order of elements is not important, so we just copy the
1542 * last entry into the new slot.
1543 */
1544 //memmove(&pList->list[i], &pList->list[i+1],
1545 // (pList->count-1 - i) * sizeof(pList->list[0]));
1546 pList->list[i] = pList->list[pList->count-1];
1547 }
1548
1549 pList->count--;
1550 pList->list[pList->count] = (Object*) 0xdecadead;
1551 return true;
1552}
1553
1554/*
1555 * Returns "true" if "obj" appears in the list.
1556 */
1557static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1558{
1559 int i;
1560
1561 for (i = 0; i < pList->count; i++) {
1562 if (pList->list[i] == obj)
1563 return true;
1564 }
1565 return false;
1566}
1567
1568/*
1569 * Print the list contents to stdout. For debugging.
1570 */
1571static void expandObjDump(const ExpandingObjectList* pList)
1572{
1573 int i;
1574 for (i = 0; i < pList->count; i++)
1575 printf(" %p", pList->list[i]);
1576}
1577
1578/*
1579 * Check for duplicate entries. Returns the index of the first instance
1580 * of the duplicated value, or -1 if no duplicates were found.
1581 */
1582static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1583{
1584 int i, j;
1585 for (i = 0; i < pList->count-1; i++) {
1586 for (j = i + 1; j < pList->count; j++) {
1587 if (pList->list[i] == pList->list[j]) {
1588 return i;
1589 }
1590 }
1591 }
1592
1593 return -1;
1594}
1595
1596
1597/*
1598 * Determine whether "child" appears in the list of objects associated
1599 * with the Monitor in "parent". If "parent" is a thin lock, we return
1600 * false immediately.
1601 */
1602static bool objectInChildList(const Object* parent, Object* child)
1603{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001604 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001605 if (!IS_LOCK_FAT(&lock)) {
1606 //LOGI("on thin\n");
1607 return false;
1608 }
1609
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001610 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001611}
1612
1613/*
1614 * Print the child list.
1615 */
1616static void dumpKids(Object* parent)
1617{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001618 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001619
1620 printf("Children of %p:", parent);
1621 expandObjDump(&mon->historyChildren);
1622 printf("\n");
1623}
1624
1625/*
1626 * Add "child" to the list of children in "parent", and add "parent" to
1627 * the list of parents in "child".
1628 */
1629static void linkParentToChild(Object* parent, Object* child)
1630{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001631 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001632 assert(IS_LOCK_FAT(&parent->lock));
1633 assert(IS_LOCK_FAT(&child->lock));
1634 assert(parent != child);
1635 Monitor* mon;
1636
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001637 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001638 assert(!expandObjHas(&mon->historyChildren, child));
1639 expandObjAddEntry(&mon->historyChildren, child);
1640
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001641 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001642 assert(!expandObjHas(&mon->historyParents, parent));
1643 expandObjAddEntry(&mon->historyParents, parent);
1644}
1645
1646
1647/*
1648 * Remove "child" from the list of children in "parent".
1649 */
1650static void unlinkParentFromChild(Object* parent, Object* child)
1651{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001652 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001653 assert(IS_LOCK_FAT(&parent->lock));
1654 assert(IS_LOCK_FAT(&child->lock));
1655 assert(parent != child);
1656 Monitor* mon;
1657
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001658 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001659 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1660 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1661 }
1662 assert(!expandObjHas(&mon->historyChildren, child));
1663 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1664
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001665 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001666 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1667 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1668 }
1669 assert(!expandObjHas(&mon->historyParents, parent));
1670 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1671}
1672
1673
1674/*
1675 * Log the monitors held by the current thread. This is done as part of
1676 * flagging an error.
1677 */
1678static void logHeldMonitors(Thread* self)
1679{
1680 char* name = NULL;
1681
1682 name = dvmGetThreadName(self);
1683 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1684 self->threadId, name);
1685 LOGW("(most-recently-acquired on top):\n");
1686 free(name);
1687
1688 LockedObjectData* lod = self->pLockedObjects;
1689 while (lod != NULL) {
1690 LOGW("--- object %p[%d] (%s)\n",
1691 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1692 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1693
1694 lod = lod->next;
1695 }
1696}
1697
1698/*
1699 * Recursively traverse the object hierarchy starting at "obj". We mark
1700 * ourselves on entry and clear the mark on exit. If we ever encounter
1701 * a marked object, we have a cycle.
1702 *
1703 * Returns "true" if all is well, "false" if we found a cycle.
1704 */
1705static bool traverseTree(Thread* self, const Object* obj)
1706{
1707 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001708 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001709
1710 /*
1711 * Have we been here before?
1712 */
1713 if (mon->historyMark) {
1714 int* rawStackTrace;
1715 int stackDepth;
1716
1717 LOGW("%s\n", kStartBanner);
1718 LOGW("Illegal lock attempt:\n");
1719 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1720
1721 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1722 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1723 free(rawStackTrace);
1724
1725 LOGW(" ");
1726 logHeldMonitors(self);
1727
1728 LOGW(" ");
1729 LOGW("Earlier, the following lock order (from last to first) was\n");
1730 LOGW("established -- stack trace is from first successful lock):\n");
1731 return false;
1732 }
1733 mon->historyMark = true;
1734
1735 /*
1736 * Examine the children. We do NOT hold these locks, so they might
1737 * very well transition from thin to fat or change ownership while
1738 * we work.
1739 *
1740 * NOTE: we rely on the fact that they cannot revert from fat to thin
1741 * while we work. This is currently a safe assumption.
1742 *
1743 * We can safely ignore thin-locked children, because by definition
1744 * they have no history and are leaf nodes. In the current
1745 * implementation we always fatten the locks to provide a place to
1746 * hang the stack trace.
1747 */
1748 ExpandingObjectList* pList = &mon->historyChildren;
1749 int i;
1750 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1751 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001752 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001753 if (!IS_LOCK_FAT(&lock))
1754 continue;
1755 if (!traverseTree(self, child)) {
1756 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1757 dvmLogRawStackTrace(mon->historyRawStackTrace,
1758 mon->historyStackDepth);
1759 mon->historyMark = false;
1760 return false;
1761 }
1762 }
1763
1764 mon->historyMark = false;
1765
1766 return true;
1767}
1768
1769/*
1770 * Update the deadlock prediction tree, based on the current thread
1771 * acquiring "acqObj". This must be called before the object is added to
1772 * the thread's list of held monitors.
1773 *
1774 * If the thread already holds the lock (recursion), or this is a known
1775 * lock configuration, we return without doing anything. Otherwise, we add
1776 * a link from the most-recently-acquired lock in this thread to "acqObj"
1777 * after ensuring that the parent lock is "fat".
1778 *
1779 * This MUST NOT be called while a GC is in progress in another thread,
1780 * because we assume exclusive access to history trees in owned monitors.
1781 */
1782static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1783{
1784 LockedObjectData* lod;
1785 LockedObjectData* mrl;
1786
1787 /*
1788 * Quick check for recursive access.
1789 */
1790 lod = dvmFindInMonitorList(self, acqObj);
1791 if (lod != NULL) {
1792 LOGV("+++ DP: recursive %p\n", acqObj);
1793 return;
1794 }
1795
1796 /*
1797 * Make the newly-acquired object's monitor "fat". In some ways this
1798 * isn't strictly necessary, but we need the GC to tell us when
1799 * "interesting" objects go away, and right now the only way to make
1800 * an object look interesting is to give it a monitor.
1801 *
1802 * This also gives us a place to hang a stack trace.
1803 *
1804 * Our thread holds the lock, so we're allowed to rewrite the lock
1805 * without worrying that something will change out from under us.
1806 */
1807 if (!IS_LOCK_FAT(&acqObj->lock)) {
1808 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001809 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001810 inflateMonitor(self, acqObj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001811 }
1812
1813 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001814 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1815 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001816 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1817 &mon->historyStackDepth);
1818 }
1819
1820 /*
1821 * We need to examine and perhaps modify the most-recently-locked
1822 * monitor. We own that, so there's no risk of another thread
1823 * stepping on us.
1824 *
1825 * Retrieve the most-recently-locked entry from our thread.
1826 */
1827 mrl = self->pLockedObjects;
1828 if (mrl == NULL)
1829 return; /* no other locks held */
1830
1831 /*
1832 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1833 * this without holding the global lock because of our assertion that
1834 * a GC is not running in parallel -- nobody except the GC can
1835 * modify a history list in a Monitor they don't own, and we own "mrl".
1836 * (There might be concurrent *reads*, but no concurrent *writes.)
1837 *
1838 * If we find it, this is a known good configuration, and we're done.
1839 */
1840 if (objectInChildList(mrl->obj, acqObj))
1841 return;
1842
1843 /*
1844 * "mrl" is going to need to have a history tree. If it's currently
1845 * a thin lock, we make it fat now. The thin lock might have a
1846 * nonzero recursive lock count, which we need to carry over.
1847 *
1848 * Our thread holds the lock, so we're allowed to rewrite the lock
1849 * without worrying that something will change out from under us.
1850 */
1851 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1852 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001853 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001854 inflateMonitor(self, mrl->obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001855 }
1856
1857 /*
1858 * We haven't seen this configuration before. We need to scan down
1859 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1860 * appear. We grab a global lock before traversing or updating the
1861 * history list.
1862 *
1863 * If we find a match for any of our held locks, we know that the lock
1864 * has previously been acquired *after* acqObj, and we throw an error.
1865 *
1866 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1867 * and do a recursive traversal, marking nodes as we cross them. If
1868 * we cross one a second time, we have a cycle and can throw an error.
1869 * (We do the flag-clearing traversal before adding the new link, so
1870 * that we're guaranteed to terminate.)
1871 *
1872 * If "acqObj" is a thin lock, it has no history, and we can create a
1873 * link to it without additional checks. [ We now guarantee that it's
1874 * always fat. ]
1875 */
1876 bool failed = false;
1877 dvmLockMutex(&gDvm.deadlockHistoryLock);
1878 linkParentToChild(mrl->obj, acqObj);
1879 if (!traverseTree(self, acqObj)) {
1880 LOGW("%s\n", kEndBanner);
1881 failed = true;
1882
1883 /* remove the entry so we're still okay when in "warning" mode */
1884 unlinkParentFromChild(mrl->obj, acqObj);
1885 }
1886 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1887
1888 if (failed) {
1889 switch (gDvm.deadlockPredictMode) {
1890 case kDPErr:
1891 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1892 break;
1893 case kDPAbort:
1894 LOGE("Aborting due to potential deadlock\n");
1895 dvmAbort();
1896 break;
1897 default:
1898 /* warn only */
1899 break;
1900 }
1901 }
1902}
1903
1904/*
1905 * We're removing "child" from existence. We want to pull all of
1906 * child's children into "parent", filtering out duplicates. This is
1907 * called during the GC.
1908 *
1909 * This does not modify "child", which might have multiple parents.
1910 */
1911static void mergeChildren(Object* parent, const Object* child)
1912{
1913 Monitor* mon;
1914 int i;
1915
1916 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001917 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001918 ExpandingObjectList* pList = &mon->historyChildren;
1919
1920 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1921 Object* grandChild = expandBufGetEntry(pList, i);
1922
1923 if (!objectInChildList(parent, grandChild)) {
1924 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1925 linkParentToChild(parent, grandChild);
1926 } else {
1927 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1928 }
1929 }
1930}
1931
1932/*
1933 * An object with a fat lock is being collected during a GC pass. We
1934 * want to remove it from any lock history trees that it is a part of.
1935 *
1936 * This may require updating the history trees in several monitors. The
1937 * monitor semantics guarantee that no other thread will be accessing
1938 * the history trees at the same time.
1939 */
1940static void removeCollectedObject(Object* obj)
1941{
1942 Monitor* mon;
1943
1944 LOGVV("+++ collecting %p\n", obj);
1945
1946#if 0
1947 /*
1948 * We're currently running through the entire set of known monitors.
1949 * This can be somewhat slow. We may want to keep lists of parents
1950 * in each child to speed up GC.
1951 */
1952 mon = gDvm.monitorList;
1953 while (mon != NULL) {
1954 Object* parent = mon->obj;
1955 if (parent != NULL) { /* value nulled for deleted entries */
1956 if (objectInChildList(parent, obj)) {
1957 LOGVV("removing child %p from parent %p\n", obj, parent);
1958 unlinkParentFromChild(parent, obj);
1959 mergeChildren(parent, obj);
1960 }
1961 }
1962 mon = mon->next;
1963 }
1964#endif
1965
1966 /*
1967 * For every parent of this object:
1968 * - merge all of our children into the parent's child list (creates
1969 * a two-way link between parent and child)
1970 * - remove ourselves from the parent's child list
1971 */
1972 ExpandingObjectList* pList;
1973 int i;
1974
1975 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001976 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001977 pList = &mon->historyParents;
1978 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1979 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001980 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001981
1982 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
1983 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
1984 }
1985 assert(!expandObjHas(&parentMon->historyChildren, obj));
1986
1987 mergeChildren(parent, obj);
1988 }
1989
1990 /*
1991 * For every child of this object:
1992 * - remove ourselves from the child's parent list
1993 */
1994 pList = &mon->historyChildren;
1995 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1996 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001997 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001998
1999 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2000 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2001 }
2002 assert(!expandObjHas(&childMon->historyParents, obj));
2003 }
2004}
2005
2006#endif /*WITH_DEADLOCK_PREDICTION*/