blob: fae35dea134a1bd106ee3e20e7da78400a5f3641 [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/*
Andy McFadden0a24ef92010-03-12 13:39:59 -0800261 * Get the thread that holds the lock on the specified object. The
262 * object may be unlocked, thin-locked, or fat-locked.
263 *
264 * The caller must lock the thread list before calling here.
265 */
266Thread* dvmGetObjectLockHolder(Object* obj)
267{
268 u4 threadId = lockOwner(obj);
269
270 if (threadId == 0)
271 return NULL;
272 return dvmGetThreadByThreadId(threadId);
273}
274
275/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800276 * Checks whether the given thread holds the given
277 * objects's lock.
278 */
279bool dvmHoldsLock(Thread* thread, Object* obj)
280{
281 if (thread == NULL || obj == NULL) {
282 return false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800283 } else {
Carl Shapiro30aa9972010-01-13 22:07:50 -0800284 return thread->threadId == lockOwner(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800285 }
286}
287
288/*
289 * Free the monitor associated with an object and make the object's lock
290 * thin again. This is called during garbage collection.
291 */
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800292static void freeObjectMonitor(Object* obj)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800293{
294 Monitor *mon;
295
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800296 assert(LW_SHAPE(obj->lock) == LW_SHAPE_FAT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800297
298#ifdef WITH_DEADLOCK_PREDICTION
299 if (gDvm.deadlockPredictMode != kDPOff)
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800300 removeCollectedObject(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800301#endif
302
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800303 mon = LW_MONITOR(obj->lock);
304 obj->lock = DVM_LOCK_INITIAL_THIN_VALUE;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800305
306 /* This lock is associated with an object
307 * that's being swept. The only possible way
308 * anyone could be holding this lock would be
309 * if some JNI code locked but didn't unlock
310 * the object, in which case we've got some bad
311 * native code somewhere.
312 */
313 assert(pthread_mutex_trylock(&mon->lock) == 0);
314 pthread_mutex_destroy(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800315#ifdef WITH_DEADLOCK_PREDICTION
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800316 expandObjClear(&mon->historyChildren);
317 expandObjClear(&mon->historyParents);
318 free(mon->historyRawStackTrace);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800319#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800320 free(mon);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800321}
322
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800323/*
324 * Frees monitor objects belonging to unmarked objects.
325 */
326void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
327{
328 Monitor handle;
329 Monitor *prev, *curr;
330 Object *obj;
331
332 assert(mon != NULL);
333 assert(*mon != NULL);
334 assert(isUnmarkedObject != NULL);
335 prev = &handle;
336 prev->next = curr = *mon;
337 while (curr != NULL) {
338 obj = curr->obj;
339 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
340 prev->next = curr = curr->next;
341 freeObjectMonitor(obj);
342 } else {
343 prev = curr;
344 curr = curr->next;
345 }
346 }
347 *mon = handle.next;
348}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800349
350/*
351 * Lock a monitor.
352 */
353static void lockMonitor(Thread* self, Monitor* mon)
354{
355 int cc;
356
357 if (mon->owner == self) {
358 mon->lockCount++;
359 } else {
360 ThreadStatus oldStatus;
361
362 if (pthread_mutex_trylock(&mon->lock) != 0) {
363 /* mutex is locked, switch to wait status and sleep on it */
364 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
365 cc = pthread_mutex_lock(&mon->lock);
366 assert(cc == 0);
367 dvmChangeStatus(self, oldStatus);
368 }
369
370 mon->owner = self;
371 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800372 }
373}
374
375/*
376 * Try to lock a monitor.
377 *
378 * Returns "true" on success.
379 */
380static bool tryLockMonitor(Thread* self, Monitor* mon)
381{
382 int cc;
383
384 if (mon->owner == self) {
385 mon->lockCount++;
386 return true;
387 } else {
388 cc = pthread_mutex_trylock(&mon->lock);
389 if (cc == 0) {
390 mon->owner = self;
391 assert(mon->lockCount == 0);
392 return true;
393 } else {
394 return false;
395 }
396 }
397}
398
399
400/*
401 * Unlock a monitor.
402 *
403 * Returns true if the unlock succeeded.
404 * If the unlock failed, an exception will be pending.
405 */
406static bool unlockMonitor(Thread* self, Monitor* mon)
407{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800408 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800409 assert(mon != NULL); // can this happen?
410
411 if (mon->owner == self) {
412 /*
413 * We own the monitor, so nobody else can be in here.
414 */
415 if (mon->lockCount == 0) {
416 int cc;
417 mon->owner = NULL;
418 cc = pthread_mutex_unlock(&mon->lock);
419 assert(cc == 0);
420 } else {
421 mon->lockCount--;
422 }
423 } else {
424 /*
425 * We don't own this, so we're not allowed to unlock it.
426 * The JNI spec says that we should throw IllegalMonitorStateException
427 * in this case.
428 */
Carl Shapiroe11f3fd2010-02-24 02:30:55 -0800429 dvmThrowExceptionFmt("Ljava/lang/IllegalMonitorStateException;",
430 "unlock of unowned monitor, self=%d owner=%d",
431 self->threadId,
432 mon->owner ? mon->owner->threadId : 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800433 return false;
434 }
435 return true;
436}
437
438/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800439 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800440 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800441 */
442static int waitSetCheck(Monitor *mon)
443{
444 Thread *fast, *slow;
445 size_t n;
446
447 assert(mon != NULL);
448 fast = slow = mon->waitSet;
449 n = 0;
450 for (;;) {
451 if (fast == NULL) return 0;
452 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800453 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800454 n += 2;
455 fast = fast->waitNext->waitNext;
456 slow = slow->waitNext;
457 }
458}
459
460/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800461 * Links a thread into a monitor's wait set. The monitor lock must be
462 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800463 */
464static void waitSetAppend(Monitor *mon, Thread *thread)
465{
466 Thread *elt;
467
468 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800469 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800470 assert(thread != NULL);
471 assert(thread->waitNext == NULL);
472 assert(waitSetCheck(mon) == 0);
473 if (mon->waitSet == NULL) {
474 mon->waitSet = thread;
475 return;
476 }
477 elt = mon->waitSet;
478 while (elt->waitNext != NULL) {
479 elt = elt->waitNext;
480 }
481 elt->waitNext = thread;
482}
483
484/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800485 * Unlinks a thread from a monitor's wait set. The monitor lock must
486 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800487 */
488static void waitSetRemove(Monitor *mon, Thread *thread)
489{
490 Thread *elt;
491
492 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800493 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800494 assert(thread != NULL);
495 assert(waitSetCheck(mon) == 0);
496 if (mon->waitSet == NULL) {
497 return;
498 }
499 if (mon->waitSet == thread) {
500 mon->waitSet = thread->waitNext;
501 thread->waitNext = NULL;
502 return;
503 }
504 elt = mon->waitSet;
505 while (elt->waitNext != NULL) {
506 if (elt->waitNext == thread) {
507 elt->waitNext = thread->waitNext;
508 thread->waitNext = NULL;
509 return;
510 }
511 elt = elt->waitNext;
512 }
513}
514
Carl Shapirob4539192010-01-04 16:50:00 -0800515/*
516 * Converts the given relative waiting time into an absolute time.
517 */
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800518void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800519{
520 s8 endSec;
521
522#ifdef HAVE_TIMEDWAIT_MONOTONIC
523 clock_gettime(CLOCK_MONOTONIC, ts);
524#else
525 {
526 struct timeval tv;
527 gettimeofday(&tv, NULL);
528 ts->tv_sec = tv.tv_sec;
529 ts->tv_nsec = tv.tv_usec * 1000;
530 }
531#endif
532 endSec = ts->tv_sec + msec / 1000;
533 if (endSec >= 0x7fffffff) {
534 LOGV("NOTE: end time exceeds epoch\n");
535 endSec = 0x7ffffffe;
536 }
537 ts->tv_sec = endSec;
538 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
539
540 /* catch rollover */
541 if (ts->tv_nsec >= 1000000000L) {
542 ts->tv_sec++;
543 ts->tv_nsec -= 1000000000L;
544 }
545}
546
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800547int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
548 s8 msec, s4 nsec)
549{
550 int ret;
551 struct timespec ts;
552 absoluteTime(msec, nsec, &ts);
553#if defined(HAVE_TIMEDWAIT_MONOTONIC)
554 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
555#else
556 ret = pthread_cond_timedwait(cond, mutex, &ts);
557#endif
558 assert(ret == 0 || ret == ETIMEDOUT);
559 return ret;
560}
561
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800562/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800563 * Wait on a monitor until timeout, interrupt, or notification. Used for
564 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
565 *
566 * If another thread calls Thread.interrupt(), we throw InterruptedException
567 * and return immediately if one of the following are true:
568 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
569 * - blocked in join(), join(long), or join(long, int) methods of Thread
570 * - blocked in sleep(long), or sleep(long, int) methods of Thread
571 * Otherwise, we set the "interrupted" flag.
572 *
573 * Checks to make sure that "nsec" is in the range 0-999999
574 * (i.e. fractions of a millisecond) and throws the appropriate
575 * exception if it isn't.
576 *
577 * The spec allows "spurious wakeups", and recommends that all code using
578 * Object.wait() do so in a loop. This appears to derive from concerns
579 * about pthread_cond_wait() on multiprocessor systems. Some commentary
580 * on the web casts doubt on whether these can/should occur.
581 *
582 * Since we're allowed to wake up "early", we clamp extremely long durations
583 * to return at the end of the 32-bit time epoch.
584 */
585static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
586 bool interruptShouldThrow)
587{
588 struct timespec ts;
589 bool wasInterrupted = false;
590 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800591 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800592
Carl Shapiro71938022009-12-22 13:49:53 -0800593 assert(self != NULL);
594 assert(mon != NULL);
595
Carl Shapiro94338aa2009-12-21 11:42:59 -0800596 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800597 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800598 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
599 "object not locked by thread before wait()");
600 return;
601 }
602
603 /*
604 * Enforce the timeout range.
605 */
606 if (msec < 0 || nsec < 0 || nsec > 999999) {
607 dvmThrowException("Ljava/lang/IllegalArgumentException;",
608 "timeout arguments out of range");
609 return;
610 }
611
612 /*
613 * Compute absolute wakeup time, if necessary.
614 */
615 if (msec == 0 && nsec == 0) {
616 timed = false;
617 } else {
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800618 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800619 timed = true;
620 }
621
622 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800623 * Add ourselves to the set of threads waiting on this monitor, and
624 * release our hold. We need to let it go even if we're a few levels
625 * deep in a recursive lock, and we need to restore that later.
626 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800627 * We append to the wait set ahead of clearing the count and owner
628 * fields so the subroutine can check that the calling thread owns
629 * the monitor. Aside from that, the order of member updates is
630 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800631 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800632 waitSetAppend(mon, self);
633 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800634 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800635 mon->owner = NULL;
636
637 /*
638 * Update thread status. If the GC wakes up, it'll ignore us, knowing
639 * that we won't touch any references in this state, and we'll check
640 * our suspend mode before we transition out.
641 */
642 if (timed)
643 dvmChangeStatus(self, THREAD_TIMED_WAIT);
644 else
645 dvmChangeStatus(self, THREAD_WAIT);
646
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800647 ret = pthread_mutex_lock(&self->waitMutex);
648 assert(ret == 0);
649
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800650 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800651 * Set waitMonitor to the monitor object we will be waiting on.
652 * When waitMonitor is non-NULL a notifying or interrupting thread
653 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800654 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800655 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800656 self->waitMonitor = mon;
657
658 /*
659 * Handle the case where the thread was interrupted before we called
660 * wait().
661 */
662 if (self->interrupted) {
663 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800664 self->waitMonitor = NULL;
665 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800666 goto done;
667 }
668
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800669 /*
670 * Release the monitor lock and wait for a notification or
671 * a timeout to occur.
672 */
673 pthread_mutex_unlock(&mon->lock);
674
675 if (!timed) {
676 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
677 assert(ret == 0);
678 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800679#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800680 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800681#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800682 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800683#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800684 assert(ret == 0 || ret == ETIMEDOUT);
685 }
686 if (self->interrupted) {
687 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800688 }
689
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800690 self->interrupted = false;
691 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800692
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800693 pthread_mutex_unlock(&self->waitMutex);
694
Carl Shapiro30aa9972010-01-13 22:07:50 -0800695 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800696 lockMonitor(self, mon);
697
Carl Shapiro142ef272010-01-25 12:51:31 -0800698done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800699 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800700 * We remove our thread from wait set after restoring the count
701 * and owner fields so the subroutine can check that the calling
702 * thread owns the monitor. Aside from that, the order of member
703 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800704 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800705 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800706 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800707 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800708
709 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
710 dvmChangeStatus(self, THREAD_RUNNING);
711
712 if (wasInterrupted) {
713 /*
714 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800715 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800716 *
717 * The doc sayeth: "The interrupted status of the current thread is
718 * cleared when this exception is thrown."
719 */
720 self->interrupted = false;
721 if (interruptShouldThrow)
722 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
723 }
724}
725
726/*
727 * Notify one thread waiting on this monitor.
728 */
729static void notifyMonitor(Thread* self, Monitor* mon)
730{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800731 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800732
Carl Shapiro71938022009-12-22 13:49:53 -0800733 assert(self != NULL);
734 assert(mon != NULL);
735
Carl Shapiro94338aa2009-12-21 11:42:59 -0800736 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800737 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800738 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
739 "object not locked by thread before notify()");
740 return;
741 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800742 /* Signal the first waiting thread in the wait set. */
743 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800744 thread = mon->waitSet;
745 mon->waitSet = thread->waitNext;
746 thread->waitNext = NULL;
747 pthread_mutex_lock(&thread->waitMutex);
748 /* Check to see if the thread is still waiting. */
749 if (thread->waitMonitor != NULL) {
750 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800751 pthread_mutex_unlock(&thread->waitMutex);
752 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800753 }
754 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800755 }
756}
757
758/*
759 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800760 */
761static void notifyAllMonitor(Thread* self, Monitor* mon)
762{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800763 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800764
Carl Shapiro71938022009-12-22 13:49:53 -0800765 assert(self != NULL);
766 assert(mon != NULL);
767
Carl Shapiro94338aa2009-12-21 11:42:59 -0800768 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800769 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800770 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
771 "object not locked by thread before notifyAll()");
772 return;
773 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800774 /* Signal all threads in the wait set. */
775 while (mon->waitSet != NULL) {
776 thread = mon->waitSet;
777 mon->waitSet = thread->waitNext;
778 thread->waitNext = NULL;
779 pthread_mutex_lock(&thread->waitMutex);
780 /* Check to see if the thread is still waiting. */
781 if (thread->waitMonitor != NULL) {
782 pthread_cond_signal(&thread->waitCond);
783 }
784 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800785 }
786}
787
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800788/*
789 * Implements monitorenter for "synchronized" stuff.
790 *
791 * This does not fail or throw an exception (unless deadlock prediction
792 * is enabled and set to "err" mode).
793 */
794void dvmLockObject(Thread* self, Object *obj)
795{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800796 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800797 Monitor *mon;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800798 ThreadStatus oldStatus;
799 useconds_t sleepDelay;
800 const useconds_t maxSleepDelay = 1 << 20;
801 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800802
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800803 assert(self != NULL);
804 assert(obj != NULL);
805 threadId = self->threadId;
806 thinp = &obj->lock;
807retry:
808 thin = *thinp;
809 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
810 /*
811 * The lock is a thin lock. The owner field is used to
812 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800813 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800814 if (LW_LOCK_OWNER(thin) == threadId) {
815 /*
816 * The calling thread owns the lock. Increment the
817 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800818 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800819 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
820 } else if (LW_LOCK_OWNER(thin) == 0) {
821 /*
822 * The lock is unowned. Install the thread id of the
823 * calling thread into the owner field. This is the
824 * common case. In performance critical code the JIT
825 * will have tried this before calling out to the VM.
826 */
827 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
828 if (!ATOMIC_CMP_SWAP((int32_t *)thinp, thin, newThin)) {
829 /*
830 * The acquire failed. Try again.
831 */
832 goto retry;
833 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800834 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800835 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
836 threadId, &obj->lock, 0, *thinp, thin);
837 /*
838 * The lock is owned by another thread. Notify the VM
839 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800840 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800841 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
842 /*
843 * Spin until the thin lock is released or inflated.
844 */
845 sleepDelay = 0;
846 for (;;) {
847 thin = *thinp;
848 /*
849 * Check the shape of the lock word. Another thread
850 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800851 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800852 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
853 if (LW_LOCK_OWNER(thin) == 0) {
854 /*
855 * The lock has been released. Install the
856 * thread id of the calling thread into the
857 * owner field.
858 */
859 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
860 if (ATOMIC_CMP_SWAP((int32_t *)thinp,
861 thin, newThin)) {
862 /*
863 * The acquire succeed. Break out of the
864 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800865 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800866 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800867 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800868 } else {
869 /*
870 * The lock has not been released. Yield so
871 * the owning thread can run.
872 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800873 if (sleepDelay == 0) {
874 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800875 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800876 } else {
877 usleep(sleepDelay);
878 if (sleepDelay < maxSleepDelay / 2) {
879 sleepDelay *= 2;
880 }
881 }
882 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800883 } else {
884 /*
885 * The thin lock was inflated by another thread.
886 * Let the VM know we are no longer waiting and
887 * try again.
888 */
889 LOG_THIN("(%d) lock %p surprise-fattened",
890 threadId, &obj->lock);
891 dvmChangeStatus(self, oldStatus);
892 goto retry;
893 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800894 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800895 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
896 threadId, &obj->lock, 0, *thinp, thin);
897 /*
898 * We have acquired the thin lock. Let the VM know that
899 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800900 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800901 dvmChangeStatus(self, oldStatus);
902 /*
903 * Fatten the lock.
904 */
905 mon = dvmCreateMonitor(obj);
906 lockMonitor(self, mon);
907 thin = *thinp;
908 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
909 thin |= (u4)mon | LW_SHAPE_FAT;
910 MEM_BARRIER();
911 obj->lock = thin;
912 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800913 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800914 } else {
915 /*
916 * The lock is a fat lock.
917 */
918 assert(LW_MONITOR(obj->lock) != NULL);
919 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800920 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800921#ifdef WITH_DEADLOCK_PREDICTION
922 /*
923 * See if we were allowed to grab the lock at this time. We do it
924 * *after* acquiring the lock, rather than before, so that we can
925 * freely update the Monitor struct. This seems counter-intuitive,
926 * but our goal is deadlock *prediction* not deadlock *prevention*.
927 * (If we actually deadlock, the situation is easy to diagnose from
928 * a thread dump, so there's no point making a special effort to do
929 * the checks before the lock is held.)
930 *
931 * This needs to happen before we add the object to the thread's
932 * monitor list, so we can tell the difference between first-lock and
933 * re-lock.
934 *
935 * It's also important that we do this while in THREAD_RUNNING, so
936 * that we don't interfere with cleanup operations in the GC.
937 */
938 if (gDvm.deadlockPredictMode != kDPOff) {
939 if (self->status != THREAD_RUNNING) {
940 LOGE("Bad thread status (%d) in DP\n", self->status);
941 dvmDumpThread(self, false);
942 dvmAbort();
943 }
944 assert(!dvmCheckException(self));
945 updateDeadlockPrediction(self, obj);
946 if (dvmCheckException(self)) {
947 /*
948 * If we're throwing an exception here, we need to free the
949 * lock. We add the object to the thread's monitor list so the
950 * "unlock" code can remove it.
951 */
952 dvmAddToMonitorList(self, obj, false);
953 dvmUnlockObject(self, obj);
954 LOGV("--- unlocked, pending is '%s'\n",
955 dvmGetException(self)->clazz->descriptor);
956 }
957 }
958
959 /*
960 * Add the locked object, and the current stack trace, to the list
961 * held by the Thread object. If deadlock prediction isn't on,
962 * don't capture the stack trace.
963 */
964 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
965#elif defined(WITH_MONITOR_TRACKING)
966 /*
967 * Add the locked object to the list held by the Thread object.
968 */
969 dvmAddToMonitorList(self, obj, false);
970#endif
971}
972
973/*
974 * Implements monitorexit for "synchronized" stuff.
975 *
976 * On failure, throws an exception and returns "false".
977 */
978bool dvmUnlockObject(Thread* self, Object *obj)
979{
Carl Shapiro94338aa2009-12-21 11:42:59 -0800980 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800981
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800982 assert(self != NULL);
983 assert(self->status == THREAD_RUNNING);
984 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800985 /*
986 * Cache the lock word as its value can change while we are
987 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800988 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800989 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800990 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
991 /*
992 * The lock is thin. We must ensure that the lock is owned
993 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800994 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800995 if (LW_LOCK_OWNER(thin) == self->threadId) {
996 /*
997 * We are the lock owner. It is safe to update the lock
998 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800999 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001000 if (LW_LOCK_COUNT(thin) == 0) {
1001 /*
1002 * The lock was not recursively acquired, the common
1003 * case. Unlock by clearing all bits except for the
1004 * hash state.
1005 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001006 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001007 } else {
1008 /*
1009 * The object was recursively acquired. Decrement the
1010 * lock recursion count field.
1011 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001012 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001013 }
1014 } else {
1015 /*
1016 * We do not own the lock. The JVM spec requires that we
1017 * throw an exception in this case.
1018 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001019 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001020 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001021 return false;
1022 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001023 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001024 /*
1025 * The lock is fat. We must check to see if unlockMonitor has
1026 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001027 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001028 assert(LW_MONITOR(obj->lock) != NULL);
1029 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001030 /*
1031 * An exception has been raised. Do not fall through.
1032 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001033 return false;
1034 }
1035 }
1036
1037#ifdef WITH_MONITOR_TRACKING
1038 /*
1039 * Remove the object from the Thread's list.
1040 */
1041 dvmRemoveFromMonitorList(self, obj);
1042#endif
1043
1044 return true;
1045}
1046
1047/*
1048 * Object.wait(). Also called for class init.
1049 */
1050void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1051 bool interruptShouldThrow)
1052{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001053 Monitor* mon = LW_MONITOR(obj->lock);
1054 u4 hashState;
1055 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001056
1057 /* If the lock is still thin, we need to fatten it.
1058 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001059 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001060 /* Make sure that 'self' holds the lock.
1061 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001062 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001063 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1064 "object not locked by thread before wait()");
1065 return;
1066 }
1067
1068 /* This thread holds the lock. We need to fatten the lock
1069 * so 'self' can block on it. Don't update the object lock
1070 * field yet, because 'self' needs to acquire the lock before
1071 * any other thread gets a chance.
1072 */
1073 mon = dvmCreateMonitor(obj);
1074
1075 /* 'self' has actually locked the object one or more times;
1076 * make sure that the monitor reflects this.
1077 */
1078 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001079 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001080 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1081 self->threadId, (uint)&obj->lock, mon->lockCount);
1082
Andy McFadden581bed72009-10-15 11:24:54 -07001083
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001084 /* Make the monitor public now that it's in the right state.
1085 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001086 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
1087 thin |= (u4)mon | LW_SHAPE_FAT;
Andy McFadden581bed72009-10-15 11:24:54 -07001088 MEM_BARRIER();
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001089 obj->lock = thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001090 }
1091
1092 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1093}
1094
1095/*
1096 * Object.notify().
1097 */
1098void dvmObjectNotify(Thread* self, Object *obj)
1099{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001100 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001101
1102 /* If the lock is still thin, there aren't any waiters;
1103 * waiting on an object forces lock fattening.
1104 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001105 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001106 /* Make sure that 'self' holds the lock.
1107 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001108 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001109 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1110 "object not locked by thread before notify()");
1111 return;
1112 }
1113
1114 /* no-op; there are no waiters to notify.
1115 */
1116 } else {
1117 /* It's a fat lock.
1118 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001119 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001120 }
1121}
1122
1123/*
1124 * Object.notifyAll().
1125 */
1126void dvmObjectNotifyAll(Thread* self, Object *obj)
1127{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001128 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001129
1130 /* If the lock is still thin, there aren't any waiters;
1131 * waiting on an object forces lock fattening.
1132 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001133 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001134 /* Make sure that 'self' holds the lock.
1135 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001136 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001137 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1138 "object not locked by thread before notifyAll()");
1139 return;
1140 }
1141
1142 /* no-op; there are no waiters to notify.
1143 */
1144 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001145 /* It's a fat lock.
1146 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001147 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001148 }
1149}
1150
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001151/*
1152 * This implements java.lang.Thread.sleep(long msec, int nsec).
1153 *
1154 * The sleep is interruptible by other threads, which means we can't just
1155 * plop into an OS sleep call. (We probably could if we wanted to send
1156 * signals around and rely on EINTR, but that's inefficient and relies
1157 * on native code respecting our signal mask.)
1158 *
1159 * We have to do all of this stuff for Object.wait() as well, so it's
1160 * easiest to just sleep on a private Monitor.
1161 *
1162 * It appears that we want sleep(0,0) to go through the motions of sleeping
1163 * for a very short duration, rather than just returning.
1164 */
1165void dvmThreadSleep(u8 msec, u4 nsec)
1166{
1167 Thread* self = dvmThreadSelf();
1168 Monitor* mon = gDvm.threadSleepMon;
1169
1170 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1171 if (msec == 0 && nsec == 0)
1172 nsec++;
1173
1174 lockMonitor(self, mon);
1175 waitMonitor(self, mon, msec, nsec, true);
1176 unlockMonitor(self, mon);
1177}
1178
1179/*
1180 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001181 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001182void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001183{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001184 assert(thread != NULL);
1185
1186 pthread_mutex_lock(&thread->waitMutex);
1187
1188 /*
1189 * If the interrupted flag is already set no additional action is
1190 * required.
1191 */
1192 if (thread->interrupted == true) {
1193 pthread_mutex_unlock(&thread->waitMutex);
1194 return;
1195 }
1196
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001197 /*
1198 * Raise the "interrupted" flag. This will cause it to bail early out
1199 * of the next wait() attempt, if it's not currently waiting on
1200 * something.
1201 */
1202 thread->interrupted = true;
1203 MEM_BARRIER();
1204
1205 /*
1206 * Is the thread waiting?
1207 *
1208 * Note that fat vs. thin doesn't matter here; waitMonitor
1209 * is only set when a thread actually waits on a monitor,
1210 * which implies that the monitor has already been fattened.
1211 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001212 if (thread->waitMonitor != NULL) {
1213 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001214 }
1215
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001216 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001217}
1218
Carl Shapiro30aa9972010-01-13 22:07:50 -08001219#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001220u4 dvmIdentityHashCode(Object *obj)
1221{
1222 return (u4)obj;
1223}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001224#else
1225static size_t arrayElementWidth(const ArrayObject *array)
1226{
1227 const char *descriptor;
1228
1229 if (dvmIsObjectArray(array)) {
1230 return sizeof(Object *);
1231 } else {
1232 descriptor = array->obj.clazz->descriptor;
1233 switch (descriptor[1]) {
1234 case 'B': return 1; /* byte */
1235 case 'C': return 2; /* char */
1236 case 'D': return 8; /* double */
1237 case 'F': return 4; /* float */
1238 case 'I': return 4; /* int */
1239 case 'J': return 8; /* long */
1240 case 'S': return 2; /* short */
1241 case 'Z': return 1; /* boolean */
1242 }
1243 }
1244 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1245 dvmDumpThread(dvmThreadSelf(), false);
1246 dvmAbort();
1247 return 0; /* Quiet the compiler. */
1248}
1249
1250static size_t arrayObjectLength(const ArrayObject *array)
1251{
1252 size_t length;
1253
1254 length = offsetof(ArrayObject, contents);
1255 length += array->length * arrayElementWidth(array);
1256 return length;
1257}
1258
1259/*
1260 * Returns the identity hash code of the given object.
1261 */
1262u4 dvmIdentityHashCode(Object *obj)
1263{
1264 Thread *self, *thread;
1265 volatile u4 *lw;
1266 size_t length;
1267 u4 lock, owner, hashState;
1268
1269 if (obj == NULL) {
1270 /*
1271 * Null is defined to have an identity hash code of 0.
1272 */
1273 return 0;
1274 }
1275 lw = &obj->lock;
1276retry:
1277 hashState = LW_HASH_STATE(*lw);
1278 if (hashState == LW_HASH_STATE_HASHED) {
1279 /*
1280 * The object has been hashed but has not had its hash code
1281 * relocated by the garbage collector. Use the raw object
1282 * address.
1283 */
1284 return (u4)obj >> 3;
1285 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1286 /*
1287 * The object has been hashed and its hash code has been
1288 * relocated by the collector. Use the value of the naturally
1289 * aligned word following the instance data.
1290 */
1291 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1292 length = arrayObjectLength((ArrayObject *)obj);
1293 length = (length + 3) & ~3;
1294 } else {
1295 length = obj->clazz->objectSize;
1296 }
1297 return *(u4 *)(((char *)obj) + length);
1298 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1299 /*
1300 * The object has never been hashed. Change the hash state to
1301 * hashed and use the raw object address.
1302 */
1303 self = dvmThreadSelf();
1304 if (self->threadId == lockOwner(obj)) {
1305 /*
1306 * We already own the lock so we can update the hash state
1307 * directly.
1308 */
1309 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1310 return (u4)obj >> 3;
1311 }
1312 /*
1313 * We do not own the lock. Try acquiring the lock. Should
1314 * this fail, we must suspend the owning thread.
1315 */
1316 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1317 /*
1318 * If the lock is thin assume it is unowned. We simulate
1319 * an acquire, update, and release with a single CAS.
1320 */
1321 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1322 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1323 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1324 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1325 (int32_t)lock)) {
1326 /*
1327 * A new lockword has been installed with a hash state
1328 * of hashed. Use the raw object address.
1329 */
1330 return (u4)obj >> 3;
1331 }
1332 } else {
1333 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1334 /*
1335 * The monitor lock has been acquired. Change the
1336 * hash state to hashed and use the raw object
1337 * address.
1338 */
1339 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1340 unlockMonitor(self, LW_MONITOR(*lw));
1341 return (u4)obj >> 3;
1342 }
1343 }
1344 /*
1345 * At this point we have failed to acquire the lock. We must
1346 * identify the owning thread and suspend it.
1347 */
1348 dvmLockThreadList(self);
1349 /*
1350 * Cache the lock word as its value can change between
1351 * determining its shape and retrieving its owner.
1352 */
1353 lock = *lw;
1354 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1355 /*
1356 * Find the thread with the corresponding thread id.
1357 */
1358 owner = LW_LOCK_OWNER(lock);
1359 assert(owner != self->threadId);
1360 /*
1361 * If the lock has no owner do not bother scanning the
1362 * thread list and fall through to the failure handler.
1363 */
1364 thread = owner ? gDvm.threadList : NULL;
1365 while (thread != NULL) {
1366 if (thread->threadId == owner) {
1367 break;
1368 }
1369 thread = thread->next;
1370 }
1371 } else {
1372 thread = LW_MONITOR(lock)->owner;
1373 }
1374 /*
1375 * If thread is NULL the object has been released since the
1376 * thread list lock was acquired. Try again.
1377 */
1378 if (thread == NULL) {
1379 dvmUnlockThreadList();
1380 goto retry;
1381 }
1382 /*
1383 * Wait for the owning thread to suspend.
1384 */
1385 dvmSuspendThread(thread);
1386 if (dvmHoldsLock(thread, obj)) {
1387 /*
1388 * The owning thread has been suspended. We can safely
1389 * change the hash state to hashed.
1390 */
1391 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1392 dvmResumeThread(thread);
1393 dvmUnlockThreadList();
1394 return (u4)obj >> 3;
1395 }
1396 /*
1397 * The wrong thread has been suspended. Try again.
1398 */
1399 dvmResumeThread(thread);
1400 dvmUnlockThreadList();
1401 goto retry;
1402 }
1403 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1404 dvmDumpThread(dvmThreadSelf(), false);
1405 dvmAbort();
1406 return 0; /* Quiet the compiler. */
1407}
1408#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001409
1410#ifdef WITH_DEADLOCK_PREDICTION
1411/*
1412 * ===========================================================================
1413 * Deadlock prediction
1414 * ===========================================================================
1415 */
1416/*
1417The idea is to predict the possibility of deadlock by recording the order
1418in which monitors are acquired. If we see an attempt to acquire a lock
1419out of order, we can identify the locks and offending code.
1420
1421To make this work, we need to keep track of the locks held by each thread,
1422and create history trees for each lock. When a thread tries to acquire
1423a new lock, we walk through the "history children" of the lock, looking
1424for a match with locks the thread already holds. If we find a match,
1425it means the thread has made a request that could result in a deadlock.
1426
1427To support recursive locks, we always allow re-locking a currently-held
1428lock, and maintain a recursion depth count.
1429
1430An ASCII-art example, where letters represent Objects:
1431
1432 A
1433 /|\
1434 / | \
1435 B | D
1436 \ |
1437 \|
1438 C
1439
1440The above is the tree we'd have after handling Object synchronization
1441sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1442a child of B. (The lines represent pointers between parent and child.
1443Every node can have multiple parents and multiple children.)
1444
1445If we hold AC, and want to lock B, we recursively search through B's
1446children to see if A or C appears. It does, so we reject the attempt.
1447(A straightforward way to implement it: add a link from C to B, then
1448determine whether the graph starting at B contains a cycle.)
1449
1450If we hold AC and want to lock D, we would succeed, creating a new link
1451from C to D.
1452
1453The lock history and a stack trace is attached to the Object's Monitor
1454struct, which means we need to fatten every Object we lock (thin locking
1455is effectively disabled). If we don't need the stack trace we can
1456avoid fattening the leaf nodes, only fattening objects that need to hold
1457history trees.
1458
1459Updates to Monitor structs are only allowed for the thread that holds
1460the Monitor, so we actually do most of our deadlock prediction work after
1461the lock has been acquired.
1462
1463When an object with a monitor is GCed, we need to remove it from the
1464history trees. There are two basic approaches:
1465 (1) For through the entire set of known monitors, search all child
1466 lists for the object in question. This is rather slow, resulting
1467 in GC passes that take upwards of 10 seconds to complete.
1468 (2) Maintain "parent" pointers in each node. Remove the entries as
1469 required. This requires additional storage and maintenance for
1470 every operation, but is significantly faster at GC time.
1471For each GCed object, we merge all of the object's children into each of
1472the object's parents.
1473*/
1474
1475#if !defined(WITH_MONITOR_TRACKING)
1476# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1477#endif
1478
1479/*
1480 * Clear out the contents of an ExpandingObjectList, freeing any
1481 * dynamic allocations.
1482 */
1483static void expandObjClear(ExpandingObjectList* pList)
1484{
1485 if (pList->list != NULL) {
1486 free(pList->list);
1487 pList->list = NULL;
1488 }
1489 pList->alloc = pList->count = 0;
1490}
1491
1492/*
1493 * Get the number of objects currently stored in the list.
1494 */
1495static inline int expandBufGetCount(const ExpandingObjectList* pList)
1496{
1497 return pList->count;
1498}
1499
1500/*
1501 * Get the Nth entry from the list.
1502 */
1503static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1504 int i)
1505{
1506 return pList->list[i];
1507}
1508
1509/*
1510 * Add a new entry to the list.
1511 *
1512 * We don't check for or try to enforce uniqueness. It's expected that
1513 * the higher-level code does this for us.
1514 */
1515static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1516{
1517 if (pList->count == pList->alloc) {
1518 /* time to expand */
1519 Object** newList;
1520
1521 if (pList->alloc == 0)
1522 pList->alloc = 4;
1523 else
1524 pList->alloc *= 2;
1525 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1526 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1527 if (newList == NULL) {
1528 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1529 dvmAbort();
1530 }
1531 pList->list = newList;
1532 }
1533
1534 pList->list[pList->count++] = obj;
1535}
1536
1537/*
1538 * Returns "true" if the element was successfully removed.
1539 */
1540static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1541{
1542 int i;
1543
1544 for (i = pList->count-1; i >= 0; i--) {
1545 if (pList->list[i] == obj)
1546 break;
1547 }
1548 if (i < 0)
1549 return false;
1550
1551 if (i != pList->count-1) {
1552 /*
1553 * The order of elements is not important, so we just copy the
1554 * last entry into the new slot.
1555 */
1556 //memmove(&pList->list[i], &pList->list[i+1],
1557 // (pList->count-1 - i) * sizeof(pList->list[0]));
1558 pList->list[i] = pList->list[pList->count-1];
1559 }
1560
1561 pList->count--;
1562 pList->list[pList->count] = (Object*) 0xdecadead;
1563 return true;
1564}
1565
1566/*
1567 * Returns "true" if "obj" appears in the list.
1568 */
1569static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1570{
1571 int i;
1572
1573 for (i = 0; i < pList->count; i++) {
1574 if (pList->list[i] == obj)
1575 return true;
1576 }
1577 return false;
1578}
1579
1580/*
1581 * Print the list contents to stdout. For debugging.
1582 */
1583static void expandObjDump(const ExpandingObjectList* pList)
1584{
1585 int i;
1586 for (i = 0; i < pList->count; i++)
1587 printf(" %p", pList->list[i]);
1588}
1589
1590/*
1591 * Check for duplicate entries. Returns the index of the first instance
1592 * of the duplicated value, or -1 if no duplicates were found.
1593 */
1594static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1595{
1596 int i, j;
1597 for (i = 0; i < pList->count-1; i++) {
1598 for (j = i + 1; j < pList->count; j++) {
1599 if (pList->list[i] == pList->list[j]) {
1600 return i;
1601 }
1602 }
1603 }
1604
1605 return -1;
1606}
1607
1608
1609/*
1610 * Determine whether "child" appears in the list of objects associated
1611 * with the Monitor in "parent". If "parent" is a thin lock, we return
1612 * false immediately.
1613 */
1614static bool objectInChildList(const Object* parent, Object* child)
1615{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001616 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001617 if (!IS_LOCK_FAT(&lock)) {
1618 //LOGI("on thin\n");
1619 return false;
1620 }
1621
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001622 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001623}
1624
1625/*
1626 * Print the child list.
1627 */
1628static void dumpKids(Object* parent)
1629{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001630 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001631
1632 printf("Children of %p:", parent);
1633 expandObjDump(&mon->historyChildren);
1634 printf("\n");
1635}
1636
1637/*
1638 * Add "child" to the list of children in "parent", and add "parent" to
1639 * the list of parents in "child".
1640 */
1641static void linkParentToChild(Object* parent, Object* child)
1642{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001643 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001644 assert(IS_LOCK_FAT(&parent->lock));
1645 assert(IS_LOCK_FAT(&child->lock));
1646 assert(parent != child);
1647 Monitor* mon;
1648
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001649 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001650 assert(!expandObjHas(&mon->historyChildren, child));
1651 expandObjAddEntry(&mon->historyChildren, child);
1652
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001653 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001654 assert(!expandObjHas(&mon->historyParents, parent));
1655 expandObjAddEntry(&mon->historyParents, parent);
1656}
1657
1658
1659/*
1660 * Remove "child" from the list of children in "parent".
1661 */
1662static void unlinkParentFromChild(Object* parent, Object* child)
1663{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001664 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001665 assert(IS_LOCK_FAT(&parent->lock));
1666 assert(IS_LOCK_FAT(&child->lock));
1667 assert(parent != child);
1668 Monitor* mon;
1669
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001670 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001671 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1672 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1673 }
1674 assert(!expandObjHas(&mon->historyChildren, child));
1675 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1676
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001677 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001678 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1679 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1680 }
1681 assert(!expandObjHas(&mon->historyParents, parent));
1682 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1683}
1684
1685
1686/*
1687 * Log the monitors held by the current thread. This is done as part of
1688 * flagging an error.
1689 */
1690static void logHeldMonitors(Thread* self)
1691{
1692 char* name = NULL;
1693
1694 name = dvmGetThreadName(self);
1695 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1696 self->threadId, name);
1697 LOGW("(most-recently-acquired on top):\n");
1698 free(name);
1699
1700 LockedObjectData* lod = self->pLockedObjects;
1701 while (lod != NULL) {
1702 LOGW("--- object %p[%d] (%s)\n",
1703 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1704 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1705
1706 lod = lod->next;
1707 }
1708}
1709
1710/*
1711 * Recursively traverse the object hierarchy starting at "obj". We mark
1712 * ourselves on entry and clear the mark on exit. If we ever encounter
1713 * a marked object, we have a cycle.
1714 *
1715 * Returns "true" if all is well, "false" if we found a cycle.
1716 */
1717static bool traverseTree(Thread* self, const Object* obj)
1718{
1719 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001720 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001721
1722 /*
1723 * Have we been here before?
1724 */
1725 if (mon->historyMark) {
1726 int* rawStackTrace;
1727 int stackDepth;
1728
1729 LOGW("%s\n", kStartBanner);
1730 LOGW("Illegal lock attempt:\n");
1731 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1732
1733 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1734 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1735 free(rawStackTrace);
1736
1737 LOGW(" ");
1738 logHeldMonitors(self);
1739
1740 LOGW(" ");
1741 LOGW("Earlier, the following lock order (from last to first) was\n");
1742 LOGW("established -- stack trace is from first successful lock):\n");
1743 return false;
1744 }
1745 mon->historyMark = true;
1746
1747 /*
1748 * Examine the children. We do NOT hold these locks, so they might
1749 * very well transition from thin to fat or change ownership while
1750 * we work.
1751 *
1752 * NOTE: we rely on the fact that they cannot revert from fat to thin
1753 * while we work. This is currently a safe assumption.
1754 *
1755 * We can safely ignore thin-locked children, because by definition
1756 * they have no history and are leaf nodes. In the current
1757 * implementation we always fatten the locks to provide a place to
1758 * hang the stack trace.
1759 */
1760 ExpandingObjectList* pList = &mon->historyChildren;
1761 int i;
1762 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1763 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001764 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001765 if (!IS_LOCK_FAT(&lock))
1766 continue;
1767 if (!traverseTree(self, child)) {
1768 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1769 dvmLogRawStackTrace(mon->historyRawStackTrace,
1770 mon->historyStackDepth);
1771 mon->historyMark = false;
1772 return false;
1773 }
1774 }
1775
1776 mon->historyMark = false;
1777
1778 return true;
1779}
1780
1781/*
1782 * Update the deadlock prediction tree, based on the current thread
1783 * acquiring "acqObj". This must be called before the object is added to
1784 * the thread's list of held monitors.
1785 *
1786 * If the thread already holds the lock (recursion), or this is a known
1787 * lock configuration, we return without doing anything. Otherwise, we add
1788 * a link from the most-recently-acquired lock in this thread to "acqObj"
1789 * after ensuring that the parent lock is "fat".
1790 *
1791 * This MUST NOT be called while a GC is in progress in another thread,
1792 * because we assume exclusive access to history trees in owned monitors.
1793 */
1794static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1795{
1796 LockedObjectData* lod;
1797 LockedObjectData* mrl;
1798
1799 /*
1800 * Quick check for recursive access.
1801 */
1802 lod = dvmFindInMonitorList(self, acqObj);
1803 if (lod != NULL) {
1804 LOGV("+++ DP: recursive %p\n", acqObj);
1805 return;
1806 }
1807
1808 /*
1809 * Make the newly-acquired object's monitor "fat". In some ways this
1810 * isn't strictly necessary, but we need the GC to tell us when
1811 * "interesting" objects go away, and right now the only way to make
1812 * an object look interesting is to give it a monitor.
1813 *
1814 * This also gives us a place to hang a stack trace.
1815 *
1816 * Our thread holds the lock, so we're allowed to rewrite the lock
1817 * without worrying that something will change out from under us.
1818 */
1819 if (!IS_LOCK_FAT(&acqObj->lock)) {
1820 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001821 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001822 Monitor* newMon = dvmCreateMonitor(acqObj);
1823 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001824 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1825 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1826 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001827 }
1828
1829 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001830 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1831 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001832 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1833 &mon->historyStackDepth);
1834 }
1835
1836 /*
1837 * We need to examine and perhaps modify the most-recently-locked
1838 * monitor. We own that, so there's no risk of another thread
1839 * stepping on us.
1840 *
1841 * Retrieve the most-recently-locked entry from our thread.
1842 */
1843 mrl = self->pLockedObjects;
1844 if (mrl == NULL)
1845 return; /* no other locks held */
1846
1847 /*
1848 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1849 * this without holding the global lock because of our assertion that
1850 * a GC is not running in parallel -- nobody except the GC can
1851 * modify a history list in a Monitor they don't own, and we own "mrl".
1852 * (There might be concurrent *reads*, but no concurrent *writes.)
1853 *
1854 * If we find it, this is a known good configuration, and we're done.
1855 */
1856 if (objectInChildList(mrl->obj, acqObj))
1857 return;
1858
1859 /*
1860 * "mrl" is going to need to have a history tree. If it's currently
1861 * a thin lock, we make it fat now. The thin lock might have a
1862 * nonzero recursive lock count, which we need to carry over.
1863 *
1864 * Our thread holds the lock, so we're allowed to rewrite the lock
1865 * without worrying that something will change out from under us.
1866 */
1867 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1868 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001869 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001870 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1871 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001872 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1873 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1874 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001875 }
1876
1877 /*
1878 * We haven't seen this configuration before. We need to scan down
1879 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1880 * appear. We grab a global lock before traversing or updating the
1881 * history list.
1882 *
1883 * If we find a match for any of our held locks, we know that the lock
1884 * has previously been acquired *after* acqObj, and we throw an error.
1885 *
1886 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1887 * and do a recursive traversal, marking nodes as we cross them. If
1888 * we cross one a second time, we have a cycle and can throw an error.
1889 * (We do the flag-clearing traversal before adding the new link, so
1890 * that we're guaranteed to terminate.)
1891 *
1892 * If "acqObj" is a thin lock, it has no history, and we can create a
1893 * link to it without additional checks. [ We now guarantee that it's
1894 * always fat. ]
1895 */
1896 bool failed = false;
1897 dvmLockMutex(&gDvm.deadlockHistoryLock);
1898 linkParentToChild(mrl->obj, acqObj);
1899 if (!traverseTree(self, acqObj)) {
1900 LOGW("%s\n", kEndBanner);
1901 failed = true;
1902
1903 /* remove the entry so we're still okay when in "warning" mode */
1904 unlinkParentFromChild(mrl->obj, acqObj);
1905 }
1906 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1907
1908 if (failed) {
1909 switch (gDvm.deadlockPredictMode) {
1910 case kDPErr:
1911 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1912 break;
1913 case kDPAbort:
1914 LOGE("Aborting due to potential deadlock\n");
1915 dvmAbort();
1916 break;
1917 default:
1918 /* warn only */
1919 break;
1920 }
1921 }
1922}
1923
1924/*
1925 * We're removing "child" from existence. We want to pull all of
1926 * child's children into "parent", filtering out duplicates. This is
1927 * called during the GC.
1928 *
1929 * This does not modify "child", which might have multiple parents.
1930 */
1931static void mergeChildren(Object* parent, const Object* child)
1932{
1933 Monitor* mon;
1934 int i;
1935
1936 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001937 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001938 ExpandingObjectList* pList = &mon->historyChildren;
1939
1940 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1941 Object* grandChild = expandBufGetEntry(pList, i);
1942
1943 if (!objectInChildList(parent, grandChild)) {
1944 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1945 linkParentToChild(parent, grandChild);
1946 } else {
1947 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1948 }
1949 }
1950}
1951
1952/*
1953 * An object with a fat lock is being collected during a GC pass. We
1954 * want to remove it from any lock history trees that it is a part of.
1955 *
1956 * This may require updating the history trees in several monitors. The
1957 * monitor semantics guarantee that no other thread will be accessing
1958 * the history trees at the same time.
1959 */
1960static void removeCollectedObject(Object* obj)
1961{
1962 Monitor* mon;
1963
1964 LOGVV("+++ collecting %p\n", obj);
1965
1966#if 0
1967 /*
1968 * We're currently running through the entire set of known monitors.
1969 * This can be somewhat slow. We may want to keep lists of parents
1970 * in each child to speed up GC.
1971 */
1972 mon = gDvm.monitorList;
1973 while (mon != NULL) {
1974 Object* parent = mon->obj;
1975 if (parent != NULL) { /* value nulled for deleted entries */
1976 if (objectInChildList(parent, obj)) {
1977 LOGVV("removing child %p from parent %p\n", obj, parent);
1978 unlinkParentFromChild(parent, obj);
1979 mergeChildren(parent, obj);
1980 }
1981 }
1982 mon = mon->next;
1983 }
1984#endif
1985
1986 /*
1987 * For every parent of this object:
1988 * - merge all of our children into the parent's child list (creates
1989 * a two-way link between parent and child)
1990 * - remove ourselves from the parent's child list
1991 */
1992 ExpandingObjectList* pList;
1993 int i;
1994
1995 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001996 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001997 pList = &mon->historyParents;
1998 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1999 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002000 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002001
2002 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2003 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2004 }
2005 assert(!expandObjHas(&parentMon->historyChildren, obj));
2006
2007 mergeChildren(parent, obj);
2008 }
2009
2010 /*
2011 * For every child of this object:
2012 * - remove ourselves from the child's parent list
2013 */
2014 pList = &mon->historyChildren;
2015 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2016 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002017 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002018
2019 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2020 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2021 }
2022 assert(!expandObjHas(&childMon->historyParents, obj));
2023 }
2024}
2025
2026#endif /*WITH_DEADLOCK_PREDICTION*/