blob: 8a1d92e0d9fd687fa77f34d0eb6594c29d9f065b [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
Carl Shapirof0c514c2010-04-09 15:03:33 -070036#include <fcntl.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080037#include <stdlib.h>
38#include <unistd.h>
39#include <pthread.h>
40#include <time.h>
41#include <sys/time.h>
42#include <errno.h>
43
44#define LOG_THIN LOGV
45
46#ifdef WITH_DEADLOCK_PREDICTION /* fwd */
47static const char* kStartBanner =
48 "<-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#";
49static const char* kEndBanner =
50 "#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#->";
51
52/*
53 * Unsorted, expanding list of objects.
54 *
55 * This is very similar to PointerSet (which came into existence after this),
56 * but these are unsorted, uniqueness is not enforced by the "add" function,
57 * and the base object isn't allocated on the heap.
58 */
59typedef struct ExpandingObjectList {
60 u2 alloc;
61 u2 count;
62 Object** list;
63} ExpandingObjectList;
64
65/* fwd */
66static void updateDeadlockPrediction(Thread* self, Object* obj);
67static void removeCollectedObject(Object* obj);
68static void expandObjClear(ExpandingObjectList* pList);
69#endif
70
71/*
72 * Every Object has a monitor associated with it, but not every Object is
73 * actually locked. Even the ones that are locked do not need a
74 * full-fledged monitor until a) there is actual contention or b) wait()
75 * is called on the Object.
76 *
77 * For Dalvik, we have implemented a scheme similar to the one described
78 * in Bacon et al.'s "Thin locks: featherweight synchronization for Java"
79 * (ACM 1998). Things are even easier for us, though, because we have
80 * a full 32 bits to work with.
81 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080082 * The two states of an Object's lock are referred to as "thin" and
83 * "fat". A lock may transition from the "thin" state to the "fat"
84 * state and this transition is referred to as inflation. Once a lock
85 * has been inflated it remains in the "fat" state indefinitely.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080086 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080087 * The lock value itself is stored in Object.lock. The LSB of the
88 * lock encodes its state. When cleared, the lock is in the "thin"
89 * state and its bits are formatted as follows:
Carl Shapiro71938022009-12-22 13:49:53 -080090 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080091 * [31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
92 * lock count thread id hash state 0
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080093 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080094 * When set, the lock is in the "fat" state and its bits are formatted
Carl Shapiro94338aa2009-12-21 11:42:59 -080095 * as follows:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080096 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080097 * [31 ---- 3] [2 ---- 1] [0]
98 * pointer hash state 1
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080099 *
100 * For an in-depth description of the mechanics of thin-vs-fat locking,
101 * read the paper referred to above.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800102 */
103
104/*
105 * Monitors provide:
106 * - mutually exclusive access to resources
107 * - a way for multiple threads to wait for notification
108 *
109 * In effect, they fill the role of both mutexes and condition variables.
110 *
111 * Only one thread can own the monitor at any time. There may be several
112 * threads waiting on it (the wait call unlocks it). One or more waiting
113 * threads may be getting interrupted or notified at any given time.
114 */
115struct Monitor {
116 Thread* owner; /* which thread currently owns the lock? */
117 int lockCount; /* owner's recursive lock depth */
118 Object* obj; /* what object are we part of [debug only] */
119
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800120 Thread* waitSet; /* threads currently waiting on this monitor */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800121
122 pthread_mutex_t lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800123
124 Monitor* next;
125
126#ifdef WITH_DEADLOCK_PREDICTION
127 /*
128 * Objects that have been locked immediately after this one in the
129 * past. We use an expanding flat array, allocated on first use, to
130 * minimize allocations. Deletions from the list, expected to be
131 * infrequent, are crunched down.
132 */
133 ExpandingObjectList historyChildren;
134
135 /*
136 * We also track parents. This isn't strictly necessary, but it makes
137 * the cleanup at GC time significantly faster.
138 */
139 ExpandingObjectList historyParents;
140
141 /* used during cycle detection */
142 bool historyMark;
143
144 /* stack trace, established the first time we locked the object */
145 int historyStackDepth;
146 int* historyRawStackTrace;
147#endif
148};
149
150
151/*
152 * Create and initialize a monitor.
153 */
154Monitor* dvmCreateMonitor(Object* obj)
155{
156 Monitor* mon;
157
158 mon = (Monitor*) calloc(1, sizeof(Monitor));
159 if (mon == NULL) {
160 LOGE("Unable to allocate monitor\n");
161 dvmAbort();
162 }
Carl Shapiro94338aa2009-12-21 11:42:59 -0800163 if (((u4)mon & 7) != 0) {
164 LOGE("Misaligned monitor: %p\n", mon);
165 dvmAbort();
166 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800167 mon->obj = obj;
168 dvmInitMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800169
170 /* replace the head of the list with the new monitor */
171 do {
172 mon->next = gDvm.monitorList;
173 } while (!ATOMIC_CMP_SWAP((int32_t*)(void*)&gDvm.monitorList,
174 (int32_t)mon->next, (int32_t)mon));
175
176 return mon;
177}
178
179/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800180 * Free the monitor list. Only used when shutting the VM down.
181 */
182void dvmFreeMonitorList(void)
183{
184 Monitor* mon;
185 Monitor* nextMon;
186
187 mon = gDvm.monitorList;
188 while (mon != NULL) {
189 nextMon = mon->next;
190
191#ifdef WITH_DEADLOCK_PREDICTION
192 expandObjClear(&mon->historyChildren);
193 expandObjClear(&mon->historyParents);
194 free(mon->historyRawStackTrace);
195#endif
196 free(mon);
197 mon = nextMon;
198 }
199}
200
201/*
202 * Log some info about our monitors.
203 */
204void dvmDumpMonitorInfo(const char* msg)
205{
206#if QUIET_ZYGOTE_MONITOR
207 if (gDvm.zygote) {
208 return;
209 }
210#endif
211
212 int totalCount;
213 int liveCount;
214
215 totalCount = liveCount = 0;
216 Monitor* mon = gDvm.monitorList;
217 while (mon != NULL) {
218 totalCount++;
219 if (mon->obj != NULL)
220 liveCount++;
221 mon = mon->next;
222 }
223
224 LOGD("%s: monitor list has %d entries (%d live)\n",
225 msg, totalCount, liveCount);
226}
227
228/*
229 * Get the object that a monitor is part of.
230 */
231Object* dvmGetMonitorObject(Monitor* mon)
232{
233 if (mon == NULL)
234 return NULL;
235 else
236 return mon->obj;
237}
238
239/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800240 * Returns the thread id of the thread owning the given lock.
241 */
242static u4 lockOwner(Object* obj)
243{
244 Thread *owner;
245 u4 lock;
246
247 assert(obj != NULL);
248 /*
249 * Since we're reading the lock value multiple times, latch it so
250 * that it doesn't change out from under us if we get preempted.
251 */
252 lock = obj->lock;
253 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
254 return LW_LOCK_OWNER(lock);
255 } else {
256 owner = LW_MONITOR(lock)->owner;
257 return owner ? owner->threadId : 0;
258 }
259}
260
261/*
Andy McFaddenfd542662010-03-12 13:39:59 -0800262 * Get the thread that holds the lock on the specified object. The
263 * object may be unlocked, thin-locked, or fat-locked.
264 *
265 * The caller must lock the thread list before calling here.
266 */
267Thread* dvmGetObjectLockHolder(Object* obj)
268{
269 u4 threadId = lockOwner(obj);
270
271 if (threadId == 0)
272 return NULL;
273 return dvmGetThreadByThreadId(threadId);
274}
275
276/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800277 * Checks whether the given thread holds the given
278 * objects's lock.
279 */
280bool dvmHoldsLock(Thread* thread, Object* obj)
281{
282 if (thread == NULL || obj == NULL) {
283 return false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800284 } else {
Carl Shapiro30aa9972010-01-13 22:07:50 -0800285 return thread->threadId == lockOwner(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800286 }
287}
288
289/*
290 * Free the monitor associated with an object and make the object's lock
291 * thin again. This is called during garbage collection.
292 */
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800293static void freeObjectMonitor(Object* obj)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800294{
295 Monitor *mon;
296
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800297 assert(LW_SHAPE(obj->lock) == LW_SHAPE_FAT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800298
299#ifdef WITH_DEADLOCK_PREDICTION
300 if (gDvm.deadlockPredictMode != kDPOff)
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800301 removeCollectedObject(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800302#endif
303
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800304 mon = LW_MONITOR(obj->lock);
305 obj->lock = DVM_LOCK_INITIAL_THIN_VALUE;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800306
307 /* This lock is associated with an object
308 * that's being swept. The only possible way
309 * anyone could be holding this lock would be
310 * if some JNI code locked but didn't unlock
311 * the object, in which case we've got some bad
312 * native code somewhere.
313 */
Carl Shapiro1ff876d2010-04-04 01:56:48 -0700314 assert(pthread_mutex_trylock(&mon->lock) == 0);
315 assert(pthread_mutex_unlock(&mon->lock) == 0);
Carl Shapiro980ffb02010-03-13 22:34:01 -0800316 dvmDestroyMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800317#ifdef WITH_DEADLOCK_PREDICTION
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800318 expandObjClear(&mon->historyChildren);
319 expandObjClear(&mon->historyParents);
320 free(mon->historyRawStackTrace);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800321#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800322 free(mon);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800323}
324
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800325/*
326 * Frees monitor objects belonging to unmarked objects.
327 */
328void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
329{
330 Monitor handle;
331 Monitor *prev, *curr;
332 Object *obj;
333
334 assert(mon != NULL);
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800335 assert(isUnmarkedObject != NULL);
336 prev = &handle;
337 prev->next = curr = *mon;
338 while (curr != NULL) {
339 obj = curr->obj;
340 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
341 prev->next = curr = curr->next;
342 freeObjectMonitor(obj);
343 } else {
344 prev = curr;
345 curr = curr->next;
346 }
347 }
348 *mon = handle.next;
349}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800350
Carl Shapirof0c514c2010-04-09 15:03:33 -0700351static char *logWriteInt(char *dst, int value)
352{
353 *dst++ = EVENT_TYPE_INT;
354 set4LE((u1 *)dst, value);
355 return dst + 4;
356}
357
358static char *logWriteString(char *dst, const char *value, size_t len)
359{
360 *dst++ = EVENT_TYPE_STRING;
361 set4LE((u1 *)dst, len);
362 dst += 4;
363 len = len < 32 ? len : 32;
364 memcpy(dst, value, len);
365 return dst + len;
366}
367
368#define EVENT_LOG_TAG_dvm_lock_contention 20003
369
370static void logContentionEvent(Thread *self, u4 waitMs, u4 samplePercent)
371{
372 const StackSaveArea *saveArea;
373 const Method *meth;
374 u4 relativePc;
375 char eventBuffer[131];
376 const char *fileName;
377 char procName[32], *selfName, *ownerName;
378 char *cp;
379 int fd, len;
380
381 saveArea = SAVEAREA_FROM_FP(self->curFrame);
382 meth = saveArea->method;
383 cp = eventBuffer;
384
385 /* Emit the event list length, 1 byte. */
386 *cp++ = 7;
387
388 /* Emit the process name, <= 37 bytes. */
389 fd = open("/proc/self/cmdline", O_RDONLY);
390 len = read(fd, procName, sizeof(procName));
391 close(fd);
392 cp = logWriteString(cp, procName, (len > 0 ? len : 0));
393
394 /* Emit the main thread status, 5 bytes. */
395 bool isMainThread = (self->systemTid == getpid());
396 cp = logWriteInt(cp, isMainThread);
397
398 /* Emit self thread name string, <= 37 bytes. */
399 selfName = dvmGetThreadName(self);
400 cp = logWriteString(cp, selfName, strlen(selfName));
401 free(selfName);
402
403 /* Emit the wait time, 5 bytes. */
404 cp = logWriteInt(cp, waitMs);
405
406 /* Emit the source code file name, <= 37 bytes. */
407 fileName = dvmGetMethodSourceFile(meth);
408 if (fileName == NULL) fileName = "";
409 cp = logWriteString(cp, fileName, strlen(fileName));
410
411 /* Emit the source code line number, 5 bytes. */
412 relativePc = saveArea->xtra.currentPc - saveArea->method->insns;
413 cp = logWriteInt(cp, dvmLineNumFromPC(meth, relativePc));
414
415 /* Emit the sample percentage, 5 bytes. */
416 cp = logWriteInt(cp, samplePercent);
417
418 assert((size_t)(cp - eventBuffer) <= sizeof(eventBuffer));
419 android_btWriteLog(EVENT_LOG_TAG_dvm_lock_contention,
420 EVENT_TYPE_LIST,
421 eventBuffer,
422 (size_t)(cp - eventBuffer));
423}
424
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800425/*
426 * Lock a monitor.
427 */
428static void lockMonitor(Thread* self, Monitor* mon)
429{
Carl Shapirof0c514c2010-04-09 15:03:33 -0700430 Thread *owner;
431 ThreadStatus oldStatus;
432 u4 waitThreshold, samplePercent;
433 u8 waitStart, waitEnd, waitMs;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800434
435 if (mon->owner == self) {
436 mon->lockCount++;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700437 return;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800438 }
Carl Shapiro045fdc92010-04-13 16:48:27 -0700439 if (dvmTryLockMutex(&mon->lock) != 0) {
Carl Shapirof0c514c2010-04-09 15:03:33 -0700440 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
441 waitThreshold = gDvm.lockProfThreshold;
442 if (waitThreshold) {
443 waitStart = dvmGetRelativeTimeUsec();
444 }
445 dvmLockMutex(&mon->lock);
446 if (waitThreshold) {
447 waitEnd = dvmGetRelativeTimeUsec();
448 }
449 dvmChangeStatus(self, oldStatus);
450 if (waitThreshold) {
451 waitMs = (waitEnd - waitStart) / 1000;
452 if (waitMs >= waitThreshold) {
453 samplePercent = 100;
454 } else {
455 samplePercent = 1 + 100 * waitMs / gDvm.lockProfSample;
456 }
457 if ((u4)rand() % 100 < samplePercent) {
458 logContentionEvent(self, waitMs, samplePercent);
459 }
460 }
461 }
462 mon->owner = self;
463 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800464}
465
466/*
467 * Try to lock a monitor.
468 *
469 * Returns "true" on success.
470 */
471static bool tryLockMonitor(Thread* self, Monitor* mon)
472{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800473 if (mon->owner == self) {
474 mon->lockCount++;
475 return true;
476 } else {
Carl Shapiro980ffb02010-03-13 22:34:01 -0800477 if (dvmTryLockMutex(&mon->lock) == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800478 mon->owner = self;
479 assert(mon->lockCount == 0);
480 return true;
481 } else {
482 return false;
483 }
484 }
485}
486
487
488/*
489 * Unlock a monitor.
490 *
491 * Returns true if the unlock succeeded.
492 * If the unlock failed, an exception will be pending.
493 */
494static bool unlockMonitor(Thread* self, Monitor* mon)
495{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800496 assert(self != NULL);
Carl Shapiro92277082010-04-06 15:35:59 -0700497 assert(mon != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800498 if (mon->owner == self) {
499 /*
500 * We own the monitor, so nobody else can be in here.
501 */
502 if (mon->lockCount == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800503 mon->owner = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800504 dvmUnlockMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800505 } else {
506 mon->lockCount--;
507 }
508 } else {
509 /*
510 * We don't own this, so we're not allowed to unlock it.
511 * The JNI spec says that we should throw IllegalMonitorStateException
512 * in this case.
513 */
Carl Shapiro91117572010-02-24 02:30:55 -0800514 dvmThrowExceptionFmt("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiro92277082010-04-06 15:35:59 -0700515 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800516 return false;
517 }
518 return true;
519}
520
521/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800522 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800523 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800524 */
525static int waitSetCheck(Monitor *mon)
526{
527 Thread *fast, *slow;
528 size_t n;
529
530 assert(mon != NULL);
531 fast = slow = mon->waitSet;
532 n = 0;
533 for (;;) {
534 if (fast == NULL) return 0;
535 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800536 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800537 n += 2;
538 fast = fast->waitNext->waitNext;
539 slow = slow->waitNext;
540 }
541}
542
543/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800544 * Links a thread into a monitor's wait set. The monitor lock must be
545 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800546 */
547static void waitSetAppend(Monitor *mon, Thread *thread)
548{
549 Thread *elt;
550
551 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800552 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800553 assert(thread != NULL);
554 assert(thread->waitNext == NULL);
555 assert(waitSetCheck(mon) == 0);
556 if (mon->waitSet == NULL) {
557 mon->waitSet = thread;
558 return;
559 }
560 elt = mon->waitSet;
561 while (elt->waitNext != NULL) {
562 elt = elt->waitNext;
563 }
564 elt->waitNext = thread;
565}
566
567/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800568 * Unlinks a thread from a monitor's wait set. The monitor lock must
569 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800570 */
571static void waitSetRemove(Monitor *mon, Thread *thread)
572{
573 Thread *elt;
574
575 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800576 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800577 assert(thread != NULL);
578 assert(waitSetCheck(mon) == 0);
579 if (mon->waitSet == NULL) {
580 return;
581 }
582 if (mon->waitSet == thread) {
583 mon->waitSet = thread->waitNext;
584 thread->waitNext = NULL;
585 return;
586 }
587 elt = mon->waitSet;
588 while (elt->waitNext != NULL) {
589 if (elt->waitNext == thread) {
590 elt->waitNext = thread->waitNext;
591 thread->waitNext = NULL;
592 return;
593 }
594 elt = elt->waitNext;
595 }
596}
597
Carl Shapirob4539192010-01-04 16:50:00 -0800598/*
599 * Converts the given relative waiting time into an absolute time.
600 */
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800601void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800602{
603 s8 endSec;
604
605#ifdef HAVE_TIMEDWAIT_MONOTONIC
606 clock_gettime(CLOCK_MONOTONIC, ts);
607#else
608 {
609 struct timeval tv;
610 gettimeofday(&tv, NULL);
611 ts->tv_sec = tv.tv_sec;
612 ts->tv_nsec = tv.tv_usec * 1000;
613 }
614#endif
615 endSec = ts->tv_sec + msec / 1000;
616 if (endSec >= 0x7fffffff) {
617 LOGV("NOTE: end time exceeds epoch\n");
618 endSec = 0x7ffffffe;
619 }
620 ts->tv_sec = endSec;
621 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
622
623 /* catch rollover */
624 if (ts->tv_nsec >= 1000000000L) {
625 ts->tv_sec++;
626 ts->tv_nsec -= 1000000000L;
627 }
628}
629
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800630int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
631 s8 msec, s4 nsec)
632{
633 int ret;
634 struct timespec ts;
635 absoluteTime(msec, nsec, &ts);
636#if defined(HAVE_TIMEDWAIT_MONOTONIC)
637 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
638#else
639 ret = pthread_cond_timedwait(cond, mutex, &ts);
640#endif
641 assert(ret == 0 || ret == ETIMEDOUT);
642 return ret;
643}
644
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800645/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800646 * Wait on a monitor until timeout, interrupt, or notification. Used for
647 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
648 *
649 * If another thread calls Thread.interrupt(), we throw InterruptedException
650 * and return immediately if one of the following are true:
651 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
652 * - blocked in join(), join(long), or join(long, int) methods of Thread
653 * - blocked in sleep(long), or sleep(long, int) methods of Thread
654 * Otherwise, we set the "interrupted" flag.
655 *
656 * Checks to make sure that "nsec" is in the range 0-999999
657 * (i.e. fractions of a millisecond) and throws the appropriate
658 * exception if it isn't.
659 *
660 * The spec allows "spurious wakeups", and recommends that all code using
661 * Object.wait() do so in a loop. This appears to derive from concerns
662 * about pthread_cond_wait() on multiprocessor systems. Some commentary
663 * on the web casts doubt on whether these can/should occur.
664 *
665 * Since we're allowed to wake up "early", we clamp extremely long durations
666 * to return at the end of the 32-bit time epoch.
667 */
668static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
669 bool interruptShouldThrow)
670{
671 struct timespec ts;
672 bool wasInterrupted = false;
673 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800674 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800675
Carl Shapiro71938022009-12-22 13:49:53 -0800676 assert(self != NULL);
677 assert(mon != NULL);
678
Carl Shapiro94338aa2009-12-21 11:42:59 -0800679 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800680 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800681 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
682 "object not locked by thread before wait()");
683 return;
684 }
685
686 /*
687 * Enforce the timeout range.
688 */
689 if (msec < 0 || nsec < 0 || nsec > 999999) {
690 dvmThrowException("Ljava/lang/IllegalArgumentException;",
691 "timeout arguments out of range");
692 return;
693 }
694
695 /*
696 * Compute absolute wakeup time, if necessary.
697 */
698 if (msec == 0 && nsec == 0) {
699 timed = false;
700 } else {
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800701 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800702 timed = true;
703 }
704
705 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800706 * Add ourselves to the set of threads waiting on this monitor, and
707 * release our hold. We need to let it go even if we're a few levels
708 * deep in a recursive lock, and we need to restore that later.
709 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800710 * We append to the wait set ahead of clearing the count and owner
711 * fields so the subroutine can check that the calling thread owns
712 * the monitor. Aside from that, the order of member updates is
713 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800714 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800715 waitSetAppend(mon, self);
716 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800717 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800718 mon->owner = NULL;
719
720 /*
721 * Update thread status. If the GC wakes up, it'll ignore us, knowing
722 * that we won't touch any references in this state, and we'll check
723 * our suspend mode before we transition out.
724 */
725 if (timed)
726 dvmChangeStatus(self, THREAD_TIMED_WAIT);
727 else
728 dvmChangeStatus(self, THREAD_WAIT);
729
Carl Shapiro980ffb02010-03-13 22:34:01 -0800730 dvmLockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800731
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800732 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800733 * Set waitMonitor to the monitor object we will be waiting on.
734 * When waitMonitor is non-NULL a notifying or interrupting thread
735 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800736 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800737 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800738 self->waitMonitor = mon;
739
740 /*
741 * Handle the case where the thread was interrupted before we called
742 * wait().
743 */
744 if (self->interrupted) {
745 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800746 self->waitMonitor = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800747 dvmUnlockMutex(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800748 goto done;
749 }
750
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800751 /*
752 * Release the monitor lock and wait for a notification or
753 * a timeout to occur.
754 */
Carl Shapiro980ffb02010-03-13 22:34:01 -0800755 dvmUnlockMutex(&mon->lock);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800756
757 if (!timed) {
758 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
759 assert(ret == 0);
760 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800761#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800762 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800763#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800764 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800765#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800766 assert(ret == 0 || ret == ETIMEDOUT);
767 }
768 if (self->interrupted) {
769 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800770 }
771
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800772 self->interrupted = false;
773 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800774
Carl Shapiro980ffb02010-03-13 22:34:01 -0800775 dvmUnlockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800776
Carl Shapiro30aa9972010-01-13 22:07:50 -0800777 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800778 lockMonitor(self, mon);
779
Carl Shapiro142ef272010-01-25 12:51:31 -0800780done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800781 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800782 * We remove our thread from wait set after restoring the count
783 * and owner fields so the subroutine can check that the calling
784 * thread owns the monitor. Aside from that, the order of member
785 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800786 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800787 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800788 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800789 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800790
791 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
792 dvmChangeStatus(self, THREAD_RUNNING);
793
794 if (wasInterrupted) {
795 /*
796 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800797 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800798 *
799 * The doc sayeth: "The interrupted status of the current thread is
800 * cleared when this exception is thrown."
801 */
802 self->interrupted = false;
803 if (interruptShouldThrow)
804 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
805 }
806}
807
808/*
809 * Notify one thread waiting on this monitor.
810 */
811static void notifyMonitor(Thread* self, Monitor* mon)
812{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800813 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800814
Carl Shapiro71938022009-12-22 13:49:53 -0800815 assert(self != NULL);
816 assert(mon != NULL);
817
Carl Shapiro94338aa2009-12-21 11:42:59 -0800818 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800819 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800820 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
821 "object not locked by thread before notify()");
822 return;
823 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800824 /* Signal the first waiting thread in the wait set. */
825 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800826 thread = mon->waitSet;
827 mon->waitSet = thread->waitNext;
828 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800829 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800830 /* Check to see if the thread is still waiting. */
831 if (thread->waitMonitor != NULL) {
832 pthread_cond_signal(&thread->waitCond);
Carl Shapiro980ffb02010-03-13 22:34:01 -0800833 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800834 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800835 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800836 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800837 }
838}
839
840/*
841 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800842 */
843static void notifyAllMonitor(Thread* self, Monitor* mon)
844{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800845 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800846
Carl Shapiro71938022009-12-22 13:49:53 -0800847 assert(self != NULL);
848 assert(mon != NULL);
849
Carl Shapiro94338aa2009-12-21 11:42:59 -0800850 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800851 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800852 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
853 "object not locked by thread before notifyAll()");
854 return;
855 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800856 /* Signal all threads in the wait set. */
857 while (mon->waitSet != NULL) {
858 thread = mon->waitSet;
859 mon->waitSet = thread->waitNext;
860 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800861 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800862 /* Check to see if the thread is still waiting. */
863 if (thread->waitMonitor != NULL) {
864 pthread_cond_signal(&thread->waitCond);
865 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800866 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800867 }
868}
869
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800870/*
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800871 * Changes the shape of a monitor from thin to fat, preserving the
872 * internal lock state. The calling thread must own the lock.
873 */
874static void inflateMonitor(Thread *self, Object *obj)
875{
876 Monitor *mon;
877 u4 thin;
878
879 assert(self != NULL);
880 assert(obj != NULL);
881 assert(LW_SHAPE(obj->lock) == LW_SHAPE_THIN);
882 assert(LW_LOCK_OWNER(obj->lock) == self->threadId);
883 /* Allocate and acquire a new monitor. */
884 mon = dvmCreateMonitor(obj);
885 lockMonitor(self, mon);
886 /* Propagate the lock state. */
887 thin = obj->lock;
888 mon->lockCount = LW_LOCK_COUNT(thin);
889 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
890 thin |= (u4)mon | LW_SHAPE_FAT;
891 /* Publish the updated lock word. */
892 MEM_BARRIER();
893 obj->lock = thin;
894}
895
896/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800897 * Implements monitorenter for "synchronized" stuff.
898 *
899 * This does not fail or throw an exception (unless deadlock prediction
900 * is enabled and set to "err" mode).
901 */
902void dvmLockObject(Thread* self, Object *obj)
903{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800904 volatile u4 *thinp;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800905 ThreadStatus oldStatus;
906 useconds_t sleepDelay;
907 const useconds_t maxSleepDelay = 1 << 20;
908 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800909
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800910 assert(self != NULL);
911 assert(obj != NULL);
912 threadId = self->threadId;
913 thinp = &obj->lock;
914retry:
915 thin = *thinp;
916 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
917 /*
918 * The lock is a thin lock. The owner field is used to
919 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800920 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800921 if (LW_LOCK_OWNER(thin) == threadId) {
922 /*
923 * The calling thread owns the lock. Increment the
924 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800925 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800926 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
927 } else if (LW_LOCK_OWNER(thin) == 0) {
928 /*
929 * The lock is unowned. Install the thread id of the
930 * calling thread into the owner field. This is the
931 * common case. In performance critical code the JIT
932 * will have tried this before calling out to the VM.
933 */
934 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
935 if (!ATOMIC_CMP_SWAP((int32_t *)thinp, thin, newThin)) {
936 /*
937 * The acquire failed. Try again.
938 */
939 goto retry;
940 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800941 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800942 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
943 threadId, &obj->lock, 0, *thinp, thin);
944 /*
945 * The lock is owned by another thread. Notify the VM
946 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800947 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800948 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
949 /*
950 * Spin until the thin lock is released or inflated.
951 */
952 sleepDelay = 0;
953 for (;;) {
954 thin = *thinp;
955 /*
956 * Check the shape of the lock word. Another thread
957 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800958 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800959 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
960 if (LW_LOCK_OWNER(thin) == 0) {
961 /*
962 * The lock has been released. Install the
963 * thread id of the calling thread into the
964 * owner field.
965 */
966 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
967 if (ATOMIC_CMP_SWAP((int32_t *)thinp,
968 thin, newThin)) {
969 /*
970 * The acquire succeed. Break out of the
971 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800972 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800973 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800974 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800975 } else {
976 /*
977 * The lock has not been released. Yield so
978 * the owning thread can run.
979 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800980 if (sleepDelay == 0) {
981 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800982 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800983 } else {
984 usleep(sleepDelay);
985 if (sleepDelay < maxSleepDelay / 2) {
986 sleepDelay *= 2;
987 }
988 }
989 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800990 } else {
991 /*
992 * The thin lock was inflated by another thread.
993 * Let the VM know we are no longer waiting and
994 * try again.
995 */
996 LOG_THIN("(%d) lock %p surprise-fattened",
997 threadId, &obj->lock);
998 dvmChangeStatus(self, oldStatus);
999 goto retry;
1000 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001001 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001002 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
1003 threadId, &obj->lock, 0, *thinp, thin);
1004 /*
1005 * We have acquired the thin lock. Let the VM know that
1006 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001007 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001008 dvmChangeStatus(self, oldStatus);
1009 /*
1010 * Fatten the lock.
1011 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001012 inflateMonitor(self, obj);
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001013 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001014 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001015 } else {
1016 /*
1017 * The lock is a fat lock.
1018 */
1019 assert(LW_MONITOR(obj->lock) != NULL);
1020 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001021 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001022#ifdef WITH_DEADLOCK_PREDICTION
1023 /*
1024 * See if we were allowed to grab the lock at this time. We do it
1025 * *after* acquiring the lock, rather than before, so that we can
1026 * freely update the Monitor struct. This seems counter-intuitive,
1027 * but our goal is deadlock *prediction* not deadlock *prevention*.
1028 * (If we actually deadlock, the situation is easy to diagnose from
1029 * a thread dump, so there's no point making a special effort to do
1030 * the checks before the lock is held.)
1031 *
1032 * This needs to happen before we add the object to the thread's
1033 * monitor list, so we can tell the difference between first-lock and
1034 * re-lock.
1035 *
1036 * It's also important that we do this while in THREAD_RUNNING, so
1037 * that we don't interfere with cleanup operations in the GC.
1038 */
1039 if (gDvm.deadlockPredictMode != kDPOff) {
1040 if (self->status != THREAD_RUNNING) {
1041 LOGE("Bad thread status (%d) in DP\n", self->status);
1042 dvmDumpThread(self, false);
1043 dvmAbort();
1044 }
1045 assert(!dvmCheckException(self));
1046 updateDeadlockPrediction(self, obj);
1047 if (dvmCheckException(self)) {
1048 /*
1049 * If we're throwing an exception here, we need to free the
1050 * lock. We add the object to the thread's monitor list so the
1051 * "unlock" code can remove it.
1052 */
1053 dvmAddToMonitorList(self, obj, false);
1054 dvmUnlockObject(self, obj);
1055 LOGV("--- unlocked, pending is '%s'\n",
1056 dvmGetException(self)->clazz->descriptor);
1057 }
1058 }
1059
1060 /*
1061 * Add the locked object, and the current stack trace, to the list
1062 * held by the Thread object. If deadlock prediction isn't on,
1063 * don't capture the stack trace.
1064 */
1065 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
1066#elif defined(WITH_MONITOR_TRACKING)
1067 /*
1068 * Add the locked object to the list held by the Thread object.
1069 */
1070 dvmAddToMonitorList(self, obj, false);
1071#endif
1072}
1073
1074/*
1075 * Implements monitorexit for "synchronized" stuff.
1076 *
1077 * On failure, throws an exception and returns "false".
1078 */
1079bool dvmUnlockObject(Thread* self, Object *obj)
1080{
Carl Shapiro94338aa2009-12-21 11:42:59 -08001081 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001082
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001083 assert(self != NULL);
1084 assert(self->status == THREAD_RUNNING);
1085 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001086 /*
1087 * Cache the lock word as its value can change while we are
1088 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001089 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001090 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001091 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
1092 /*
1093 * The lock is thin. We must ensure that the lock is owned
1094 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001095 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001096 if (LW_LOCK_OWNER(thin) == self->threadId) {
1097 /*
1098 * We are the lock owner. It is safe to update the lock
1099 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001100 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001101 if (LW_LOCK_COUNT(thin) == 0) {
1102 /*
1103 * The lock was not recursively acquired, the common
1104 * case. Unlock by clearing all bits except for the
1105 * hash state.
1106 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001107 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001108 } else {
1109 /*
1110 * The object was recursively acquired. Decrement the
1111 * lock recursion count field.
1112 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001113 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001114 }
1115 } else {
1116 /*
1117 * We do not own the lock. The JVM spec requires that we
1118 * throw an exception in this case.
1119 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001120 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001121 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001122 return false;
1123 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001124 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001125 /*
1126 * The lock is fat. We must check to see if unlockMonitor has
1127 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001128 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001129 assert(LW_MONITOR(obj->lock) != NULL);
1130 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001131 /*
1132 * An exception has been raised. Do not fall through.
1133 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001134 return false;
1135 }
1136 }
1137
1138#ifdef WITH_MONITOR_TRACKING
1139 /*
1140 * Remove the object from the Thread's list.
1141 */
1142 dvmRemoveFromMonitorList(self, obj);
1143#endif
1144
1145 return true;
1146}
1147
1148/*
1149 * Object.wait(). Also called for class init.
1150 */
1151void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1152 bool interruptShouldThrow)
1153{
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001154 Monitor* mon;
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001155 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001156
1157 /* If the lock is still thin, we need to fatten it.
1158 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001159 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001160 /* Make sure that 'self' holds the lock.
1161 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001162 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001163 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1164 "object not locked by thread before wait()");
1165 return;
1166 }
1167
1168 /* This thread holds the lock. We need to fatten the lock
1169 * so 'self' can block on it. Don't update the object lock
1170 * field yet, because 'self' needs to acquire the lock before
1171 * any other thread gets a chance.
1172 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001173 inflateMonitor(self, obj);
1174 LOG_THIN("(%d) lock %p fattened by wait() to count %d",
1175 self->threadId, &obj->lock, mon->lockCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001176 }
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001177 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001178 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1179}
1180
1181/*
1182 * Object.notify().
1183 */
1184void dvmObjectNotify(Thread* self, Object *obj)
1185{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001186 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001187
1188 /* If the lock is still thin, there aren't any waiters;
1189 * waiting on an object forces lock fattening.
1190 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001191 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001192 /* Make sure that 'self' holds the lock.
1193 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001194 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001195 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1196 "object not locked by thread before notify()");
1197 return;
1198 }
1199
1200 /* no-op; there are no waiters to notify.
1201 */
1202 } else {
1203 /* It's a fat lock.
1204 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001205 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001206 }
1207}
1208
1209/*
1210 * Object.notifyAll().
1211 */
1212void dvmObjectNotifyAll(Thread* self, Object *obj)
1213{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001214 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001215
1216 /* If the lock is still thin, there aren't any waiters;
1217 * waiting on an object forces lock fattening.
1218 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001219 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001220 /* Make sure that 'self' holds the lock.
1221 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001222 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001223 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1224 "object not locked by thread before notifyAll()");
1225 return;
1226 }
1227
1228 /* no-op; there are no waiters to notify.
1229 */
1230 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001231 /* It's a fat lock.
1232 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001233 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001234 }
1235}
1236
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001237/*
1238 * This implements java.lang.Thread.sleep(long msec, int nsec).
1239 *
1240 * The sleep is interruptible by other threads, which means we can't just
1241 * plop into an OS sleep call. (We probably could if we wanted to send
1242 * signals around and rely on EINTR, but that's inefficient and relies
1243 * on native code respecting our signal mask.)
1244 *
1245 * We have to do all of this stuff for Object.wait() as well, so it's
1246 * easiest to just sleep on a private Monitor.
1247 *
1248 * It appears that we want sleep(0,0) to go through the motions of sleeping
1249 * for a very short duration, rather than just returning.
1250 */
1251void dvmThreadSleep(u8 msec, u4 nsec)
1252{
1253 Thread* self = dvmThreadSelf();
1254 Monitor* mon = gDvm.threadSleepMon;
1255
1256 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1257 if (msec == 0 && nsec == 0)
1258 nsec++;
1259
1260 lockMonitor(self, mon);
1261 waitMonitor(self, mon, msec, nsec, true);
1262 unlockMonitor(self, mon);
1263}
1264
1265/*
1266 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001267 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001268void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001269{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001270 assert(thread != NULL);
1271
Carl Shapiro980ffb02010-03-13 22:34:01 -08001272 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001273
1274 /*
1275 * If the interrupted flag is already set no additional action is
1276 * required.
1277 */
1278 if (thread->interrupted == true) {
Carl Shapiro980ffb02010-03-13 22:34:01 -08001279 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001280 return;
1281 }
1282
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001283 /*
1284 * Raise the "interrupted" flag. This will cause it to bail early out
1285 * of the next wait() attempt, if it's not currently waiting on
1286 * something.
1287 */
1288 thread->interrupted = true;
1289 MEM_BARRIER();
1290
1291 /*
1292 * Is the thread waiting?
1293 *
1294 * Note that fat vs. thin doesn't matter here; waitMonitor
1295 * is only set when a thread actually waits on a monitor,
1296 * which implies that the monitor has already been fattened.
1297 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001298 if (thread->waitMonitor != NULL) {
1299 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001300 }
1301
Carl Shapiro980ffb02010-03-13 22:34:01 -08001302 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001303}
1304
Carl Shapiro30aa9972010-01-13 22:07:50 -08001305#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001306u4 dvmIdentityHashCode(Object *obj)
1307{
1308 return (u4)obj;
1309}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001310#else
Carl Shapiro30aa9972010-01-13 22:07:50 -08001311/*
1312 * Returns the identity hash code of the given object.
1313 */
1314u4 dvmIdentityHashCode(Object *obj)
1315{
1316 Thread *self, *thread;
1317 volatile u4 *lw;
1318 size_t length;
1319 u4 lock, owner, hashState;
1320
1321 if (obj == NULL) {
1322 /*
1323 * Null is defined to have an identity hash code of 0.
1324 */
1325 return 0;
1326 }
1327 lw = &obj->lock;
1328retry:
1329 hashState = LW_HASH_STATE(*lw);
1330 if (hashState == LW_HASH_STATE_HASHED) {
1331 /*
1332 * The object has been hashed but has not had its hash code
1333 * relocated by the garbage collector. Use the raw object
1334 * address.
1335 */
1336 return (u4)obj >> 3;
1337 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1338 /*
1339 * The object has been hashed and its hash code has been
1340 * relocated by the collector. Use the value of the naturally
1341 * aligned word following the instance data.
1342 */
1343 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
Carl Shapiro1e714bb2010-03-16 03:26:49 -07001344 length = dvmArrayObjectLength((ArrayObject *)obj);
Carl Shapiro30aa9972010-01-13 22:07:50 -08001345 length = (length + 3) & ~3;
1346 } else {
1347 length = obj->clazz->objectSize;
1348 }
1349 return *(u4 *)(((char *)obj) + length);
1350 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1351 /*
1352 * The object has never been hashed. Change the hash state to
1353 * hashed and use the raw object address.
1354 */
1355 self = dvmThreadSelf();
1356 if (self->threadId == lockOwner(obj)) {
1357 /*
1358 * We already own the lock so we can update the hash state
1359 * directly.
1360 */
1361 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1362 return (u4)obj >> 3;
1363 }
1364 /*
1365 * We do not own the lock. Try acquiring the lock. Should
1366 * this fail, we must suspend the owning thread.
1367 */
1368 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1369 /*
1370 * If the lock is thin assume it is unowned. We simulate
1371 * an acquire, update, and release with a single CAS.
1372 */
1373 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1374 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1375 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1376 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1377 (int32_t)lock)) {
1378 /*
1379 * A new lockword has been installed with a hash state
1380 * of hashed. Use the raw object address.
1381 */
1382 return (u4)obj >> 3;
1383 }
1384 } else {
1385 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1386 /*
1387 * The monitor lock has been acquired. Change the
1388 * hash state to hashed and use the raw object
1389 * address.
1390 */
1391 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1392 unlockMonitor(self, LW_MONITOR(*lw));
1393 return (u4)obj >> 3;
1394 }
1395 }
1396 /*
1397 * At this point we have failed to acquire the lock. We must
1398 * identify the owning thread and suspend it.
1399 */
1400 dvmLockThreadList(self);
1401 /*
1402 * Cache the lock word as its value can change between
1403 * determining its shape and retrieving its owner.
1404 */
1405 lock = *lw;
1406 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1407 /*
1408 * Find the thread with the corresponding thread id.
1409 */
1410 owner = LW_LOCK_OWNER(lock);
1411 assert(owner != self->threadId);
1412 /*
1413 * If the lock has no owner do not bother scanning the
1414 * thread list and fall through to the failure handler.
1415 */
1416 thread = owner ? gDvm.threadList : NULL;
1417 while (thread != NULL) {
1418 if (thread->threadId == owner) {
1419 break;
1420 }
1421 thread = thread->next;
1422 }
1423 } else {
1424 thread = LW_MONITOR(lock)->owner;
1425 }
1426 /*
1427 * If thread is NULL the object has been released since the
1428 * thread list lock was acquired. Try again.
1429 */
1430 if (thread == NULL) {
1431 dvmUnlockThreadList();
1432 goto retry;
1433 }
1434 /*
1435 * Wait for the owning thread to suspend.
1436 */
1437 dvmSuspendThread(thread);
1438 if (dvmHoldsLock(thread, obj)) {
1439 /*
1440 * The owning thread has been suspended. We can safely
1441 * change the hash state to hashed.
1442 */
1443 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1444 dvmResumeThread(thread);
1445 dvmUnlockThreadList();
1446 return (u4)obj >> 3;
1447 }
1448 /*
1449 * The wrong thread has been suspended. Try again.
1450 */
1451 dvmResumeThread(thread);
1452 dvmUnlockThreadList();
1453 goto retry;
1454 }
1455 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1456 dvmDumpThread(dvmThreadSelf(), false);
1457 dvmAbort();
1458 return 0; /* Quiet the compiler. */
1459}
1460#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001461
1462#ifdef WITH_DEADLOCK_PREDICTION
1463/*
1464 * ===========================================================================
1465 * Deadlock prediction
1466 * ===========================================================================
1467 */
1468/*
1469The idea is to predict the possibility of deadlock by recording the order
1470in which monitors are acquired. If we see an attempt to acquire a lock
1471out of order, we can identify the locks and offending code.
1472
1473To make this work, we need to keep track of the locks held by each thread,
1474and create history trees for each lock. When a thread tries to acquire
1475a new lock, we walk through the "history children" of the lock, looking
1476for a match with locks the thread already holds. If we find a match,
1477it means the thread has made a request that could result in a deadlock.
1478
1479To support recursive locks, we always allow re-locking a currently-held
1480lock, and maintain a recursion depth count.
1481
1482An ASCII-art example, where letters represent Objects:
1483
1484 A
1485 /|\
1486 / | \
1487 B | D
1488 \ |
1489 \|
1490 C
1491
1492The above is the tree we'd have after handling Object synchronization
1493sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1494a child of B. (The lines represent pointers between parent and child.
1495Every node can have multiple parents and multiple children.)
1496
1497If we hold AC, and want to lock B, we recursively search through B's
1498children to see if A or C appears. It does, so we reject the attempt.
1499(A straightforward way to implement it: add a link from C to B, then
1500determine whether the graph starting at B contains a cycle.)
1501
1502If we hold AC and want to lock D, we would succeed, creating a new link
1503from C to D.
1504
1505The lock history and a stack trace is attached to the Object's Monitor
1506struct, which means we need to fatten every Object we lock (thin locking
1507is effectively disabled). If we don't need the stack trace we can
1508avoid fattening the leaf nodes, only fattening objects that need to hold
1509history trees.
1510
1511Updates to Monitor structs are only allowed for the thread that holds
1512the Monitor, so we actually do most of our deadlock prediction work after
1513the lock has been acquired.
1514
1515When an object with a monitor is GCed, we need to remove it from the
1516history trees. There are two basic approaches:
1517 (1) For through the entire set of known monitors, search all child
1518 lists for the object in question. This is rather slow, resulting
1519 in GC passes that take upwards of 10 seconds to complete.
1520 (2) Maintain "parent" pointers in each node. Remove the entries as
1521 required. This requires additional storage and maintenance for
1522 every operation, but is significantly faster at GC time.
1523For each GCed object, we merge all of the object's children into each of
1524the object's parents.
1525*/
1526
1527#if !defined(WITH_MONITOR_TRACKING)
1528# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1529#endif
1530
1531/*
1532 * Clear out the contents of an ExpandingObjectList, freeing any
1533 * dynamic allocations.
1534 */
1535static void expandObjClear(ExpandingObjectList* pList)
1536{
1537 if (pList->list != NULL) {
1538 free(pList->list);
1539 pList->list = NULL;
1540 }
1541 pList->alloc = pList->count = 0;
1542}
1543
1544/*
1545 * Get the number of objects currently stored in the list.
1546 */
1547static inline int expandBufGetCount(const ExpandingObjectList* pList)
1548{
1549 return pList->count;
1550}
1551
1552/*
1553 * Get the Nth entry from the list.
1554 */
1555static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1556 int i)
1557{
1558 return pList->list[i];
1559}
1560
1561/*
1562 * Add a new entry to the list.
1563 *
1564 * We don't check for or try to enforce uniqueness. It's expected that
1565 * the higher-level code does this for us.
1566 */
1567static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1568{
1569 if (pList->count == pList->alloc) {
1570 /* time to expand */
1571 Object** newList;
1572
1573 if (pList->alloc == 0)
1574 pList->alloc = 4;
1575 else
1576 pList->alloc *= 2;
1577 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1578 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1579 if (newList == NULL) {
1580 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1581 dvmAbort();
1582 }
1583 pList->list = newList;
1584 }
1585
1586 pList->list[pList->count++] = obj;
1587}
1588
1589/*
1590 * Returns "true" if the element was successfully removed.
1591 */
1592static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1593{
1594 int i;
1595
1596 for (i = pList->count-1; i >= 0; i--) {
1597 if (pList->list[i] == obj)
1598 break;
1599 }
1600 if (i < 0)
1601 return false;
1602
1603 if (i != pList->count-1) {
1604 /*
1605 * The order of elements is not important, so we just copy the
1606 * last entry into the new slot.
1607 */
1608 //memmove(&pList->list[i], &pList->list[i+1],
1609 // (pList->count-1 - i) * sizeof(pList->list[0]));
1610 pList->list[i] = pList->list[pList->count-1];
1611 }
1612
1613 pList->count--;
1614 pList->list[pList->count] = (Object*) 0xdecadead;
1615 return true;
1616}
1617
1618/*
1619 * Returns "true" if "obj" appears in the list.
1620 */
1621static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1622{
1623 int i;
1624
1625 for (i = 0; i < pList->count; i++) {
1626 if (pList->list[i] == obj)
1627 return true;
1628 }
1629 return false;
1630}
1631
1632/*
1633 * Print the list contents to stdout. For debugging.
1634 */
1635static void expandObjDump(const ExpandingObjectList* pList)
1636{
1637 int i;
1638 for (i = 0; i < pList->count; i++)
1639 printf(" %p", pList->list[i]);
1640}
1641
1642/*
1643 * Check for duplicate entries. Returns the index of the first instance
1644 * of the duplicated value, or -1 if no duplicates were found.
1645 */
1646static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1647{
1648 int i, j;
1649 for (i = 0; i < pList->count-1; i++) {
1650 for (j = i + 1; j < pList->count; j++) {
1651 if (pList->list[i] == pList->list[j]) {
1652 return i;
1653 }
1654 }
1655 }
1656
1657 return -1;
1658}
1659
1660
1661/*
1662 * Determine whether "child" appears in the list of objects associated
1663 * with the Monitor in "parent". If "parent" is a thin lock, we return
1664 * false immediately.
1665 */
1666static bool objectInChildList(const Object* parent, Object* child)
1667{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001668 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001669 if (!IS_LOCK_FAT(&lock)) {
1670 //LOGI("on thin\n");
1671 return false;
1672 }
1673
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001674 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001675}
1676
1677/*
1678 * Print the child list.
1679 */
1680static void dumpKids(Object* parent)
1681{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001682 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001683
1684 printf("Children of %p:", parent);
1685 expandObjDump(&mon->historyChildren);
1686 printf("\n");
1687}
1688
1689/*
1690 * Add "child" to the list of children in "parent", and add "parent" to
1691 * the list of parents in "child".
1692 */
1693static void linkParentToChild(Object* parent, Object* child)
1694{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001695 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001696 assert(IS_LOCK_FAT(&parent->lock));
1697 assert(IS_LOCK_FAT(&child->lock));
1698 assert(parent != child);
1699 Monitor* mon;
1700
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001701 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001702 assert(!expandObjHas(&mon->historyChildren, child));
1703 expandObjAddEntry(&mon->historyChildren, child);
1704
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001705 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001706 assert(!expandObjHas(&mon->historyParents, parent));
1707 expandObjAddEntry(&mon->historyParents, parent);
1708}
1709
1710
1711/*
1712 * Remove "child" from the list of children in "parent".
1713 */
1714static void unlinkParentFromChild(Object* parent, Object* child)
1715{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001716 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001717 assert(IS_LOCK_FAT(&parent->lock));
1718 assert(IS_LOCK_FAT(&child->lock));
1719 assert(parent != child);
1720 Monitor* mon;
1721
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001722 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001723 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1724 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1725 }
1726 assert(!expandObjHas(&mon->historyChildren, child));
1727 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1728
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001729 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001730 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1731 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1732 }
1733 assert(!expandObjHas(&mon->historyParents, parent));
1734 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1735}
1736
1737
1738/*
1739 * Log the monitors held by the current thread. This is done as part of
1740 * flagging an error.
1741 */
1742static void logHeldMonitors(Thread* self)
1743{
1744 char* name = NULL;
1745
1746 name = dvmGetThreadName(self);
1747 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1748 self->threadId, name);
1749 LOGW("(most-recently-acquired on top):\n");
1750 free(name);
1751
1752 LockedObjectData* lod = self->pLockedObjects;
1753 while (lod != NULL) {
1754 LOGW("--- object %p[%d] (%s)\n",
1755 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1756 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1757
1758 lod = lod->next;
1759 }
1760}
1761
1762/*
1763 * Recursively traverse the object hierarchy starting at "obj". We mark
1764 * ourselves on entry and clear the mark on exit. If we ever encounter
1765 * a marked object, we have a cycle.
1766 *
1767 * Returns "true" if all is well, "false" if we found a cycle.
1768 */
1769static bool traverseTree(Thread* self, const Object* obj)
1770{
1771 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001772 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001773
1774 /*
1775 * Have we been here before?
1776 */
1777 if (mon->historyMark) {
1778 int* rawStackTrace;
1779 int stackDepth;
1780
1781 LOGW("%s\n", kStartBanner);
1782 LOGW("Illegal lock attempt:\n");
1783 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1784
1785 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1786 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1787 free(rawStackTrace);
1788
1789 LOGW(" ");
1790 logHeldMonitors(self);
1791
1792 LOGW(" ");
1793 LOGW("Earlier, the following lock order (from last to first) was\n");
1794 LOGW("established -- stack trace is from first successful lock):\n");
1795 return false;
1796 }
1797 mon->historyMark = true;
1798
1799 /*
1800 * Examine the children. We do NOT hold these locks, so they might
1801 * very well transition from thin to fat or change ownership while
1802 * we work.
1803 *
1804 * NOTE: we rely on the fact that they cannot revert from fat to thin
1805 * while we work. This is currently a safe assumption.
1806 *
1807 * We can safely ignore thin-locked children, because by definition
1808 * they have no history and are leaf nodes. In the current
1809 * implementation we always fatten the locks to provide a place to
1810 * hang the stack trace.
1811 */
1812 ExpandingObjectList* pList = &mon->historyChildren;
1813 int i;
1814 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1815 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001816 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001817 if (!IS_LOCK_FAT(&lock))
1818 continue;
1819 if (!traverseTree(self, child)) {
1820 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1821 dvmLogRawStackTrace(mon->historyRawStackTrace,
1822 mon->historyStackDepth);
1823 mon->historyMark = false;
1824 return false;
1825 }
1826 }
1827
1828 mon->historyMark = false;
1829
1830 return true;
1831}
1832
1833/*
1834 * Update the deadlock prediction tree, based on the current thread
1835 * acquiring "acqObj". This must be called before the object is added to
1836 * the thread's list of held monitors.
1837 *
1838 * If the thread already holds the lock (recursion), or this is a known
1839 * lock configuration, we return without doing anything. Otherwise, we add
1840 * a link from the most-recently-acquired lock in this thread to "acqObj"
1841 * after ensuring that the parent lock is "fat".
1842 *
1843 * This MUST NOT be called while a GC is in progress in another thread,
1844 * because we assume exclusive access to history trees in owned monitors.
1845 */
1846static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1847{
1848 LockedObjectData* lod;
1849 LockedObjectData* mrl;
1850
1851 /*
1852 * Quick check for recursive access.
1853 */
1854 lod = dvmFindInMonitorList(self, acqObj);
1855 if (lod != NULL) {
1856 LOGV("+++ DP: recursive %p\n", acqObj);
1857 return;
1858 }
1859
1860 /*
1861 * Make the newly-acquired object's monitor "fat". In some ways this
1862 * isn't strictly necessary, but we need the GC to tell us when
1863 * "interesting" objects go away, and right now the only way to make
1864 * an object look interesting is to give it a monitor.
1865 *
1866 * This also gives us a place to hang a stack trace.
1867 *
1868 * Our thread holds the lock, so we're allowed to rewrite the lock
1869 * without worrying that something will change out from under us.
1870 */
1871 if (!IS_LOCK_FAT(&acqObj->lock)) {
1872 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001873 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001874 inflateMonitor(self, acqObj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001875 }
1876
1877 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001878 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1879 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001880 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1881 &mon->historyStackDepth);
1882 }
1883
1884 /*
1885 * We need to examine and perhaps modify the most-recently-locked
1886 * monitor. We own that, so there's no risk of another thread
1887 * stepping on us.
1888 *
1889 * Retrieve the most-recently-locked entry from our thread.
1890 */
1891 mrl = self->pLockedObjects;
1892 if (mrl == NULL)
1893 return; /* no other locks held */
1894
1895 /*
1896 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1897 * this without holding the global lock because of our assertion that
1898 * a GC is not running in parallel -- nobody except the GC can
1899 * modify a history list in a Monitor they don't own, and we own "mrl".
1900 * (There might be concurrent *reads*, but no concurrent *writes.)
1901 *
1902 * If we find it, this is a known good configuration, and we're done.
1903 */
1904 if (objectInChildList(mrl->obj, acqObj))
1905 return;
1906
1907 /*
1908 * "mrl" is going to need to have a history tree. If it's currently
1909 * a thin lock, we make it fat now. The thin lock might have a
1910 * nonzero recursive lock count, which we need to carry over.
1911 *
1912 * Our thread holds the lock, so we're allowed to rewrite the lock
1913 * without worrying that something will change out from under us.
1914 */
1915 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1916 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001917 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001918 inflateMonitor(self, mrl->obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001919 }
1920
1921 /*
1922 * We haven't seen this configuration before. We need to scan down
1923 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1924 * appear. We grab a global lock before traversing or updating the
1925 * history list.
1926 *
1927 * If we find a match for any of our held locks, we know that the lock
1928 * has previously been acquired *after* acqObj, and we throw an error.
1929 *
1930 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1931 * and do a recursive traversal, marking nodes as we cross them. If
1932 * we cross one a second time, we have a cycle and can throw an error.
1933 * (We do the flag-clearing traversal before adding the new link, so
1934 * that we're guaranteed to terminate.)
1935 *
1936 * If "acqObj" is a thin lock, it has no history, and we can create a
1937 * link to it without additional checks. [ We now guarantee that it's
1938 * always fat. ]
1939 */
1940 bool failed = false;
1941 dvmLockMutex(&gDvm.deadlockHistoryLock);
1942 linkParentToChild(mrl->obj, acqObj);
1943 if (!traverseTree(self, acqObj)) {
1944 LOGW("%s\n", kEndBanner);
1945 failed = true;
1946
1947 /* remove the entry so we're still okay when in "warning" mode */
1948 unlinkParentFromChild(mrl->obj, acqObj);
1949 }
1950 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1951
1952 if (failed) {
1953 switch (gDvm.deadlockPredictMode) {
1954 case kDPErr:
1955 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1956 break;
1957 case kDPAbort:
1958 LOGE("Aborting due to potential deadlock\n");
1959 dvmAbort();
1960 break;
1961 default:
1962 /* warn only */
1963 break;
1964 }
1965 }
1966}
1967
1968/*
1969 * We're removing "child" from existence. We want to pull all of
1970 * child's children into "parent", filtering out duplicates. This is
1971 * called during the GC.
1972 *
1973 * This does not modify "child", which might have multiple parents.
1974 */
1975static void mergeChildren(Object* parent, const Object* child)
1976{
1977 Monitor* mon;
1978 int i;
1979
1980 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001981 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001982 ExpandingObjectList* pList = &mon->historyChildren;
1983
1984 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1985 Object* grandChild = expandBufGetEntry(pList, i);
1986
1987 if (!objectInChildList(parent, grandChild)) {
1988 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1989 linkParentToChild(parent, grandChild);
1990 } else {
1991 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1992 }
1993 }
1994}
1995
1996/*
1997 * An object with a fat lock is being collected during a GC pass. We
1998 * want to remove it from any lock history trees that it is a part of.
1999 *
2000 * This may require updating the history trees in several monitors. The
2001 * monitor semantics guarantee that no other thread will be accessing
2002 * the history trees at the same time.
2003 */
2004static void removeCollectedObject(Object* obj)
2005{
2006 Monitor* mon;
2007
2008 LOGVV("+++ collecting %p\n", obj);
2009
2010#if 0
2011 /*
2012 * We're currently running through the entire set of known monitors.
2013 * This can be somewhat slow. We may want to keep lists of parents
2014 * in each child to speed up GC.
2015 */
2016 mon = gDvm.monitorList;
2017 while (mon != NULL) {
2018 Object* parent = mon->obj;
2019 if (parent != NULL) { /* value nulled for deleted entries */
2020 if (objectInChildList(parent, obj)) {
2021 LOGVV("removing child %p from parent %p\n", obj, parent);
2022 unlinkParentFromChild(parent, obj);
2023 mergeChildren(parent, obj);
2024 }
2025 }
2026 mon = mon->next;
2027 }
2028#endif
2029
2030 /*
2031 * For every parent of this object:
2032 * - merge all of our children into the parent's child list (creates
2033 * a two-way link between parent and child)
2034 * - remove ourselves from the parent's child list
2035 */
2036 ExpandingObjectList* pList;
2037 int i;
2038
2039 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002040 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002041 pList = &mon->historyParents;
2042 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2043 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002044 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002045
2046 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2047 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2048 }
2049 assert(!expandObjHas(&parentMon->historyChildren, obj));
2050
2051 mergeChildren(parent, obj);
2052 }
2053
2054 /*
2055 * For every child of this object:
2056 * - remove ourselves from the child's parent list
2057 */
2058 pList = &mon->historyChildren;
2059 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2060 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002061 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002062
2063 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2064 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2065 }
2066 assert(!expandObjHas(&childMon->historyParents, obj));
2067 }
2068}
2069
2070#endif /*WITH_DEADLOCK_PREDICTION*/