blob: 47edd0d855ece3e2fbb676bac42989204904cf3d [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andy McFadden581bed72009-10-15 11:24:54 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Fundamental synchronization mechanisms.
19 *
20 * The top part of the file has operations on "monitor" structs; the
21 * next part has the native calls on objects.
22 *
23 * The current implementation uses "thin locking" to avoid allocating
24 * an Object's full Monitor struct until absolutely necessary (i.e.,
25 * during contention or a call to wait()).
26 *
27 * TODO: make improvements to thin locking
28 * We may be able to improve performance and reduce memory requirements by:
29 * - reverting to a thin lock once the Monitor is no longer necessary
30 * - using a pool of monitor objects, with some sort of recycling scheme
31 *
32 * TODO: recycle native-level monitors when objects are garbage collected.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080033 */
34#include "Dalvik.h"
35
36#include <stdlib.h>
37#include <unistd.h>
38#include <pthread.h>
39#include <time.h>
40#include <sys/time.h>
41#include <errno.h>
42
43#define LOG_THIN LOGV
44
45#ifdef WITH_DEADLOCK_PREDICTION /* fwd */
46static const char* kStartBanner =
47 "<-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#";
48static const char* kEndBanner =
49 "#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#->";
50
51/*
52 * Unsorted, expanding list of objects.
53 *
54 * This is very similar to PointerSet (which came into existence after this),
55 * but these are unsorted, uniqueness is not enforced by the "add" function,
56 * and the base object isn't allocated on the heap.
57 */
58typedef struct ExpandingObjectList {
59 u2 alloc;
60 u2 count;
61 Object** list;
62} ExpandingObjectList;
63
64/* fwd */
65static void updateDeadlockPrediction(Thread* self, Object* obj);
66static void removeCollectedObject(Object* obj);
67static void expandObjClear(ExpandingObjectList* pList);
68#endif
69
70/*
71 * Every Object has a monitor associated with it, but not every Object is
72 * actually locked. Even the ones that are locked do not need a
73 * full-fledged monitor until a) there is actual contention or b) wait()
74 * is called on the Object.
75 *
76 * For Dalvik, we have implemented a scheme similar to the one described
77 * in Bacon et al.'s "Thin locks: featherweight synchronization for Java"
78 * (ACM 1998). Things are even easier for us, though, because we have
79 * a full 32 bits to work with.
80 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080081 * The two states of an Object's lock are referred to as "thin" and
82 * "fat". A lock may transition from the "thin" state to the "fat"
83 * state and this transition is referred to as inflation. Once a lock
84 * has been inflated it remains in the "fat" state indefinitely.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080085 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080086 * The lock value itself is stored in Object.lock. The LSB of the
87 * lock encodes its state. When cleared, the lock is in the "thin"
88 * state and its bits are formatted as follows:
Carl Shapiro71938022009-12-22 13:49:53 -080089 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080090 * [31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
91 * lock count thread id hash state 0
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080092 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080093 * When set, the lock is in the "fat" state and its bits are formatted
Carl Shapiro94338aa2009-12-21 11:42:59 -080094 * as follows:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080095 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080096 * [31 ---- 3] [2 ---- 1] [0]
97 * pointer hash state 1
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080098 *
99 * For an in-depth description of the mechanics of thin-vs-fat locking,
100 * read the paper referred to above.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800101 */
102
103/*
104 * Monitors provide:
105 * - mutually exclusive access to resources
106 * - a way for multiple threads to wait for notification
107 *
108 * In effect, they fill the role of both mutexes and condition variables.
109 *
110 * Only one thread can own the monitor at any time. There may be several
111 * threads waiting on it (the wait call unlocks it). One or more waiting
112 * threads may be getting interrupted or notified at any given time.
113 */
114struct Monitor {
115 Thread* owner; /* which thread currently owns the lock? */
116 int lockCount; /* owner's recursive lock depth */
117 Object* obj; /* what object are we part of [debug only] */
118
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800119 Thread* waitSet; /* threads currently waiting on this monitor */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800120
121 pthread_mutex_t lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800122
123 Monitor* next;
124
125#ifdef WITH_DEADLOCK_PREDICTION
126 /*
127 * Objects that have been locked immediately after this one in the
128 * past. We use an expanding flat array, allocated on first use, to
129 * minimize allocations. Deletions from the list, expected to be
130 * infrequent, are crunched down.
131 */
132 ExpandingObjectList historyChildren;
133
134 /*
135 * We also track parents. This isn't strictly necessary, but it makes
136 * the cleanup at GC time significantly faster.
137 */
138 ExpandingObjectList historyParents;
139
140 /* used during cycle detection */
141 bool historyMark;
142
143 /* stack trace, established the first time we locked the object */
144 int historyStackDepth;
145 int* historyRawStackTrace;
146#endif
147};
148
149
150/*
151 * Create and initialize a monitor.
152 */
153Monitor* dvmCreateMonitor(Object* obj)
154{
155 Monitor* mon;
156
157 mon = (Monitor*) calloc(1, sizeof(Monitor));
158 if (mon == NULL) {
159 LOGE("Unable to allocate monitor\n");
160 dvmAbort();
161 }
Carl Shapiro94338aa2009-12-21 11:42:59 -0800162 if (((u4)mon & 7) != 0) {
163 LOGE("Misaligned monitor: %p\n", mon);
164 dvmAbort();
165 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800166 mon->obj = obj;
167 dvmInitMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800168
169 /* replace the head of the list with the new monitor */
170 do {
171 mon->next = gDvm.monitorList;
172 } while (!ATOMIC_CMP_SWAP((int32_t*)(void*)&gDvm.monitorList,
173 (int32_t)mon->next, (int32_t)mon));
174
175 return mon;
176}
177
178/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800179 * Free the monitor list. Only used when shutting the VM down.
180 */
181void dvmFreeMonitorList(void)
182{
183 Monitor* mon;
184 Monitor* nextMon;
185
186 mon = gDvm.monitorList;
187 while (mon != NULL) {
188 nextMon = mon->next;
189
190#ifdef WITH_DEADLOCK_PREDICTION
191 expandObjClear(&mon->historyChildren);
192 expandObjClear(&mon->historyParents);
193 free(mon->historyRawStackTrace);
194#endif
195 free(mon);
196 mon = nextMon;
197 }
198}
199
200/*
201 * Log some info about our monitors.
202 */
203void dvmDumpMonitorInfo(const char* msg)
204{
205#if QUIET_ZYGOTE_MONITOR
206 if (gDvm.zygote) {
207 return;
208 }
209#endif
210
211 int totalCount;
212 int liveCount;
213
214 totalCount = liveCount = 0;
215 Monitor* mon = gDvm.monitorList;
216 while (mon != NULL) {
217 totalCount++;
218 if (mon->obj != NULL)
219 liveCount++;
220 mon = mon->next;
221 }
222
223 LOGD("%s: monitor list has %d entries (%d live)\n",
224 msg, totalCount, liveCount);
225}
226
227/*
228 * Get the object that a monitor is part of.
229 */
230Object* dvmGetMonitorObject(Monitor* mon)
231{
232 if (mon == NULL)
233 return NULL;
234 else
235 return mon->obj;
236}
237
238/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800239 * Returns the thread id of the thread owning the given lock.
240 */
241static u4 lockOwner(Object* obj)
242{
243 Thread *owner;
244 u4 lock;
245
246 assert(obj != NULL);
247 /*
248 * Since we're reading the lock value multiple times, latch it so
249 * that it doesn't change out from under us if we get preempted.
250 */
251 lock = obj->lock;
252 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
253 return LW_LOCK_OWNER(lock);
254 } else {
255 owner = LW_MONITOR(lock)->owner;
256 return owner ? owner->threadId : 0;
257 }
258}
259
260/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800261 * Checks whether the given thread holds the given
262 * objects's lock.
263 */
264bool dvmHoldsLock(Thread* thread, Object* obj)
265{
266 if (thread == NULL || obj == NULL) {
267 return false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800268 } else {
Carl Shapiro30aa9972010-01-13 22:07:50 -0800269 return thread->threadId == lockOwner(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800270 }
271}
272
273/*
274 * Free the monitor associated with an object and make the object's lock
275 * thin again. This is called during garbage collection.
276 */
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800277static void freeObjectMonitor(Object* obj)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800278{
279 Monitor *mon;
280
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800281 assert(LW_SHAPE(obj->lock) == LW_SHAPE_FAT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800282
283#ifdef WITH_DEADLOCK_PREDICTION
284 if (gDvm.deadlockPredictMode != kDPOff)
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800285 removeCollectedObject(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800286#endif
287
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800288 mon = LW_MONITOR(obj->lock);
289 obj->lock = DVM_LOCK_INITIAL_THIN_VALUE;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800290
291 /* This lock is associated with an object
292 * that's being swept. The only possible way
293 * anyone could be holding this lock would be
294 * if some JNI code locked but didn't unlock
295 * the object, in which case we've got some bad
296 * native code somewhere.
297 */
298 assert(pthread_mutex_trylock(&mon->lock) == 0);
299 pthread_mutex_destroy(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800300#ifdef WITH_DEADLOCK_PREDICTION
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800301 expandObjClear(&mon->historyChildren);
302 expandObjClear(&mon->historyParents);
303 free(mon->historyRawStackTrace);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800304#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800305 free(mon);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800306}
307
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800308/*
309 * Frees monitor objects belonging to unmarked objects.
310 */
311void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
312{
313 Monitor handle;
314 Monitor *prev, *curr;
315 Object *obj;
316
317 assert(mon != NULL);
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800318 assert(isUnmarkedObject != NULL);
319 prev = &handle;
320 prev->next = curr = *mon;
321 while (curr != NULL) {
322 obj = curr->obj;
323 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
324 prev->next = curr = curr->next;
325 freeObjectMonitor(obj);
326 } else {
327 prev = curr;
328 curr = curr->next;
329 }
330 }
331 *mon = handle.next;
332}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800333
334/*
335 * Lock a monitor.
336 */
337static void lockMonitor(Thread* self, Monitor* mon)
338{
339 int cc;
340
341 if (mon->owner == self) {
342 mon->lockCount++;
343 } else {
344 ThreadStatus oldStatus;
345
346 if (pthread_mutex_trylock(&mon->lock) != 0) {
347 /* mutex is locked, switch to wait status and sleep on it */
348 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
349 cc = pthread_mutex_lock(&mon->lock);
350 assert(cc == 0);
351 dvmChangeStatus(self, oldStatus);
352 }
353
354 mon->owner = self;
355 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800356 }
357}
358
359/*
360 * Try to lock a monitor.
361 *
362 * Returns "true" on success.
363 */
364static bool tryLockMonitor(Thread* self, Monitor* mon)
365{
366 int cc;
367
368 if (mon->owner == self) {
369 mon->lockCount++;
370 return true;
371 } else {
372 cc = pthread_mutex_trylock(&mon->lock);
373 if (cc == 0) {
374 mon->owner = self;
375 assert(mon->lockCount == 0);
376 return true;
377 } else {
378 return false;
379 }
380 }
381}
382
383
384/*
385 * Unlock a monitor.
386 *
387 * Returns true if the unlock succeeded.
388 * If the unlock failed, an exception will be pending.
389 */
390static bool unlockMonitor(Thread* self, Monitor* mon)
391{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800392 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800393 assert(mon != NULL); // can this happen?
394
395 if (mon->owner == self) {
396 /*
397 * We own the monitor, so nobody else can be in here.
398 */
399 if (mon->lockCount == 0) {
400 int cc;
401 mon->owner = NULL;
402 cc = pthread_mutex_unlock(&mon->lock);
403 assert(cc == 0);
404 } else {
405 mon->lockCount--;
406 }
407 } else {
408 /*
409 * We don't own this, so we're not allowed to unlock it.
410 * The JNI spec says that we should throw IllegalMonitorStateException
411 * in this case.
412 */
413 if (mon->owner == NULL) {
414 //LOGW("Unlock fat %p: not owned\n", mon->obj);
415 } else {
416 //LOGW("Unlock fat %p: id %d vs %d\n",
417 // mon->obj, mon->owner->threadId, self->threadId);
418 }
419 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
420 "unlock of unowned monitor");
421 return false;
422 }
423 return true;
424}
425
426/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800427 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800428 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800429 */
430static int waitSetCheck(Monitor *mon)
431{
432 Thread *fast, *slow;
433 size_t n;
434
435 assert(mon != NULL);
436 fast = slow = mon->waitSet;
437 n = 0;
438 for (;;) {
439 if (fast == NULL) return 0;
440 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800441 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800442 n += 2;
443 fast = fast->waitNext->waitNext;
444 slow = slow->waitNext;
445 }
446}
447
448/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800449 * Links a thread into a monitor's wait set. The monitor lock must be
450 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800451 */
452static void waitSetAppend(Monitor *mon, Thread *thread)
453{
454 Thread *elt;
455
456 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800457 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800458 assert(thread != NULL);
459 assert(thread->waitNext == NULL);
460 assert(waitSetCheck(mon) == 0);
461 if (mon->waitSet == NULL) {
462 mon->waitSet = thread;
463 return;
464 }
465 elt = mon->waitSet;
466 while (elt->waitNext != NULL) {
467 elt = elt->waitNext;
468 }
469 elt->waitNext = thread;
470}
471
472/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800473 * Unlinks a thread from a monitor's wait set. The monitor lock must
474 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800475 */
476static void waitSetRemove(Monitor *mon, Thread *thread)
477{
478 Thread *elt;
479
480 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800481 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800482 assert(thread != NULL);
483 assert(waitSetCheck(mon) == 0);
484 if (mon->waitSet == NULL) {
485 return;
486 }
487 if (mon->waitSet == thread) {
488 mon->waitSet = thread->waitNext;
489 thread->waitNext = NULL;
490 return;
491 }
492 elt = mon->waitSet;
493 while (elt->waitNext != NULL) {
494 if (elt->waitNext == thread) {
495 elt->waitNext = thread->waitNext;
496 thread->waitNext = NULL;
497 return;
498 }
499 elt = elt->waitNext;
500 }
501}
502
Carl Shapirob4539192010-01-04 16:50:00 -0800503/*
504 * Converts the given relative waiting time into an absolute time.
505 */
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800506void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800507{
508 s8 endSec;
509
510#ifdef HAVE_TIMEDWAIT_MONOTONIC
511 clock_gettime(CLOCK_MONOTONIC, ts);
512#else
513 {
514 struct timeval tv;
515 gettimeofday(&tv, NULL);
516 ts->tv_sec = tv.tv_sec;
517 ts->tv_nsec = tv.tv_usec * 1000;
518 }
519#endif
520 endSec = ts->tv_sec + msec / 1000;
521 if (endSec >= 0x7fffffff) {
522 LOGV("NOTE: end time exceeds epoch\n");
523 endSec = 0x7ffffffe;
524 }
525 ts->tv_sec = endSec;
526 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
527
528 /* catch rollover */
529 if (ts->tv_nsec >= 1000000000L) {
530 ts->tv_sec++;
531 ts->tv_nsec -= 1000000000L;
532 }
533}
534
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800535int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
536 s8 msec, s4 nsec)
537{
538 int ret;
539 struct timespec ts;
540 absoluteTime(msec, nsec, &ts);
541#if defined(HAVE_TIMEDWAIT_MONOTONIC)
542 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
543#else
544 ret = pthread_cond_timedwait(cond, mutex, &ts);
545#endif
546 assert(ret == 0 || ret == ETIMEDOUT);
547 return ret;
548}
549
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800550/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800551 * Wait on a monitor until timeout, interrupt, or notification. Used for
552 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
553 *
554 * If another thread calls Thread.interrupt(), we throw InterruptedException
555 * and return immediately if one of the following are true:
556 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
557 * - blocked in join(), join(long), or join(long, int) methods of Thread
558 * - blocked in sleep(long), or sleep(long, int) methods of Thread
559 * Otherwise, we set the "interrupted" flag.
560 *
561 * Checks to make sure that "nsec" is in the range 0-999999
562 * (i.e. fractions of a millisecond) and throws the appropriate
563 * exception if it isn't.
564 *
565 * The spec allows "spurious wakeups", and recommends that all code using
566 * Object.wait() do so in a loop. This appears to derive from concerns
567 * about pthread_cond_wait() on multiprocessor systems. Some commentary
568 * on the web casts doubt on whether these can/should occur.
569 *
570 * Since we're allowed to wake up "early", we clamp extremely long durations
571 * to return at the end of the 32-bit time epoch.
572 */
573static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
574 bool interruptShouldThrow)
575{
576 struct timespec ts;
577 bool wasInterrupted = false;
578 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800579 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800580
Carl Shapiro71938022009-12-22 13:49:53 -0800581 assert(self != NULL);
582 assert(mon != NULL);
583
Carl Shapiro94338aa2009-12-21 11:42:59 -0800584 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800585 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800586 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
587 "object not locked by thread before wait()");
588 return;
589 }
590
591 /*
592 * Enforce the timeout range.
593 */
594 if (msec < 0 || nsec < 0 || nsec > 999999) {
595 dvmThrowException("Ljava/lang/IllegalArgumentException;",
596 "timeout arguments out of range");
597 return;
598 }
599
600 /*
601 * Compute absolute wakeup time, if necessary.
602 */
603 if (msec == 0 && nsec == 0) {
604 timed = false;
605 } else {
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800606 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800607 timed = true;
608 }
609
610 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800611 * Add ourselves to the set of threads waiting on this monitor, and
612 * release our hold. We need to let it go even if we're a few levels
613 * deep in a recursive lock, and we need to restore that later.
614 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800615 * We append to the wait set ahead of clearing the count and owner
616 * fields so the subroutine can check that the calling thread owns
617 * the monitor. Aside from that, the order of member updates is
618 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800619 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800620 waitSetAppend(mon, self);
621 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800622 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800623 mon->owner = NULL;
624
625 /*
626 * Update thread status. If the GC wakes up, it'll ignore us, knowing
627 * that we won't touch any references in this state, and we'll check
628 * our suspend mode before we transition out.
629 */
630 if (timed)
631 dvmChangeStatus(self, THREAD_TIMED_WAIT);
632 else
633 dvmChangeStatus(self, THREAD_WAIT);
634
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800635 ret = pthread_mutex_lock(&self->waitMutex);
636 assert(ret == 0);
637
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800638 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800639 * Set waitMonitor to the monitor object we will be waiting on.
640 * When waitMonitor is non-NULL a notifying or interrupting thread
641 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800642 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800643 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800644 self->waitMonitor = mon;
645
646 /*
647 * Handle the case where the thread was interrupted before we called
648 * wait().
649 */
650 if (self->interrupted) {
651 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800652 self->waitMonitor = NULL;
653 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800654 goto done;
655 }
656
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800657 /*
658 * Release the monitor lock and wait for a notification or
659 * a timeout to occur.
660 */
661 pthread_mutex_unlock(&mon->lock);
662
663 if (!timed) {
664 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
665 assert(ret == 0);
666 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800667#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800668 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800669#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800670 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800671#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800672 assert(ret == 0 || ret == ETIMEDOUT);
673 }
674 if (self->interrupted) {
675 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800676 }
677
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800678 self->interrupted = false;
679 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800680
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800681 pthread_mutex_unlock(&self->waitMutex);
682
Carl Shapiro30aa9972010-01-13 22:07:50 -0800683 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800684 lockMonitor(self, mon);
685
Carl Shapiro142ef272010-01-25 12:51:31 -0800686done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800687 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800688 * We remove our thread from wait set after restoring the count
689 * and owner fields so the subroutine can check that the calling
690 * thread owns the monitor. Aside from that, the order of member
691 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800692 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800693 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800694 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800695 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800696
697 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
698 dvmChangeStatus(self, THREAD_RUNNING);
699
700 if (wasInterrupted) {
701 /*
702 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800703 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800704 *
705 * The doc sayeth: "The interrupted status of the current thread is
706 * cleared when this exception is thrown."
707 */
708 self->interrupted = false;
709 if (interruptShouldThrow)
710 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
711 }
712}
713
714/*
715 * Notify one thread waiting on this monitor.
716 */
717static void notifyMonitor(Thread* self, Monitor* mon)
718{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800719 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800720
Carl Shapiro71938022009-12-22 13:49:53 -0800721 assert(self != NULL);
722 assert(mon != NULL);
723
Carl Shapiro94338aa2009-12-21 11:42:59 -0800724 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800725 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800726 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
727 "object not locked by thread before notify()");
728 return;
729 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800730 /* Signal the first waiting thread in the wait set. */
731 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800732 thread = mon->waitSet;
733 mon->waitSet = thread->waitNext;
734 thread->waitNext = NULL;
735 pthread_mutex_lock(&thread->waitMutex);
736 /* Check to see if the thread is still waiting. */
737 if (thread->waitMonitor != NULL) {
738 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800739 pthread_mutex_unlock(&thread->waitMutex);
740 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800741 }
742 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800743 }
744}
745
746/*
747 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800748 */
749static void notifyAllMonitor(Thread* self, Monitor* mon)
750{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800751 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800752
Carl Shapiro71938022009-12-22 13:49:53 -0800753 assert(self != NULL);
754 assert(mon != NULL);
755
Carl Shapiro94338aa2009-12-21 11:42:59 -0800756 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800757 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800758 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
759 "object not locked by thread before notifyAll()");
760 return;
761 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800762 /* Signal all threads in the wait set. */
763 while (mon->waitSet != NULL) {
764 thread = mon->waitSet;
765 mon->waitSet = thread->waitNext;
766 thread->waitNext = NULL;
767 pthread_mutex_lock(&thread->waitMutex);
768 /* Check to see if the thread is still waiting. */
769 if (thread->waitMonitor != NULL) {
770 pthread_cond_signal(&thread->waitCond);
771 }
772 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800773 }
774}
775
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800776/*
777 * Implements monitorenter for "synchronized" stuff.
778 *
779 * This does not fail or throw an exception (unless deadlock prediction
780 * is enabled and set to "err" mode).
781 */
782void dvmLockObject(Thread* self, Object *obj)
783{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800784 volatile u4 *thinp = &obj->lock;
785 u4 hashState;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800786 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800787 u4 threadId = self->threadId;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800788 Monitor *mon;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800789
790 /* First, try to grab the lock as if it's thin;
791 * this is the common case and will usually succeed.
792 */
Carl Shapiro30aa9972010-01-13 22:07:50 -0800793 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800794 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800795 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800796 if (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800797 hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800798 (int32_t)thin)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800799 /* The lock is either a thin lock held by someone (possibly 'self'),
800 * or a fat lock.
801 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800802 if (LW_LOCK_OWNER(*thinp) == threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800803 /* 'self' is already holding the thin lock; we can just
804 * bump the count. Atomic operations are not necessary
805 * because only the thread holding the lock is allowed
806 * to modify the Lock field.
807 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800808 *thinp += 1 << LW_LOCK_COUNT_SHIFT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800809 } else {
810 /* If this is a thin lock we need to spin on it, if it's fat
811 * we need to acquire the monitor.
812 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800813 if (LW_SHAPE(*thinp) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800814 ThreadStatus oldStatus;
815 static const unsigned long maxSleepDelay = 1 * 1024 * 1024;
816 unsigned long sleepDelay;
817
818 LOG_THIN("(%d) spin on lock 0x%08x: 0x%08x (0x%08x) 0x%08x\n",
819 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800820 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800821
822 /* The lock is still thin, but some other thread is
823 * holding it. Let the VM know that we're about
824 * to wait on another thread.
825 */
826 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
827
828 /* Spin until the other thread lets go.
829 */
830 sleepDelay = 0;
831 do {
832 /* In addition to looking for an unlock,
833 * we need to watch out for some other thread
834 * fattening the lock behind our back.
835 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800836 while (LW_LOCK_OWNER(*thinp) != 0) {
837 if (LW_SHAPE(*thinp) == LW_SHAPE_FAT) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800838 /* The lock has been fattened already.
839 */
840 LOG_THIN("(%d) lock 0x%08x surprise-fattened\n",
841 threadId, (uint)&obj->lock);
842 dvmChangeStatus(self, oldStatus);
843 goto fat_lock;
844 }
845
846 if (sleepDelay == 0) {
847 sched_yield();
848 sleepDelay = 1 * 1000;
849 } else {
850 usleep(sleepDelay);
851 if (sleepDelay < maxSleepDelay / 2) {
852 sleepDelay *= 2;
853 }
854 }
855 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800856 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800857 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800858 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800859 } while (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800860 (int32_t)hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800861 (int32_t)thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800862 LOG_THIN("(%d) spin on lock done 0x%08x: "
863 "0x%08x (0x%08x) 0x%08x\n",
864 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800865 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800866
867 /* We've got the thin lock; let the VM know that we're
868 * done waiting.
869 */
870 dvmChangeStatus(self, oldStatus);
871
872 /* Fatten the lock. Note this relinquishes ownership.
873 * We could also create the monitor in an "owned" state
874 * to avoid "re-locking" it in fat_lock.
875 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800876 mon = dvmCreateMonitor(obj);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800877 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
878 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800879 LOG_THIN("(%d) lock 0x%08x fattened\n",
880 threadId, (uint)&obj->lock);
881
882 /* Fall through to acquire the newly fat lock.
883 */
884 }
885
886 /* The lock is already fat, which means
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800887 * that obj->lock is a regular (Monitor *).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800888 */
889 fat_lock:
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800890 assert(LW_MONITOR(obj->lock) != NULL);
891 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800892 }
893 }
894 // else, the lock was acquired with the ATOMIC_CMP_SWAP().
895
896#ifdef WITH_DEADLOCK_PREDICTION
897 /*
898 * See if we were allowed to grab the lock at this time. We do it
899 * *after* acquiring the lock, rather than before, so that we can
900 * freely update the Monitor struct. This seems counter-intuitive,
901 * but our goal is deadlock *prediction* not deadlock *prevention*.
902 * (If we actually deadlock, the situation is easy to diagnose from
903 * a thread dump, so there's no point making a special effort to do
904 * the checks before the lock is held.)
905 *
906 * This needs to happen before we add the object to the thread's
907 * monitor list, so we can tell the difference between first-lock and
908 * re-lock.
909 *
910 * It's also important that we do this while in THREAD_RUNNING, so
911 * that we don't interfere with cleanup operations in the GC.
912 */
913 if (gDvm.deadlockPredictMode != kDPOff) {
914 if (self->status != THREAD_RUNNING) {
915 LOGE("Bad thread status (%d) in DP\n", self->status);
916 dvmDumpThread(self, false);
917 dvmAbort();
918 }
919 assert(!dvmCheckException(self));
920 updateDeadlockPrediction(self, obj);
921 if (dvmCheckException(self)) {
922 /*
923 * If we're throwing an exception here, we need to free the
924 * lock. We add the object to the thread's monitor list so the
925 * "unlock" code can remove it.
926 */
927 dvmAddToMonitorList(self, obj, false);
928 dvmUnlockObject(self, obj);
929 LOGV("--- unlocked, pending is '%s'\n",
930 dvmGetException(self)->clazz->descriptor);
931 }
932 }
933
934 /*
935 * Add the locked object, and the current stack trace, to the list
936 * held by the Thread object. If deadlock prediction isn't on,
937 * don't capture the stack trace.
938 */
939 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
940#elif defined(WITH_MONITOR_TRACKING)
941 /*
942 * Add the locked object to the list held by the Thread object.
943 */
944 dvmAddToMonitorList(self, obj, false);
945#endif
946}
947
948/*
949 * Implements monitorexit for "synchronized" stuff.
950 *
951 * On failure, throws an exception and returns "false".
952 */
953bool dvmUnlockObject(Thread* self, Object *obj)
954{
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800955 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800956 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800957
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800958 assert(self != NULL);
959 assert(self->status == THREAD_RUNNING);
960 assert(obj != NULL);
961
962 thinp = &obj->lock;
963 /*
964 * Cache the lock word as its value can change while we are
965 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800966 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800967 thin = *thinp;
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800968 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
969 /*
970 * The lock is thin. We must ensure that the lock is owned
971 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800972 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800973 if (LW_LOCK_OWNER(thin) == self->threadId) {
974 /*
975 * We are the lock owner. It is safe to update the lock
976 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800977 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800978 if (LW_LOCK_COUNT(thin) == 0) {
979 /*
980 * The lock was not recursively acquired, the common
981 * case. Unlock by clearing all bits except for the
982 * hash state.
983 */
984 *thinp &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
985 } else {
986 /*
987 * The object was recursively acquired. Decrement the
988 * lock recursion count field.
989 */
990 *thinp -= 1 << LW_LOCK_COUNT_SHIFT;
991 }
992 } else {
993 /*
994 * We do not own the lock. The JVM spec requires that we
995 * throw an exception in this case.
996 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800997 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800998 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800999 return false;
1000 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001001 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001002 /*
1003 * The lock is fat. We must check to see if unlockMonitor has
1004 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001005 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001006 assert(LW_MONITOR(obj->lock) != NULL);
1007 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001008 /*
1009 * An exception has been raised. Do not fall through.
1010 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001011 return false;
1012 }
1013 }
1014
1015#ifdef WITH_MONITOR_TRACKING
1016 /*
1017 * Remove the object from the Thread's list.
1018 */
1019 dvmRemoveFromMonitorList(self, obj);
1020#endif
1021
1022 return true;
1023}
1024
1025/*
1026 * Object.wait(). Also called for class init.
1027 */
1028void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1029 bool interruptShouldThrow)
1030{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001031 Monitor* mon = LW_MONITOR(obj->lock);
1032 u4 hashState;
1033 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001034
1035 /* If the lock is still thin, we need to fatten it.
1036 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001037 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001038 /* Make sure that 'self' holds the lock.
1039 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001040 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001041 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1042 "object not locked by thread before wait()");
1043 return;
1044 }
1045
1046 /* This thread holds the lock. We need to fatten the lock
1047 * so 'self' can block on it. Don't update the object lock
1048 * field yet, because 'self' needs to acquire the lock before
1049 * any other thread gets a chance.
1050 */
1051 mon = dvmCreateMonitor(obj);
1052
1053 /* 'self' has actually locked the object one or more times;
1054 * make sure that the monitor reflects this.
1055 */
1056 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001057 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001058 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1059 self->threadId, (uint)&obj->lock, mon->lockCount);
1060
Andy McFadden581bed72009-10-15 11:24:54 -07001061
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001062 /* Make the monitor public now that it's in the right state.
1063 */
Andy McFadden581bed72009-10-15 11:24:54 -07001064 MEM_BARRIER();
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001065 hashState = LW_HASH_STATE(thin) << LW_HASH_STATE_SHIFT;
1066 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001067 }
1068
1069 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1070}
1071
1072/*
1073 * Object.notify().
1074 */
1075void dvmObjectNotify(Thread* self, Object *obj)
1076{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001077 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001078
1079 /* If the lock is still thin, there aren't any waiters;
1080 * waiting on an object forces lock fattening.
1081 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001082 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001083 /* Make sure that 'self' holds the lock.
1084 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001085 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001086 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1087 "object not locked by thread before notify()");
1088 return;
1089 }
1090
1091 /* no-op; there are no waiters to notify.
1092 */
1093 } else {
1094 /* It's a fat lock.
1095 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001096 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001097 }
1098}
1099
1100/*
1101 * Object.notifyAll().
1102 */
1103void dvmObjectNotifyAll(Thread* self, Object *obj)
1104{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001105 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001106
1107 /* If the lock is still thin, there aren't any waiters;
1108 * waiting on an object forces lock fattening.
1109 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001110 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001111 /* Make sure that 'self' holds the lock.
1112 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001113 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001114 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1115 "object not locked by thread before notifyAll()");
1116 return;
1117 }
1118
1119 /* no-op; there are no waiters to notify.
1120 */
1121 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001122 /* It's a fat lock.
1123 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001124 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001125 }
1126}
1127
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001128/*
1129 * This implements java.lang.Thread.sleep(long msec, int nsec).
1130 *
1131 * The sleep is interruptible by other threads, which means we can't just
1132 * plop into an OS sleep call. (We probably could if we wanted to send
1133 * signals around and rely on EINTR, but that's inefficient and relies
1134 * on native code respecting our signal mask.)
1135 *
1136 * We have to do all of this stuff for Object.wait() as well, so it's
1137 * easiest to just sleep on a private Monitor.
1138 *
1139 * It appears that we want sleep(0,0) to go through the motions of sleeping
1140 * for a very short duration, rather than just returning.
1141 */
1142void dvmThreadSleep(u8 msec, u4 nsec)
1143{
1144 Thread* self = dvmThreadSelf();
1145 Monitor* mon = gDvm.threadSleepMon;
1146
1147 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1148 if (msec == 0 && nsec == 0)
1149 nsec++;
1150
1151 lockMonitor(self, mon);
1152 waitMonitor(self, mon, msec, nsec, true);
1153 unlockMonitor(self, mon);
1154}
1155
1156/*
1157 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001158 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001159void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001160{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001161 assert(thread != NULL);
1162
1163 pthread_mutex_lock(&thread->waitMutex);
1164
1165 /*
1166 * If the interrupted flag is already set no additional action is
1167 * required.
1168 */
1169 if (thread->interrupted == true) {
1170 pthread_mutex_unlock(&thread->waitMutex);
1171 return;
1172 }
1173
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001174 /*
1175 * Raise the "interrupted" flag. This will cause it to bail early out
1176 * of the next wait() attempt, if it's not currently waiting on
1177 * something.
1178 */
1179 thread->interrupted = true;
1180 MEM_BARRIER();
1181
1182 /*
1183 * Is the thread waiting?
1184 *
1185 * Note that fat vs. thin doesn't matter here; waitMonitor
1186 * is only set when a thread actually waits on a monitor,
1187 * which implies that the monitor has already been fattened.
1188 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001189 if (thread->waitMonitor != NULL) {
1190 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001191 }
1192
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001193 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001194}
1195
Carl Shapiro30aa9972010-01-13 22:07:50 -08001196#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001197u4 dvmIdentityHashCode(Object *obj)
1198{
1199 return (u4)obj;
1200}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001201#else
1202static size_t arrayElementWidth(const ArrayObject *array)
1203{
1204 const char *descriptor;
1205
1206 if (dvmIsObjectArray(array)) {
1207 return sizeof(Object *);
1208 } else {
1209 descriptor = array->obj.clazz->descriptor;
1210 switch (descriptor[1]) {
1211 case 'B': return 1; /* byte */
1212 case 'C': return 2; /* char */
1213 case 'D': return 8; /* double */
1214 case 'F': return 4; /* float */
1215 case 'I': return 4; /* int */
1216 case 'J': return 8; /* long */
1217 case 'S': return 2; /* short */
1218 case 'Z': return 1; /* boolean */
1219 }
1220 }
1221 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1222 dvmDumpThread(dvmThreadSelf(), false);
1223 dvmAbort();
1224 return 0; /* Quiet the compiler. */
1225}
1226
1227static size_t arrayObjectLength(const ArrayObject *array)
1228{
1229 size_t length;
1230
1231 length = offsetof(ArrayObject, contents);
1232 length += array->length * arrayElementWidth(array);
1233 return length;
1234}
1235
1236/*
1237 * Returns the identity hash code of the given object.
1238 */
1239u4 dvmIdentityHashCode(Object *obj)
1240{
1241 Thread *self, *thread;
1242 volatile u4 *lw;
1243 size_t length;
1244 u4 lock, owner, hashState;
1245
1246 if (obj == NULL) {
1247 /*
1248 * Null is defined to have an identity hash code of 0.
1249 */
1250 return 0;
1251 }
1252 lw = &obj->lock;
1253retry:
1254 hashState = LW_HASH_STATE(*lw);
1255 if (hashState == LW_HASH_STATE_HASHED) {
1256 /*
1257 * The object has been hashed but has not had its hash code
1258 * relocated by the garbage collector. Use the raw object
1259 * address.
1260 */
1261 return (u4)obj >> 3;
1262 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1263 /*
1264 * The object has been hashed and its hash code has been
1265 * relocated by the collector. Use the value of the naturally
1266 * aligned word following the instance data.
1267 */
1268 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1269 length = arrayObjectLength((ArrayObject *)obj);
1270 length = (length + 3) & ~3;
1271 } else {
1272 length = obj->clazz->objectSize;
1273 }
1274 return *(u4 *)(((char *)obj) + length);
1275 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1276 /*
1277 * The object has never been hashed. Change the hash state to
1278 * hashed and use the raw object address.
1279 */
1280 self = dvmThreadSelf();
1281 if (self->threadId == lockOwner(obj)) {
1282 /*
1283 * We already own the lock so we can update the hash state
1284 * directly.
1285 */
1286 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1287 return (u4)obj >> 3;
1288 }
1289 /*
1290 * We do not own the lock. Try acquiring the lock. Should
1291 * this fail, we must suspend the owning thread.
1292 */
1293 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1294 /*
1295 * If the lock is thin assume it is unowned. We simulate
1296 * an acquire, update, and release with a single CAS.
1297 */
1298 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1299 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1300 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1301 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1302 (int32_t)lock)) {
1303 /*
1304 * A new lockword has been installed with a hash state
1305 * of hashed. Use the raw object address.
1306 */
1307 return (u4)obj >> 3;
1308 }
1309 } else {
1310 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1311 /*
1312 * The monitor lock has been acquired. Change the
1313 * hash state to hashed and use the raw object
1314 * address.
1315 */
1316 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1317 unlockMonitor(self, LW_MONITOR(*lw));
1318 return (u4)obj >> 3;
1319 }
1320 }
1321 /*
1322 * At this point we have failed to acquire the lock. We must
1323 * identify the owning thread and suspend it.
1324 */
1325 dvmLockThreadList(self);
1326 /*
1327 * Cache the lock word as its value can change between
1328 * determining its shape and retrieving its owner.
1329 */
1330 lock = *lw;
1331 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1332 /*
1333 * Find the thread with the corresponding thread id.
1334 */
1335 owner = LW_LOCK_OWNER(lock);
1336 assert(owner != self->threadId);
1337 /*
1338 * If the lock has no owner do not bother scanning the
1339 * thread list and fall through to the failure handler.
1340 */
1341 thread = owner ? gDvm.threadList : NULL;
1342 while (thread != NULL) {
1343 if (thread->threadId == owner) {
1344 break;
1345 }
1346 thread = thread->next;
1347 }
1348 } else {
1349 thread = LW_MONITOR(lock)->owner;
1350 }
1351 /*
1352 * If thread is NULL the object has been released since the
1353 * thread list lock was acquired. Try again.
1354 */
1355 if (thread == NULL) {
1356 dvmUnlockThreadList();
1357 goto retry;
1358 }
1359 /*
1360 * Wait for the owning thread to suspend.
1361 */
1362 dvmSuspendThread(thread);
1363 if (dvmHoldsLock(thread, obj)) {
1364 /*
1365 * The owning thread has been suspended. We can safely
1366 * change the hash state to hashed.
1367 */
1368 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1369 dvmResumeThread(thread);
1370 dvmUnlockThreadList();
1371 return (u4)obj >> 3;
1372 }
1373 /*
1374 * The wrong thread has been suspended. Try again.
1375 */
1376 dvmResumeThread(thread);
1377 dvmUnlockThreadList();
1378 goto retry;
1379 }
1380 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1381 dvmDumpThread(dvmThreadSelf(), false);
1382 dvmAbort();
1383 return 0; /* Quiet the compiler. */
1384}
1385#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001386
1387#ifdef WITH_DEADLOCK_PREDICTION
1388/*
1389 * ===========================================================================
1390 * Deadlock prediction
1391 * ===========================================================================
1392 */
1393/*
1394The idea is to predict the possibility of deadlock by recording the order
1395in which monitors are acquired. If we see an attempt to acquire a lock
1396out of order, we can identify the locks and offending code.
1397
1398To make this work, we need to keep track of the locks held by each thread,
1399and create history trees for each lock. When a thread tries to acquire
1400a new lock, we walk through the "history children" of the lock, looking
1401for a match with locks the thread already holds. If we find a match,
1402it means the thread has made a request that could result in a deadlock.
1403
1404To support recursive locks, we always allow re-locking a currently-held
1405lock, and maintain a recursion depth count.
1406
1407An ASCII-art example, where letters represent Objects:
1408
1409 A
1410 /|\
1411 / | \
1412 B | D
1413 \ |
1414 \|
1415 C
1416
1417The above is the tree we'd have after handling Object synchronization
1418sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1419a child of B. (The lines represent pointers between parent and child.
1420Every node can have multiple parents and multiple children.)
1421
1422If we hold AC, and want to lock B, we recursively search through B's
1423children to see if A or C appears. It does, so we reject the attempt.
1424(A straightforward way to implement it: add a link from C to B, then
1425determine whether the graph starting at B contains a cycle.)
1426
1427If we hold AC and want to lock D, we would succeed, creating a new link
1428from C to D.
1429
1430The lock history and a stack trace is attached to the Object's Monitor
1431struct, which means we need to fatten every Object we lock (thin locking
1432is effectively disabled). If we don't need the stack trace we can
1433avoid fattening the leaf nodes, only fattening objects that need to hold
1434history trees.
1435
1436Updates to Monitor structs are only allowed for the thread that holds
1437the Monitor, so we actually do most of our deadlock prediction work after
1438the lock has been acquired.
1439
1440When an object with a monitor is GCed, we need to remove it from the
1441history trees. There are two basic approaches:
1442 (1) For through the entire set of known monitors, search all child
1443 lists for the object in question. This is rather slow, resulting
1444 in GC passes that take upwards of 10 seconds to complete.
1445 (2) Maintain "parent" pointers in each node. Remove the entries as
1446 required. This requires additional storage and maintenance for
1447 every operation, but is significantly faster at GC time.
1448For each GCed object, we merge all of the object's children into each of
1449the object's parents.
1450*/
1451
1452#if !defined(WITH_MONITOR_TRACKING)
1453# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1454#endif
1455
1456/*
1457 * Clear out the contents of an ExpandingObjectList, freeing any
1458 * dynamic allocations.
1459 */
1460static void expandObjClear(ExpandingObjectList* pList)
1461{
1462 if (pList->list != NULL) {
1463 free(pList->list);
1464 pList->list = NULL;
1465 }
1466 pList->alloc = pList->count = 0;
1467}
1468
1469/*
1470 * Get the number of objects currently stored in the list.
1471 */
1472static inline int expandBufGetCount(const ExpandingObjectList* pList)
1473{
1474 return pList->count;
1475}
1476
1477/*
1478 * Get the Nth entry from the list.
1479 */
1480static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1481 int i)
1482{
1483 return pList->list[i];
1484}
1485
1486/*
1487 * Add a new entry to the list.
1488 *
1489 * We don't check for or try to enforce uniqueness. It's expected that
1490 * the higher-level code does this for us.
1491 */
1492static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1493{
1494 if (pList->count == pList->alloc) {
1495 /* time to expand */
1496 Object** newList;
1497
1498 if (pList->alloc == 0)
1499 pList->alloc = 4;
1500 else
1501 pList->alloc *= 2;
1502 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1503 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1504 if (newList == NULL) {
1505 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1506 dvmAbort();
1507 }
1508 pList->list = newList;
1509 }
1510
1511 pList->list[pList->count++] = obj;
1512}
1513
1514/*
1515 * Returns "true" if the element was successfully removed.
1516 */
1517static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1518{
1519 int i;
1520
1521 for (i = pList->count-1; i >= 0; i--) {
1522 if (pList->list[i] == obj)
1523 break;
1524 }
1525 if (i < 0)
1526 return false;
1527
1528 if (i != pList->count-1) {
1529 /*
1530 * The order of elements is not important, so we just copy the
1531 * last entry into the new slot.
1532 */
1533 //memmove(&pList->list[i], &pList->list[i+1],
1534 // (pList->count-1 - i) * sizeof(pList->list[0]));
1535 pList->list[i] = pList->list[pList->count-1];
1536 }
1537
1538 pList->count--;
1539 pList->list[pList->count] = (Object*) 0xdecadead;
1540 return true;
1541}
1542
1543/*
1544 * Returns "true" if "obj" appears in the list.
1545 */
1546static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1547{
1548 int i;
1549
1550 for (i = 0; i < pList->count; i++) {
1551 if (pList->list[i] == obj)
1552 return true;
1553 }
1554 return false;
1555}
1556
1557/*
1558 * Print the list contents to stdout. For debugging.
1559 */
1560static void expandObjDump(const ExpandingObjectList* pList)
1561{
1562 int i;
1563 for (i = 0; i < pList->count; i++)
1564 printf(" %p", pList->list[i]);
1565}
1566
1567/*
1568 * Check for duplicate entries. Returns the index of the first instance
1569 * of the duplicated value, or -1 if no duplicates were found.
1570 */
1571static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1572{
1573 int i, j;
1574 for (i = 0; i < pList->count-1; i++) {
1575 for (j = i + 1; j < pList->count; j++) {
1576 if (pList->list[i] == pList->list[j]) {
1577 return i;
1578 }
1579 }
1580 }
1581
1582 return -1;
1583}
1584
1585
1586/*
1587 * Determine whether "child" appears in the list of objects associated
1588 * with the Monitor in "parent". If "parent" is a thin lock, we return
1589 * false immediately.
1590 */
1591static bool objectInChildList(const Object* parent, Object* child)
1592{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001593 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001594 if (!IS_LOCK_FAT(&lock)) {
1595 //LOGI("on thin\n");
1596 return false;
1597 }
1598
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001599 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001600}
1601
1602/*
1603 * Print the child list.
1604 */
1605static void dumpKids(Object* parent)
1606{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001607 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001608
1609 printf("Children of %p:", parent);
1610 expandObjDump(&mon->historyChildren);
1611 printf("\n");
1612}
1613
1614/*
1615 * Add "child" to the list of children in "parent", and add "parent" to
1616 * the list of parents in "child".
1617 */
1618static void linkParentToChild(Object* parent, Object* child)
1619{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001620 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001621 assert(IS_LOCK_FAT(&parent->lock));
1622 assert(IS_LOCK_FAT(&child->lock));
1623 assert(parent != child);
1624 Monitor* mon;
1625
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001626 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001627 assert(!expandObjHas(&mon->historyChildren, child));
1628 expandObjAddEntry(&mon->historyChildren, child);
1629
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001630 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001631 assert(!expandObjHas(&mon->historyParents, parent));
1632 expandObjAddEntry(&mon->historyParents, parent);
1633}
1634
1635
1636/*
1637 * Remove "child" from the list of children in "parent".
1638 */
1639static void unlinkParentFromChild(Object* parent, Object* child)
1640{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001641 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001642 assert(IS_LOCK_FAT(&parent->lock));
1643 assert(IS_LOCK_FAT(&child->lock));
1644 assert(parent != child);
1645 Monitor* mon;
1646
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001647 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001648 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1649 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1650 }
1651 assert(!expandObjHas(&mon->historyChildren, child));
1652 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1653
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001654 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001655 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1656 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1657 }
1658 assert(!expandObjHas(&mon->historyParents, parent));
1659 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1660}
1661
1662
1663/*
1664 * Log the monitors held by the current thread. This is done as part of
1665 * flagging an error.
1666 */
1667static void logHeldMonitors(Thread* self)
1668{
1669 char* name = NULL;
1670
1671 name = dvmGetThreadName(self);
1672 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1673 self->threadId, name);
1674 LOGW("(most-recently-acquired on top):\n");
1675 free(name);
1676
1677 LockedObjectData* lod = self->pLockedObjects;
1678 while (lod != NULL) {
1679 LOGW("--- object %p[%d] (%s)\n",
1680 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1681 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1682
1683 lod = lod->next;
1684 }
1685}
1686
1687/*
1688 * Recursively traverse the object hierarchy starting at "obj". We mark
1689 * ourselves on entry and clear the mark on exit. If we ever encounter
1690 * a marked object, we have a cycle.
1691 *
1692 * Returns "true" if all is well, "false" if we found a cycle.
1693 */
1694static bool traverseTree(Thread* self, const Object* obj)
1695{
1696 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001697 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001698
1699 /*
1700 * Have we been here before?
1701 */
1702 if (mon->historyMark) {
1703 int* rawStackTrace;
1704 int stackDepth;
1705
1706 LOGW("%s\n", kStartBanner);
1707 LOGW("Illegal lock attempt:\n");
1708 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1709
1710 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1711 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1712 free(rawStackTrace);
1713
1714 LOGW(" ");
1715 logHeldMonitors(self);
1716
1717 LOGW(" ");
1718 LOGW("Earlier, the following lock order (from last to first) was\n");
1719 LOGW("established -- stack trace is from first successful lock):\n");
1720 return false;
1721 }
1722 mon->historyMark = true;
1723
1724 /*
1725 * Examine the children. We do NOT hold these locks, so they might
1726 * very well transition from thin to fat or change ownership while
1727 * we work.
1728 *
1729 * NOTE: we rely on the fact that they cannot revert from fat to thin
1730 * while we work. This is currently a safe assumption.
1731 *
1732 * We can safely ignore thin-locked children, because by definition
1733 * they have no history and are leaf nodes. In the current
1734 * implementation we always fatten the locks to provide a place to
1735 * hang the stack trace.
1736 */
1737 ExpandingObjectList* pList = &mon->historyChildren;
1738 int i;
1739 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1740 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001741 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001742 if (!IS_LOCK_FAT(&lock))
1743 continue;
1744 if (!traverseTree(self, child)) {
1745 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1746 dvmLogRawStackTrace(mon->historyRawStackTrace,
1747 mon->historyStackDepth);
1748 mon->historyMark = false;
1749 return false;
1750 }
1751 }
1752
1753 mon->historyMark = false;
1754
1755 return true;
1756}
1757
1758/*
1759 * Update the deadlock prediction tree, based on the current thread
1760 * acquiring "acqObj". This must be called before the object is added to
1761 * the thread's list of held monitors.
1762 *
1763 * If the thread already holds the lock (recursion), or this is a known
1764 * lock configuration, we return without doing anything. Otherwise, we add
1765 * a link from the most-recently-acquired lock in this thread to "acqObj"
1766 * after ensuring that the parent lock is "fat".
1767 *
1768 * This MUST NOT be called while a GC is in progress in another thread,
1769 * because we assume exclusive access to history trees in owned monitors.
1770 */
1771static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1772{
1773 LockedObjectData* lod;
1774 LockedObjectData* mrl;
1775
1776 /*
1777 * Quick check for recursive access.
1778 */
1779 lod = dvmFindInMonitorList(self, acqObj);
1780 if (lod != NULL) {
1781 LOGV("+++ DP: recursive %p\n", acqObj);
1782 return;
1783 }
1784
1785 /*
1786 * Make the newly-acquired object's monitor "fat". In some ways this
1787 * isn't strictly necessary, but we need the GC to tell us when
1788 * "interesting" objects go away, and right now the only way to make
1789 * an object look interesting is to give it a monitor.
1790 *
1791 * This also gives us a place to hang a stack trace.
1792 *
1793 * Our thread holds the lock, so we're allowed to rewrite the lock
1794 * without worrying that something will change out from under us.
1795 */
1796 if (!IS_LOCK_FAT(&acqObj->lock)) {
1797 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001798 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001799 Monitor* newMon = dvmCreateMonitor(acqObj);
1800 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001801 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1802 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1803 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001804 }
1805
1806 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001807 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1808 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001809 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1810 &mon->historyStackDepth);
1811 }
1812
1813 /*
1814 * We need to examine and perhaps modify the most-recently-locked
1815 * monitor. We own that, so there's no risk of another thread
1816 * stepping on us.
1817 *
1818 * Retrieve the most-recently-locked entry from our thread.
1819 */
1820 mrl = self->pLockedObjects;
1821 if (mrl == NULL)
1822 return; /* no other locks held */
1823
1824 /*
1825 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1826 * this without holding the global lock because of our assertion that
1827 * a GC is not running in parallel -- nobody except the GC can
1828 * modify a history list in a Monitor they don't own, and we own "mrl".
1829 * (There might be concurrent *reads*, but no concurrent *writes.)
1830 *
1831 * If we find it, this is a known good configuration, and we're done.
1832 */
1833 if (objectInChildList(mrl->obj, acqObj))
1834 return;
1835
1836 /*
1837 * "mrl" is going to need to have a history tree. If it's currently
1838 * a thin lock, we make it fat now. The thin lock might have a
1839 * nonzero recursive lock count, which we need to carry over.
1840 *
1841 * Our thread holds the lock, so we're allowed to rewrite the lock
1842 * without worrying that something will change out from under us.
1843 */
1844 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1845 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001846 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001847 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1848 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001849 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1850 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1851 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001852 }
1853
1854 /*
1855 * We haven't seen this configuration before. We need to scan down
1856 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1857 * appear. We grab a global lock before traversing or updating the
1858 * history list.
1859 *
1860 * If we find a match for any of our held locks, we know that the lock
1861 * has previously been acquired *after* acqObj, and we throw an error.
1862 *
1863 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1864 * and do a recursive traversal, marking nodes as we cross them. If
1865 * we cross one a second time, we have a cycle and can throw an error.
1866 * (We do the flag-clearing traversal before adding the new link, so
1867 * that we're guaranteed to terminate.)
1868 *
1869 * If "acqObj" is a thin lock, it has no history, and we can create a
1870 * link to it without additional checks. [ We now guarantee that it's
1871 * always fat. ]
1872 */
1873 bool failed = false;
1874 dvmLockMutex(&gDvm.deadlockHistoryLock);
1875 linkParentToChild(mrl->obj, acqObj);
1876 if (!traverseTree(self, acqObj)) {
1877 LOGW("%s\n", kEndBanner);
1878 failed = true;
1879
1880 /* remove the entry so we're still okay when in "warning" mode */
1881 unlinkParentFromChild(mrl->obj, acqObj);
1882 }
1883 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1884
1885 if (failed) {
1886 switch (gDvm.deadlockPredictMode) {
1887 case kDPErr:
1888 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1889 break;
1890 case kDPAbort:
1891 LOGE("Aborting due to potential deadlock\n");
1892 dvmAbort();
1893 break;
1894 default:
1895 /* warn only */
1896 break;
1897 }
1898 }
1899}
1900
1901/*
1902 * We're removing "child" from existence. We want to pull all of
1903 * child's children into "parent", filtering out duplicates. This is
1904 * called during the GC.
1905 *
1906 * This does not modify "child", which might have multiple parents.
1907 */
1908static void mergeChildren(Object* parent, const Object* child)
1909{
1910 Monitor* mon;
1911 int i;
1912
1913 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001914 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001915 ExpandingObjectList* pList = &mon->historyChildren;
1916
1917 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1918 Object* grandChild = expandBufGetEntry(pList, i);
1919
1920 if (!objectInChildList(parent, grandChild)) {
1921 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1922 linkParentToChild(parent, grandChild);
1923 } else {
1924 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1925 }
1926 }
1927}
1928
1929/*
1930 * An object with a fat lock is being collected during a GC pass. We
1931 * want to remove it from any lock history trees that it is a part of.
1932 *
1933 * This may require updating the history trees in several monitors. The
1934 * monitor semantics guarantee that no other thread will be accessing
1935 * the history trees at the same time.
1936 */
1937static void removeCollectedObject(Object* obj)
1938{
1939 Monitor* mon;
1940
1941 LOGVV("+++ collecting %p\n", obj);
1942
1943#if 0
1944 /*
1945 * We're currently running through the entire set of known monitors.
1946 * This can be somewhat slow. We may want to keep lists of parents
1947 * in each child to speed up GC.
1948 */
1949 mon = gDvm.monitorList;
1950 while (mon != NULL) {
1951 Object* parent = mon->obj;
1952 if (parent != NULL) { /* value nulled for deleted entries */
1953 if (objectInChildList(parent, obj)) {
1954 LOGVV("removing child %p from parent %p\n", obj, parent);
1955 unlinkParentFromChild(parent, obj);
1956 mergeChildren(parent, obj);
1957 }
1958 }
1959 mon = mon->next;
1960 }
1961#endif
1962
1963 /*
1964 * For every parent of this object:
1965 * - merge all of our children into the parent's child list (creates
1966 * a two-way link between parent and child)
1967 * - remove ourselves from the parent's child list
1968 */
1969 ExpandingObjectList* pList;
1970 int i;
1971
1972 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001973 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001974 pList = &mon->historyParents;
1975 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1976 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001977 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001978
1979 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
1980 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
1981 }
1982 assert(!expandObjHas(&parentMon->historyChildren, obj));
1983
1984 mergeChildren(parent, obj);
1985 }
1986
1987 /*
1988 * For every child of this object:
1989 * - remove ourselves from the child's parent list
1990 */
1991 pList = &mon->historyChildren;
1992 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1993 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001994 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001995
1996 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
1997 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
1998 }
1999 assert(!expandObjHas(&childMon->historyParents, obj));
2000 }
2001}
2002
2003#endif /*WITH_DEADLOCK_PREDICTION*/