blob: b7a83bdd65358973aae0fc9418a879f38c4a4b48 [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 *
601 * The order of operations here isn't significant, because we still
602 * hold the pthread mutex.
603 */
604 int prevLockCount;
605
606 prevLockCount = mon->lockCount;
607 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800608 mon->owner = NULL;
609
610 /*
611 * Update thread status. If the GC wakes up, it'll ignore us, knowing
612 * that we won't touch any references in this state, and we'll check
613 * our suspend mode before we transition out.
614 */
615 if (timed)
616 dvmChangeStatus(self, THREAD_TIMED_WAIT);
617 else
618 dvmChangeStatus(self, THREAD_WAIT);
619
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800620 ret = pthread_mutex_lock(&self->waitMutex);
621 assert(ret == 0);
622
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800623 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800624 * Set waitMonitor to the monitor object we will be waiting on.
625 * When waitMonitor is non-NULL a notifying or interrupting thread
626 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800627 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800628 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800629 self->waitMonitor = mon;
630
631 /*
632 * Handle the case where the thread was interrupted before we called
633 * wait().
634 */
635 if (self->interrupted) {
636 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800637 self->waitMonitor = NULL;
638 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800639 goto done;
640 }
641
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800642 waitSetAppend(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800643
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800644 /*
645 * Release the monitor lock and wait for a notification or
646 * a timeout to occur.
647 */
648 pthread_mutex_unlock(&mon->lock);
649
650 if (!timed) {
651 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
652 assert(ret == 0);
653 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800654#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800655 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800656#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800657 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800658#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800659 assert(ret == 0 || ret == ETIMEDOUT);
660 }
661 if (self->interrupted) {
662 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800663 }
664
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800665 self->interrupted = false;
666 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800667
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800668 pthread_mutex_unlock(&self->waitMutex);
669
Carl Shapiro30aa9972010-01-13 22:07:50 -0800670 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800671 lockMonitor(self, mon);
672
673 waitSetRemove(mon, self);
674
675done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800676 /*
677 * Put everything back. Again, we hold the pthread mutex, so the order
678 * here isn't significant.
679 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800680 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800681 mon->lockCount = prevLockCount;
682
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 Shapiro8d7f9b22009-12-21 20:23:45 -0800941 volatile u4 *thinp = &obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800942 u4 threadId = self->threadId;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800943 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800944
945 /* Check the common case, where 'self' has locked 'obj' once, first.
946 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800947 thin = *thinp;
948 if (LW_LOCK_OWNER(thin) == threadId && LW_LOCK_COUNT(thin) == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800949 /* Unlock 'obj' by clearing our threadId from 'thin'.
950 * The lock protects the lock field itself, so it's
951 * safe to update non-atomically.
952 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800953 *thinp &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
954 } else if (LW_SHAPE(*thinp) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800955 /* If the object is locked, it had better be locked by us.
956 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800957 if (LW_LOCK_OWNER(*thinp) != threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800958 /* The JNI spec says that we should throw an exception
959 * in this case.
960 */
961 //LOGW("Unlock thin %p: id %d vs %d\n",
962 // obj, (*thinp & 0xfff), threadId);
963 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
964 "unlock of unowned monitor");
965 return false;
966 }
967
968 /* It's a thin lock, but 'self' has locked 'obj'
969 * more than once. Decrement the count.
970 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800971 *thinp -= 1 << LW_LOCK_COUNT_SHIFT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800972 } else {
973 /* It's a fat lock.
974 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800975 assert(LW_MONITOR(obj->lock) != NULL);
976 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800977 /* exception has been raised */
978 return false;
979 }
980 }
981
982#ifdef WITH_MONITOR_TRACKING
983 /*
984 * Remove the object from the Thread's list.
985 */
986 dvmRemoveFromMonitorList(self, obj);
987#endif
988
989 return true;
990}
991
992/*
993 * Object.wait(). Also called for class init.
994 */
995void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
996 bool interruptShouldThrow)
997{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800998 Monitor* mon = LW_MONITOR(obj->lock);
999 u4 hashState;
1000 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001001
1002 /* If the lock is still thin, we need to fatten it.
1003 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001004 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001005 /* Make sure that 'self' holds the lock.
1006 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001007 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001008 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1009 "object not locked by thread before wait()");
1010 return;
1011 }
1012
1013 /* This thread holds the lock. We need to fatten the lock
1014 * so 'self' can block on it. Don't update the object lock
1015 * field yet, because 'self' needs to acquire the lock before
1016 * any other thread gets a chance.
1017 */
1018 mon = dvmCreateMonitor(obj);
1019
1020 /* 'self' has actually locked the object one or more times;
1021 * make sure that the monitor reflects this.
1022 */
1023 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001024 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001025 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1026 self->threadId, (uint)&obj->lock, mon->lockCount);
1027
Andy McFadden581bed72009-10-15 11:24:54 -07001028
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001029 /* Make the monitor public now that it's in the right state.
1030 */
Andy McFadden581bed72009-10-15 11:24:54 -07001031 MEM_BARRIER();
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001032 hashState = LW_HASH_STATE(thin) << LW_HASH_STATE_SHIFT;
1033 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001034 }
1035
1036 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1037}
1038
1039/*
1040 * Object.notify().
1041 */
1042void dvmObjectNotify(Thread* self, Object *obj)
1043{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001044 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001045
1046 /* If the lock is still thin, there aren't any waiters;
1047 * waiting on an object forces lock fattening.
1048 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001049 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001050 /* Make sure that 'self' holds the lock.
1051 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001052 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001053 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1054 "object not locked by thread before notify()");
1055 return;
1056 }
1057
1058 /* no-op; there are no waiters to notify.
1059 */
1060 } else {
1061 /* It's a fat lock.
1062 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001063 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001064 }
1065}
1066
1067/*
1068 * Object.notifyAll().
1069 */
1070void dvmObjectNotifyAll(Thread* self, Object *obj)
1071{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001072 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001073
1074 /* If the lock is still thin, there aren't any waiters;
1075 * waiting on an object forces lock fattening.
1076 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001077 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001078 /* Make sure that 'self' holds the lock.
1079 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001080 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001081 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1082 "object not locked by thread before notifyAll()");
1083 return;
1084 }
1085
1086 /* no-op; there are no waiters to notify.
1087 */
1088 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001089 /* It's a fat lock.
1090 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001091 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001092 }
1093}
1094
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001095/*
1096 * This implements java.lang.Thread.sleep(long msec, int nsec).
1097 *
1098 * The sleep is interruptible by other threads, which means we can't just
1099 * plop into an OS sleep call. (We probably could if we wanted to send
1100 * signals around and rely on EINTR, but that's inefficient and relies
1101 * on native code respecting our signal mask.)
1102 *
1103 * We have to do all of this stuff for Object.wait() as well, so it's
1104 * easiest to just sleep on a private Monitor.
1105 *
1106 * It appears that we want sleep(0,0) to go through the motions of sleeping
1107 * for a very short duration, rather than just returning.
1108 */
1109void dvmThreadSleep(u8 msec, u4 nsec)
1110{
1111 Thread* self = dvmThreadSelf();
1112 Monitor* mon = gDvm.threadSleepMon;
1113
1114 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1115 if (msec == 0 && nsec == 0)
1116 nsec++;
1117
1118 lockMonitor(self, mon);
1119 waitMonitor(self, mon, msec, nsec, true);
1120 unlockMonitor(self, mon);
1121}
1122
1123/*
1124 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001125 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001126void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001127{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001128 assert(thread != NULL);
1129
1130 pthread_mutex_lock(&thread->waitMutex);
1131
1132 /*
1133 * If the interrupted flag is already set no additional action is
1134 * required.
1135 */
1136 if (thread->interrupted == true) {
1137 pthread_mutex_unlock(&thread->waitMutex);
1138 return;
1139 }
1140
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001141 /*
1142 * Raise the "interrupted" flag. This will cause it to bail early out
1143 * of the next wait() attempt, if it's not currently waiting on
1144 * something.
1145 */
1146 thread->interrupted = true;
1147 MEM_BARRIER();
1148
1149 /*
1150 * Is the thread waiting?
1151 *
1152 * Note that fat vs. thin doesn't matter here; waitMonitor
1153 * is only set when a thread actually waits on a monitor,
1154 * which implies that the monitor has already been fattened.
1155 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001156 if (thread->waitMonitor != NULL) {
1157 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001158 }
1159
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001160 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001161}
1162
Carl Shapiro30aa9972010-01-13 22:07:50 -08001163#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001164u4 dvmIdentityHashCode(Object *obj)
1165{
1166 return (u4)obj;
1167}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001168#else
1169static size_t arrayElementWidth(const ArrayObject *array)
1170{
1171 const char *descriptor;
1172
1173 if (dvmIsObjectArray(array)) {
1174 return sizeof(Object *);
1175 } else {
1176 descriptor = array->obj.clazz->descriptor;
1177 switch (descriptor[1]) {
1178 case 'B': return 1; /* byte */
1179 case 'C': return 2; /* char */
1180 case 'D': return 8; /* double */
1181 case 'F': return 4; /* float */
1182 case 'I': return 4; /* int */
1183 case 'J': return 8; /* long */
1184 case 'S': return 2; /* short */
1185 case 'Z': return 1; /* boolean */
1186 }
1187 }
1188 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1189 dvmDumpThread(dvmThreadSelf(), false);
1190 dvmAbort();
1191 return 0; /* Quiet the compiler. */
1192}
1193
1194static size_t arrayObjectLength(const ArrayObject *array)
1195{
1196 size_t length;
1197
1198 length = offsetof(ArrayObject, contents);
1199 length += array->length * arrayElementWidth(array);
1200 return length;
1201}
1202
1203/*
1204 * Returns the identity hash code of the given object.
1205 */
1206u4 dvmIdentityHashCode(Object *obj)
1207{
1208 Thread *self, *thread;
1209 volatile u4 *lw;
1210 size_t length;
1211 u4 lock, owner, hashState;
1212
1213 if (obj == NULL) {
1214 /*
1215 * Null is defined to have an identity hash code of 0.
1216 */
1217 return 0;
1218 }
1219 lw = &obj->lock;
1220retry:
1221 hashState = LW_HASH_STATE(*lw);
1222 if (hashState == LW_HASH_STATE_HASHED) {
1223 /*
1224 * The object has been hashed but has not had its hash code
1225 * relocated by the garbage collector. Use the raw object
1226 * address.
1227 */
1228 return (u4)obj >> 3;
1229 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1230 /*
1231 * The object has been hashed and its hash code has been
1232 * relocated by the collector. Use the value of the naturally
1233 * aligned word following the instance data.
1234 */
1235 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1236 length = arrayObjectLength((ArrayObject *)obj);
1237 length = (length + 3) & ~3;
1238 } else {
1239 length = obj->clazz->objectSize;
1240 }
1241 return *(u4 *)(((char *)obj) + length);
1242 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1243 /*
1244 * The object has never been hashed. Change the hash state to
1245 * hashed and use the raw object address.
1246 */
1247 self = dvmThreadSelf();
1248 if (self->threadId == lockOwner(obj)) {
1249 /*
1250 * We already own the lock so we can update the hash state
1251 * directly.
1252 */
1253 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1254 return (u4)obj >> 3;
1255 }
1256 /*
1257 * We do not own the lock. Try acquiring the lock. Should
1258 * this fail, we must suspend the owning thread.
1259 */
1260 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1261 /*
1262 * If the lock is thin assume it is unowned. We simulate
1263 * an acquire, update, and release with a single CAS.
1264 */
1265 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1266 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1267 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1268 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1269 (int32_t)lock)) {
1270 /*
1271 * A new lockword has been installed with a hash state
1272 * of hashed. Use the raw object address.
1273 */
1274 return (u4)obj >> 3;
1275 }
1276 } else {
1277 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1278 /*
1279 * The monitor lock has been acquired. Change the
1280 * hash state to hashed and use the raw object
1281 * address.
1282 */
1283 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1284 unlockMonitor(self, LW_MONITOR(*lw));
1285 return (u4)obj >> 3;
1286 }
1287 }
1288 /*
1289 * At this point we have failed to acquire the lock. We must
1290 * identify the owning thread and suspend it.
1291 */
1292 dvmLockThreadList(self);
1293 /*
1294 * Cache the lock word as its value can change between
1295 * determining its shape and retrieving its owner.
1296 */
1297 lock = *lw;
1298 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1299 /*
1300 * Find the thread with the corresponding thread id.
1301 */
1302 owner = LW_LOCK_OWNER(lock);
1303 assert(owner != self->threadId);
1304 /*
1305 * If the lock has no owner do not bother scanning the
1306 * thread list and fall through to the failure handler.
1307 */
1308 thread = owner ? gDvm.threadList : NULL;
1309 while (thread != NULL) {
1310 if (thread->threadId == owner) {
1311 break;
1312 }
1313 thread = thread->next;
1314 }
1315 } else {
1316 thread = LW_MONITOR(lock)->owner;
1317 }
1318 /*
1319 * If thread is NULL the object has been released since the
1320 * thread list lock was acquired. Try again.
1321 */
1322 if (thread == NULL) {
1323 dvmUnlockThreadList();
1324 goto retry;
1325 }
1326 /*
1327 * Wait for the owning thread to suspend.
1328 */
1329 dvmSuspendThread(thread);
1330 if (dvmHoldsLock(thread, obj)) {
1331 /*
1332 * The owning thread has been suspended. We can safely
1333 * change the hash state to hashed.
1334 */
1335 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1336 dvmResumeThread(thread);
1337 dvmUnlockThreadList();
1338 return (u4)obj >> 3;
1339 }
1340 /*
1341 * The wrong thread has been suspended. Try again.
1342 */
1343 dvmResumeThread(thread);
1344 dvmUnlockThreadList();
1345 goto retry;
1346 }
1347 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1348 dvmDumpThread(dvmThreadSelf(), false);
1349 dvmAbort();
1350 return 0; /* Quiet the compiler. */
1351}
1352#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001353
1354#ifdef WITH_DEADLOCK_PREDICTION
1355/*
1356 * ===========================================================================
1357 * Deadlock prediction
1358 * ===========================================================================
1359 */
1360/*
1361The idea is to predict the possibility of deadlock by recording the order
1362in which monitors are acquired. If we see an attempt to acquire a lock
1363out of order, we can identify the locks and offending code.
1364
1365To make this work, we need to keep track of the locks held by each thread,
1366and create history trees for each lock. When a thread tries to acquire
1367a new lock, we walk through the "history children" of the lock, looking
1368for a match with locks the thread already holds. If we find a match,
1369it means the thread has made a request that could result in a deadlock.
1370
1371To support recursive locks, we always allow re-locking a currently-held
1372lock, and maintain a recursion depth count.
1373
1374An ASCII-art example, where letters represent Objects:
1375
1376 A
1377 /|\
1378 / | \
1379 B | D
1380 \ |
1381 \|
1382 C
1383
1384The above is the tree we'd have after handling Object synchronization
1385sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1386a child of B. (The lines represent pointers between parent and child.
1387Every node can have multiple parents and multiple children.)
1388
1389If we hold AC, and want to lock B, we recursively search through B's
1390children to see if A or C appears. It does, so we reject the attempt.
1391(A straightforward way to implement it: add a link from C to B, then
1392determine whether the graph starting at B contains a cycle.)
1393
1394If we hold AC and want to lock D, we would succeed, creating a new link
1395from C to D.
1396
1397The lock history and a stack trace is attached to the Object's Monitor
1398struct, which means we need to fatten every Object we lock (thin locking
1399is effectively disabled). If we don't need the stack trace we can
1400avoid fattening the leaf nodes, only fattening objects that need to hold
1401history trees.
1402
1403Updates to Monitor structs are only allowed for the thread that holds
1404the Monitor, so we actually do most of our deadlock prediction work after
1405the lock has been acquired.
1406
1407When an object with a monitor is GCed, we need to remove it from the
1408history trees. There are two basic approaches:
1409 (1) For through the entire set of known monitors, search all child
1410 lists for the object in question. This is rather slow, resulting
1411 in GC passes that take upwards of 10 seconds to complete.
1412 (2) Maintain "parent" pointers in each node. Remove the entries as
1413 required. This requires additional storage and maintenance for
1414 every operation, but is significantly faster at GC time.
1415For each GCed object, we merge all of the object's children into each of
1416the object's parents.
1417*/
1418
1419#if !defined(WITH_MONITOR_TRACKING)
1420# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1421#endif
1422
1423/*
1424 * Clear out the contents of an ExpandingObjectList, freeing any
1425 * dynamic allocations.
1426 */
1427static void expandObjClear(ExpandingObjectList* pList)
1428{
1429 if (pList->list != NULL) {
1430 free(pList->list);
1431 pList->list = NULL;
1432 }
1433 pList->alloc = pList->count = 0;
1434}
1435
1436/*
1437 * Get the number of objects currently stored in the list.
1438 */
1439static inline int expandBufGetCount(const ExpandingObjectList* pList)
1440{
1441 return pList->count;
1442}
1443
1444/*
1445 * Get the Nth entry from the list.
1446 */
1447static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1448 int i)
1449{
1450 return pList->list[i];
1451}
1452
1453/*
1454 * Add a new entry to the list.
1455 *
1456 * We don't check for or try to enforce uniqueness. It's expected that
1457 * the higher-level code does this for us.
1458 */
1459static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1460{
1461 if (pList->count == pList->alloc) {
1462 /* time to expand */
1463 Object** newList;
1464
1465 if (pList->alloc == 0)
1466 pList->alloc = 4;
1467 else
1468 pList->alloc *= 2;
1469 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1470 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1471 if (newList == NULL) {
1472 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1473 dvmAbort();
1474 }
1475 pList->list = newList;
1476 }
1477
1478 pList->list[pList->count++] = obj;
1479}
1480
1481/*
1482 * Returns "true" if the element was successfully removed.
1483 */
1484static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1485{
1486 int i;
1487
1488 for (i = pList->count-1; i >= 0; i--) {
1489 if (pList->list[i] == obj)
1490 break;
1491 }
1492 if (i < 0)
1493 return false;
1494
1495 if (i != pList->count-1) {
1496 /*
1497 * The order of elements is not important, so we just copy the
1498 * last entry into the new slot.
1499 */
1500 //memmove(&pList->list[i], &pList->list[i+1],
1501 // (pList->count-1 - i) * sizeof(pList->list[0]));
1502 pList->list[i] = pList->list[pList->count-1];
1503 }
1504
1505 pList->count--;
1506 pList->list[pList->count] = (Object*) 0xdecadead;
1507 return true;
1508}
1509
1510/*
1511 * Returns "true" if "obj" appears in the list.
1512 */
1513static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1514{
1515 int i;
1516
1517 for (i = 0; i < pList->count; i++) {
1518 if (pList->list[i] == obj)
1519 return true;
1520 }
1521 return false;
1522}
1523
1524/*
1525 * Print the list contents to stdout. For debugging.
1526 */
1527static void expandObjDump(const ExpandingObjectList* pList)
1528{
1529 int i;
1530 for (i = 0; i < pList->count; i++)
1531 printf(" %p", pList->list[i]);
1532}
1533
1534/*
1535 * Check for duplicate entries. Returns the index of the first instance
1536 * of the duplicated value, or -1 if no duplicates were found.
1537 */
1538static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1539{
1540 int i, j;
1541 for (i = 0; i < pList->count-1; i++) {
1542 for (j = i + 1; j < pList->count; j++) {
1543 if (pList->list[i] == pList->list[j]) {
1544 return i;
1545 }
1546 }
1547 }
1548
1549 return -1;
1550}
1551
1552
1553/*
1554 * Determine whether "child" appears in the list of objects associated
1555 * with the Monitor in "parent". If "parent" is a thin lock, we return
1556 * false immediately.
1557 */
1558static bool objectInChildList(const Object* parent, Object* child)
1559{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001560 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001561 if (!IS_LOCK_FAT(&lock)) {
1562 //LOGI("on thin\n");
1563 return false;
1564 }
1565
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001566 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001567}
1568
1569/*
1570 * Print the child list.
1571 */
1572static void dumpKids(Object* parent)
1573{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001574 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001575
1576 printf("Children of %p:", parent);
1577 expandObjDump(&mon->historyChildren);
1578 printf("\n");
1579}
1580
1581/*
1582 * Add "child" to the list of children in "parent", and add "parent" to
1583 * the list of parents in "child".
1584 */
1585static void linkParentToChild(Object* parent, Object* child)
1586{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001587 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001588 assert(IS_LOCK_FAT(&parent->lock));
1589 assert(IS_LOCK_FAT(&child->lock));
1590 assert(parent != child);
1591 Monitor* mon;
1592
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001593 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001594 assert(!expandObjHas(&mon->historyChildren, child));
1595 expandObjAddEntry(&mon->historyChildren, child);
1596
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001597 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001598 assert(!expandObjHas(&mon->historyParents, parent));
1599 expandObjAddEntry(&mon->historyParents, parent);
1600}
1601
1602
1603/*
1604 * Remove "child" from the list of children in "parent".
1605 */
1606static void unlinkParentFromChild(Object* parent, Object* child)
1607{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001608 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001609 assert(IS_LOCK_FAT(&parent->lock));
1610 assert(IS_LOCK_FAT(&child->lock));
1611 assert(parent != child);
1612 Monitor* mon;
1613
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001614 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001615 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1616 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1617 }
1618 assert(!expandObjHas(&mon->historyChildren, child));
1619 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1620
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001621 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001622 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1623 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1624 }
1625 assert(!expandObjHas(&mon->historyParents, parent));
1626 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1627}
1628
1629
1630/*
1631 * Log the monitors held by the current thread. This is done as part of
1632 * flagging an error.
1633 */
1634static void logHeldMonitors(Thread* self)
1635{
1636 char* name = NULL;
1637
1638 name = dvmGetThreadName(self);
1639 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1640 self->threadId, name);
1641 LOGW("(most-recently-acquired on top):\n");
1642 free(name);
1643
1644 LockedObjectData* lod = self->pLockedObjects;
1645 while (lod != NULL) {
1646 LOGW("--- object %p[%d] (%s)\n",
1647 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1648 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1649
1650 lod = lod->next;
1651 }
1652}
1653
1654/*
1655 * Recursively traverse the object hierarchy starting at "obj". We mark
1656 * ourselves on entry and clear the mark on exit. If we ever encounter
1657 * a marked object, we have a cycle.
1658 *
1659 * Returns "true" if all is well, "false" if we found a cycle.
1660 */
1661static bool traverseTree(Thread* self, const Object* obj)
1662{
1663 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001664 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001665
1666 /*
1667 * Have we been here before?
1668 */
1669 if (mon->historyMark) {
1670 int* rawStackTrace;
1671 int stackDepth;
1672
1673 LOGW("%s\n", kStartBanner);
1674 LOGW("Illegal lock attempt:\n");
1675 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1676
1677 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1678 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1679 free(rawStackTrace);
1680
1681 LOGW(" ");
1682 logHeldMonitors(self);
1683
1684 LOGW(" ");
1685 LOGW("Earlier, the following lock order (from last to first) was\n");
1686 LOGW("established -- stack trace is from first successful lock):\n");
1687 return false;
1688 }
1689 mon->historyMark = true;
1690
1691 /*
1692 * Examine the children. We do NOT hold these locks, so they might
1693 * very well transition from thin to fat or change ownership while
1694 * we work.
1695 *
1696 * NOTE: we rely on the fact that they cannot revert from fat to thin
1697 * while we work. This is currently a safe assumption.
1698 *
1699 * We can safely ignore thin-locked children, because by definition
1700 * they have no history and are leaf nodes. In the current
1701 * implementation we always fatten the locks to provide a place to
1702 * hang the stack trace.
1703 */
1704 ExpandingObjectList* pList = &mon->historyChildren;
1705 int i;
1706 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1707 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001708 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001709 if (!IS_LOCK_FAT(&lock))
1710 continue;
1711 if (!traverseTree(self, child)) {
1712 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1713 dvmLogRawStackTrace(mon->historyRawStackTrace,
1714 mon->historyStackDepth);
1715 mon->historyMark = false;
1716 return false;
1717 }
1718 }
1719
1720 mon->historyMark = false;
1721
1722 return true;
1723}
1724
1725/*
1726 * Update the deadlock prediction tree, based on the current thread
1727 * acquiring "acqObj". This must be called before the object is added to
1728 * the thread's list of held monitors.
1729 *
1730 * If the thread already holds the lock (recursion), or this is a known
1731 * lock configuration, we return without doing anything. Otherwise, we add
1732 * a link from the most-recently-acquired lock in this thread to "acqObj"
1733 * after ensuring that the parent lock is "fat".
1734 *
1735 * This MUST NOT be called while a GC is in progress in another thread,
1736 * because we assume exclusive access to history trees in owned monitors.
1737 */
1738static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1739{
1740 LockedObjectData* lod;
1741 LockedObjectData* mrl;
1742
1743 /*
1744 * Quick check for recursive access.
1745 */
1746 lod = dvmFindInMonitorList(self, acqObj);
1747 if (lod != NULL) {
1748 LOGV("+++ DP: recursive %p\n", acqObj);
1749 return;
1750 }
1751
1752 /*
1753 * Make the newly-acquired object's monitor "fat". In some ways this
1754 * isn't strictly necessary, but we need the GC to tell us when
1755 * "interesting" objects go away, and right now the only way to make
1756 * an object look interesting is to give it a monitor.
1757 *
1758 * This also gives us a place to hang a stack trace.
1759 *
1760 * Our thread holds the lock, so we're allowed to rewrite the lock
1761 * without worrying that something will change out from under us.
1762 */
1763 if (!IS_LOCK_FAT(&acqObj->lock)) {
1764 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001765 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001766 Monitor* newMon = dvmCreateMonitor(acqObj);
1767 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001768 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1769 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1770 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001771 }
1772
1773 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001774 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1775 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001776 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1777 &mon->historyStackDepth);
1778 }
1779
1780 /*
1781 * We need to examine and perhaps modify the most-recently-locked
1782 * monitor. We own that, so there's no risk of another thread
1783 * stepping on us.
1784 *
1785 * Retrieve the most-recently-locked entry from our thread.
1786 */
1787 mrl = self->pLockedObjects;
1788 if (mrl == NULL)
1789 return; /* no other locks held */
1790
1791 /*
1792 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1793 * this without holding the global lock because of our assertion that
1794 * a GC is not running in parallel -- nobody except the GC can
1795 * modify a history list in a Monitor they don't own, and we own "mrl".
1796 * (There might be concurrent *reads*, but no concurrent *writes.)
1797 *
1798 * If we find it, this is a known good configuration, and we're done.
1799 */
1800 if (objectInChildList(mrl->obj, acqObj))
1801 return;
1802
1803 /*
1804 * "mrl" is going to need to have a history tree. If it's currently
1805 * a thin lock, we make it fat now. The thin lock might have a
1806 * nonzero recursive lock count, which we need to carry over.
1807 *
1808 * Our thread holds the lock, so we're allowed to rewrite the lock
1809 * without worrying that something will change out from under us.
1810 */
1811 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1812 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001813 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001814 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1815 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001816 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1817 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1818 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001819 }
1820
1821 /*
1822 * We haven't seen this configuration before. We need to scan down
1823 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1824 * appear. We grab a global lock before traversing or updating the
1825 * history list.
1826 *
1827 * If we find a match for any of our held locks, we know that the lock
1828 * has previously been acquired *after* acqObj, and we throw an error.
1829 *
1830 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1831 * and do a recursive traversal, marking nodes as we cross them. If
1832 * we cross one a second time, we have a cycle and can throw an error.
1833 * (We do the flag-clearing traversal before adding the new link, so
1834 * that we're guaranteed to terminate.)
1835 *
1836 * If "acqObj" is a thin lock, it has no history, and we can create a
1837 * link to it without additional checks. [ We now guarantee that it's
1838 * always fat. ]
1839 */
1840 bool failed = false;
1841 dvmLockMutex(&gDvm.deadlockHistoryLock);
1842 linkParentToChild(mrl->obj, acqObj);
1843 if (!traverseTree(self, acqObj)) {
1844 LOGW("%s\n", kEndBanner);
1845 failed = true;
1846
1847 /* remove the entry so we're still okay when in "warning" mode */
1848 unlinkParentFromChild(mrl->obj, acqObj);
1849 }
1850 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1851
1852 if (failed) {
1853 switch (gDvm.deadlockPredictMode) {
1854 case kDPErr:
1855 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1856 break;
1857 case kDPAbort:
1858 LOGE("Aborting due to potential deadlock\n");
1859 dvmAbort();
1860 break;
1861 default:
1862 /* warn only */
1863 break;
1864 }
1865 }
1866}
1867
1868/*
1869 * We're removing "child" from existence. We want to pull all of
1870 * child's children into "parent", filtering out duplicates. This is
1871 * called during the GC.
1872 *
1873 * This does not modify "child", which might have multiple parents.
1874 */
1875static void mergeChildren(Object* parent, const Object* child)
1876{
1877 Monitor* mon;
1878 int i;
1879
1880 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001881 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001882 ExpandingObjectList* pList = &mon->historyChildren;
1883
1884 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1885 Object* grandChild = expandBufGetEntry(pList, i);
1886
1887 if (!objectInChildList(parent, grandChild)) {
1888 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1889 linkParentToChild(parent, grandChild);
1890 } else {
1891 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1892 }
1893 }
1894}
1895
1896/*
1897 * An object with a fat lock is being collected during a GC pass. We
1898 * want to remove it from any lock history trees that it is a part of.
1899 *
1900 * This may require updating the history trees in several monitors. The
1901 * monitor semantics guarantee that no other thread will be accessing
1902 * the history trees at the same time.
1903 */
1904static void removeCollectedObject(Object* obj)
1905{
1906 Monitor* mon;
1907
1908 LOGVV("+++ collecting %p\n", obj);
1909
1910#if 0
1911 /*
1912 * We're currently running through the entire set of known monitors.
1913 * This can be somewhat slow. We may want to keep lists of parents
1914 * in each child to speed up GC.
1915 */
1916 mon = gDvm.monitorList;
1917 while (mon != NULL) {
1918 Object* parent = mon->obj;
1919 if (parent != NULL) { /* value nulled for deleted entries */
1920 if (objectInChildList(parent, obj)) {
1921 LOGVV("removing child %p from parent %p\n", obj, parent);
1922 unlinkParentFromChild(parent, obj);
1923 mergeChildren(parent, obj);
1924 }
1925 }
1926 mon = mon->next;
1927 }
1928#endif
1929
1930 /*
1931 * For every parent of this object:
1932 * - merge all of our children into the parent's child list (creates
1933 * a two-way link between parent and child)
1934 * - remove ourselves from the parent's child list
1935 */
1936 ExpandingObjectList* pList;
1937 int i;
1938
1939 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001940 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001941 pList = &mon->historyParents;
1942 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1943 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001944 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001945
1946 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
1947 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
1948 }
1949 assert(!expandObjHas(&parentMon->historyChildren, obj));
1950
1951 mergeChildren(parent, obj);
1952 }
1953
1954 /*
1955 * For every child of this object:
1956 * - remove ourselves from the child's parent list
1957 */
1958 pList = &mon->historyChildren;
1959 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1960 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001961 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001962
1963 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
1964 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
1965 }
1966 assert(!expandObjHas(&childMon->historyParents, obj));
1967 }
1968}
1969
1970#endif /*WITH_DEADLOCK_PREDICTION*/
1971