blob: 595f9db0d3694ff677e5a78bbc0cc4173eec1235 [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 */
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800507void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800508{
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
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800536int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
537 s8 msec, s4 nsec)
538{
539 int ret;
540 struct timespec ts;
541 absoluteTime(msec, nsec, &ts);
542#if defined(HAVE_TIMEDWAIT_MONOTONIC)
543 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
544#else
545 ret = pthread_cond_timedwait(cond, mutex, &ts);
546#endif
547 assert(ret == 0 || ret == ETIMEDOUT);
548 return ret;
549}
550
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800551/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800552 * Wait on a monitor until timeout, interrupt, or notification. Used for
553 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
554 *
555 * If another thread calls Thread.interrupt(), we throw InterruptedException
556 * and return immediately if one of the following are true:
557 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
558 * - blocked in join(), join(long), or join(long, int) methods of Thread
559 * - blocked in sleep(long), or sleep(long, int) methods of Thread
560 * Otherwise, we set the "interrupted" flag.
561 *
562 * Checks to make sure that "nsec" is in the range 0-999999
563 * (i.e. fractions of a millisecond) and throws the appropriate
564 * exception if it isn't.
565 *
566 * The spec allows "spurious wakeups", and recommends that all code using
567 * Object.wait() do so in a loop. This appears to derive from concerns
568 * about pthread_cond_wait() on multiprocessor systems. Some commentary
569 * on the web casts doubt on whether these can/should occur.
570 *
571 * Since we're allowed to wake up "early", we clamp extremely long durations
572 * to return at the end of the 32-bit time epoch.
573 */
574static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
575 bool interruptShouldThrow)
576{
577 struct timespec ts;
578 bool wasInterrupted = false;
579 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800580 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800581
Carl Shapiro71938022009-12-22 13:49:53 -0800582 assert(self != NULL);
583 assert(mon != NULL);
584
Carl Shapiro94338aa2009-12-21 11:42:59 -0800585 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800586 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800587 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
588 "object not locked by thread before wait()");
589 return;
590 }
591
592 /*
593 * Enforce the timeout range.
594 */
595 if (msec < 0 || nsec < 0 || nsec > 999999) {
596 dvmThrowException("Ljava/lang/IllegalArgumentException;",
597 "timeout arguments out of range");
598 return;
599 }
600
601 /*
602 * Compute absolute wakeup time, if necessary.
603 */
604 if (msec == 0 && nsec == 0) {
605 timed = false;
606 } else {
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800607 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800608 timed = true;
609 }
610
611 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800612 * Add ourselves to the set of threads waiting on this monitor, and
613 * release our hold. We need to let it go even if we're a few levels
614 * deep in a recursive lock, and we need to restore that later.
615 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800616 * We append to the wait set ahead of clearing the count and owner
617 * fields so the subroutine can check that the calling thread owns
618 * the monitor. Aside from that, the order of member updates is
619 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800620 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800621 waitSetAppend(mon, self);
622 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800623 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800624 mon->owner = NULL;
625
626 /*
627 * Update thread status. If the GC wakes up, it'll ignore us, knowing
628 * that we won't touch any references in this state, and we'll check
629 * our suspend mode before we transition out.
630 */
631 if (timed)
632 dvmChangeStatus(self, THREAD_TIMED_WAIT);
633 else
634 dvmChangeStatus(self, THREAD_WAIT);
635
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800636 ret = pthread_mutex_lock(&self->waitMutex);
637 assert(ret == 0);
638
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800639 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800640 * Set waitMonitor to the monitor object we will be waiting on.
641 * When waitMonitor is non-NULL a notifying or interrupting thread
642 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800643 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800644 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800645 self->waitMonitor = mon;
646
647 /*
648 * Handle the case where the thread was interrupted before we called
649 * wait().
650 */
651 if (self->interrupted) {
652 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800653 self->waitMonitor = NULL;
654 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800655 goto done;
656 }
657
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800658 /*
659 * Release the monitor lock and wait for a notification or
660 * a timeout to occur.
661 */
662 pthread_mutex_unlock(&mon->lock);
663
664 if (!timed) {
665 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
666 assert(ret == 0);
667 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800668#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800669 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800670#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800671 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800672#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800673 assert(ret == 0 || ret == ETIMEDOUT);
674 }
675 if (self->interrupted) {
676 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800677 }
678
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800679 self->interrupted = false;
680 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800681
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800682 pthread_mutex_unlock(&self->waitMutex);
683
Carl Shapiro30aa9972010-01-13 22:07:50 -0800684 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800685 lockMonitor(self, mon);
686
Carl Shapiro142ef272010-01-25 12:51:31 -0800687done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800688 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800689 * We remove our thread from wait set after restoring the count
690 * and owner fields so the subroutine can check that the calling
691 * thread owns the monitor. Aside from that, the order of member
692 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800693 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800694 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800695 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800696 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800697
698 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
699 dvmChangeStatus(self, THREAD_RUNNING);
700
701 if (wasInterrupted) {
702 /*
703 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800704 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800705 *
706 * The doc sayeth: "The interrupted status of the current thread is
707 * cleared when this exception is thrown."
708 */
709 self->interrupted = false;
710 if (interruptShouldThrow)
711 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
712 }
713}
714
715/*
716 * Notify one thread waiting on this monitor.
717 */
718static void notifyMonitor(Thread* self, Monitor* mon)
719{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800720 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800721
Carl Shapiro71938022009-12-22 13:49:53 -0800722 assert(self != NULL);
723 assert(mon != NULL);
724
Carl Shapiro94338aa2009-12-21 11:42:59 -0800725 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800726 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800727 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
728 "object not locked by thread before notify()");
729 return;
730 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800731 /* Signal the first waiting thread in the wait set. */
732 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800733 thread = mon->waitSet;
734 mon->waitSet = thread->waitNext;
735 thread->waitNext = NULL;
736 pthread_mutex_lock(&thread->waitMutex);
737 /* Check to see if the thread is still waiting. */
738 if (thread->waitMonitor != NULL) {
739 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800740 pthread_mutex_unlock(&thread->waitMutex);
741 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800742 }
743 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800744 }
745}
746
747/*
748 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800749 */
750static void notifyAllMonitor(Thread* self, Monitor* mon)
751{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800752 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800753
Carl Shapiro71938022009-12-22 13:49:53 -0800754 assert(self != NULL);
755 assert(mon != NULL);
756
Carl Shapiro94338aa2009-12-21 11:42:59 -0800757 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800758 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800759 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
760 "object not locked by thread before notifyAll()");
761 return;
762 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800763 /* Signal all threads in the wait set. */
764 while (mon->waitSet != NULL) {
765 thread = mon->waitSet;
766 mon->waitSet = thread->waitNext;
767 thread->waitNext = NULL;
768 pthread_mutex_lock(&thread->waitMutex);
769 /* Check to see if the thread is still waiting. */
770 if (thread->waitMonitor != NULL) {
771 pthread_cond_signal(&thread->waitCond);
772 }
773 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800774 }
775}
776
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800777/*
778 * Implements monitorenter for "synchronized" stuff.
779 *
780 * This does not fail or throw an exception (unless deadlock prediction
781 * is enabled and set to "err" mode).
782 */
783void dvmLockObject(Thread* self, Object *obj)
784{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800785 volatile u4 *thinp = &obj->lock;
786 u4 hashState;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800787 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800788 u4 threadId = self->threadId;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800789 Monitor *mon;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800790
791 /* First, try to grab the lock as if it's thin;
792 * this is the common case and will usually succeed.
793 */
Carl Shapiro30aa9972010-01-13 22:07:50 -0800794 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800795 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800796 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800797 if (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800798 hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800799 (int32_t)thin)) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800800 /* The lock is either a thin lock held by someone (possibly 'self'),
801 * or a fat lock.
802 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800803 if (LW_LOCK_OWNER(*thinp) == threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800804 /* 'self' is already holding the thin lock; we can just
805 * bump the count. Atomic operations are not necessary
806 * because only the thread holding the lock is allowed
807 * to modify the Lock field.
808 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800809 *thinp += 1 << LW_LOCK_COUNT_SHIFT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800810 } else {
811 /* If this is a thin lock we need to spin on it, if it's fat
812 * we need to acquire the monitor.
813 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800814 if (LW_SHAPE(*thinp) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800815 ThreadStatus oldStatus;
816 static const unsigned long maxSleepDelay = 1 * 1024 * 1024;
817 unsigned long sleepDelay;
818
819 LOG_THIN("(%d) spin on lock 0x%08x: 0x%08x (0x%08x) 0x%08x\n",
820 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800821 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800822
823 /* The lock is still thin, but some other thread is
824 * holding it. Let the VM know that we're about
825 * to wait on another thread.
826 */
827 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
828
829 /* Spin until the other thread lets go.
830 */
831 sleepDelay = 0;
832 do {
833 /* In addition to looking for an unlock,
834 * we need to watch out for some other thread
835 * fattening the lock behind our back.
836 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800837 while (LW_LOCK_OWNER(*thinp) != 0) {
838 if (LW_SHAPE(*thinp) == LW_SHAPE_FAT) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800839 /* The lock has been fattened already.
840 */
841 LOG_THIN("(%d) lock 0x%08x surprise-fattened\n",
842 threadId, (uint)&obj->lock);
843 dvmChangeStatus(self, oldStatus);
844 goto fat_lock;
845 }
846
847 if (sleepDelay == 0) {
848 sched_yield();
849 sleepDelay = 1 * 1000;
850 } else {
851 usleep(sleepDelay);
852 if (sleepDelay < maxSleepDelay / 2) {
853 sleepDelay *= 2;
854 }
855 }
856 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800857 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800858 thin = threadId << LW_LOCK_OWNER_SHIFT;
Carl Shapiro30aa9972010-01-13 22:07:50 -0800859 thin |= hashState;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800860 } while (!ATOMIC_CMP_SWAP((int32_t *)thinp,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800861 (int32_t)hashState,
Carl Shapiro94338aa2009-12-21 11:42:59 -0800862 (int32_t)thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800863 LOG_THIN("(%d) spin on lock done 0x%08x: "
864 "0x%08x (0x%08x) 0x%08x\n",
865 threadId, (uint)&obj->lock,
Carl Shapiro30aa9972010-01-13 22:07:50 -0800866 hashState, *thinp, thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800867
868 /* We've got the thin lock; let the VM know that we're
869 * done waiting.
870 */
871 dvmChangeStatus(self, oldStatus);
872
873 /* Fatten the lock. Note this relinquishes ownership.
874 * We could also create the monitor in an "owned" state
875 * to avoid "re-locking" it in fat_lock.
876 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800877 mon = dvmCreateMonitor(obj);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800878 hashState = LW_HASH_STATE(*thinp) << LW_HASH_STATE_SHIFT;
879 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800880 LOG_THIN("(%d) lock 0x%08x fattened\n",
881 threadId, (uint)&obj->lock);
882
883 /* Fall through to acquire the newly fat lock.
884 */
885 }
886
887 /* The lock is already fat, which means
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800888 * that obj->lock is a regular (Monitor *).
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800889 */
890 fat_lock:
Carl Shapiro8d7f9b22009-12-21 20:23:45 -0800891 assert(LW_MONITOR(obj->lock) != NULL);
892 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800893 }
894 }
895 // else, the lock was acquired with the ATOMIC_CMP_SWAP().
896
897#ifdef WITH_DEADLOCK_PREDICTION
898 /*
899 * See if we were allowed to grab the lock at this time. We do it
900 * *after* acquiring the lock, rather than before, so that we can
901 * freely update the Monitor struct. This seems counter-intuitive,
902 * but our goal is deadlock *prediction* not deadlock *prevention*.
903 * (If we actually deadlock, the situation is easy to diagnose from
904 * a thread dump, so there's no point making a special effort to do
905 * the checks before the lock is held.)
906 *
907 * This needs to happen before we add the object to the thread's
908 * monitor list, so we can tell the difference between first-lock and
909 * re-lock.
910 *
911 * It's also important that we do this while in THREAD_RUNNING, so
912 * that we don't interfere with cleanup operations in the GC.
913 */
914 if (gDvm.deadlockPredictMode != kDPOff) {
915 if (self->status != THREAD_RUNNING) {
916 LOGE("Bad thread status (%d) in DP\n", self->status);
917 dvmDumpThread(self, false);
918 dvmAbort();
919 }
920 assert(!dvmCheckException(self));
921 updateDeadlockPrediction(self, obj);
922 if (dvmCheckException(self)) {
923 /*
924 * If we're throwing an exception here, we need to free the
925 * lock. We add the object to the thread's monitor list so the
926 * "unlock" code can remove it.
927 */
928 dvmAddToMonitorList(self, obj, false);
929 dvmUnlockObject(self, obj);
930 LOGV("--- unlocked, pending is '%s'\n",
931 dvmGetException(self)->clazz->descriptor);
932 }
933 }
934
935 /*
936 * Add the locked object, and the current stack trace, to the list
937 * held by the Thread object. If deadlock prediction isn't on,
938 * don't capture the stack trace.
939 */
940 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
941#elif defined(WITH_MONITOR_TRACKING)
942 /*
943 * Add the locked object to the list held by the Thread object.
944 */
945 dvmAddToMonitorList(self, obj, false);
946#endif
947}
948
949/*
950 * Implements monitorexit for "synchronized" stuff.
951 *
952 * On failure, throws an exception and returns "false".
953 */
954bool dvmUnlockObject(Thread* self, Object *obj)
955{
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800956 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800957 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800958
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800959 assert(self != NULL);
960 assert(self->status == THREAD_RUNNING);
961 assert(obj != NULL);
962
963 thinp = &obj->lock;
964 /*
965 * Cache the lock word as its value can change while we are
966 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800967 */
Carl Shapiro94338aa2009-12-21 11:42:59 -0800968 thin = *thinp;
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800969 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
970 /*
971 * The lock is thin. We must ensure that the lock is owned
972 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800973 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800974 if (LW_LOCK_OWNER(thin) == self->threadId) {
975 /*
976 * We are the lock owner. It is safe to update the lock
977 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800978 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800979 if (LW_LOCK_COUNT(thin) == 0) {
980 /*
981 * The lock was not recursively acquired, the common
982 * case. Unlock by clearing all bits except for the
983 * hash state.
984 */
985 *thinp &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
986 } else {
987 /*
988 * The object was recursively acquired. Decrement the
989 * lock recursion count field.
990 */
991 *thinp -= 1 << LW_LOCK_COUNT_SHIFT;
992 }
993 } else {
994 /*
995 * We do not own the lock. The JVM spec requires that we
996 * throw an exception in this case.
997 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800998 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -0800999 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001000 return false;
1001 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001002 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001003 /*
1004 * The lock is fat. We must check to see if unlockMonitor has
1005 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001006 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001007 assert(LW_MONITOR(obj->lock) != NULL);
1008 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001009 /*
1010 * An exception has been raised. Do not fall through.
1011 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001012 return false;
1013 }
1014 }
1015
1016#ifdef WITH_MONITOR_TRACKING
1017 /*
1018 * Remove the object from the Thread's list.
1019 */
1020 dvmRemoveFromMonitorList(self, obj);
1021#endif
1022
1023 return true;
1024}
1025
1026/*
1027 * Object.wait(). Also called for class init.
1028 */
1029void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1030 bool interruptShouldThrow)
1031{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001032 Monitor* mon = LW_MONITOR(obj->lock);
1033 u4 hashState;
1034 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001035
1036 /* If the lock is still thin, we need to fatten it.
1037 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001038 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001039 /* Make sure that 'self' holds the lock.
1040 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001041 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001042 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1043 "object not locked by thread before wait()");
1044 return;
1045 }
1046
1047 /* This thread holds the lock. We need to fatten the lock
1048 * so 'self' can block on it. Don't update the object lock
1049 * field yet, because 'self' needs to acquire the lock before
1050 * any other thread gets a chance.
1051 */
1052 mon = dvmCreateMonitor(obj);
1053
1054 /* 'self' has actually locked the object one or more times;
1055 * make sure that the monitor reflects this.
1056 */
1057 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001058 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001059 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1060 self->threadId, (uint)&obj->lock, mon->lockCount);
1061
Andy McFadden581bed72009-10-15 11:24:54 -07001062
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001063 /* Make the monitor public now that it's in the right state.
1064 */
Andy McFadden581bed72009-10-15 11:24:54 -07001065 MEM_BARRIER();
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001066 hashState = LW_HASH_STATE(thin) << LW_HASH_STATE_SHIFT;
1067 obj->lock = (u4)mon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001068 }
1069
1070 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1071}
1072
1073/*
1074 * Object.notify().
1075 */
1076void dvmObjectNotify(Thread* self, Object *obj)
1077{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001078 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001079
1080 /* If the lock is still thin, there aren't any waiters;
1081 * waiting on an object forces lock fattening.
1082 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001083 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001084 /* Make sure that 'self' holds the lock.
1085 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001086 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001087 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1088 "object not locked by thread before notify()");
1089 return;
1090 }
1091
1092 /* no-op; there are no waiters to notify.
1093 */
1094 } else {
1095 /* It's a fat lock.
1096 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001097 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001098 }
1099}
1100
1101/*
1102 * Object.notifyAll().
1103 */
1104void dvmObjectNotifyAll(Thread* self, Object *obj)
1105{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001106 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001107
1108 /* If the lock is still thin, there aren't any waiters;
1109 * waiting on an object forces lock fattening.
1110 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001111 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001112 /* Make sure that 'self' holds the lock.
1113 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001114 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001115 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1116 "object not locked by thread before notifyAll()");
1117 return;
1118 }
1119
1120 /* no-op; there are no waiters to notify.
1121 */
1122 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001123 /* It's a fat lock.
1124 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001125 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001126 }
1127}
1128
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001129/*
1130 * This implements java.lang.Thread.sleep(long msec, int nsec).
1131 *
1132 * The sleep is interruptible by other threads, which means we can't just
1133 * plop into an OS sleep call. (We probably could if we wanted to send
1134 * signals around and rely on EINTR, but that's inefficient and relies
1135 * on native code respecting our signal mask.)
1136 *
1137 * We have to do all of this stuff for Object.wait() as well, so it's
1138 * easiest to just sleep on a private Monitor.
1139 *
1140 * It appears that we want sleep(0,0) to go through the motions of sleeping
1141 * for a very short duration, rather than just returning.
1142 */
1143void dvmThreadSleep(u8 msec, u4 nsec)
1144{
1145 Thread* self = dvmThreadSelf();
1146 Monitor* mon = gDvm.threadSleepMon;
1147
1148 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1149 if (msec == 0 && nsec == 0)
1150 nsec++;
1151
1152 lockMonitor(self, mon);
1153 waitMonitor(self, mon, msec, nsec, true);
1154 unlockMonitor(self, mon);
1155}
1156
1157/*
1158 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001159 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001160void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001161{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001162 assert(thread != NULL);
1163
1164 pthread_mutex_lock(&thread->waitMutex);
1165
1166 /*
1167 * If the interrupted flag is already set no additional action is
1168 * required.
1169 */
1170 if (thread->interrupted == true) {
1171 pthread_mutex_unlock(&thread->waitMutex);
1172 return;
1173 }
1174
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001175 /*
1176 * Raise the "interrupted" flag. This will cause it to bail early out
1177 * of the next wait() attempt, if it's not currently waiting on
1178 * something.
1179 */
1180 thread->interrupted = true;
1181 MEM_BARRIER();
1182
1183 /*
1184 * Is the thread waiting?
1185 *
1186 * Note that fat vs. thin doesn't matter here; waitMonitor
1187 * is only set when a thread actually waits on a monitor,
1188 * which implies that the monitor has already been fattened.
1189 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001190 if (thread->waitMonitor != NULL) {
1191 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001192 }
1193
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001194 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001195}
1196
Carl Shapiro30aa9972010-01-13 22:07:50 -08001197#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001198u4 dvmIdentityHashCode(Object *obj)
1199{
1200 return (u4)obj;
1201}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001202#else
1203static size_t arrayElementWidth(const ArrayObject *array)
1204{
1205 const char *descriptor;
1206
1207 if (dvmIsObjectArray(array)) {
1208 return sizeof(Object *);
1209 } else {
1210 descriptor = array->obj.clazz->descriptor;
1211 switch (descriptor[1]) {
1212 case 'B': return 1; /* byte */
1213 case 'C': return 2; /* char */
1214 case 'D': return 8; /* double */
1215 case 'F': return 4; /* float */
1216 case 'I': return 4; /* int */
1217 case 'J': return 8; /* long */
1218 case 'S': return 2; /* short */
1219 case 'Z': return 1; /* boolean */
1220 }
1221 }
1222 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1223 dvmDumpThread(dvmThreadSelf(), false);
1224 dvmAbort();
1225 return 0; /* Quiet the compiler. */
1226}
1227
1228static size_t arrayObjectLength(const ArrayObject *array)
1229{
1230 size_t length;
1231
1232 length = offsetof(ArrayObject, contents);
1233 length += array->length * arrayElementWidth(array);
1234 return length;
1235}
1236
1237/*
1238 * Returns the identity hash code of the given object.
1239 */
1240u4 dvmIdentityHashCode(Object *obj)
1241{
1242 Thread *self, *thread;
1243 volatile u4 *lw;
1244 size_t length;
1245 u4 lock, owner, hashState;
1246
1247 if (obj == NULL) {
1248 /*
1249 * Null is defined to have an identity hash code of 0.
1250 */
1251 return 0;
1252 }
1253 lw = &obj->lock;
1254retry:
1255 hashState = LW_HASH_STATE(*lw);
1256 if (hashState == LW_HASH_STATE_HASHED) {
1257 /*
1258 * The object has been hashed but has not had its hash code
1259 * relocated by the garbage collector. Use the raw object
1260 * address.
1261 */
1262 return (u4)obj >> 3;
1263 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1264 /*
1265 * The object has been hashed and its hash code has been
1266 * relocated by the collector. Use the value of the naturally
1267 * aligned word following the instance data.
1268 */
1269 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1270 length = arrayObjectLength((ArrayObject *)obj);
1271 length = (length + 3) & ~3;
1272 } else {
1273 length = obj->clazz->objectSize;
1274 }
1275 return *(u4 *)(((char *)obj) + length);
1276 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1277 /*
1278 * The object has never been hashed. Change the hash state to
1279 * hashed and use the raw object address.
1280 */
1281 self = dvmThreadSelf();
1282 if (self->threadId == lockOwner(obj)) {
1283 /*
1284 * We already own the lock so we can update the hash state
1285 * directly.
1286 */
1287 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1288 return (u4)obj >> 3;
1289 }
1290 /*
1291 * We do not own the lock. Try acquiring the lock. Should
1292 * this fail, we must suspend the owning thread.
1293 */
1294 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1295 /*
1296 * If the lock is thin assume it is unowned. We simulate
1297 * an acquire, update, and release with a single CAS.
1298 */
1299 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1300 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1301 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1302 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1303 (int32_t)lock)) {
1304 /*
1305 * A new lockword has been installed with a hash state
1306 * of hashed. Use the raw object address.
1307 */
1308 return (u4)obj >> 3;
1309 }
1310 } else {
1311 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1312 /*
1313 * The monitor lock has been acquired. Change the
1314 * hash state to hashed and use the raw object
1315 * address.
1316 */
1317 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1318 unlockMonitor(self, LW_MONITOR(*lw));
1319 return (u4)obj >> 3;
1320 }
1321 }
1322 /*
1323 * At this point we have failed to acquire the lock. We must
1324 * identify the owning thread and suspend it.
1325 */
1326 dvmLockThreadList(self);
1327 /*
1328 * Cache the lock word as its value can change between
1329 * determining its shape and retrieving its owner.
1330 */
1331 lock = *lw;
1332 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1333 /*
1334 * Find the thread with the corresponding thread id.
1335 */
1336 owner = LW_LOCK_OWNER(lock);
1337 assert(owner != self->threadId);
1338 /*
1339 * If the lock has no owner do not bother scanning the
1340 * thread list and fall through to the failure handler.
1341 */
1342 thread = owner ? gDvm.threadList : NULL;
1343 while (thread != NULL) {
1344 if (thread->threadId == owner) {
1345 break;
1346 }
1347 thread = thread->next;
1348 }
1349 } else {
1350 thread = LW_MONITOR(lock)->owner;
1351 }
1352 /*
1353 * If thread is NULL the object has been released since the
1354 * thread list lock was acquired. Try again.
1355 */
1356 if (thread == NULL) {
1357 dvmUnlockThreadList();
1358 goto retry;
1359 }
1360 /*
1361 * Wait for the owning thread to suspend.
1362 */
1363 dvmSuspendThread(thread);
1364 if (dvmHoldsLock(thread, obj)) {
1365 /*
1366 * The owning thread has been suspended. We can safely
1367 * change the hash state to hashed.
1368 */
1369 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1370 dvmResumeThread(thread);
1371 dvmUnlockThreadList();
1372 return (u4)obj >> 3;
1373 }
1374 /*
1375 * The wrong thread has been suspended. Try again.
1376 */
1377 dvmResumeThread(thread);
1378 dvmUnlockThreadList();
1379 goto retry;
1380 }
1381 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1382 dvmDumpThread(dvmThreadSelf(), false);
1383 dvmAbort();
1384 return 0; /* Quiet the compiler. */
1385}
1386#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001387
1388#ifdef WITH_DEADLOCK_PREDICTION
1389/*
1390 * ===========================================================================
1391 * Deadlock prediction
1392 * ===========================================================================
1393 */
1394/*
1395The idea is to predict the possibility of deadlock by recording the order
1396in which monitors are acquired. If we see an attempt to acquire a lock
1397out of order, we can identify the locks and offending code.
1398
1399To make this work, we need to keep track of the locks held by each thread,
1400and create history trees for each lock. When a thread tries to acquire
1401a new lock, we walk through the "history children" of the lock, looking
1402for a match with locks the thread already holds. If we find a match,
1403it means the thread has made a request that could result in a deadlock.
1404
1405To support recursive locks, we always allow re-locking a currently-held
1406lock, and maintain a recursion depth count.
1407
1408An ASCII-art example, where letters represent Objects:
1409
1410 A
1411 /|\
1412 / | \
1413 B | D
1414 \ |
1415 \|
1416 C
1417
1418The above is the tree we'd have after handling Object synchronization
1419sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1420a child of B. (The lines represent pointers between parent and child.
1421Every node can have multiple parents and multiple children.)
1422
1423If we hold AC, and want to lock B, we recursively search through B's
1424children to see if A or C appears. It does, so we reject the attempt.
1425(A straightforward way to implement it: add a link from C to B, then
1426determine whether the graph starting at B contains a cycle.)
1427
1428If we hold AC and want to lock D, we would succeed, creating a new link
1429from C to D.
1430
1431The lock history and a stack trace is attached to the Object's Monitor
1432struct, which means we need to fatten every Object we lock (thin locking
1433is effectively disabled). If we don't need the stack trace we can
1434avoid fattening the leaf nodes, only fattening objects that need to hold
1435history trees.
1436
1437Updates to Monitor structs are only allowed for the thread that holds
1438the Monitor, so we actually do most of our deadlock prediction work after
1439the lock has been acquired.
1440
1441When an object with a monitor is GCed, we need to remove it from the
1442history trees. There are two basic approaches:
1443 (1) For through the entire set of known monitors, search all child
1444 lists for the object in question. This is rather slow, resulting
1445 in GC passes that take upwards of 10 seconds to complete.
1446 (2) Maintain "parent" pointers in each node. Remove the entries as
1447 required. This requires additional storage and maintenance for
1448 every operation, but is significantly faster at GC time.
1449For each GCed object, we merge all of the object's children into each of
1450the object's parents.
1451*/
1452
1453#if !defined(WITH_MONITOR_TRACKING)
1454# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1455#endif
1456
1457/*
1458 * Clear out the contents of an ExpandingObjectList, freeing any
1459 * dynamic allocations.
1460 */
1461static void expandObjClear(ExpandingObjectList* pList)
1462{
1463 if (pList->list != NULL) {
1464 free(pList->list);
1465 pList->list = NULL;
1466 }
1467 pList->alloc = pList->count = 0;
1468}
1469
1470/*
1471 * Get the number of objects currently stored in the list.
1472 */
1473static inline int expandBufGetCount(const ExpandingObjectList* pList)
1474{
1475 return pList->count;
1476}
1477
1478/*
1479 * Get the Nth entry from the list.
1480 */
1481static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1482 int i)
1483{
1484 return pList->list[i];
1485}
1486
1487/*
1488 * Add a new entry to the list.
1489 *
1490 * We don't check for or try to enforce uniqueness. It's expected that
1491 * the higher-level code does this for us.
1492 */
1493static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1494{
1495 if (pList->count == pList->alloc) {
1496 /* time to expand */
1497 Object** newList;
1498
1499 if (pList->alloc == 0)
1500 pList->alloc = 4;
1501 else
1502 pList->alloc *= 2;
1503 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1504 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1505 if (newList == NULL) {
1506 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1507 dvmAbort();
1508 }
1509 pList->list = newList;
1510 }
1511
1512 pList->list[pList->count++] = obj;
1513}
1514
1515/*
1516 * Returns "true" if the element was successfully removed.
1517 */
1518static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1519{
1520 int i;
1521
1522 for (i = pList->count-1; i >= 0; i--) {
1523 if (pList->list[i] == obj)
1524 break;
1525 }
1526 if (i < 0)
1527 return false;
1528
1529 if (i != pList->count-1) {
1530 /*
1531 * The order of elements is not important, so we just copy the
1532 * last entry into the new slot.
1533 */
1534 //memmove(&pList->list[i], &pList->list[i+1],
1535 // (pList->count-1 - i) * sizeof(pList->list[0]));
1536 pList->list[i] = pList->list[pList->count-1];
1537 }
1538
1539 pList->count--;
1540 pList->list[pList->count] = (Object*) 0xdecadead;
1541 return true;
1542}
1543
1544/*
1545 * Returns "true" if "obj" appears in the list.
1546 */
1547static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1548{
1549 int i;
1550
1551 for (i = 0; i < pList->count; i++) {
1552 if (pList->list[i] == obj)
1553 return true;
1554 }
1555 return false;
1556}
1557
1558/*
1559 * Print the list contents to stdout. For debugging.
1560 */
1561static void expandObjDump(const ExpandingObjectList* pList)
1562{
1563 int i;
1564 for (i = 0; i < pList->count; i++)
1565 printf(" %p", pList->list[i]);
1566}
1567
1568/*
1569 * Check for duplicate entries. Returns the index of the first instance
1570 * of the duplicated value, or -1 if no duplicates were found.
1571 */
1572static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1573{
1574 int i, j;
1575 for (i = 0; i < pList->count-1; i++) {
1576 for (j = i + 1; j < pList->count; j++) {
1577 if (pList->list[i] == pList->list[j]) {
1578 return i;
1579 }
1580 }
1581 }
1582
1583 return -1;
1584}
1585
1586
1587/*
1588 * Determine whether "child" appears in the list of objects associated
1589 * with the Monitor in "parent". If "parent" is a thin lock, we return
1590 * false immediately.
1591 */
1592static bool objectInChildList(const Object* parent, Object* child)
1593{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001594 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001595 if (!IS_LOCK_FAT(&lock)) {
1596 //LOGI("on thin\n");
1597 return false;
1598 }
1599
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001600 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001601}
1602
1603/*
1604 * Print the child list.
1605 */
1606static void dumpKids(Object* parent)
1607{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001608 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001609
1610 printf("Children of %p:", parent);
1611 expandObjDump(&mon->historyChildren);
1612 printf("\n");
1613}
1614
1615/*
1616 * Add "child" to the list of children in "parent", and add "parent" to
1617 * the list of parents in "child".
1618 */
1619static void linkParentToChild(Object* parent, Object* child)
1620{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001621 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001622 assert(IS_LOCK_FAT(&parent->lock));
1623 assert(IS_LOCK_FAT(&child->lock));
1624 assert(parent != child);
1625 Monitor* mon;
1626
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001627 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001628 assert(!expandObjHas(&mon->historyChildren, child));
1629 expandObjAddEntry(&mon->historyChildren, child);
1630
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001631 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001632 assert(!expandObjHas(&mon->historyParents, parent));
1633 expandObjAddEntry(&mon->historyParents, parent);
1634}
1635
1636
1637/*
1638 * Remove "child" from the list of children in "parent".
1639 */
1640static void unlinkParentFromChild(Object* parent, Object* child)
1641{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001642 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001643 assert(IS_LOCK_FAT(&parent->lock));
1644 assert(IS_LOCK_FAT(&child->lock));
1645 assert(parent != child);
1646 Monitor* mon;
1647
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001648 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001649 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1650 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1651 }
1652 assert(!expandObjHas(&mon->historyChildren, child));
1653 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1654
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001655 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001656 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1657 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1658 }
1659 assert(!expandObjHas(&mon->historyParents, parent));
1660 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1661}
1662
1663
1664/*
1665 * Log the monitors held by the current thread. This is done as part of
1666 * flagging an error.
1667 */
1668static void logHeldMonitors(Thread* self)
1669{
1670 char* name = NULL;
1671
1672 name = dvmGetThreadName(self);
1673 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1674 self->threadId, name);
1675 LOGW("(most-recently-acquired on top):\n");
1676 free(name);
1677
1678 LockedObjectData* lod = self->pLockedObjects;
1679 while (lod != NULL) {
1680 LOGW("--- object %p[%d] (%s)\n",
1681 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1682 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1683
1684 lod = lod->next;
1685 }
1686}
1687
1688/*
1689 * Recursively traverse the object hierarchy starting at "obj". We mark
1690 * ourselves on entry and clear the mark on exit. If we ever encounter
1691 * a marked object, we have a cycle.
1692 *
1693 * Returns "true" if all is well, "false" if we found a cycle.
1694 */
1695static bool traverseTree(Thread* self, const Object* obj)
1696{
1697 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001698 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001699
1700 /*
1701 * Have we been here before?
1702 */
1703 if (mon->historyMark) {
1704 int* rawStackTrace;
1705 int stackDepth;
1706
1707 LOGW("%s\n", kStartBanner);
1708 LOGW("Illegal lock attempt:\n");
1709 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1710
1711 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1712 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1713 free(rawStackTrace);
1714
1715 LOGW(" ");
1716 logHeldMonitors(self);
1717
1718 LOGW(" ");
1719 LOGW("Earlier, the following lock order (from last to first) was\n");
1720 LOGW("established -- stack trace is from first successful lock):\n");
1721 return false;
1722 }
1723 mon->historyMark = true;
1724
1725 /*
1726 * Examine the children. We do NOT hold these locks, so they might
1727 * very well transition from thin to fat or change ownership while
1728 * we work.
1729 *
1730 * NOTE: we rely on the fact that they cannot revert from fat to thin
1731 * while we work. This is currently a safe assumption.
1732 *
1733 * We can safely ignore thin-locked children, because by definition
1734 * they have no history and are leaf nodes. In the current
1735 * implementation we always fatten the locks to provide a place to
1736 * hang the stack trace.
1737 */
1738 ExpandingObjectList* pList = &mon->historyChildren;
1739 int i;
1740 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1741 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001742 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001743 if (!IS_LOCK_FAT(&lock))
1744 continue;
1745 if (!traverseTree(self, child)) {
1746 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1747 dvmLogRawStackTrace(mon->historyRawStackTrace,
1748 mon->historyStackDepth);
1749 mon->historyMark = false;
1750 return false;
1751 }
1752 }
1753
1754 mon->historyMark = false;
1755
1756 return true;
1757}
1758
1759/*
1760 * Update the deadlock prediction tree, based on the current thread
1761 * acquiring "acqObj". This must be called before the object is added to
1762 * the thread's list of held monitors.
1763 *
1764 * If the thread already holds the lock (recursion), or this is a known
1765 * lock configuration, we return without doing anything. Otherwise, we add
1766 * a link from the most-recently-acquired lock in this thread to "acqObj"
1767 * after ensuring that the parent lock is "fat".
1768 *
1769 * This MUST NOT be called while a GC is in progress in another thread,
1770 * because we assume exclusive access to history trees in owned monitors.
1771 */
1772static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1773{
1774 LockedObjectData* lod;
1775 LockedObjectData* mrl;
1776
1777 /*
1778 * Quick check for recursive access.
1779 */
1780 lod = dvmFindInMonitorList(self, acqObj);
1781 if (lod != NULL) {
1782 LOGV("+++ DP: recursive %p\n", acqObj);
1783 return;
1784 }
1785
1786 /*
1787 * Make the newly-acquired object's monitor "fat". In some ways this
1788 * isn't strictly necessary, but we need the GC to tell us when
1789 * "interesting" objects go away, and right now the only way to make
1790 * an object look interesting is to give it a monitor.
1791 *
1792 * This also gives us a place to hang a stack trace.
1793 *
1794 * Our thread holds the lock, so we're allowed to rewrite the lock
1795 * without worrying that something will change out from under us.
1796 */
1797 if (!IS_LOCK_FAT(&acqObj->lock)) {
1798 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001799 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001800 Monitor* newMon = dvmCreateMonitor(acqObj);
1801 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001802 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1803 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1804 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001805 }
1806
1807 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001808 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1809 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001810 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1811 &mon->historyStackDepth);
1812 }
1813
1814 /*
1815 * We need to examine and perhaps modify the most-recently-locked
1816 * monitor. We own that, so there's no risk of another thread
1817 * stepping on us.
1818 *
1819 * Retrieve the most-recently-locked entry from our thread.
1820 */
1821 mrl = self->pLockedObjects;
1822 if (mrl == NULL)
1823 return; /* no other locks held */
1824
1825 /*
1826 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1827 * this without holding the global lock because of our assertion that
1828 * a GC is not running in parallel -- nobody except the GC can
1829 * modify a history list in a Monitor they don't own, and we own "mrl".
1830 * (There might be concurrent *reads*, but no concurrent *writes.)
1831 *
1832 * If we find it, this is a known good configuration, and we're done.
1833 */
1834 if (objectInChildList(mrl->obj, acqObj))
1835 return;
1836
1837 /*
1838 * "mrl" is going to need to have a history tree. If it's currently
1839 * a thin lock, we make it fat now. The thin lock might have a
1840 * nonzero recursive lock count, which we need to carry over.
1841 *
1842 * Our thread holds the lock, so we're allowed to rewrite the lock
1843 * without worrying that something will change out from under us.
1844 */
1845 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1846 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001847 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001848 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1849 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001850 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1851 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1852 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001853 }
1854
1855 /*
1856 * We haven't seen this configuration before. We need to scan down
1857 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1858 * appear. We grab a global lock before traversing or updating the
1859 * history list.
1860 *
1861 * If we find a match for any of our held locks, we know that the lock
1862 * has previously been acquired *after* acqObj, and we throw an error.
1863 *
1864 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1865 * and do a recursive traversal, marking nodes as we cross them. If
1866 * we cross one a second time, we have a cycle and can throw an error.
1867 * (We do the flag-clearing traversal before adding the new link, so
1868 * that we're guaranteed to terminate.)
1869 *
1870 * If "acqObj" is a thin lock, it has no history, and we can create a
1871 * link to it without additional checks. [ We now guarantee that it's
1872 * always fat. ]
1873 */
1874 bool failed = false;
1875 dvmLockMutex(&gDvm.deadlockHistoryLock);
1876 linkParentToChild(mrl->obj, acqObj);
1877 if (!traverseTree(self, acqObj)) {
1878 LOGW("%s\n", kEndBanner);
1879 failed = true;
1880
1881 /* remove the entry so we're still okay when in "warning" mode */
1882 unlinkParentFromChild(mrl->obj, acqObj);
1883 }
1884 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1885
1886 if (failed) {
1887 switch (gDvm.deadlockPredictMode) {
1888 case kDPErr:
1889 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1890 break;
1891 case kDPAbort:
1892 LOGE("Aborting due to potential deadlock\n");
1893 dvmAbort();
1894 break;
1895 default:
1896 /* warn only */
1897 break;
1898 }
1899 }
1900}
1901
1902/*
1903 * We're removing "child" from existence. We want to pull all of
1904 * child's children into "parent", filtering out duplicates. This is
1905 * called during the GC.
1906 *
1907 * This does not modify "child", which might have multiple parents.
1908 */
1909static void mergeChildren(Object* parent, const Object* child)
1910{
1911 Monitor* mon;
1912 int i;
1913
1914 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001915 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001916 ExpandingObjectList* pList = &mon->historyChildren;
1917
1918 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1919 Object* grandChild = expandBufGetEntry(pList, i);
1920
1921 if (!objectInChildList(parent, grandChild)) {
1922 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1923 linkParentToChild(parent, grandChild);
1924 } else {
1925 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1926 }
1927 }
1928}
1929
1930/*
1931 * An object with a fat lock is being collected during a GC pass. We
1932 * want to remove it from any lock history trees that it is a part of.
1933 *
1934 * This may require updating the history trees in several monitors. The
1935 * monitor semantics guarantee that no other thread will be accessing
1936 * the history trees at the same time.
1937 */
1938static void removeCollectedObject(Object* obj)
1939{
1940 Monitor* mon;
1941
1942 LOGVV("+++ collecting %p\n", obj);
1943
1944#if 0
1945 /*
1946 * We're currently running through the entire set of known monitors.
1947 * This can be somewhat slow. We may want to keep lists of parents
1948 * in each child to speed up GC.
1949 */
1950 mon = gDvm.monitorList;
1951 while (mon != NULL) {
1952 Object* parent = mon->obj;
1953 if (parent != NULL) { /* value nulled for deleted entries */
1954 if (objectInChildList(parent, obj)) {
1955 LOGVV("removing child %p from parent %p\n", obj, parent);
1956 unlinkParentFromChild(parent, obj);
1957 mergeChildren(parent, obj);
1958 }
1959 }
1960 mon = mon->next;
1961 }
1962#endif
1963
1964 /*
1965 * For every parent of this object:
1966 * - merge all of our children into the parent's child list (creates
1967 * a two-way link between parent and child)
1968 * - remove ourselves from the parent's child list
1969 */
1970 ExpandingObjectList* pList;
1971 int i;
1972
1973 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001974 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001975 pList = &mon->historyParents;
1976 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1977 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001978 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001979
1980 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
1981 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
1982 }
1983 assert(!expandObjHas(&parentMon->historyChildren, obj));
1984
1985 mergeChildren(parent, obj);
1986 }
1987
1988 /*
1989 * For every child of this object:
1990 * - remove ourselves from the child's parent list
1991 */
1992 pList = &mon->historyChildren;
1993 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1994 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001995 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001996
1997 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
1998 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
1999 }
2000 assert(!expandObjHas(&childMon->historyParents, obj));
2001 }
2002}
2003
2004#endif /*WITH_DEADLOCK_PREDICTION*/