blob: acd916cb82c5134ade91264b994c69cba52d56d8 [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);
318 assert(*mon != NULL);
319 assert(isUnmarkedObject != NULL);
320 prev = &handle;
321 prev->next = curr = *mon;
322 while (curr != NULL) {
323 obj = curr->obj;
324 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
325 prev->next = curr = curr->next;
326 freeObjectMonitor(obj);
327 } else {
328 prev = curr;
329 curr = curr->next;
330 }
331 }
332 *mon = handle.next;
333}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800334
335/*
336 * Lock a monitor.
337 */
338static void lockMonitor(Thread* self, Monitor* mon)
339{
340 int cc;
341
342 if (mon->owner == self) {
343 mon->lockCount++;
344 } else {
345 ThreadStatus oldStatus;
346
347 if (pthread_mutex_trylock(&mon->lock) != 0) {
348 /* mutex is locked, switch to wait status and sleep on it */
349 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
350 cc = pthread_mutex_lock(&mon->lock);
351 assert(cc == 0);
352 dvmChangeStatus(self, oldStatus);
353 }
354
355 mon->owner = self;
356 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800357 }
358}
359
360/*
361 * Try to lock a monitor.
362 *
363 * Returns "true" on success.
364 */
365static bool tryLockMonitor(Thread* self, Monitor* mon)
366{
367 int cc;
368
369 if (mon->owner == self) {
370 mon->lockCount++;
371 return true;
372 } else {
373 cc = pthread_mutex_trylock(&mon->lock);
374 if (cc == 0) {
375 mon->owner = self;
376 assert(mon->lockCount == 0);
377 return true;
378 } else {
379 return false;
380 }
381 }
382}
383
384
385/*
386 * Unlock a monitor.
387 *
388 * Returns true if the unlock succeeded.
389 * If the unlock failed, an exception will be pending.
390 */
391static bool unlockMonitor(Thread* self, Monitor* mon)
392{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800393 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800394 assert(mon != NULL); // can this happen?
395
396 if (mon->owner == self) {
397 /*
398 * We own the monitor, so nobody else can be in here.
399 */
400 if (mon->lockCount == 0) {
401 int cc;
402 mon->owner = NULL;
403 cc = pthread_mutex_unlock(&mon->lock);
404 assert(cc == 0);
405 } else {
406 mon->lockCount--;
407 }
408 } else {
409 /*
410 * We don't own this, so we're not allowed to unlock it.
411 * The JNI spec says that we should throw IllegalMonitorStateException
412 * in this case.
413 */
414 if (mon->owner == NULL) {
415 //LOGW("Unlock fat %p: not owned\n", mon->obj);
416 } else {
417 //LOGW("Unlock fat %p: id %d vs %d\n",
418 // mon->obj, mon->owner->threadId, self->threadId);
419 }
420 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
421 "unlock of unowned monitor");
422 return false;
423 }
424 return true;
425}
426
427/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800428 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800429 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800430 */
431static int waitSetCheck(Monitor *mon)
432{
433 Thread *fast, *slow;
434 size_t n;
435
436 assert(mon != NULL);
437 fast = slow = mon->waitSet;
438 n = 0;
439 for (;;) {
440 if (fast == NULL) return 0;
441 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800442 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800443 n += 2;
444 fast = fast->waitNext->waitNext;
445 slow = slow->waitNext;
446 }
447}
448
449/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800450 * Links a thread into a monitor's wait set. The monitor lock must be
451 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800452 */
453static void waitSetAppend(Monitor *mon, Thread *thread)
454{
455 Thread *elt;
456
457 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800458 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800459 assert(thread != NULL);
460 assert(thread->waitNext == NULL);
461 assert(waitSetCheck(mon) == 0);
462 if (mon->waitSet == NULL) {
463 mon->waitSet = thread;
464 return;
465 }
466 elt = mon->waitSet;
467 while (elt->waitNext != NULL) {
468 elt = elt->waitNext;
469 }
470 elt->waitNext = thread;
471}
472
473/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800474 * Unlinks a thread from a monitor's wait set. The monitor lock must
475 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800476 */
477static void waitSetRemove(Monitor *mon, Thread *thread)
478{
479 Thread *elt;
480
481 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800482 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800483 assert(thread != NULL);
484 assert(waitSetCheck(mon) == 0);
485 if (mon->waitSet == NULL) {
486 return;
487 }
488 if (mon->waitSet == thread) {
489 mon->waitSet = thread->waitNext;
490 thread->waitNext = NULL;
491 return;
492 }
493 elt = mon->waitSet;
494 while (elt->waitNext != NULL) {
495 if (elt->waitNext == thread) {
496 elt->waitNext = thread->waitNext;
497 thread->waitNext = NULL;
498 return;
499 }
500 elt = elt->waitNext;
501 }
502}
503
Carl Shapirob4539192010-01-04 16:50:00 -0800504/*
505 * Converts the given relative waiting time into an absolute time.
506 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800507static void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
508{
509 s8 endSec;
510
511#ifdef HAVE_TIMEDWAIT_MONOTONIC
512 clock_gettime(CLOCK_MONOTONIC, ts);
513#else
514 {
515 struct timeval tv;
516 gettimeofday(&tv, NULL);
517 ts->tv_sec = tv.tv_sec;
518 ts->tv_nsec = tv.tv_usec * 1000;
519 }
520#endif
521 endSec = ts->tv_sec + msec / 1000;
522 if (endSec >= 0x7fffffff) {
523 LOGV("NOTE: end time exceeds epoch\n");
524 endSec = 0x7ffffffe;
525 }
526 ts->tv_sec = endSec;
527 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
528
529 /* catch rollover */
530 if (ts->tv_nsec >= 1000000000L) {
531 ts->tv_sec++;
532 ts->tv_nsec -= 1000000000L;
533 }
534}
535
536/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800537 * Wait on a monitor until timeout, interrupt, or notification. Used for
538 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
539 *
540 * If another thread calls Thread.interrupt(), we throw InterruptedException
541 * and return immediately if one of the following are true:
542 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
543 * - blocked in join(), join(long), or join(long, int) methods of Thread
544 * - blocked in sleep(long), or sleep(long, int) methods of Thread
545 * Otherwise, we set the "interrupted" flag.
546 *
547 * Checks to make sure that "nsec" is in the range 0-999999
548 * (i.e. fractions of a millisecond) and throws the appropriate
549 * exception if it isn't.
550 *
551 * The spec allows "spurious wakeups", and recommends that all code using
552 * Object.wait() do so in a loop. This appears to derive from concerns
553 * about pthread_cond_wait() on multiprocessor systems. Some commentary
554 * on the web casts doubt on whether these can/should occur.
555 *
556 * Since we're allowed to wake up "early", we clamp extremely long durations
557 * to return at the end of the 32-bit time epoch.
558 */
559static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
560 bool interruptShouldThrow)
561{
562 struct timespec ts;
563 bool wasInterrupted = false;
564 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800565 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800566
Carl Shapiro71938022009-12-22 13:49:53 -0800567 assert(self != NULL);
568 assert(mon != NULL);
569
Carl Shapiro94338aa2009-12-21 11:42:59 -0800570 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800571 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800572 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
573 "object not locked by thread before wait()");
574 return;
575 }
576
577 /*
578 * Enforce the timeout range.
579 */
580 if (msec < 0 || nsec < 0 || nsec > 999999) {
581 dvmThrowException("Ljava/lang/IllegalArgumentException;",
582 "timeout arguments out of range");
583 return;
584 }
585
586 /*
587 * Compute absolute wakeup time, if necessary.
588 */
589 if (msec == 0 && nsec == 0) {
590 timed = false;
591 } else {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800592 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800593 timed = true;
594 }
595
596 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800597 * Add ourselves to the set of threads waiting on this monitor, and
598 * release our hold. We need to let it go even if we're a few levels
599 * deep in a recursive lock, and we need to restore that later.
600 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800601 * We append to the wait set ahead of clearing the count and owner
602 * fields so the subroutine can check that the calling thread owns
603 * the monitor. Aside from that, the order of member updates is
604 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800605 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800606 waitSetAppend(mon, self);
607 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800608 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800609 mon->owner = NULL;
610
611 /*
612 * Update thread status. If the GC wakes up, it'll ignore us, knowing
613 * that we won't touch any references in this state, and we'll check
614 * our suspend mode before we transition out.
615 */
616 if (timed)
617 dvmChangeStatus(self, THREAD_TIMED_WAIT);
618 else
619 dvmChangeStatus(self, THREAD_WAIT);
620
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800621 ret = pthread_mutex_lock(&self->waitMutex);
622 assert(ret == 0);
623
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800624 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800625 * Set waitMonitor to the monitor object we will be waiting on.
626 * When waitMonitor is non-NULL a notifying or interrupting thread
627 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800628 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800629 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800630 self->waitMonitor = mon;
631
632 /*
633 * Handle the case where the thread was interrupted before we called
634 * wait().
635 */
636 if (self->interrupted) {
637 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800638 self->waitMonitor = NULL;
639 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800640 goto done;
641 }
642
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800643 /*
644 * Release the monitor lock and wait for a notification or
645 * a timeout to occur.
646 */
647 pthread_mutex_unlock(&mon->lock);
648
649 if (!timed) {
650 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
651 assert(ret == 0);
652 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800653#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800654 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800655#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800656 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800657#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800658 assert(ret == 0 || ret == ETIMEDOUT);
659 }
660 if (self->interrupted) {
661 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800662 }
663
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800664 self->interrupted = false;
665 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800666
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800667 pthread_mutex_unlock(&self->waitMutex);
668
Carl Shapiro30aa9972010-01-13 22:07:50 -0800669 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800670 lockMonitor(self, mon);
671
Carl Shapiro142ef272010-01-25 12:51:31 -0800672done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800673 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800674 * We remove our thread from wait set after restoring the count
675 * and owner fields so the subroutine can check that the calling
676 * thread owns the monitor. Aside from that, the order of member
677 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800678 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800679 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800680 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800681 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800682
683 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
684 dvmChangeStatus(self, THREAD_RUNNING);
685
686 if (wasInterrupted) {
687 /*
688 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800689 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800690 *
691 * The doc sayeth: "The interrupted status of the current thread is
692 * cleared when this exception is thrown."
693 */
694 self->interrupted = false;
695 if (interruptShouldThrow)
696 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
697 }
698}
699
700/*
701 * Notify one thread waiting on this monitor.
702 */
703static void notifyMonitor(Thread* self, Monitor* mon)
704{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800705 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800706
Carl Shapiro71938022009-12-22 13:49:53 -0800707 assert(self != NULL);
708 assert(mon != NULL);
709
Carl Shapiro94338aa2009-12-21 11:42:59 -0800710 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800711 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800712 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
713 "object not locked by thread before notify()");
714 return;
715 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800716 /* Signal the first waiting thread in the wait set. */
717 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800718 thread = mon->waitSet;
719 mon->waitSet = thread->waitNext;
720 thread->waitNext = NULL;
721 pthread_mutex_lock(&thread->waitMutex);
722 /* Check to see if the thread is still waiting. */
723 if (thread->waitMonitor != NULL) {
724 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800725 pthread_mutex_unlock(&thread->waitMutex);
726 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800727 }
728 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800729 }
730}
731
732/*
733 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800734 */
735static void notifyAllMonitor(Thread* self, Monitor* mon)
736{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800737 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800738
Carl Shapiro71938022009-12-22 13:49:53 -0800739 assert(self != NULL);
740 assert(mon != NULL);
741
Carl Shapiro94338aa2009-12-21 11:42:59 -0800742 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800743 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800744 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
745 "object not locked by thread before notifyAll()");
746 return;
747 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800748 /* Signal all threads in the wait set. */
749 while (mon->waitSet != NULL) {
750 thread = mon->waitSet;
751 mon->waitSet = thread->waitNext;
752 thread->waitNext = NULL;
753 pthread_mutex_lock(&thread->waitMutex);
754 /* Check to see if the thread is still waiting. */
755 if (thread->waitMonitor != NULL) {
756 pthread_cond_signal(&thread->waitCond);
757 }
758 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800759 }
760}
761
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800762/*
763 * Implements monitorenter for "synchronized" stuff.
764 *
765 * This does not fail or throw an exception (unless deadlock prediction
766 * is enabled and set to "err" mode).
767 */
768void dvmLockObject(Thread* self, Object *obj)
769{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800770 volatile u4 *thinp = &obj->lock;
771 u4 hashState;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800772 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800773 u4 threadId = self->threadId;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800774 Monitor *mon;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800775
776 /* First, try to grab the lock as if it's thin;
777 * this is the common case and will usually succeed.
778 */
Carl Shapiro30aa9972010-01-13 22:07:50 -0800779 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800780 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800781 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800782 if (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800783 hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800784 (int32_t)thin)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800785 /* The lock is either a thin lock held by someone (possibly 'self'),
786 * or a fat lock.
787 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800788 if (LW_LOCK_OWNER(*thinp) == threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800789 /* 'self' is already holding the thin lock; we can just
790 * bump the count. Atomic operations are not necessary
791 * because only the thread holding the lock is allowed
792 * to modify the Lock field.
793 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800794 *thinp += 1 << LW_LOCK_COUNT_SHIFT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800795 } else {
796 /* If this is a thin lock we need to spin on it, if it's fat
797 * we need to acquire the monitor.
798 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800799 if (LW_SHAPE(*thinp) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800800 ThreadStatus oldStatus;
801 static const unsigned long maxSleepDelay = 1 * 1024 * 1024;
802 unsigned long sleepDelay;
803
804 LOG_THIN("(%d) spin on lock 0x%08x: 0x%08x (0x%08x) 0x%08x\n",
805 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800806 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800807
808 /* The lock is still thin, but some other thread is
809 * holding it. Let the VM know that we're about
810 * to wait on another thread.
811 */
812 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
813
814 /* Spin until the other thread lets go.
815 */
816 sleepDelay = 0;
817 do {
818 /* In addition to looking for an unlock,
819 * we need to watch out for some other thread
820 * fattening the lock behind our back.
821 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800822 while (LW_LOCK_OWNER(*thinp) != 0) {
823 if (LW_SHAPE(*thinp) == LW_SHAPE_FAT) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800824 /* The lock has been fattened already.
825 */
826 LOG_THIN("(%d) lock 0x%08x surprise-fattened\n",
827 threadId, (uint)&obj->lock);
828 dvmChangeStatus(self, oldStatus);
829 goto fat_lock;
830 }
831
832 if (sleepDelay == 0) {
833 sched_yield();
834 sleepDelay = 1 * 1000;
835 } else {
836 usleep(sleepDelay);
837 if (sleepDelay < maxSleepDelay / 2) {
838 sleepDelay *= 2;
839 }
840 }
841 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800842 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800843 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800844 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800845 } while (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800846 (int32_t)hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800847 (int32_t)thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800848 LOG_THIN("(%d) spin on lock done 0x%08x: "
849 "0x%08x (0x%08x) 0x%08x\n",
850 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800851 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800852
853 /* We've got the thin lock; let the VM know that we're
854 * done waiting.
855 */
856 dvmChangeStatus(self, oldStatus);
857
858 /* Fatten the lock. Note this relinquishes ownership.
859 * We could also create the monitor in an "owned" state
860 * to avoid "re-locking" it in fat_lock.
861 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800862 mon = dvmCreateMonitor(obj);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800863 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
864 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800865 LOG_THIN("(%d) lock 0x%08x fattened\n",
866 threadId, (uint)&obj->lock);
867
868 /* Fall through to acquire the newly fat lock.
869 */
870 }
871
872 /* The lock is already fat, which means
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800873 * that obj->lock is a regular (Monitor *).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800874 */
875 fat_lock:
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800876 assert(LW_MONITOR(obj->lock) != NULL);
877 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800878 }
879 }
880 // else, the lock was acquired with the ATOMIC_CMP_SWAP().
881
882#ifdef WITH_DEADLOCK_PREDICTION
883 /*
884 * See if we were allowed to grab the lock at this time. We do it
885 * *after* acquiring the lock, rather than before, so that we can
886 * freely update the Monitor struct. This seems counter-intuitive,
887 * but our goal is deadlock *prediction* not deadlock *prevention*.
888 * (If we actually deadlock, the situation is easy to diagnose from
889 * a thread dump, so there's no point making a special effort to do
890 * the checks before the lock is held.)
891 *
892 * This needs to happen before we add the object to the thread's
893 * monitor list, so we can tell the difference between first-lock and
894 * re-lock.
895 *
896 * It's also important that we do this while in THREAD_RUNNING, so
897 * that we don't interfere with cleanup operations in the GC.
898 */
899 if (gDvm.deadlockPredictMode != kDPOff) {
900 if (self->status != THREAD_RUNNING) {
901 LOGE("Bad thread status (%d) in DP\n", self->status);
902 dvmDumpThread(self, false);
903 dvmAbort();
904 }
905 assert(!dvmCheckException(self));
906 updateDeadlockPrediction(self, obj);
907 if (dvmCheckException(self)) {
908 /*
909 * If we're throwing an exception here, we need to free the
910 * lock. We add the object to the thread's monitor list so the
911 * "unlock" code can remove it.
912 */
913 dvmAddToMonitorList(self, obj, false);
914 dvmUnlockObject(self, obj);
915 LOGV("--- unlocked, pending is '%s'\n",
916 dvmGetException(self)->clazz->descriptor);
917 }
918 }
919
920 /*
921 * Add the locked object, and the current stack trace, to the list
922 * held by the Thread object. If deadlock prediction isn't on,
923 * don't capture the stack trace.
924 */
925 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
926#elif defined(WITH_MONITOR_TRACKING)
927 /*
928 * Add the locked object to the list held by the Thread object.
929 */
930 dvmAddToMonitorList(self, obj, false);
931#endif
932}
933
934/*
935 * Implements monitorexit for "synchronized" stuff.
936 *
937 * On failure, throws an exception and returns "false".
938 */
939bool dvmUnlockObject(Thread* self, Object *obj)
940{
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800941 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800942 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800943
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800944 assert(self != NULL);
945 assert(self->status == THREAD_RUNNING);
946 assert(obj != NULL);
947
948 thinp = &obj->lock;
949 /*
950 * Cache the lock word as its value can change while we are
951 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800952 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800953 thin = *thinp;
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800954 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
955 /*
956 * The lock is thin. We must ensure that the lock is owned
957 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800958 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800959 if (LW_LOCK_OWNER(thin) == self->threadId) {
960 /*
961 * We are the lock owner. It is safe to update the lock
962 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800963 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800964 if (LW_LOCK_COUNT(thin) == 0) {
965 /*
966 * The lock was not recursively acquired, the common
967 * case. Unlock by clearing all bits except for the
968 * hash state.
969 */
970 *thinp &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
971 } else {
972 /*
973 * The object was recursively acquired. Decrement the
974 * lock recursion count field.
975 */
976 *thinp -= 1 << LW_LOCK_COUNT_SHIFT;
977 }
978 } else {
979 /*
980 * We do not own the lock. The JVM spec requires that we
981 * throw an exception in this case.
982 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800983 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800984 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800985 return false;
986 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800987 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800988 /*
989 * The lock is fat. We must check to see if unlockMonitor has
990 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800991 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800992 assert(LW_MONITOR(obj->lock) != NULL);
993 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800994 /*
995 * An exception has been raised. Do not fall through.
996 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800997 return false;
998 }
999 }
1000
1001#ifdef WITH_MONITOR_TRACKING
1002 /*
1003 * Remove the object from the Thread's list.
1004 */
1005 dvmRemoveFromMonitorList(self, obj);
1006#endif
1007
1008 return true;
1009}
1010
1011/*
1012 * Object.wait(). Also called for class init.
1013 */
1014void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1015 bool interruptShouldThrow)
1016{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001017 Monitor* mon = LW_MONITOR(obj->lock);
1018 u4 hashState;
1019 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001020
1021 /* If the lock is still thin, we need to fatten it.
1022 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001023 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001024 /* Make sure that 'self' holds the lock.
1025 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001026 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001027 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1028 "object not locked by thread before wait()");
1029 return;
1030 }
1031
1032 /* This thread holds the lock. We need to fatten the lock
1033 * so 'self' can block on it. Don't update the object lock
1034 * field yet, because 'self' needs to acquire the lock before
1035 * any other thread gets a chance.
1036 */
1037 mon = dvmCreateMonitor(obj);
1038
1039 /* 'self' has actually locked the object one or more times;
1040 * make sure that the monitor reflects this.
1041 */
1042 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001043 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001044 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1045 self->threadId, (uint)&obj->lock, mon->lockCount);
1046
Andy McFadden581bed72009-10-15 11:24:54 -07001047
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001048 /* Make the monitor public now that it's in the right state.
1049 */
Andy McFadden581bed72009-10-15 11:24:54 -07001050 MEM_BARRIER();
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001051 hashState = LW_HASH_STATE(thin) << LW_HASH_STATE_SHIFT;
1052 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001053 }
1054
1055 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1056}
1057
1058/*
1059 * Object.notify().
1060 */
1061void dvmObjectNotify(Thread* self, Object *obj)
1062{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001063 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001064
1065 /* If the lock is still thin, there aren't any waiters;
1066 * waiting on an object forces lock fattening.
1067 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001068 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001069 /* Make sure that 'self' holds the lock.
1070 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001071 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001072 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1073 "object not locked by thread before notify()");
1074 return;
1075 }
1076
1077 /* no-op; there are no waiters to notify.
1078 */
1079 } else {
1080 /* It's a fat lock.
1081 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001082 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001083 }
1084}
1085
1086/*
1087 * Object.notifyAll().
1088 */
1089void dvmObjectNotifyAll(Thread* self, Object *obj)
1090{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001091 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001092
1093 /* If the lock is still thin, there aren't any waiters;
1094 * waiting on an object forces lock fattening.
1095 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001096 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001097 /* Make sure that 'self' holds the lock.
1098 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001099 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001100 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1101 "object not locked by thread before notifyAll()");
1102 return;
1103 }
1104
1105 /* no-op; there are no waiters to notify.
1106 */
1107 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001108 /* It's a fat lock.
1109 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001110 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001111 }
1112}
1113
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001114/*
1115 * This implements java.lang.Thread.sleep(long msec, int nsec).
1116 *
1117 * The sleep is interruptible by other threads, which means we can't just
1118 * plop into an OS sleep call. (We probably could if we wanted to send
1119 * signals around and rely on EINTR, but that's inefficient and relies
1120 * on native code respecting our signal mask.)
1121 *
1122 * We have to do all of this stuff for Object.wait() as well, so it's
1123 * easiest to just sleep on a private Monitor.
1124 *
1125 * It appears that we want sleep(0,0) to go through the motions of sleeping
1126 * for a very short duration, rather than just returning.
1127 */
1128void dvmThreadSleep(u8 msec, u4 nsec)
1129{
1130 Thread* self = dvmThreadSelf();
1131 Monitor* mon = gDvm.threadSleepMon;
1132
1133 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1134 if (msec == 0 && nsec == 0)
1135 nsec++;
1136
1137 lockMonitor(self, mon);
1138 waitMonitor(self, mon, msec, nsec, true);
1139 unlockMonitor(self, mon);
1140}
1141
1142/*
1143 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001144 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001145void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001146{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001147 assert(thread != NULL);
1148
1149 pthread_mutex_lock(&thread->waitMutex);
1150
1151 /*
1152 * If the interrupted flag is already set no additional action is
1153 * required.
1154 */
1155 if (thread->interrupted == true) {
1156 pthread_mutex_unlock(&thread->waitMutex);
1157 return;
1158 }
1159
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001160 /*
1161 * Raise the "interrupted" flag. This will cause it to bail early out
1162 * of the next wait() attempt, if it's not currently waiting on
1163 * something.
1164 */
1165 thread->interrupted = true;
1166 MEM_BARRIER();
1167
1168 /*
1169 * Is the thread waiting?
1170 *
1171 * Note that fat vs. thin doesn't matter here; waitMonitor
1172 * is only set when a thread actually waits on a monitor,
1173 * which implies that the monitor has already been fattened.
1174 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001175 if (thread->waitMonitor != NULL) {
1176 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001177 }
1178
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001179 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001180}
1181
Carl Shapiro30aa9972010-01-13 22:07:50 -08001182#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001183u4 dvmIdentityHashCode(Object *obj)
1184{
1185 return (u4)obj;
1186}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001187#else
1188static size_t arrayElementWidth(const ArrayObject *array)
1189{
1190 const char *descriptor;
1191
1192 if (dvmIsObjectArray(array)) {
1193 return sizeof(Object *);
1194 } else {
1195 descriptor = array->obj.clazz->descriptor;
1196 switch (descriptor[1]) {
1197 case 'B': return 1; /* byte */
1198 case 'C': return 2; /* char */
1199 case 'D': return 8; /* double */
1200 case 'F': return 4; /* float */
1201 case 'I': return 4; /* int */
1202 case 'J': return 8; /* long */
1203 case 'S': return 2; /* short */
1204 case 'Z': return 1; /* boolean */
1205 }
1206 }
1207 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1208 dvmDumpThread(dvmThreadSelf(), false);
1209 dvmAbort();
1210 return 0; /* Quiet the compiler. */
1211}
1212
1213static size_t arrayObjectLength(const ArrayObject *array)
1214{
1215 size_t length;
1216
1217 length = offsetof(ArrayObject, contents);
1218 length += array->length * arrayElementWidth(array);
1219 return length;
1220}
1221
1222/*
1223 * Returns the identity hash code of the given object.
1224 */
1225u4 dvmIdentityHashCode(Object *obj)
1226{
1227 Thread *self, *thread;
1228 volatile u4 *lw;
1229 size_t length;
1230 u4 lock, owner, hashState;
1231
1232 if (obj == NULL) {
1233 /*
1234 * Null is defined to have an identity hash code of 0.
1235 */
1236 return 0;
1237 }
1238 lw = &obj->lock;
1239retry:
1240 hashState = LW_HASH_STATE(*lw);
1241 if (hashState == LW_HASH_STATE_HASHED) {
1242 /*
1243 * The object has been hashed but has not had its hash code
1244 * relocated by the garbage collector. Use the raw object
1245 * address.
1246 */
1247 return (u4)obj >> 3;
1248 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1249 /*
1250 * The object has been hashed and its hash code has been
1251 * relocated by the collector. Use the value of the naturally
1252 * aligned word following the instance data.
1253 */
1254 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1255 length = arrayObjectLength((ArrayObject *)obj);
1256 length = (length + 3) & ~3;
1257 } else {
1258 length = obj->clazz->objectSize;
1259 }
1260 return *(u4 *)(((char *)obj) + length);
1261 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1262 /*
1263 * The object has never been hashed. Change the hash state to
1264 * hashed and use the raw object address.
1265 */
1266 self = dvmThreadSelf();
1267 if (self->threadId == lockOwner(obj)) {
1268 /*
1269 * We already own the lock so we can update the hash state
1270 * directly.
1271 */
1272 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1273 return (u4)obj >> 3;
1274 }
1275 /*
1276 * We do not own the lock. Try acquiring the lock. Should
1277 * this fail, we must suspend the owning thread.
1278 */
1279 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1280 /*
1281 * If the lock is thin assume it is unowned. We simulate
1282 * an acquire, update, and release with a single CAS.
1283 */
1284 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1285 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1286 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1287 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1288 (int32_t)lock)) {
1289 /*
1290 * A new lockword has been installed with a hash state
1291 * of hashed. Use the raw object address.
1292 */
1293 return (u4)obj >> 3;
1294 }
1295 } else {
1296 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1297 /*
1298 * The monitor lock has been acquired. Change the
1299 * hash state to hashed and use the raw object
1300 * address.
1301 */
1302 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1303 unlockMonitor(self, LW_MONITOR(*lw));
1304 return (u4)obj >> 3;
1305 }
1306 }
1307 /*
1308 * At this point we have failed to acquire the lock. We must
1309 * identify the owning thread and suspend it.
1310 */
1311 dvmLockThreadList(self);
1312 /*
1313 * Cache the lock word as its value can change between
1314 * determining its shape and retrieving its owner.
1315 */
1316 lock = *lw;
1317 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1318 /*
1319 * Find the thread with the corresponding thread id.
1320 */
1321 owner = LW_LOCK_OWNER(lock);
1322 assert(owner != self->threadId);
1323 /*
1324 * If the lock has no owner do not bother scanning the
1325 * thread list and fall through to the failure handler.
1326 */
1327 thread = owner ? gDvm.threadList : NULL;
1328 while (thread != NULL) {
1329 if (thread->threadId == owner) {
1330 break;
1331 }
1332 thread = thread->next;
1333 }
1334 } else {
1335 thread = LW_MONITOR(lock)->owner;
1336 }
1337 /*
1338 * If thread is NULL the object has been released since the
1339 * thread list lock was acquired. Try again.
1340 */
1341 if (thread == NULL) {
1342 dvmUnlockThreadList();
1343 goto retry;
1344 }
1345 /*
1346 * Wait for the owning thread to suspend.
1347 */
1348 dvmSuspendThread(thread);
1349 if (dvmHoldsLock(thread, obj)) {
1350 /*
1351 * The owning thread has been suspended. We can safely
1352 * change the hash state to hashed.
1353 */
1354 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1355 dvmResumeThread(thread);
1356 dvmUnlockThreadList();
1357 return (u4)obj >> 3;
1358 }
1359 /*
1360 * The wrong thread has been suspended. Try again.
1361 */
1362 dvmResumeThread(thread);
1363 dvmUnlockThreadList();
1364 goto retry;
1365 }
1366 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1367 dvmDumpThread(dvmThreadSelf(), false);
1368 dvmAbort();
1369 return 0; /* Quiet the compiler. */
1370}
1371#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001372
1373#ifdef WITH_DEADLOCK_PREDICTION
1374/*
1375 * ===========================================================================
1376 * Deadlock prediction
1377 * ===========================================================================
1378 */
1379/*
1380The idea is to predict the possibility of deadlock by recording the order
1381in which monitors are acquired. If we see an attempt to acquire a lock
1382out of order, we can identify the locks and offending code.
1383
1384To make this work, we need to keep track of the locks held by each thread,
1385and create history trees for each lock. When a thread tries to acquire
1386a new lock, we walk through the "history children" of the lock, looking
1387for a match with locks the thread already holds. If we find a match,
1388it means the thread has made a request that could result in a deadlock.
1389
1390To support recursive locks, we always allow re-locking a currently-held
1391lock, and maintain a recursion depth count.
1392
1393An ASCII-art example, where letters represent Objects:
1394
1395 A
1396 /|\
1397 / | \
1398 B | D
1399 \ |
1400 \|
1401 C
1402
1403The above is the tree we'd have after handling Object synchronization
1404sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1405a child of B. (The lines represent pointers between parent and child.
1406Every node can have multiple parents and multiple children.)
1407
1408If we hold AC, and want to lock B, we recursively search through B's
1409children to see if A or C appears. It does, so we reject the attempt.
1410(A straightforward way to implement it: add a link from C to B, then
1411determine whether the graph starting at B contains a cycle.)
1412
1413If we hold AC and want to lock D, we would succeed, creating a new link
1414from C to D.
1415
1416The lock history and a stack trace is attached to the Object's Monitor
1417struct, which means we need to fatten every Object we lock (thin locking
1418is effectively disabled). If we don't need the stack trace we can
1419avoid fattening the leaf nodes, only fattening objects that need to hold
1420history trees.
1421
1422Updates to Monitor structs are only allowed for the thread that holds
1423the Monitor, so we actually do most of our deadlock prediction work after
1424the lock has been acquired.
1425
1426When an object with a monitor is GCed, we need to remove it from the
1427history trees. There are two basic approaches:
1428 (1) For through the entire set of known monitors, search all child
1429 lists for the object in question. This is rather slow, resulting
1430 in GC passes that take upwards of 10 seconds to complete.
1431 (2) Maintain "parent" pointers in each node. Remove the entries as
1432 required. This requires additional storage and maintenance for
1433 every operation, but is significantly faster at GC time.
1434For each GCed object, we merge all of the object's children into each of
1435the object's parents.
1436*/
1437
1438#if !defined(WITH_MONITOR_TRACKING)
1439# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1440#endif
1441
1442/*
1443 * Clear out the contents of an ExpandingObjectList, freeing any
1444 * dynamic allocations.
1445 */
1446static void expandObjClear(ExpandingObjectList* pList)
1447{
1448 if (pList->list != NULL) {
1449 free(pList->list);
1450 pList->list = NULL;
1451 }
1452 pList->alloc = pList->count = 0;
1453}
1454
1455/*
1456 * Get the number of objects currently stored in the list.
1457 */
1458static inline int expandBufGetCount(const ExpandingObjectList* pList)
1459{
1460 return pList->count;
1461}
1462
1463/*
1464 * Get the Nth entry from the list.
1465 */
1466static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1467 int i)
1468{
1469 return pList->list[i];
1470}
1471
1472/*
1473 * Add a new entry to the list.
1474 *
1475 * We don't check for or try to enforce uniqueness. It's expected that
1476 * the higher-level code does this for us.
1477 */
1478static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1479{
1480 if (pList->count == pList->alloc) {
1481 /* time to expand */
1482 Object** newList;
1483
1484 if (pList->alloc == 0)
1485 pList->alloc = 4;
1486 else
1487 pList->alloc *= 2;
1488 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1489 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1490 if (newList == NULL) {
1491 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1492 dvmAbort();
1493 }
1494 pList->list = newList;
1495 }
1496
1497 pList->list[pList->count++] = obj;
1498}
1499
1500/*
1501 * Returns "true" if the element was successfully removed.
1502 */
1503static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1504{
1505 int i;
1506
1507 for (i = pList->count-1; i >= 0; i--) {
1508 if (pList->list[i] == obj)
1509 break;
1510 }
1511 if (i < 0)
1512 return false;
1513
1514 if (i != pList->count-1) {
1515 /*
1516 * The order of elements is not important, so we just copy the
1517 * last entry into the new slot.
1518 */
1519 //memmove(&pList->list[i], &pList->list[i+1],
1520 // (pList->count-1 - i) * sizeof(pList->list[0]));
1521 pList->list[i] = pList->list[pList->count-1];
1522 }
1523
1524 pList->count--;
1525 pList->list[pList->count] = (Object*) 0xdecadead;
1526 return true;
1527}
1528
1529/*
1530 * Returns "true" if "obj" appears in the list.
1531 */
1532static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1533{
1534 int i;
1535
1536 for (i = 0; i < pList->count; i++) {
1537 if (pList->list[i] == obj)
1538 return true;
1539 }
1540 return false;
1541}
1542
1543/*
1544 * Print the list contents to stdout. For debugging.
1545 */
1546static void expandObjDump(const ExpandingObjectList* pList)
1547{
1548 int i;
1549 for (i = 0; i < pList->count; i++)
1550 printf(" %p", pList->list[i]);
1551}
1552
1553/*
1554 * Check for duplicate entries. Returns the index of the first instance
1555 * of the duplicated value, or -1 if no duplicates were found.
1556 */
1557static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1558{
1559 int i, j;
1560 for (i = 0; i < pList->count-1; i++) {
1561 for (j = i + 1; j < pList->count; j++) {
1562 if (pList->list[i] == pList->list[j]) {
1563 return i;
1564 }
1565 }
1566 }
1567
1568 return -1;
1569}
1570
1571
1572/*
1573 * Determine whether "child" appears in the list of objects associated
1574 * with the Monitor in "parent". If "parent" is a thin lock, we return
1575 * false immediately.
1576 */
1577static bool objectInChildList(const Object* parent, Object* child)
1578{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001579 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001580 if (!IS_LOCK_FAT(&lock)) {
1581 //LOGI("on thin\n");
1582 return false;
1583 }
1584
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001585 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001586}
1587
1588/*
1589 * Print the child list.
1590 */
1591static void dumpKids(Object* parent)
1592{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001593 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001594
1595 printf("Children of %p:", parent);
1596 expandObjDump(&mon->historyChildren);
1597 printf("\n");
1598}
1599
1600/*
1601 * Add "child" to the list of children in "parent", and add "parent" to
1602 * the list of parents in "child".
1603 */
1604static void linkParentToChild(Object* parent, Object* child)
1605{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001606 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001607 assert(IS_LOCK_FAT(&parent->lock));
1608 assert(IS_LOCK_FAT(&child->lock));
1609 assert(parent != child);
1610 Monitor* mon;
1611
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001612 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001613 assert(!expandObjHas(&mon->historyChildren, child));
1614 expandObjAddEntry(&mon->historyChildren, child);
1615
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001616 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001617 assert(!expandObjHas(&mon->historyParents, parent));
1618 expandObjAddEntry(&mon->historyParents, parent);
1619}
1620
1621
1622/*
1623 * Remove "child" from the list of children in "parent".
1624 */
1625static void unlinkParentFromChild(Object* parent, Object* child)
1626{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001627 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
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 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1635 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1636 }
1637 assert(!expandObjHas(&mon->historyChildren, child));
1638 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1639
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001640 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001641 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1642 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1643 }
1644 assert(!expandObjHas(&mon->historyParents, parent));
1645 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1646}
1647
1648
1649/*
1650 * Log the monitors held by the current thread. This is done as part of
1651 * flagging an error.
1652 */
1653static void logHeldMonitors(Thread* self)
1654{
1655 char* name = NULL;
1656
1657 name = dvmGetThreadName(self);
1658 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1659 self->threadId, name);
1660 LOGW("(most-recently-acquired on top):\n");
1661 free(name);
1662
1663 LockedObjectData* lod = self->pLockedObjects;
1664 while (lod != NULL) {
1665 LOGW("--- object %p[%d] (%s)\n",
1666 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1667 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1668
1669 lod = lod->next;
1670 }
1671}
1672
1673/*
1674 * Recursively traverse the object hierarchy starting at "obj". We mark
1675 * ourselves on entry and clear the mark on exit. If we ever encounter
1676 * a marked object, we have a cycle.
1677 *
1678 * Returns "true" if all is well, "false" if we found a cycle.
1679 */
1680static bool traverseTree(Thread* self, const Object* obj)
1681{
1682 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001683 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001684
1685 /*
1686 * Have we been here before?
1687 */
1688 if (mon->historyMark) {
1689 int* rawStackTrace;
1690 int stackDepth;
1691
1692 LOGW("%s\n", kStartBanner);
1693 LOGW("Illegal lock attempt:\n");
1694 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1695
1696 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1697 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1698 free(rawStackTrace);
1699
1700 LOGW(" ");
1701 logHeldMonitors(self);
1702
1703 LOGW(" ");
1704 LOGW("Earlier, the following lock order (from last to first) was\n");
1705 LOGW("established -- stack trace is from first successful lock):\n");
1706 return false;
1707 }
1708 mon->historyMark = true;
1709
1710 /*
1711 * Examine the children. We do NOT hold these locks, so they might
1712 * very well transition from thin to fat or change ownership while
1713 * we work.
1714 *
1715 * NOTE: we rely on the fact that they cannot revert from fat to thin
1716 * while we work. This is currently a safe assumption.
1717 *
1718 * We can safely ignore thin-locked children, because by definition
1719 * they have no history and are leaf nodes. In the current
1720 * implementation we always fatten the locks to provide a place to
1721 * hang the stack trace.
1722 */
1723 ExpandingObjectList* pList = &mon->historyChildren;
1724 int i;
1725 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1726 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001727 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001728 if (!IS_LOCK_FAT(&lock))
1729 continue;
1730 if (!traverseTree(self, child)) {
1731 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1732 dvmLogRawStackTrace(mon->historyRawStackTrace,
1733 mon->historyStackDepth);
1734 mon->historyMark = false;
1735 return false;
1736 }
1737 }
1738
1739 mon->historyMark = false;
1740
1741 return true;
1742}
1743
1744/*
1745 * Update the deadlock prediction tree, based on the current thread
1746 * acquiring "acqObj". This must be called before the object is added to
1747 * the thread's list of held monitors.
1748 *
1749 * If the thread already holds the lock (recursion), or this is a known
1750 * lock configuration, we return without doing anything. Otherwise, we add
1751 * a link from the most-recently-acquired lock in this thread to "acqObj"
1752 * after ensuring that the parent lock is "fat".
1753 *
1754 * This MUST NOT be called while a GC is in progress in another thread,
1755 * because we assume exclusive access to history trees in owned monitors.
1756 */
1757static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1758{
1759 LockedObjectData* lod;
1760 LockedObjectData* mrl;
1761
1762 /*
1763 * Quick check for recursive access.
1764 */
1765 lod = dvmFindInMonitorList(self, acqObj);
1766 if (lod != NULL) {
1767 LOGV("+++ DP: recursive %p\n", acqObj);
1768 return;
1769 }
1770
1771 /*
1772 * Make the newly-acquired object's monitor "fat". In some ways this
1773 * isn't strictly necessary, but we need the GC to tell us when
1774 * "interesting" objects go away, and right now the only way to make
1775 * an object look interesting is to give it a monitor.
1776 *
1777 * This also gives us a place to hang a stack trace.
1778 *
1779 * Our thread holds the lock, so we're allowed to rewrite the lock
1780 * without worrying that something will change out from under us.
1781 */
1782 if (!IS_LOCK_FAT(&acqObj->lock)) {
1783 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001784 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001785 Monitor* newMon = dvmCreateMonitor(acqObj);
1786 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001787 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1788 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1789 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001790 }
1791
1792 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001793 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1794 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001795 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1796 &mon->historyStackDepth);
1797 }
1798
1799 /*
1800 * We need to examine and perhaps modify the most-recently-locked
1801 * monitor. We own that, so there's no risk of another thread
1802 * stepping on us.
1803 *
1804 * Retrieve the most-recently-locked entry from our thread.
1805 */
1806 mrl = self->pLockedObjects;
1807 if (mrl == NULL)
1808 return; /* no other locks held */
1809
1810 /*
1811 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1812 * this without holding the global lock because of our assertion that
1813 * a GC is not running in parallel -- nobody except the GC can
1814 * modify a history list in a Monitor they don't own, and we own "mrl".
1815 * (There might be concurrent *reads*, but no concurrent *writes.)
1816 *
1817 * If we find it, this is a known good configuration, and we're done.
1818 */
1819 if (objectInChildList(mrl->obj, acqObj))
1820 return;
1821
1822 /*
1823 * "mrl" is going to need to have a history tree. If it's currently
1824 * a thin lock, we make it fat now. The thin lock might have a
1825 * nonzero recursive lock count, which we need to carry over.
1826 *
1827 * Our thread holds the lock, so we're allowed to rewrite the lock
1828 * without worrying that something will change out from under us.
1829 */
1830 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1831 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001832 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001833 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1834 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001835 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1836 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1837 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001838 }
1839
1840 /*
1841 * We haven't seen this configuration before. We need to scan down
1842 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1843 * appear. We grab a global lock before traversing or updating the
1844 * history list.
1845 *
1846 * If we find a match for any of our held locks, we know that the lock
1847 * has previously been acquired *after* acqObj, and we throw an error.
1848 *
1849 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1850 * and do a recursive traversal, marking nodes as we cross them. If
1851 * we cross one a second time, we have a cycle and can throw an error.
1852 * (We do the flag-clearing traversal before adding the new link, so
1853 * that we're guaranteed to terminate.)
1854 *
1855 * If "acqObj" is a thin lock, it has no history, and we can create a
1856 * link to it without additional checks. [ We now guarantee that it's
1857 * always fat. ]
1858 */
1859 bool failed = false;
1860 dvmLockMutex(&gDvm.deadlockHistoryLock);
1861 linkParentToChild(mrl->obj, acqObj);
1862 if (!traverseTree(self, acqObj)) {
1863 LOGW("%s\n", kEndBanner);
1864 failed = true;
1865
1866 /* remove the entry so we're still okay when in "warning" mode */
1867 unlinkParentFromChild(mrl->obj, acqObj);
1868 }
1869 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1870
1871 if (failed) {
1872 switch (gDvm.deadlockPredictMode) {
1873 case kDPErr:
1874 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1875 break;
1876 case kDPAbort:
1877 LOGE("Aborting due to potential deadlock\n");
1878 dvmAbort();
1879 break;
1880 default:
1881 /* warn only */
1882 break;
1883 }
1884 }
1885}
1886
1887/*
1888 * We're removing "child" from existence. We want to pull all of
1889 * child's children into "parent", filtering out duplicates. This is
1890 * called during the GC.
1891 *
1892 * This does not modify "child", which might have multiple parents.
1893 */
1894static void mergeChildren(Object* parent, const Object* child)
1895{
1896 Monitor* mon;
1897 int i;
1898
1899 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001900 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001901 ExpandingObjectList* pList = &mon->historyChildren;
1902
1903 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1904 Object* grandChild = expandBufGetEntry(pList, i);
1905
1906 if (!objectInChildList(parent, grandChild)) {
1907 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1908 linkParentToChild(parent, grandChild);
1909 } else {
1910 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1911 }
1912 }
1913}
1914
1915/*
1916 * An object with a fat lock is being collected during a GC pass. We
1917 * want to remove it from any lock history trees that it is a part of.
1918 *
1919 * This may require updating the history trees in several monitors. The
1920 * monitor semantics guarantee that no other thread will be accessing
1921 * the history trees at the same time.
1922 */
1923static void removeCollectedObject(Object* obj)
1924{
1925 Monitor* mon;
1926
1927 LOGVV("+++ collecting %p\n", obj);
1928
1929#if 0
1930 /*
1931 * We're currently running through the entire set of known monitors.
1932 * This can be somewhat slow. We may want to keep lists of parents
1933 * in each child to speed up GC.
1934 */
1935 mon = gDvm.monitorList;
1936 while (mon != NULL) {
1937 Object* parent = mon->obj;
1938 if (parent != NULL) { /* value nulled for deleted entries */
1939 if (objectInChildList(parent, obj)) {
1940 LOGVV("removing child %p from parent %p\n", obj, parent);
1941 unlinkParentFromChild(parent, obj);
1942 mergeChildren(parent, obj);
1943 }
1944 }
1945 mon = mon->next;
1946 }
1947#endif
1948
1949 /*
1950 * For every parent of this object:
1951 * - merge all of our children into the parent's child list (creates
1952 * a two-way link between parent and child)
1953 * - remove ourselves from the parent's child list
1954 */
1955 ExpandingObjectList* pList;
1956 int i;
1957
1958 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001959 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001960 pList = &mon->historyParents;
1961 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1962 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001963 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001964
1965 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
1966 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
1967 }
1968 assert(!expandObjHas(&parentMon->historyChildren, obj));
1969
1970 mergeChildren(parent, obj);
1971 }
1972
1973 /*
1974 * For every child of this object:
1975 * - remove ourselves from the child's parent list
1976 */
1977 pList = &mon->historyChildren;
1978 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1979 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001980 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001981
1982 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
1983 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
1984 }
1985 assert(!expandObjHas(&childMon->historyParents, obj));
1986 }
1987}
1988
1989#endif /*WITH_DEADLOCK_PREDICTION*/
1990