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