blob: 90df500c04ec85be10f88d3299e9130b77e22eec [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;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700361 len = len < 32 ? len : 32;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700362 set4LE((u1 *)dst, len);
363 dst += 4;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700364 memcpy(dst, value, len);
365 return dst + len;
366}
367
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700368#define EVENT_LOG_TAG_dvm_lock_sample 20003
Carl Shapirof0c514c2010-04-09 15:03:33 -0700369
370static void logContentionEvent(Thread *self, u4 waitMs, u4 samplePercent)
371{
372 const StackSaveArea *saveArea;
373 const Method *meth;
374 u4 relativePc;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700375 char eventBuffer[132];
Carl Shapirof0c514c2010-04-09 15:03:33 -0700376 const char *fileName;
Carl Shapiroe3c01da2010-05-20 22:54:18 -0700377 char procName[33], *selfName;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700378 char *cp;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700379 size_t len;
380 int fd;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700381
382 saveArea = SAVEAREA_FROM_FP(self->curFrame);
383 meth = saveArea->method;
384 cp = eventBuffer;
385
386 /* Emit the event list length, 1 byte. */
387 *cp++ = 7;
388
389 /* Emit the process name, <= 37 bytes. */
390 fd = open("/proc/self/cmdline", O_RDONLY);
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700391 memset(procName, 0, sizeof(procName));
392 read(fd, procName, sizeof(procName) - 1);
Carl Shapirof0c514c2010-04-09 15:03:33 -0700393 close(fd);
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700394 len = strlen(procName);
395 cp = logWriteString(cp, procName, len);
Carl Shapirof0c514c2010-04-09 15:03:33 -0700396
397 /* Emit the main thread status, 5 bytes. */
398 bool isMainThread = (self->systemTid == getpid());
399 cp = logWriteInt(cp, isMainThread);
400
401 /* Emit self thread name string, <= 37 bytes. */
402 selfName = dvmGetThreadName(self);
403 cp = logWriteString(cp, selfName, strlen(selfName));
404 free(selfName);
405
406 /* Emit the wait time, 5 bytes. */
407 cp = logWriteInt(cp, waitMs);
408
409 /* Emit the source code file name, <= 37 bytes. */
410 fileName = dvmGetMethodSourceFile(meth);
411 if (fileName == NULL) fileName = "";
412 cp = logWriteString(cp, fileName, strlen(fileName));
413
414 /* Emit the source code line number, 5 bytes. */
415 relativePc = saveArea->xtra.currentPc - saveArea->method->insns;
416 cp = logWriteInt(cp, dvmLineNumFromPC(meth, relativePc));
417
418 /* Emit the sample percentage, 5 bytes. */
419 cp = logWriteInt(cp, samplePercent);
420
421 assert((size_t)(cp - eventBuffer) <= sizeof(eventBuffer));
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700422 android_btWriteLog(EVENT_LOG_TAG_dvm_lock_sample,
Carl Shapirof0c514c2010-04-09 15:03:33 -0700423 EVENT_TYPE_LIST,
424 eventBuffer,
425 (size_t)(cp - eventBuffer));
426}
427
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800428/*
429 * Lock a monitor.
430 */
431static void lockMonitor(Thread* self, Monitor* mon)
432{
Carl Shapirof0c514c2010-04-09 15:03:33 -0700433 ThreadStatus oldStatus;
434 u4 waitThreshold, samplePercent;
435 u8 waitStart, waitEnd, waitMs;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800436
437 if (mon->owner == self) {
438 mon->lockCount++;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700439 return;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800440 }
Carl Shapiro045fdc92010-04-13 16:48:27 -0700441 if (dvmTryLockMutex(&mon->lock) != 0) {
Carl Shapirof0c514c2010-04-09 15:03:33 -0700442 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
443 waitThreshold = gDvm.lockProfThreshold;
444 if (waitThreshold) {
445 waitStart = dvmGetRelativeTimeUsec();
446 }
447 dvmLockMutex(&mon->lock);
448 if (waitThreshold) {
449 waitEnd = dvmGetRelativeTimeUsec();
450 }
451 dvmChangeStatus(self, oldStatus);
452 if (waitThreshold) {
453 waitMs = (waitEnd - waitStart) / 1000;
454 if (waitMs >= waitThreshold) {
455 samplePercent = 100;
456 } else {
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700457 samplePercent = 100 * waitMs / waitThreshold;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700458 }
Carl Shapirob8fcf572010-04-16 17:33:15 -0700459 if (samplePercent != 0 && ((u4)rand() % 100 < samplePercent)) {
Carl Shapirof0c514c2010-04-09 15:03:33 -0700460 logContentionEvent(self, waitMs, samplePercent);
461 }
462 }
463 }
464 mon->owner = self;
465 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800466}
467
468/*
469 * Try to lock a monitor.
470 *
471 * Returns "true" on success.
472 */
473static bool tryLockMonitor(Thread* self, Monitor* mon)
474{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800475 if (mon->owner == self) {
476 mon->lockCount++;
477 return true;
478 } else {
Carl Shapiro980ffb02010-03-13 22:34:01 -0800479 if (dvmTryLockMutex(&mon->lock) == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800480 mon->owner = self;
481 assert(mon->lockCount == 0);
482 return true;
483 } else {
484 return false;
485 }
486 }
487}
488
489
490/*
491 * Unlock a monitor.
492 *
493 * Returns true if the unlock succeeded.
494 * If the unlock failed, an exception will be pending.
495 */
496static bool unlockMonitor(Thread* self, Monitor* mon)
497{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800498 assert(self != NULL);
Carl Shapiro92277082010-04-06 15:35:59 -0700499 assert(mon != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800500 if (mon->owner == self) {
501 /*
502 * We own the monitor, so nobody else can be in here.
503 */
504 if (mon->lockCount == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800505 mon->owner = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800506 dvmUnlockMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800507 } else {
508 mon->lockCount--;
509 }
510 } else {
511 /*
512 * We don't own this, so we're not allowed to unlock it.
513 * The JNI spec says that we should throw IllegalMonitorStateException
514 * in this case.
515 */
Carl Shapiro8782d7c2010-04-19 20:10:35 -0700516 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
517 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800518 return false;
519 }
520 return true;
521}
522
523/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800524 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800525 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800526 */
527static int waitSetCheck(Monitor *mon)
528{
529 Thread *fast, *slow;
530 size_t n;
531
532 assert(mon != NULL);
533 fast = slow = mon->waitSet;
534 n = 0;
535 for (;;) {
536 if (fast == NULL) return 0;
537 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800538 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800539 n += 2;
540 fast = fast->waitNext->waitNext;
541 slow = slow->waitNext;
542 }
543}
544
545/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800546 * Links a thread into a monitor's wait set. The monitor lock must be
547 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800548 */
549static void waitSetAppend(Monitor *mon, Thread *thread)
550{
551 Thread *elt;
552
553 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800554 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800555 assert(thread != NULL);
556 assert(thread->waitNext == NULL);
557 assert(waitSetCheck(mon) == 0);
558 if (mon->waitSet == NULL) {
559 mon->waitSet = thread;
560 return;
561 }
562 elt = mon->waitSet;
563 while (elt->waitNext != NULL) {
564 elt = elt->waitNext;
565 }
566 elt->waitNext = thread;
567}
568
569/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800570 * Unlinks a thread from a monitor's wait set. The monitor lock must
571 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800572 */
573static void waitSetRemove(Monitor *mon, Thread *thread)
574{
575 Thread *elt;
576
577 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800578 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800579 assert(thread != NULL);
580 assert(waitSetCheck(mon) == 0);
581 if (mon->waitSet == NULL) {
582 return;
583 }
584 if (mon->waitSet == thread) {
585 mon->waitSet = thread->waitNext;
586 thread->waitNext = NULL;
587 return;
588 }
589 elt = mon->waitSet;
590 while (elt->waitNext != NULL) {
591 if (elt->waitNext == thread) {
592 elt->waitNext = thread->waitNext;
593 thread->waitNext = NULL;
594 return;
595 }
596 elt = elt->waitNext;
597 }
598}
599
Carl Shapirob4539192010-01-04 16:50:00 -0800600/*
601 * Converts the given relative waiting time into an absolute time.
602 */
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800603void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800604{
605 s8 endSec;
606
607#ifdef HAVE_TIMEDWAIT_MONOTONIC
608 clock_gettime(CLOCK_MONOTONIC, ts);
609#else
610 {
611 struct timeval tv;
612 gettimeofday(&tv, NULL);
613 ts->tv_sec = tv.tv_sec;
614 ts->tv_nsec = tv.tv_usec * 1000;
615 }
616#endif
617 endSec = ts->tv_sec + msec / 1000;
618 if (endSec >= 0x7fffffff) {
619 LOGV("NOTE: end time exceeds epoch\n");
620 endSec = 0x7ffffffe;
621 }
622 ts->tv_sec = endSec;
623 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
624
625 /* catch rollover */
626 if (ts->tv_nsec >= 1000000000L) {
627 ts->tv_sec++;
628 ts->tv_nsec -= 1000000000L;
629 }
630}
631
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800632int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
633 s8 msec, s4 nsec)
634{
635 int ret;
636 struct timespec ts;
637 absoluteTime(msec, nsec, &ts);
638#if defined(HAVE_TIMEDWAIT_MONOTONIC)
639 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
640#else
641 ret = pthread_cond_timedwait(cond, mutex, &ts);
642#endif
643 assert(ret == 0 || ret == ETIMEDOUT);
644 return ret;
645}
646
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800647/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800648 * Wait on a monitor until timeout, interrupt, or notification. Used for
649 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
650 *
651 * If another thread calls Thread.interrupt(), we throw InterruptedException
652 * and return immediately if one of the following are true:
653 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
654 * - blocked in join(), join(long), or join(long, int) methods of Thread
655 * - blocked in sleep(long), or sleep(long, int) methods of Thread
656 * Otherwise, we set the "interrupted" flag.
657 *
658 * Checks to make sure that "nsec" is in the range 0-999999
659 * (i.e. fractions of a millisecond) and throws the appropriate
660 * exception if it isn't.
661 *
662 * The spec allows "spurious wakeups", and recommends that all code using
663 * Object.wait() do so in a loop. This appears to derive from concerns
664 * about pthread_cond_wait() on multiprocessor systems. Some commentary
665 * on the web casts doubt on whether these can/should occur.
666 *
667 * Since we're allowed to wake up "early", we clamp extremely long durations
668 * to return at the end of the 32-bit time epoch.
669 */
670static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
671 bool interruptShouldThrow)
672{
673 struct timespec ts;
674 bool wasInterrupted = false;
675 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800676 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800677
Carl Shapiro71938022009-12-22 13:49:53 -0800678 assert(self != NULL);
679 assert(mon != NULL);
680
Carl Shapiro94338aa2009-12-21 11:42:59 -0800681 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800682 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800683 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
684 "object not locked by thread before wait()");
685 return;
686 }
687
688 /*
689 * Enforce the timeout range.
690 */
691 if (msec < 0 || nsec < 0 || nsec > 999999) {
692 dvmThrowException("Ljava/lang/IllegalArgumentException;",
693 "timeout arguments out of range");
694 return;
695 }
696
697 /*
698 * Compute absolute wakeup time, if necessary.
699 */
700 if (msec == 0 && nsec == 0) {
701 timed = false;
702 } else {
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800703 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800704 timed = true;
705 }
706
707 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800708 * Add ourselves to the set of threads waiting on this monitor, and
709 * release our hold. We need to let it go even if we're a few levels
710 * deep in a recursive lock, and we need to restore that later.
711 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800712 * We append to the wait set ahead of clearing the count and owner
713 * fields so the subroutine can check that the calling thread owns
714 * the monitor. Aside from that, the order of member updates is
715 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800716 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800717 waitSetAppend(mon, self);
718 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800719 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800720 mon->owner = NULL;
721
722 /*
723 * Update thread status. If the GC wakes up, it'll ignore us, knowing
724 * that we won't touch any references in this state, and we'll check
725 * our suspend mode before we transition out.
726 */
727 if (timed)
728 dvmChangeStatus(self, THREAD_TIMED_WAIT);
729 else
730 dvmChangeStatus(self, THREAD_WAIT);
731
Carl Shapiro980ffb02010-03-13 22:34:01 -0800732 dvmLockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800733
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800734 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800735 * Set waitMonitor to the monitor object we will be waiting on.
736 * When waitMonitor is non-NULL a notifying or interrupting thread
737 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800738 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800739 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800740 self->waitMonitor = mon;
741
742 /*
743 * Handle the case where the thread was interrupted before we called
744 * wait().
745 */
746 if (self->interrupted) {
747 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800748 self->waitMonitor = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800749 dvmUnlockMutex(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800750 goto done;
751 }
752
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800753 /*
754 * Release the monitor lock and wait for a notification or
755 * a timeout to occur.
756 */
Carl Shapiro980ffb02010-03-13 22:34:01 -0800757 dvmUnlockMutex(&mon->lock);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800758
759 if (!timed) {
760 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
761 assert(ret == 0);
762 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800763#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800764 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800765#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800766 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800767#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800768 assert(ret == 0 || ret == ETIMEDOUT);
769 }
770 if (self->interrupted) {
771 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800772 }
773
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800774 self->interrupted = false;
775 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800776
Carl Shapiro980ffb02010-03-13 22:34:01 -0800777 dvmUnlockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800778
Carl Shapiro30aa9972010-01-13 22:07:50 -0800779 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800780 lockMonitor(self, mon);
781
Carl Shapiro142ef272010-01-25 12:51:31 -0800782done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800783 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800784 * We remove our thread from wait set after restoring the count
785 * and owner fields so the subroutine can check that the calling
786 * thread owns the monitor. Aside from that, the order of member
787 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800788 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800789 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800790 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800791 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800792
793 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
794 dvmChangeStatus(self, THREAD_RUNNING);
795
796 if (wasInterrupted) {
797 /*
798 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800799 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800800 *
801 * The doc sayeth: "The interrupted status of the current thread is
802 * cleared when this exception is thrown."
803 */
804 self->interrupted = false;
805 if (interruptShouldThrow)
806 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
807 }
808}
809
810/*
811 * Notify one thread waiting on this monitor.
812 */
813static void notifyMonitor(Thread* self, Monitor* mon)
814{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800815 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800816
Carl Shapiro71938022009-12-22 13:49:53 -0800817 assert(self != NULL);
818 assert(mon != NULL);
819
Carl Shapiro94338aa2009-12-21 11:42:59 -0800820 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800821 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800822 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
823 "object not locked by thread before notify()");
824 return;
825 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800826 /* Signal the first waiting thread in the wait set. */
827 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800828 thread = mon->waitSet;
829 mon->waitSet = thread->waitNext;
830 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800831 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800832 /* Check to see if the thread is still waiting. */
833 if (thread->waitMonitor != NULL) {
834 pthread_cond_signal(&thread->waitCond);
Carl Shapiro980ffb02010-03-13 22:34:01 -0800835 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800836 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800837 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800838 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800839 }
840}
841
842/*
843 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800844 */
845static void notifyAllMonitor(Thread* self, Monitor* mon)
846{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800847 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800848
Carl Shapiro71938022009-12-22 13:49:53 -0800849 assert(self != NULL);
850 assert(mon != NULL);
851
Carl Shapiro94338aa2009-12-21 11:42:59 -0800852 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800853 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800854 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
855 "object not locked by thread before notifyAll()");
856 return;
857 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800858 /* Signal all threads in the wait set. */
859 while (mon->waitSet != NULL) {
860 thread = mon->waitSet;
861 mon->waitSet = thread->waitNext;
862 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800863 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800864 /* Check to see if the thread is still waiting. */
865 if (thread->waitMonitor != NULL) {
866 pthread_cond_signal(&thread->waitCond);
867 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800868 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800869 }
870}
871
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800872/*
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800873 * Changes the shape of a monitor from thin to fat, preserving the
874 * internal lock state. The calling thread must own the lock.
875 */
876static void inflateMonitor(Thread *self, Object *obj)
877{
878 Monitor *mon;
879 u4 thin;
880
881 assert(self != NULL);
882 assert(obj != NULL);
883 assert(LW_SHAPE(obj->lock) == LW_SHAPE_THIN);
884 assert(LW_LOCK_OWNER(obj->lock) == self->threadId);
885 /* Allocate and acquire a new monitor. */
886 mon = dvmCreateMonitor(obj);
887 lockMonitor(self, mon);
888 /* Propagate the lock state. */
889 thin = obj->lock;
890 mon->lockCount = LW_LOCK_COUNT(thin);
891 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
892 thin |= (u4)mon | LW_SHAPE_FAT;
893 /* Publish the updated lock word. */
894 MEM_BARRIER();
895 obj->lock = thin;
896}
897
898/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800899 * Implements monitorenter for "synchronized" stuff.
900 *
901 * This does not fail or throw an exception (unless deadlock prediction
902 * is enabled and set to "err" mode).
903 */
904void dvmLockObject(Thread* self, Object *obj)
905{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800906 volatile u4 *thinp;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800907 ThreadStatus oldStatus;
908 useconds_t sleepDelay;
909 const useconds_t maxSleepDelay = 1 << 20;
910 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800911
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800912 assert(self != NULL);
913 assert(obj != NULL);
914 threadId = self->threadId;
915 thinp = &obj->lock;
916retry:
917 thin = *thinp;
918 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
919 /*
920 * The lock is a thin lock. The owner field is used to
921 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800922 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800923 if (LW_LOCK_OWNER(thin) == threadId) {
924 /*
925 * The calling thread owns the lock. Increment the
926 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800927 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800928 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
929 } else if (LW_LOCK_OWNER(thin) == 0) {
930 /*
931 * The lock is unowned. Install the thread id of the
932 * calling thread into the owner field. This is the
933 * common case. In performance critical code the JIT
934 * will have tried this before calling out to the VM.
935 */
936 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
937 if (!ATOMIC_CMP_SWAP((int32_t *)thinp, thin, newThin)) {
938 /*
939 * The acquire failed. Try again.
940 */
941 goto retry;
942 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800943 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800944 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
945 threadId, &obj->lock, 0, *thinp, thin);
946 /*
947 * The lock is owned by another thread. Notify the VM
948 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800949 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800950 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
951 /*
952 * Spin until the thin lock is released or inflated.
953 */
954 sleepDelay = 0;
955 for (;;) {
956 thin = *thinp;
957 /*
958 * Check the shape of the lock word. Another thread
959 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800960 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800961 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
962 if (LW_LOCK_OWNER(thin) == 0) {
963 /*
964 * The lock has been released. Install the
965 * thread id of the calling thread into the
966 * owner field.
967 */
968 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
969 if (ATOMIC_CMP_SWAP((int32_t *)thinp,
970 thin, newThin)) {
971 /*
972 * The acquire succeed. Break out of the
973 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800974 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800975 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800976 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800977 } else {
978 /*
979 * The lock has not been released. Yield so
980 * the owning thread can run.
981 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800982 if (sleepDelay == 0) {
983 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800984 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800985 } else {
986 usleep(sleepDelay);
987 if (sleepDelay < maxSleepDelay / 2) {
988 sleepDelay *= 2;
989 }
990 }
991 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800992 } else {
993 /*
994 * The thin lock was inflated by another thread.
995 * Let the VM know we are no longer waiting and
996 * try again.
997 */
998 LOG_THIN("(%d) lock %p surprise-fattened",
999 threadId, &obj->lock);
1000 dvmChangeStatus(self, oldStatus);
1001 goto retry;
1002 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001003 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001004 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
1005 threadId, &obj->lock, 0, *thinp, thin);
1006 /*
1007 * We have acquired the thin lock. Let the VM know that
1008 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001009 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001010 dvmChangeStatus(self, oldStatus);
1011 /*
1012 * Fatten the lock.
1013 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001014 inflateMonitor(self, obj);
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001015 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001016 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001017 } else {
1018 /*
1019 * The lock is a fat lock.
1020 */
1021 assert(LW_MONITOR(obj->lock) != NULL);
1022 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001023 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001024#ifdef WITH_DEADLOCK_PREDICTION
1025 /*
1026 * See if we were allowed to grab the lock at this time. We do it
1027 * *after* acquiring the lock, rather than before, so that we can
1028 * freely update the Monitor struct. This seems counter-intuitive,
1029 * but our goal is deadlock *prediction* not deadlock *prevention*.
1030 * (If we actually deadlock, the situation is easy to diagnose from
1031 * a thread dump, so there's no point making a special effort to do
1032 * the checks before the lock is held.)
1033 *
1034 * This needs to happen before we add the object to the thread's
1035 * monitor list, so we can tell the difference between first-lock and
1036 * re-lock.
1037 *
1038 * It's also important that we do this while in THREAD_RUNNING, so
1039 * that we don't interfere with cleanup operations in the GC.
1040 */
1041 if (gDvm.deadlockPredictMode != kDPOff) {
1042 if (self->status != THREAD_RUNNING) {
1043 LOGE("Bad thread status (%d) in DP\n", self->status);
1044 dvmDumpThread(self, false);
1045 dvmAbort();
1046 }
1047 assert(!dvmCheckException(self));
1048 updateDeadlockPrediction(self, obj);
1049 if (dvmCheckException(self)) {
1050 /*
1051 * If we're throwing an exception here, we need to free the
1052 * lock. We add the object to the thread's monitor list so the
1053 * "unlock" code can remove it.
1054 */
1055 dvmAddToMonitorList(self, obj, false);
1056 dvmUnlockObject(self, obj);
1057 LOGV("--- unlocked, pending is '%s'\n",
1058 dvmGetException(self)->clazz->descriptor);
1059 }
1060 }
1061
1062 /*
1063 * Add the locked object, and the current stack trace, to the list
1064 * held by the Thread object. If deadlock prediction isn't on,
1065 * don't capture the stack trace.
1066 */
1067 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
1068#elif defined(WITH_MONITOR_TRACKING)
1069 /*
1070 * Add the locked object to the list held by the Thread object.
1071 */
1072 dvmAddToMonitorList(self, obj, false);
1073#endif
1074}
1075
1076/*
1077 * Implements monitorexit for "synchronized" stuff.
1078 *
1079 * On failure, throws an exception and returns "false".
1080 */
1081bool dvmUnlockObject(Thread* self, Object *obj)
1082{
Carl Shapiro94338aa2009-12-21 11:42:59 -08001083 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001084
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001085 assert(self != NULL);
1086 assert(self->status == THREAD_RUNNING);
1087 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001088 /*
1089 * Cache the lock word as its value can change while we are
1090 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001091 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001092 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001093 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
1094 /*
1095 * The lock is thin. We must ensure that the lock is owned
1096 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001097 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001098 if (LW_LOCK_OWNER(thin) == self->threadId) {
1099 /*
1100 * We are the lock owner. It is safe to update the lock
1101 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001102 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001103 if (LW_LOCK_COUNT(thin) == 0) {
1104 /*
1105 * The lock was not recursively acquired, the common
1106 * case. Unlock by clearing all bits except for the
1107 * hash state.
1108 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001109 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001110 } else {
1111 /*
1112 * The object was recursively acquired. Decrement the
1113 * lock recursion count field.
1114 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001115 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001116 }
1117 } else {
1118 /*
1119 * We do not own the lock. The JVM spec requires that we
1120 * throw an exception in this case.
1121 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001122 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001123 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001124 return false;
1125 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001126 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001127 /*
1128 * The lock is fat. We must check to see if unlockMonitor has
1129 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001130 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001131 assert(LW_MONITOR(obj->lock) != NULL);
1132 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001133 /*
1134 * An exception has been raised. Do not fall through.
1135 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001136 return false;
1137 }
1138 }
1139
1140#ifdef WITH_MONITOR_TRACKING
1141 /*
1142 * Remove the object from the Thread's list.
1143 */
1144 dvmRemoveFromMonitorList(self, obj);
1145#endif
1146
1147 return true;
1148}
1149
1150/*
1151 * Object.wait(). Also called for class init.
1152 */
1153void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1154 bool interruptShouldThrow)
1155{
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001156 Monitor* mon;
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001157 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001158
1159 /* If the lock is still thin, we need to fatten it.
1160 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001161 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001162 /* Make sure that 'self' holds the lock.
1163 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001164 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001165 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1166 "object not locked by thread before wait()");
1167 return;
1168 }
1169
1170 /* This thread holds the lock. We need to fatten the lock
1171 * so 'self' can block on it. Don't update the object lock
1172 * field yet, because 'self' needs to acquire the lock before
1173 * any other thread gets a chance.
1174 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001175 inflateMonitor(self, obj);
1176 LOG_THIN("(%d) lock %p fattened by wait() to count %d",
1177 self->threadId, &obj->lock, mon->lockCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001178 }
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001179 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001180 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1181}
1182
1183/*
1184 * Object.notify().
1185 */
1186void dvmObjectNotify(Thread* self, Object *obj)
1187{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001188 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001189
1190 /* If the lock is still thin, there aren't any waiters;
1191 * waiting on an object forces lock fattening.
1192 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001193 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001194 /* Make sure that 'self' holds the lock.
1195 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001196 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001197 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1198 "object not locked by thread before notify()");
1199 return;
1200 }
1201
1202 /* no-op; there are no waiters to notify.
1203 */
1204 } else {
1205 /* It's a fat lock.
1206 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001207 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001208 }
1209}
1210
1211/*
1212 * Object.notifyAll().
1213 */
1214void dvmObjectNotifyAll(Thread* self, Object *obj)
1215{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001216 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001217
1218 /* If the lock is still thin, there aren't any waiters;
1219 * waiting on an object forces lock fattening.
1220 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001221 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001222 /* Make sure that 'self' holds the lock.
1223 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001224 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001225 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1226 "object not locked by thread before notifyAll()");
1227 return;
1228 }
1229
1230 /* no-op; there are no waiters to notify.
1231 */
1232 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001233 /* It's a fat lock.
1234 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001235 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001236 }
1237}
1238
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001239/*
1240 * This implements java.lang.Thread.sleep(long msec, int nsec).
1241 *
1242 * The sleep is interruptible by other threads, which means we can't just
1243 * plop into an OS sleep call. (We probably could if we wanted to send
1244 * signals around and rely on EINTR, but that's inefficient and relies
1245 * on native code respecting our signal mask.)
1246 *
1247 * We have to do all of this stuff for Object.wait() as well, so it's
1248 * easiest to just sleep on a private Monitor.
1249 *
1250 * It appears that we want sleep(0,0) to go through the motions of sleeping
1251 * for a very short duration, rather than just returning.
1252 */
1253void dvmThreadSleep(u8 msec, u4 nsec)
1254{
1255 Thread* self = dvmThreadSelf();
1256 Monitor* mon = gDvm.threadSleepMon;
1257
1258 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1259 if (msec == 0 && nsec == 0)
1260 nsec++;
1261
1262 lockMonitor(self, mon);
1263 waitMonitor(self, mon, msec, nsec, true);
1264 unlockMonitor(self, mon);
1265}
1266
1267/*
1268 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001269 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001270void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001271{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001272 assert(thread != NULL);
1273
Carl Shapiro980ffb02010-03-13 22:34:01 -08001274 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001275
1276 /*
1277 * If the interrupted flag is already set no additional action is
1278 * required.
1279 */
1280 if (thread->interrupted == true) {
Carl Shapiro980ffb02010-03-13 22:34:01 -08001281 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001282 return;
1283 }
1284
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001285 /*
1286 * Raise the "interrupted" flag. This will cause it to bail early out
1287 * of the next wait() attempt, if it's not currently waiting on
1288 * something.
1289 */
1290 thread->interrupted = true;
1291 MEM_BARRIER();
1292
1293 /*
1294 * Is the thread waiting?
1295 *
1296 * Note that fat vs. thin doesn't matter here; waitMonitor
1297 * is only set when a thread actually waits on a monitor,
1298 * which implies that the monitor has already been fattened.
1299 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001300 if (thread->waitMonitor != NULL) {
1301 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001302 }
1303
Carl Shapiro980ffb02010-03-13 22:34:01 -08001304 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001305}
1306
Carl Shapiro30aa9972010-01-13 22:07:50 -08001307#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001308u4 dvmIdentityHashCode(Object *obj)
1309{
1310 return (u4)obj;
1311}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001312#else
Carl Shapiro30aa9972010-01-13 22:07:50 -08001313/*
1314 * Returns the identity hash code of the given object.
1315 */
1316u4 dvmIdentityHashCode(Object *obj)
1317{
1318 Thread *self, *thread;
1319 volatile u4 *lw;
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001320 size_t size;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001321 u4 lock, owner, hashState;
1322
1323 if (obj == NULL) {
1324 /*
1325 * Null is defined to have an identity hash code of 0.
1326 */
1327 return 0;
1328 }
1329 lw = &obj->lock;
1330retry:
1331 hashState = LW_HASH_STATE(*lw);
1332 if (hashState == LW_HASH_STATE_HASHED) {
1333 /*
1334 * The object has been hashed but has not had its hash code
1335 * relocated by the garbage collector. Use the raw object
1336 * address.
1337 */
1338 return (u4)obj >> 3;
1339 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1340 /*
1341 * The object has been hashed and its hash code has been
1342 * relocated by the collector. Use the value of the naturally
1343 * aligned word following the instance data.
1344 */
Carl Shapiroc48b6d02010-05-04 11:19:53 -07001345 assert(obj->clazz != gDvm.classJavaLangClass);
1346 assert(obj->clazz != gDvm.unlinkedJavaLangClass);
Carl Shapiro30aa9972010-01-13 22:07:50 -08001347 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001348 size = dvmArrayObjectSize((ArrayObject *)obj);
Carl Shapiroc48b6d02010-05-04 11:19:53 -07001349 size = (size + 2) & ~2;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001350 } else {
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001351 size = obj->clazz->objectSize;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001352 }
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001353 return *(u4 *)(((char *)obj) + size);
Carl Shapiro30aa9972010-01-13 22:07:50 -08001354 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1355 /*
1356 * The object has never been hashed. Change the hash state to
1357 * hashed and use the raw object address.
1358 */
1359 self = dvmThreadSelf();
1360 if (self->threadId == lockOwner(obj)) {
1361 /*
1362 * We already own the lock so we can update the hash state
1363 * directly.
1364 */
1365 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1366 return (u4)obj >> 3;
1367 }
1368 /*
1369 * We do not own the lock. Try acquiring the lock. Should
1370 * this fail, we must suspend the owning thread.
1371 */
1372 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1373 /*
1374 * If the lock is thin assume it is unowned. We simulate
1375 * an acquire, update, and release with a single CAS.
1376 */
1377 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1378 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1379 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1380 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1381 (int32_t)lock)) {
1382 /*
1383 * A new lockword has been installed with a hash state
1384 * of hashed. Use the raw object address.
1385 */
1386 return (u4)obj >> 3;
1387 }
1388 } else {
1389 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1390 /*
1391 * The monitor lock has been acquired. Change the
1392 * hash state to hashed and use the raw object
1393 * address.
1394 */
1395 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1396 unlockMonitor(self, LW_MONITOR(*lw));
1397 return (u4)obj >> 3;
1398 }
1399 }
1400 /*
1401 * At this point we have failed to acquire the lock. We must
1402 * identify the owning thread and suspend it.
1403 */
1404 dvmLockThreadList(self);
1405 /*
1406 * Cache the lock word as its value can change between
1407 * determining its shape and retrieving its owner.
1408 */
1409 lock = *lw;
1410 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1411 /*
1412 * Find the thread with the corresponding thread id.
1413 */
1414 owner = LW_LOCK_OWNER(lock);
1415 assert(owner != self->threadId);
1416 /*
1417 * If the lock has no owner do not bother scanning the
1418 * thread list and fall through to the failure handler.
1419 */
1420 thread = owner ? gDvm.threadList : NULL;
1421 while (thread != NULL) {
1422 if (thread->threadId == owner) {
1423 break;
1424 }
1425 thread = thread->next;
1426 }
1427 } else {
1428 thread = LW_MONITOR(lock)->owner;
1429 }
1430 /*
1431 * If thread is NULL the object has been released since the
1432 * thread list lock was acquired. Try again.
1433 */
1434 if (thread == NULL) {
1435 dvmUnlockThreadList();
1436 goto retry;
1437 }
1438 /*
1439 * Wait for the owning thread to suspend.
1440 */
1441 dvmSuspendThread(thread);
1442 if (dvmHoldsLock(thread, obj)) {
1443 /*
1444 * The owning thread has been suspended. We can safely
1445 * change the hash state to hashed.
1446 */
1447 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1448 dvmResumeThread(thread);
1449 dvmUnlockThreadList();
1450 return (u4)obj >> 3;
1451 }
1452 /*
1453 * The wrong thread has been suspended. Try again.
1454 */
1455 dvmResumeThread(thread);
1456 dvmUnlockThreadList();
1457 goto retry;
1458 }
1459 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1460 dvmDumpThread(dvmThreadSelf(), false);
1461 dvmAbort();
1462 return 0; /* Quiet the compiler. */
1463}
1464#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001465
1466#ifdef WITH_DEADLOCK_PREDICTION
1467/*
1468 * ===========================================================================
1469 * Deadlock prediction
1470 * ===========================================================================
1471 */
1472/*
1473The idea is to predict the possibility of deadlock by recording the order
1474in which monitors are acquired. If we see an attempt to acquire a lock
1475out of order, we can identify the locks and offending code.
1476
1477To make this work, we need to keep track of the locks held by each thread,
1478and create history trees for each lock. When a thread tries to acquire
1479a new lock, we walk through the "history children" of the lock, looking
1480for a match with locks the thread already holds. If we find a match,
1481it means the thread has made a request that could result in a deadlock.
1482
1483To support recursive locks, we always allow re-locking a currently-held
1484lock, and maintain a recursion depth count.
1485
1486An ASCII-art example, where letters represent Objects:
1487
1488 A
1489 /|\
1490 / | \
1491 B | D
1492 \ |
1493 \|
1494 C
1495
1496The above is the tree we'd have after handling Object synchronization
1497sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1498a child of B. (The lines represent pointers between parent and child.
1499Every node can have multiple parents and multiple children.)
1500
1501If we hold AC, and want to lock B, we recursively search through B's
1502children to see if A or C appears. It does, so we reject the attempt.
1503(A straightforward way to implement it: add a link from C to B, then
1504determine whether the graph starting at B contains a cycle.)
1505
1506If we hold AC and want to lock D, we would succeed, creating a new link
1507from C to D.
1508
1509The lock history and a stack trace is attached to the Object's Monitor
1510struct, which means we need to fatten every Object we lock (thin locking
1511is effectively disabled). If we don't need the stack trace we can
1512avoid fattening the leaf nodes, only fattening objects that need to hold
1513history trees.
1514
1515Updates to Monitor structs are only allowed for the thread that holds
1516the Monitor, so we actually do most of our deadlock prediction work after
1517the lock has been acquired.
1518
1519When an object with a monitor is GCed, we need to remove it from the
1520history trees. There are two basic approaches:
1521 (1) For through the entire set of known monitors, search all child
1522 lists for the object in question. This is rather slow, resulting
1523 in GC passes that take upwards of 10 seconds to complete.
1524 (2) Maintain "parent" pointers in each node. Remove the entries as
1525 required. This requires additional storage and maintenance for
1526 every operation, but is significantly faster at GC time.
1527For each GCed object, we merge all of the object's children into each of
1528the object's parents.
1529*/
1530
1531#if !defined(WITH_MONITOR_TRACKING)
1532# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1533#endif
1534
1535/*
1536 * Clear out the contents of an ExpandingObjectList, freeing any
1537 * dynamic allocations.
1538 */
1539static void expandObjClear(ExpandingObjectList* pList)
1540{
1541 if (pList->list != NULL) {
1542 free(pList->list);
1543 pList->list = NULL;
1544 }
1545 pList->alloc = pList->count = 0;
1546}
1547
1548/*
1549 * Get the number of objects currently stored in the list.
1550 */
1551static inline int expandBufGetCount(const ExpandingObjectList* pList)
1552{
1553 return pList->count;
1554}
1555
1556/*
1557 * Get the Nth entry from the list.
1558 */
1559static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1560 int i)
1561{
1562 return pList->list[i];
1563}
1564
1565/*
1566 * Add a new entry to the list.
1567 *
1568 * We don't check for or try to enforce uniqueness. It's expected that
1569 * the higher-level code does this for us.
1570 */
1571static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1572{
1573 if (pList->count == pList->alloc) {
1574 /* time to expand */
1575 Object** newList;
1576
1577 if (pList->alloc == 0)
1578 pList->alloc = 4;
1579 else
1580 pList->alloc *= 2;
1581 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1582 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1583 if (newList == NULL) {
1584 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1585 dvmAbort();
1586 }
1587 pList->list = newList;
1588 }
1589
1590 pList->list[pList->count++] = obj;
1591}
1592
1593/*
1594 * Returns "true" if the element was successfully removed.
1595 */
1596static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1597{
1598 int i;
1599
1600 for (i = pList->count-1; i >= 0; i--) {
1601 if (pList->list[i] == obj)
1602 break;
1603 }
1604 if (i < 0)
1605 return false;
1606
1607 if (i != pList->count-1) {
1608 /*
1609 * The order of elements is not important, so we just copy the
1610 * last entry into the new slot.
1611 */
1612 //memmove(&pList->list[i], &pList->list[i+1],
1613 // (pList->count-1 - i) * sizeof(pList->list[0]));
1614 pList->list[i] = pList->list[pList->count-1];
1615 }
1616
1617 pList->count--;
1618 pList->list[pList->count] = (Object*) 0xdecadead;
1619 return true;
1620}
1621
1622/*
1623 * Returns "true" if "obj" appears in the list.
1624 */
1625static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1626{
1627 int i;
1628
1629 for (i = 0; i < pList->count; i++) {
1630 if (pList->list[i] == obj)
1631 return true;
1632 }
1633 return false;
1634}
1635
1636/*
1637 * Print the list contents to stdout. For debugging.
1638 */
1639static void expandObjDump(const ExpandingObjectList* pList)
1640{
1641 int i;
1642 for (i = 0; i < pList->count; i++)
1643 printf(" %p", pList->list[i]);
1644}
1645
1646/*
1647 * Check for duplicate entries. Returns the index of the first instance
1648 * of the duplicated value, or -1 if no duplicates were found.
1649 */
1650static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1651{
1652 int i, j;
1653 for (i = 0; i < pList->count-1; i++) {
1654 for (j = i + 1; j < pList->count; j++) {
1655 if (pList->list[i] == pList->list[j]) {
1656 return i;
1657 }
1658 }
1659 }
1660
1661 return -1;
1662}
1663
1664
1665/*
1666 * Determine whether "child" appears in the list of objects associated
1667 * with the Monitor in "parent". If "parent" is a thin lock, we return
1668 * false immediately.
1669 */
1670static bool objectInChildList(const Object* parent, Object* child)
1671{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001672 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001673 if (!IS_LOCK_FAT(&lock)) {
1674 //LOGI("on thin\n");
1675 return false;
1676 }
1677
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001678 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001679}
1680
1681/*
1682 * Print the child list.
1683 */
1684static void dumpKids(Object* parent)
1685{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001686 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001687
1688 printf("Children of %p:", parent);
1689 expandObjDump(&mon->historyChildren);
1690 printf("\n");
1691}
1692
1693/*
1694 * Add "child" to the list of children in "parent", and add "parent" to
1695 * the list of parents in "child".
1696 */
1697static void linkParentToChild(Object* parent, Object* child)
1698{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001699 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001700 assert(IS_LOCK_FAT(&parent->lock));
1701 assert(IS_LOCK_FAT(&child->lock));
1702 assert(parent != child);
1703 Monitor* mon;
1704
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001705 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001706 assert(!expandObjHas(&mon->historyChildren, child));
1707 expandObjAddEntry(&mon->historyChildren, child);
1708
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001709 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001710 assert(!expandObjHas(&mon->historyParents, parent));
1711 expandObjAddEntry(&mon->historyParents, parent);
1712}
1713
1714
1715/*
1716 * Remove "child" from the list of children in "parent".
1717 */
1718static void unlinkParentFromChild(Object* parent, Object* child)
1719{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001720 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001721 assert(IS_LOCK_FAT(&parent->lock));
1722 assert(IS_LOCK_FAT(&child->lock));
1723 assert(parent != child);
1724 Monitor* mon;
1725
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001726 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001727 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1728 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1729 }
1730 assert(!expandObjHas(&mon->historyChildren, child));
1731 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1732
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001733 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001734 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1735 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1736 }
1737 assert(!expandObjHas(&mon->historyParents, parent));
1738 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1739}
1740
1741
1742/*
1743 * Log the monitors held by the current thread. This is done as part of
1744 * flagging an error.
1745 */
1746static void logHeldMonitors(Thread* self)
1747{
1748 char* name = NULL;
1749
1750 name = dvmGetThreadName(self);
1751 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1752 self->threadId, name);
1753 LOGW("(most-recently-acquired on top):\n");
1754 free(name);
1755
1756 LockedObjectData* lod = self->pLockedObjects;
1757 while (lod != NULL) {
1758 LOGW("--- object %p[%d] (%s)\n",
1759 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1760 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1761
1762 lod = lod->next;
1763 }
1764}
1765
1766/*
1767 * Recursively traverse the object hierarchy starting at "obj". We mark
1768 * ourselves on entry and clear the mark on exit. If we ever encounter
1769 * a marked object, we have a cycle.
1770 *
1771 * Returns "true" if all is well, "false" if we found a cycle.
1772 */
1773static bool traverseTree(Thread* self, const Object* obj)
1774{
1775 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001776 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001777
1778 /*
1779 * Have we been here before?
1780 */
1781 if (mon->historyMark) {
1782 int* rawStackTrace;
1783 int stackDepth;
1784
1785 LOGW("%s\n", kStartBanner);
1786 LOGW("Illegal lock attempt:\n");
1787 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1788
1789 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1790 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1791 free(rawStackTrace);
1792
1793 LOGW(" ");
1794 logHeldMonitors(self);
1795
1796 LOGW(" ");
1797 LOGW("Earlier, the following lock order (from last to first) was\n");
1798 LOGW("established -- stack trace is from first successful lock):\n");
1799 return false;
1800 }
1801 mon->historyMark = true;
1802
1803 /*
1804 * Examine the children. We do NOT hold these locks, so they might
1805 * very well transition from thin to fat or change ownership while
1806 * we work.
1807 *
1808 * NOTE: we rely on the fact that they cannot revert from fat to thin
1809 * while we work. This is currently a safe assumption.
1810 *
1811 * We can safely ignore thin-locked children, because by definition
1812 * they have no history and are leaf nodes. In the current
1813 * implementation we always fatten the locks to provide a place to
1814 * hang the stack trace.
1815 */
1816 ExpandingObjectList* pList = &mon->historyChildren;
1817 int i;
1818 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1819 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001820 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001821 if (!IS_LOCK_FAT(&lock))
1822 continue;
1823 if (!traverseTree(self, child)) {
1824 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1825 dvmLogRawStackTrace(mon->historyRawStackTrace,
1826 mon->historyStackDepth);
1827 mon->historyMark = false;
1828 return false;
1829 }
1830 }
1831
1832 mon->historyMark = false;
1833
1834 return true;
1835}
1836
1837/*
1838 * Update the deadlock prediction tree, based on the current thread
1839 * acquiring "acqObj". This must be called before the object is added to
1840 * the thread's list of held monitors.
1841 *
1842 * If the thread already holds the lock (recursion), or this is a known
1843 * lock configuration, we return without doing anything. Otherwise, we add
1844 * a link from the most-recently-acquired lock in this thread to "acqObj"
1845 * after ensuring that the parent lock is "fat".
1846 *
1847 * This MUST NOT be called while a GC is in progress in another thread,
1848 * because we assume exclusive access to history trees in owned monitors.
1849 */
1850static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1851{
1852 LockedObjectData* lod;
1853 LockedObjectData* mrl;
1854
1855 /*
1856 * Quick check for recursive access.
1857 */
1858 lod = dvmFindInMonitorList(self, acqObj);
1859 if (lod != NULL) {
1860 LOGV("+++ DP: recursive %p\n", acqObj);
1861 return;
1862 }
1863
1864 /*
1865 * Make the newly-acquired object's monitor "fat". In some ways this
1866 * isn't strictly necessary, but we need the GC to tell us when
1867 * "interesting" objects go away, and right now the only way to make
1868 * an object look interesting is to give it a monitor.
1869 *
1870 * This also gives us a place to hang a stack trace.
1871 *
1872 * Our thread holds the lock, so we're allowed to rewrite the lock
1873 * without worrying that something will change out from under us.
1874 */
1875 if (!IS_LOCK_FAT(&acqObj->lock)) {
1876 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001877 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001878 inflateMonitor(self, acqObj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001879 }
1880
1881 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001882 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1883 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001884 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1885 &mon->historyStackDepth);
1886 }
1887
1888 /*
1889 * We need to examine and perhaps modify the most-recently-locked
1890 * monitor. We own that, so there's no risk of another thread
1891 * stepping on us.
1892 *
1893 * Retrieve the most-recently-locked entry from our thread.
1894 */
1895 mrl = self->pLockedObjects;
1896 if (mrl == NULL)
1897 return; /* no other locks held */
1898
1899 /*
1900 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1901 * this without holding the global lock because of our assertion that
1902 * a GC is not running in parallel -- nobody except the GC can
1903 * modify a history list in a Monitor they don't own, and we own "mrl".
1904 * (There might be concurrent *reads*, but no concurrent *writes.)
1905 *
1906 * If we find it, this is a known good configuration, and we're done.
1907 */
1908 if (objectInChildList(mrl->obj, acqObj))
1909 return;
1910
1911 /*
1912 * "mrl" is going to need to have a history tree. If it's currently
1913 * a thin lock, we make it fat now. The thin lock might have a
1914 * nonzero recursive lock count, which we need to carry over.
1915 *
1916 * Our thread holds the lock, so we're allowed to rewrite the lock
1917 * without worrying that something will change out from under us.
1918 */
1919 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1920 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001921 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001922 inflateMonitor(self, mrl->obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001923 }
1924
1925 /*
1926 * We haven't seen this configuration before. We need to scan down
1927 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1928 * appear. We grab a global lock before traversing or updating the
1929 * history list.
1930 *
1931 * If we find a match for any of our held locks, we know that the lock
1932 * has previously been acquired *after* acqObj, and we throw an error.
1933 *
1934 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1935 * and do a recursive traversal, marking nodes as we cross them. If
1936 * we cross one a second time, we have a cycle and can throw an error.
1937 * (We do the flag-clearing traversal before adding the new link, so
1938 * that we're guaranteed to terminate.)
1939 *
1940 * If "acqObj" is a thin lock, it has no history, and we can create a
1941 * link to it without additional checks. [ We now guarantee that it's
1942 * always fat. ]
1943 */
1944 bool failed = false;
1945 dvmLockMutex(&gDvm.deadlockHistoryLock);
1946 linkParentToChild(mrl->obj, acqObj);
1947 if (!traverseTree(self, acqObj)) {
1948 LOGW("%s\n", kEndBanner);
1949 failed = true;
1950
1951 /* remove the entry so we're still okay when in "warning" mode */
1952 unlinkParentFromChild(mrl->obj, acqObj);
1953 }
1954 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1955
1956 if (failed) {
1957 switch (gDvm.deadlockPredictMode) {
1958 case kDPErr:
1959 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1960 break;
1961 case kDPAbort:
1962 LOGE("Aborting due to potential deadlock\n");
1963 dvmAbort();
1964 break;
1965 default:
1966 /* warn only */
1967 break;
1968 }
1969 }
1970}
1971
1972/*
1973 * We're removing "child" from existence. We want to pull all of
1974 * child's children into "parent", filtering out duplicates. This is
1975 * called during the GC.
1976 *
1977 * This does not modify "child", which might have multiple parents.
1978 */
1979static void mergeChildren(Object* parent, const Object* child)
1980{
1981 Monitor* mon;
1982 int i;
1983
1984 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001985 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001986 ExpandingObjectList* pList = &mon->historyChildren;
1987
1988 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1989 Object* grandChild = expandBufGetEntry(pList, i);
1990
1991 if (!objectInChildList(parent, grandChild)) {
1992 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1993 linkParentToChild(parent, grandChild);
1994 } else {
1995 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
1996 }
1997 }
1998}
1999
2000/*
2001 * An object with a fat lock is being collected during a GC pass. We
2002 * want to remove it from any lock history trees that it is a part of.
2003 *
2004 * This may require updating the history trees in several monitors. The
2005 * monitor semantics guarantee that no other thread will be accessing
2006 * the history trees at the same time.
2007 */
2008static void removeCollectedObject(Object* obj)
2009{
2010 Monitor* mon;
2011
2012 LOGVV("+++ collecting %p\n", obj);
2013
2014#if 0
2015 /*
2016 * We're currently running through the entire set of known monitors.
2017 * This can be somewhat slow. We may want to keep lists of parents
2018 * in each child to speed up GC.
2019 */
2020 mon = gDvm.monitorList;
2021 while (mon != NULL) {
2022 Object* parent = mon->obj;
2023 if (parent != NULL) { /* value nulled for deleted entries */
2024 if (objectInChildList(parent, obj)) {
2025 LOGVV("removing child %p from parent %p\n", obj, parent);
2026 unlinkParentFromChild(parent, obj);
2027 mergeChildren(parent, obj);
2028 }
2029 }
2030 mon = mon->next;
2031 }
2032#endif
2033
2034 /*
2035 * For every parent of this object:
2036 * - merge all of our children into the parent's child list (creates
2037 * a two-way link between parent and child)
2038 * - remove ourselves from the parent's child list
2039 */
2040 ExpandingObjectList* pList;
2041 int i;
2042
2043 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002044 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002045 pList = &mon->historyParents;
2046 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2047 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002048 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002049
2050 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2051 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2052 }
2053 assert(!expandObjHas(&parentMon->historyChildren, obj));
2054
2055 mergeChildren(parent, obj);
2056 }
2057
2058 /*
2059 * For every child of this object:
2060 * - remove ourselves from the child's parent list
2061 */
2062 pList = &mon->historyChildren;
2063 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2064 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002065 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002066
2067 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2068 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2069 }
2070 assert(!expandObjHas(&childMon->historyParents, obj));
2071 }
2072}
2073
2074#endif /*WITH_DEADLOCK_PREDICTION*/