blob: 7afe514d5b5ae025eb8e174ee34196f09058480f [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 Shapiro6b4ba582010-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 McFadden0a24ef92010-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 */
314 assert(pthread_mutex_trylock(&mon->lock) == 0);
315 pthread_mutex_destroy(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800316#ifdef WITH_DEADLOCK_PREDICTION
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800317 expandObjClear(&mon->historyChildren);
318 expandObjClear(&mon->historyParents);
319 free(mon->historyRawStackTrace);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800320#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800321 free(mon);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800322}
323
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800324/*
325 * Frees monitor objects belonging to unmarked objects.
326 */
327void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
328{
329 Monitor handle;
330 Monitor *prev, *curr;
331 Object *obj;
332
333 assert(mon != NULL);
334 assert(*mon != NULL);
335 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 Shapiro6b4ba582010-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 Shapiro6b4ba582010-04-09 15:03:33 -0700362 set4LE((u1 *)dst, len);
363 dst += 4;
Carl Shapiro6b4ba582010-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 Shapiro6b4ba582010-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 Shapiro6b4ba582010-04-09 15:03:33 -0700376 const char *fileName;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700377 char procName[33], *selfName, *ownerName;
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700378 char *cp;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700379 size_t len;
380 int fd;
Carl Shapiro6b4ba582010-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 Shapiro6b4ba582010-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 Shapiro6b4ba582010-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
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700421 /* Emit a trailing newline, apparently the EVENT_TYPE_LIST convention. */
422 *cp = '\n';
423
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700424 assert((size_t)(cp - eventBuffer) <= sizeof(eventBuffer));
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700425 android_btWriteLog(EVENT_LOG_TAG_dvm_lock_sample,
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700426 EVENT_TYPE_LIST,
427 eventBuffer,
428 (size_t)(cp - eventBuffer));
429}
430
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800431/*
432 * Lock a monitor.
433 */
434static void lockMonitor(Thread* self, Monitor* mon)
435{
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700436 Thread *owner;
437 ThreadStatus oldStatus;
438 u4 waitThreshold, samplePercent;
439 u8 waitStart, waitEnd, waitMs;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800440
441 if (mon->owner == self) {
442 mon->lockCount++;
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700443 return;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800444 }
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700445 if (pthread_mutex_trylock(&mon->lock) != 0) {
446 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
447 waitThreshold = gDvm.lockProfThreshold;
448 if (waitThreshold) {
449 waitStart = dvmGetRelativeTimeUsec();
450 }
451 dvmLockMutex(&mon->lock);
452 if (waitThreshold) {
453 waitEnd = dvmGetRelativeTimeUsec();
454 }
455 dvmChangeStatus(self, oldStatus);
456 if (waitThreshold) {
457 waitMs = (waitEnd - waitStart) / 1000;
458 if (waitMs >= waitThreshold) {
459 samplePercent = 100;
460 } else {
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700461 samplePercent = 100 * waitMs / waitThreshold;
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700462 }
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700463 if (samplePercent != 0 && ((u4)rand() % 100 < samplePercent)) {
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700464 logContentionEvent(self, waitMs, samplePercent);
465 }
466 }
467 }
468 mon->owner = self;
469 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800470}
471
472/*
473 * Try to lock a monitor.
474 *
475 * Returns "true" on success.
476 */
477static bool tryLockMonitor(Thread* self, Monitor* mon)
478{
479 int cc;
480
481 if (mon->owner == self) {
482 mon->lockCount++;
483 return true;
484 } else {
485 cc = pthread_mutex_trylock(&mon->lock);
486 if (cc == 0) {
487 mon->owner = self;
488 assert(mon->lockCount == 0);
489 return true;
490 } else {
491 return false;
492 }
493 }
494}
495
496
497/*
498 * Unlock a monitor.
499 *
500 * Returns true if the unlock succeeded.
501 * If the unlock failed, an exception will be pending.
502 */
503static bool unlockMonitor(Thread* self, Monitor* mon)
504{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800505 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800506 assert(mon != NULL); // can this happen?
507
508 if (mon->owner == self) {
509 /*
510 * We own the monitor, so nobody else can be in here.
511 */
512 if (mon->lockCount == 0) {
513 int cc;
514 mon->owner = NULL;
515 cc = pthread_mutex_unlock(&mon->lock);
516 assert(cc == 0);
517 } else {
518 mon->lockCount--;
519 }
520 } else {
521 /*
522 * We don't own this, so we're not allowed to unlock it.
523 * The JNI spec says that we should throw IllegalMonitorStateException
524 * in this case.
525 */
Carl Shapiroe11f3fd2010-02-24 02:30:55 -0800526 dvmThrowExceptionFmt("Ljava/lang/IllegalMonitorStateException;",
527 "unlock of unowned monitor, self=%d owner=%d",
528 self->threadId,
529 mon->owner ? mon->owner->threadId : 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800530 return false;
531 }
532 return true;
533}
534
535/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800536 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800537 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800538 */
539static int waitSetCheck(Monitor *mon)
540{
541 Thread *fast, *slow;
542 size_t n;
543
544 assert(mon != NULL);
545 fast = slow = mon->waitSet;
546 n = 0;
547 for (;;) {
548 if (fast == NULL) return 0;
549 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800550 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800551 n += 2;
552 fast = fast->waitNext->waitNext;
553 slow = slow->waitNext;
554 }
555}
556
557/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800558 * Links a thread into a monitor's wait set. The monitor lock must be
559 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800560 */
561static void waitSetAppend(Monitor *mon, Thread *thread)
562{
563 Thread *elt;
564
565 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800566 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800567 assert(thread != NULL);
568 assert(thread->waitNext == NULL);
569 assert(waitSetCheck(mon) == 0);
570 if (mon->waitSet == NULL) {
571 mon->waitSet = thread;
572 return;
573 }
574 elt = mon->waitSet;
575 while (elt->waitNext != NULL) {
576 elt = elt->waitNext;
577 }
578 elt->waitNext = thread;
579}
580
581/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800582 * Unlinks a thread from a monitor's wait set. The monitor lock must
583 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800584 */
585static void waitSetRemove(Monitor *mon, Thread *thread)
586{
587 Thread *elt;
588
589 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800590 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800591 assert(thread != NULL);
592 assert(waitSetCheck(mon) == 0);
593 if (mon->waitSet == NULL) {
594 return;
595 }
596 if (mon->waitSet == thread) {
597 mon->waitSet = thread->waitNext;
598 thread->waitNext = NULL;
599 return;
600 }
601 elt = mon->waitSet;
602 while (elt->waitNext != NULL) {
603 if (elt->waitNext == thread) {
604 elt->waitNext = thread->waitNext;
605 thread->waitNext = NULL;
606 return;
607 }
608 elt = elt->waitNext;
609 }
610}
611
Carl Shapirob4539192010-01-04 16:50:00 -0800612/*
613 * Converts the given relative waiting time into an absolute time.
614 */
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800615void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800616{
617 s8 endSec;
618
619#ifdef HAVE_TIMEDWAIT_MONOTONIC
620 clock_gettime(CLOCK_MONOTONIC, ts);
621#else
622 {
623 struct timeval tv;
624 gettimeofday(&tv, NULL);
625 ts->tv_sec = tv.tv_sec;
626 ts->tv_nsec = tv.tv_usec * 1000;
627 }
628#endif
629 endSec = ts->tv_sec + msec / 1000;
630 if (endSec >= 0x7fffffff) {
631 LOGV("NOTE: end time exceeds epoch\n");
632 endSec = 0x7ffffffe;
633 }
634 ts->tv_sec = endSec;
635 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
636
637 /* catch rollover */
638 if (ts->tv_nsec >= 1000000000L) {
639 ts->tv_sec++;
640 ts->tv_nsec -= 1000000000L;
641 }
642}
643
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800644int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
645 s8 msec, s4 nsec)
646{
647 int ret;
648 struct timespec ts;
649 absoluteTime(msec, nsec, &ts);
650#if defined(HAVE_TIMEDWAIT_MONOTONIC)
651 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
652#else
653 ret = pthread_cond_timedwait(cond, mutex, &ts);
654#endif
655 assert(ret == 0 || ret == ETIMEDOUT);
656 return ret;
657}
658
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800659/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800660 * Wait on a monitor until timeout, interrupt, or notification. Used for
661 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
662 *
663 * If another thread calls Thread.interrupt(), we throw InterruptedException
664 * and return immediately if one of the following are true:
665 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
666 * - blocked in join(), join(long), or join(long, int) methods of Thread
667 * - blocked in sleep(long), or sleep(long, int) methods of Thread
668 * Otherwise, we set the "interrupted" flag.
669 *
670 * Checks to make sure that "nsec" is in the range 0-999999
671 * (i.e. fractions of a millisecond) and throws the appropriate
672 * exception if it isn't.
673 *
674 * The spec allows "spurious wakeups", and recommends that all code using
675 * Object.wait() do so in a loop. This appears to derive from concerns
676 * about pthread_cond_wait() on multiprocessor systems. Some commentary
677 * on the web casts doubt on whether these can/should occur.
678 *
679 * Since we're allowed to wake up "early", we clamp extremely long durations
680 * to return at the end of the 32-bit time epoch.
681 */
682static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
683 bool interruptShouldThrow)
684{
685 struct timespec ts;
686 bool wasInterrupted = false;
687 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800688 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800689
Carl Shapiro71938022009-12-22 13:49:53 -0800690 assert(self != NULL);
691 assert(mon != NULL);
692
Carl Shapiro94338aa2009-12-21 11:42:59 -0800693 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800694 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800695 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
696 "object not locked by thread before wait()");
697 return;
698 }
699
700 /*
701 * Enforce the timeout range.
702 */
703 if (msec < 0 || nsec < 0 || nsec > 999999) {
704 dvmThrowException("Ljava/lang/IllegalArgumentException;",
705 "timeout arguments out of range");
706 return;
707 }
708
709 /*
710 * Compute absolute wakeup time, if necessary.
711 */
712 if (msec == 0 && nsec == 0) {
713 timed = false;
714 } else {
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800715 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800716 timed = true;
717 }
718
719 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800720 * Add ourselves to the set of threads waiting on this monitor, and
721 * release our hold. We need to let it go even if we're a few levels
722 * deep in a recursive lock, and we need to restore that later.
723 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800724 * We append to the wait set ahead of clearing the count and owner
725 * fields so the subroutine can check that the calling thread owns
726 * the monitor. Aside from that, the order of member updates is
727 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800728 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800729 waitSetAppend(mon, self);
730 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800731 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800732 mon->owner = NULL;
733
734 /*
735 * Update thread status. If the GC wakes up, it'll ignore us, knowing
736 * that we won't touch any references in this state, and we'll check
737 * our suspend mode before we transition out.
738 */
739 if (timed)
740 dvmChangeStatus(self, THREAD_TIMED_WAIT);
741 else
742 dvmChangeStatus(self, THREAD_WAIT);
743
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800744 ret = pthread_mutex_lock(&self->waitMutex);
745 assert(ret == 0);
746
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800747 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800748 * Set waitMonitor to the monitor object we will be waiting on.
749 * When waitMonitor is non-NULL a notifying or interrupting thread
750 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800751 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800752 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800753 self->waitMonitor = mon;
754
755 /*
756 * Handle the case where the thread was interrupted before we called
757 * wait().
758 */
759 if (self->interrupted) {
760 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800761 self->waitMonitor = NULL;
762 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800763 goto done;
764 }
765
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800766 /*
767 * Release the monitor lock and wait for a notification or
768 * a timeout to occur.
769 */
770 pthread_mutex_unlock(&mon->lock);
771
772 if (!timed) {
773 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
774 assert(ret == 0);
775 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800776#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800777 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800778#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800779 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800780#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800781 assert(ret == 0 || ret == ETIMEDOUT);
782 }
783 if (self->interrupted) {
784 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800785 }
786
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800787 self->interrupted = false;
788 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800789
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800790 pthread_mutex_unlock(&self->waitMutex);
791
Carl Shapiro30aa9972010-01-13 22:07:50 -0800792 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800793 lockMonitor(self, mon);
794
Carl Shapiro142ef272010-01-25 12:51:31 -0800795done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800796 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800797 * We remove our thread from wait set after restoring the count
798 * and owner fields so the subroutine can check that the calling
799 * thread owns the monitor. Aside from that, the order of member
800 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800801 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800802 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800803 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800804 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800805
806 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
807 dvmChangeStatus(self, THREAD_RUNNING);
808
809 if (wasInterrupted) {
810 /*
811 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800812 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800813 *
814 * The doc sayeth: "The interrupted status of the current thread is
815 * cleared when this exception is thrown."
816 */
817 self->interrupted = false;
818 if (interruptShouldThrow)
819 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
820 }
821}
822
823/*
824 * Notify one thread waiting on this monitor.
825 */
826static void notifyMonitor(Thread* self, Monitor* mon)
827{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800828 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800829
Carl Shapiro71938022009-12-22 13:49:53 -0800830 assert(self != NULL);
831 assert(mon != NULL);
832
Carl Shapiro94338aa2009-12-21 11:42:59 -0800833 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800834 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800835 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
836 "object not locked by thread before notify()");
837 return;
838 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800839 /* Signal the first waiting thread in the wait set. */
840 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800841 thread = mon->waitSet;
842 mon->waitSet = thread->waitNext;
843 thread->waitNext = NULL;
844 pthread_mutex_lock(&thread->waitMutex);
845 /* Check to see if the thread is still waiting. */
846 if (thread->waitMonitor != NULL) {
847 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800848 pthread_mutex_unlock(&thread->waitMutex);
849 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800850 }
851 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800852 }
853}
854
855/*
856 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800857 */
858static void notifyAllMonitor(Thread* self, Monitor* mon)
859{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800860 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800861
Carl Shapiro71938022009-12-22 13:49:53 -0800862 assert(self != NULL);
863 assert(mon != NULL);
864
Carl Shapiro94338aa2009-12-21 11:42:59 -0800865 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800866 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800867 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
868 "object not locked by thread before notifyAll()");
869 return;
870 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800871 /* Signal all threads in the wait set. */
872 while (mon->waitSet != NULL) {
873 thread = mon->waitSet;
874 mon->waitSet = thread->waitNext;
875 thread->waitNext = NULL;
876 pthread_mutex_lock(&thread->waitMutex);
877 /* Check to see if the thread is still waiting. */
878 if (thread->waitMonitor != NULL) {
879 pthread_cond_signal(&thread->waitCond);
880 }
881 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800882 }
883}
884
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800885/*
886 * Implements monitorenter for "synchronized" stuff.
887 *
888 * This does not fail or throw an exception (unless deadlock prediction
889 * is enabled and set to "err" mode).
890 */
891void dvmLockObject(Thread* self, Object *obj)
892{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800893 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800894 Monitor *mon;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800895 ThreadStatus oldStatus;
896 useconds_t sleepDelay;
897 const useconds_t maxSleepDelay = 1 << 20;
898 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800899
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800900 assert(self != NULL);
901 assert(obj != NULL);
902 threadId = self->threadId;
903 thinp = &obj->lock;
904retry:
905 thin = *thinp;
906 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
907 /*
908 * The lock is a thin lock. The owner field is used to
909 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800910 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800911 if (LW_LOCK_OWNER(thin) == threadId) {
912 /*
913 * The calling thread owns the lock. Increment the
914 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800915 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800916 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
917 } else if (LW_LOCK_OWNER(thin) == 0) {
918 /*
919 * The lock is unowned. Install the thread id of the
920 * calling thread into the owner field. This is the
921 * common case. In performance critical code the JIT
922 * will have tried this before calling out to the VM.
923 */
924 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
925 if (!ATOMIC_CMP_SWAP((int32_t *)thinp, thin, newThin)) {
926 /*
927 * The acquire failed. Try again.
928 */
929 goto retry;
930 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800931 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800932 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
933 threadId, &obj->lock, 0, *thinp, thin);
934 /*
935 * The lock is owned by another thread. Notify the VM
936 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800937 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800938 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
939 /*
940 * Spin until the thin lock is released or inflated.
941 */
942 sleepDelay = 0;
943 for (;;) {
944 thin = *thinp;
945 /*
946 * Check the shape of the lock word. Another thread
947 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800948 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800949 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
950 if (LW_LOCK_OWNER(thin) == 0) {
951 /*
952 * The lock has been released. Install the
953 * thread id of the calling thread into the
954 * owner field.
955 */
956 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
957 if (ATOMIC_CMP_SWAP((int32_t *)thinp,
958 thin, newThin)) {
959 /*
960 * The acquire succeed. Break out of the
961 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800962 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800963 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800964 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800965 } else {
966 /*
967 * The lock has not been released. Yield so
968 * the owning thread can run.
969 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800970 if (sleepDelay == 0) {
971 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800972 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800973 } else {
974 usleep(sleepDelay);
975 if (sleepDelay < maxSleepDelay / 2) {
976 sleepDelay *= 2;
977 }
978 }
979 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800980 } else {
981 /*
982 * The thin lock was inflated by another thread.
983 * Let the VM know we are no longer waiting and
984 * try again.
985 */
986 LOG_THIN("(%d) lock %p surprise-fattened",
987 threadId, &obj->lock);
988 dvmChangeStatus(self, oldStatus);
989 goto retry;
990 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800991 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800992 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
993 threadId, &obj->lock, 0, *thinp, thin);
994 /*
995 * We have acquired the thin lock. Let the VM know that
996 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800997 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800998 dvmChangeStatus(self, oldStatus);
999 /*
1000 * Fatten the lock.
1001 */
1002 mon = dvmCreateMonitor(obj);
1003 lockMonitor(self, mon);
1004 thin = *thinp;
1005 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
1006 thin |= (u4)mon | LW_SHAPE_FAT;
1007 MEM_BARRIER();
1008 obj->lock = thin;
1009 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001010 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001011 } else {
1012 /*
1013 * The lock is a fat lock.
1014 */
1015 assert(LW_MONITOR(obj->lock) != NULL);
1016 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001017 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001018#ifdef WITH_DEADLOCK_PREDICTION
1019 /*
1020 * See if we were allowed to grab the lock at this time. We do it
1021 * *after* acquiring the lock, rather than before, so that we can
1022 * freely update the Monitor struct. This seems counter-intuitive,
1023 * but our goal is deadlock *prediction* not deadlock *prevention*.
1024 * (If we actually deadlock, the situation is easy to diagnose from
1025 * a thread dump, so there's no point making a special effort to do
1026 * the checks before the lock is held.)
1027 *
1028 * This needs to happen before we add the object to the thread's
1029 * monitor list, so we can tell the difference between first-lock and
1030 * re-lock.
1031 *
1032 * It's also important that we do this while in THREAD_RUNNING, so
1033 * that we don't interfere with cleanup operations in the GC.
1034 */
1035 if (gDvm.deadlockPredictMode != kDPOff) {
1036 if (self->status != THREAD_RUNNING) {
1037 LOGE("Bad thread status (%d) in DP\n", self->status);
1038 dvmDumpThread(self, false);
1039 dvmAbort();
1040 }
1041 assert(!dvmCheckException(self));
1042 updateDeadlockPrediction(self, obj);
1043 if (dvmCheckException(self)) {
1044 /*
1045 * If we're throwing an exception here, we need to free the
1046 * lock. We add the object to the thread's monitor list so the
1047 * "unlock" code can remove it.
1048 */
1049 dvmAddToMonitorList(self, obj, false);
1050 dvmUnlockObject(self, obj);
1051 LOGV("--- unlocked, pending is '%s'\n",
1052 dvmGetException(self)->clazz->descriptor);
1053 }
1054 }
1055
1056 /*
1057 * Add the locked object, and the current stack trace, to the list
1058 * held by the Thread object. If deadlock prediction isn't on,
1059 * don't capture the stack trace.
1060 */
1061 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
1062#elif defined(WITH_MONITOR_TRACKING)
1063 /*
1064 * Add the locked object to the list held by the Thread object.
1065 */
1066 dvmAddToMonitorList(self, obj, false);
1067#endif
1068}
1069
1070/*
1071 * Implements monitorexit for "synchronized" stuff.
1072 *
1073 * On failure, throws an exception and returns "false".
1074 */
1075bool dvmUnlockObject(Thread* self, Object *obj)
1076{
Carl Shapiro94338aa2009-12-21 11:42:59 -08001077 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001078
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001079 assert(self != NULL);
1080 assert(self->status == THREAD_RUNNING);
1081 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001082 /*
1083 * Cache the lock word as its value can change while we are
1084 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001085 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001086 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001087 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
1088 /*
1089 * The lock is thin. We must ensure that the lock is owned
1090 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001091 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001092 if (LW_LOCK_OWNER(thin) == self->threadId) {
1093 /*
1094 * We are the lock owner. It is safe to update the lock
1095 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001096 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001097 if (LW_LOCK_COUNT(thin) == 0) {
1098 /*
1099 * The lock was not recursively acquired, the common
1100 * case. Unlock by clearing all bits except for the
1101 * hash state.
1102 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001103 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001104 } else {
1105 /*
1106 * The object was recursively acquired. Decrement the
1107 * lock recursion count field.
1108 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001109 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001110 }
1111 } else {
1112 /*
1113 * We do not own the lock. The JVM spec requires that we
1114 * throw an exception in this case.
1115 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001116 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001117 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001118 return false;
1119 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001120 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001121 /*
1122 * The lock is fat. We must check to see if unlockMonitor has
1123 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001124 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001125 assert(LW_MONITOR(obj->lock) != NULL);
1126 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001127 /*
1128 * An exception has been raised. Do not fall through.
1129 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001130 return false;
1131 }
1132 }
1133
1134#ifdef WITH_MONITOR_TRACKING
1135 /*
1136 * Remove the object from the Thread's list.
1137 */
1138 dvmRemoveFromMonitorList(self, obj);
1139#endif
1140
1141 return true;
1142}
1143
1144/*
1145 * Object.wait(). Also called for class init.
1146 */
1147void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1148 bool interruptShouldThrow)
1149{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001150 Monitor* mon = LW_MONITOR(obj->lock);
1151 u4 hashState;
1152 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001153
1154 /* If the lock is still thin, we need to fatten it.
1155 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001156 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001157 /* Make sure that 'self' holds the lock.
1158 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001159 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001160 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1161 "object not locked by thread before wait()");
1162 return;
1163 }
1164
1165 /* This thread holds the lock. We need to fatten the lock
1166 * so 'self' can block on it. Don't update the object lock
1167 * field yet, because 'self' needs to acquire the lock before
1168 * any other thread gets a chance.
1169 */
1170 mon = dvmCreateMonitor(obj);
1171
1172 /* 'self' has actually locked the object one or more times;
1173 * make sure that the monitor reflects this.
1174 */
1175 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001176 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001177 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1178 self->threadId, (uint)&obj->lock, mon->lockCount);
1179
Andy McFadden581bed72009-10-15 11:24:54 -07001180
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001181 /* Make the monitor public now that it's in the right state.
1182 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001183 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
1184 thin |= (u4)mon | LW_SHAPE_FAT;
Andy McFadden581bed72009-10-15 11:24:54 -07001185 MEM_BARRIER();
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001186 obj->lock = thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001187 }
1188
1189 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1190}
1191
1192/*
1193 * Object.notify().
1194 */
1195void dvmObjectNotify(Thread* self, Object *obj)
1196{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001197 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001198
1199 /* If the lock is still thin, there aren't any waiters;
1200 * waiting on an object forces lock fattening.
1201 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001202 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001203 /* Make sure that 'self' holds the lock.
1204 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001205 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001206 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1207 "object not locked by thread before notify()");
1208 return;
1209 }
1210
1211 /* no-op; there are no waiters to notify.
1212 */
1213 } else {
1214 /* It's a fat lock.
1215 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001216 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001217 }
1218}
1219
1220/*
1221 * Object.notifyAll().
1222 */
1223void dvmObjectNotifyAll(Thread* self, Object *obj)
1224{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001225 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001226
1227 /* If the lock is still thin, there aren't any waiters;
1228 * waiting on an object forces lock fattening.
1229 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001230 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001231 /* Make sure that 'self' holds the lock.
1232 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001233 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001234 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1235 "object not locked by thread before notifyAll()");
1236 return;
1237 }
1238
1239 /* no-op; there are no waiters to notify.
1240 */
1241 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001242 /* It's a fat lock.
1243 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001244 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001245 }
1246}
1247
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001248/*
1249 * This implements java.lang.Thread.sleep(long msec, int nsec).
1250 *
1251 * The sleep is interruptible by other threads, which means we can't just
1252 * plop into an OS sleep call. (We probably could if we wanted to send
1253 * signals around and rely on EINTR, but that's inefficient and relies
1254 * on native code respecting our signal mask.)
1255 *
1256 * We have to do all of this stuff for Object.wait() as well, so it's
1257 * easiest to just sleep on a private Monitor.
1258 *
1259 * It appears that we want sleep(0,0) to go through the motions of sleeping
1260 * for a very short duration, rather than just returning.
1261 */
1262void dvmThreadSleep(u8 msec, u4 nsec)
1263{
1264 Thread* self = dvmThreadSelf();
1265 Monitor* mon = gDvm.threadSleepMon;
1266
1267 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1268 if (msec == 0 && nsec == 0)
1269 nsec++;
1270
1271 lockMonitor(self, mon);
1272 waitMonitor(self, mon, msec, nsec, true);
1273 unlockMonitor(self, mon);
1274}
1275
1276/*
1277 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001278 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001279void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001280{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001281 assert(thread != NULL);
1282
1283 pthread_mutex_lock(&thread->waitMutex);
1284
1285 /*
1286 * If the interrupted flag is already set no additional action is
1287 * required.
1288 */
1289 if (thread->interrupted == true) {
1290 pthread_mutex_unlock(&thread->waitMutex);
1291 return;
1292 }
1293
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001294 /*
1295 * Raise the "interrupted" flag. This will cause it to bail early out
1296 * of the next wait() attempt, if it's not currently waiting on
1297 * something.
1298 */
1299 thread->interrupted = true;
1300 MEM_BARRIER();
1301
1302 /*
1303 * Is the thread waiting?
1304 *
1305 * Note that fat vs. thin doesn't matter here; waitMonitor
1306 * is only set when a thread actually waits on a monitor,
1307 * which implies that the monitor has already been fattened.
1308 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001309 if (thread->waitMonitor != NULL) {
1310 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001311 }
1312
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001313 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001314}
1315
Carl Shapiro30aa9972010-01-13 22:07:50 -08001316#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001317u4 dvmIdentityHashCode(Object *obj)
1318{
1319 return (u4)obj;
1320}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001321#else
1322static size_t arrayElementWidth(const ArrayObject *array)
1323{
1324 const char *descriptor;
1325
1326 if (dvmIsObjectArray(array)) {
1327 return sizeof(Object *);
1328 } else {
1329 descriptor = array->obj.clazz->descriptor;
1330 switch (descriptor[1]) {
1331 case 'B': return 1; /* byte */
1332 case 'C': return 2; /* char */
1333 case 'D': return 8; /* double */
1334 case 'F': return 4; /* float */
1335 case 'I': return 4; /* int */
1336 case 'J': return 8; /* long */
1337 case 'S': return 2; /* short */
1338 case 'Z': return 1; /* boolean */
1339 }
1340 }
1341 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1342 dvmDumpThread(dvmThreadSelf(), false);
1343 dvmAbort();
1344 return 0; /* Quiet the compiler. */
1345}
1346
1347static size_t arrayObjectLength(const ArrayObject *array)
1348{
1349 size_t length;
1350
1351 length = offsetof(ArrayObject, contents);
1352 length += array->length * arrayElementWidth(array);
1353 return length;
1354}
1355
1356/*
1357 * Returns the identity hash code of the given object.
1358 */
1359u4 dvmIdentityHashCode(Object *obj)
1360{
1361 Thread *self, *thread;
1362 volatile u4 *lw;
1363 size_t length;
1364 u4 lock, owner, hashState;
1365
1366 if (obj == NULL) {
1367 /*
1368 * Null is defined to have an identity hash code of 0.
1369 */
1370 return 0;
1371 }
1372 lw = &obj->lock;
1373retry:
1374 hashState = LW_HASH_STATE(*lw);
1375 if (hashState == LW_HASH_STATE_HASHED) {
1376 /*
1377 * The object has been hashed but has not had its hash code
1378 * relocated by the garbage collector. Use the raw object
1379 * address.
1380 */
1381 return (u4)obj >> 3;
1382 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1383 /*
1384 * The object has been hashed and its hash code has been
1385 * relocated by the collector. Use the value of the naturally
1386 * aligned word following the instance data.
1387 */
1388 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1389 length = arrayObjectLength((ArrayObject *)obj);
1390 length = (length + 3) & ~3;
1391 } else {
1392 length = obj->clazz->objectSize;
1393 }
1394 return *(u4 *)(((char *)obj) + length);
1395 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1396 /*
1397 * The object has never been hashed. Change the hash state to
1398 * hashed and use the raw object address.
1399 */
1400 self = dvmThreadSelf();
1401 if (self->threadId == lockOwner(obj)) {
1402 /*
1403 * We already own the lock so we can update the hash state
1404 * directly.
1405 */
1406 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1407 return (u4)obj >> 3;
1408 }
1409 /*
1410 * We do not own the lock. Try acquiring the lock. Should
1411 * this fail, we must suspend the owning thread.
1412 */
1413 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1414 /*
1415 * If the lock is thin assume it is unowned. We simulate
1416 * an acquire, update, and release with a single CAS.
1417 */
1418 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1419 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1420 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1421 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1422 (int32_t)lock)) {
1423 /*
1424 * A new lockword has been installed with a hash state
1425 * of hashed. Use the raw object address.
1426 */
1427 return (u4)obj >> 3;
1428 }
1429 } else {
1430 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1431 /*
1432 * The monitor lock has been acquired. Change the
1433 * hash state to hashed and use the raw object
1434 * address.
1435 */
1436 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1437 unlockMonitor(self, LW_MONITOR(*lw));
1438 return (u4)obj >> 3;
1439 }
1440 }
1441 /*
1442 * At this point we have failed to acquire the lock. We must
1443 * identify the owning thread and suspend it.
1444 */
1445 dvmLockThreadList(self);
1446 /*
1447 * Cache the lock word as its value can change between
1448 * determining its shape and retrieving its owner.
1449 */
1450 lock = *lw;
1451 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1452 /*
1453 * Find the thread with the corresponding thread id.
1454 */
1455 owner = LW_LOCK_OWNER(lock);
1456 assert(owner != self->threadId);
1457 /*
1458 * If the lock has no owner do not bother scanning the
1459 * thread list and fall through to the failure handler.
1460 */
1461 thread = owner ? gDvm.threadList : NULL;
1462 while (thread != NULL) {
1463 if (thread->threadId == owner) {
1464 break;
1465 }
1466 thread = thread->next;
1467 }
1468 } else {
1469 thread = LW_MONITOR(lock)->owner;
1470 }
1471 /*
1472 * If thread is NULL the object has been released since the
1473 * thread list lock was acquired. Try again.
1474 */
1475 if (thread == NULL) {
1476 dvmUnlockThreadList();
1477 goto retry;
1478 }
1479 /*
1480 * Wait for the owning thread to suspend.
1481 */
1482 dvmSuspendThread(thread);
1483 if (dvmHoldsLock(thread, obj)) {
1484 /*
1485 * The owning thread has been suspended. We can safely
1486 * change the hash state to hashed.
1487 */
1488 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1489 dvmResumeThread(thread);
1490 dvmUnlockThreadList();
1491 return (u4)obj >> 3;
1492 }
1493 /*
1494 * The wrong thread has been suspended. Try again.
1495 */
1496 dvmResumeThread(thread);
1497 dvmUnlockThreadList();
1498 goto retry;
1499 }
1500 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1501 dvmDumpThread(dvmThreadSelf(), false);
1502 dvmAbort();
1503 return 0; /* Quiet the compiler. */
1504}
1505#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001506
1507#ifdef WITH_DEADLOCK_PREDICTION
1508/*
1509 * ===========================================================================
1510 * Deadlock prediction
1511 * ===========================================================================
1512 */
1513/*
1514The idea is to predict the possibility of deadlock by recording the order
1515in which monitors are acquired. If we see an attempt to acquire a lock
1516out of order, we can identify the locks and offending code.
1517
1518To make this work, we need to keep track of the locks held by each thread,
1519and create history trees for each lock. When a thread tries to acquire
1520a new lock, we walk through the "history children" of the lock, looking
1521for a match with locks the thread already holds. If we find a match,
1522it means the thread has made a request that could result in a deadlock.
1523
1524To support recursive locks, we always allow re-locking a currently-held
1525lock, and maintain a recursion depth count.
1526
1527An ASCII-art example, where letters represent Objects:
1528
1529 A
1530 /|\
1531 / | \
1532 B | D
1533 \ |
1534 \|
1535 C
1536
1537The above is the tree we'd have after handling Object synchronization
1538sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1539a child of B. (The lines represent pointers between parent and child.
1540Every node can have multiple parents and multiple children.)
1541
1542If we hold AC, and want to lock B, we recursively search through B's
1543children to see if A or C appears. It does, so we reject the attempt.
1544(A straightforward way to implement it: add a link from C to B, then
1545determine whether the graph starting at B contains a cycle.)
1546
1547If we hold AC and want to lock D, we would succeed, creating a new link
1548from C to D.
1549
1550The lock history and a stack trace is attached to the Object's Monitor
1551struct, which means we need to fatten every Object we lock (thin locking
1552is effectively disabled). If we don't need the stack trace we can
1553avoid fattening the leaf nodes, only fattening objects that need to hold
1554history trees.
1555
1556Updates to Monitor structs are only allowed for the thread that holds
1557the Monitor, so we actually do most of our deadlock prediction work after
1558the lock has been acquired.
1559
1560When an object with a monitor is GCed, we need to remove it from the
1561history trees. There are two basic approaches:
1562 (1) For through the entire set of known monitors, search all child
1563 lists for the object in question. This is rather slow, resulting
1564 in GC passes that take upwards of 10 seconds to complete.
1565 (2) Maintain "parent" pointers in each node. Remove the entries as
1566 required. This requires additional storage and maintenance for
1567 every operation, but is significantly faster at GC time.
1568For each GCed object, we merge all of the object's children into each of
1569the object's parents.
1570*/
1571
1572#if !defined(WITH_MONITOR_TRACKING)
1573# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1574#endif
1575
1576/*
1577 * Clear out the contents of an ExpandingObjectList, freeing any
1578 * dynamic allocations.
1579 */
1580static void expandObjClear(ExpandingObjectList* pList)
1581{
1582 if (pList->list != NULL) {
1583 free(pList->list);
1584 pList->list = NULL;
1585 }
1586 pList->alloc = pList->count = 0;
1587}
1588
1589/*
1590 * Get the number of objects currently stored in the list.
1591 */
1592static inline int expandBufGetCount(const ExpandingObjectList* pList)
1593{
1594 return pList->count;
1595}
1596
1597/*
1598 * Get the Nth entry from the list.
1599 */
1600static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1601 int i)
1602{
1603 return pList->list[i];
1604}
1605
1606/*
1607 * Add a new entry to the list.
1608 *
1609 * We don't check for or try to enforce uniqueness. It's expected that
1610 * the higher-level code does this for us.
1611 */
1612static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1613{
1614 if (pList->count == pList->alloc) {
1615 /* time to expand */
1616 Object** newList;
1617
1618 if (pList->alloc == 0)
1619 pList->alloc = 4;
1620 else
1621 pList->alloc *= 2;
1622 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1623 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1624 if (newList == NULL) {
1625 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1626 dvmAbort();
1627 }
1628 pList->list = newList;
1629 }
1630
1631 pList->list[pList->count++] = obj;
1632}
1633
1634/*
1635 * Returns "true" if the element was successfully removed.
1636 */
1637static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1638{
1639 int i;
1640
1641 for (i = pList->count-1; i >= 0; i--) {
1642 if (pList->list[i] == obj)
1643 break;
1644 }
1645 if (i < 0)
1646 return false;
1647
1648 if (i != pList->count-1) {
1649 /*
1650 * The order of elements is not important, so we just copy the
1651 * last entry into the new slot.
1652 */
1653 //memmove(&pList->list[i], &pList->list[i+1],
1654 // (pList->count-1 - i) * sizeof(pList->list[0]));
1655 pList->list[i] = pList->list[pList->count-1];
1656 }
1657
1658 pList->count--;
1659 pList->list[pList->count] = (Object*) 0xdecadead;
1660 return true;
1661}
1662
1663/*
1664 * Returns "true" if "obj" appears in the list.
1665 */
1666static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1667{
1668 int i;
1669
1670 for (i = 0; i < pList->count; i++) {
1671 if (pList->list[i] == obj)
1672 return true;
1673 }
1674 return false;
1675}
1676
1677/*
1678 * Print the list contents to stdout. For debugging.
1679 */
1680static void expandObjDump(const ExpandingObjectList* pList)
1681{
1682 int i;
1683 for (i = 0; i < pList->count; i++)
1684 printf(" %p", pList->list[i]);
1685}
1686
1687/*
1688 * Check for duplicate entries. Returns the index of the first instance
1689 * of the duplicated value, or -1 if no duplicates were found.
1690 */
1691static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1692{
1693 int i, j;
1694 for (i = 0; i < pList->count-1; i++) {
1695 for (j = i + 1; j < pList->count; j++) {
1696 if (pList->list[i] == pList->list[j]) {
1697 return i;
1698 }
1699 }
1700 }
1701
1702 return -1;
1703}
1704
1705
1706/*
1707 * Determine whether "child" appears in the list of objects associated
1708 * with the Monitor in "parent". If "parent" is a thin lock, we return
1709 * false immediately.
1710 */
1711static bool objectInChildList(const Object* parent, Object* child)
1712{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001713 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001714 if (!IS_LOCK_FAT(&lock)) {
1715 //LOGI("on thin\n");
1716 return false;
1717 }
1718
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001719 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001720}
1721
1722/*
1723 * Print the child list.
1724 */
1725static void dumpKids(Object* parent)
1726{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001727 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001728
1729 printf("Children of %p:", parent);
1730 expandObjDump(&mon->historyChildren);
1731 printf("\n");
1732}
1733
1734/*
1735 * Add "child" to the list of children in "parent", and add "parent" to
1736 * the list of parents in "child".
1737 */
1738static void linkParentToChild(Object* parent, Object* child)
1739{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001740 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001741 assert(IS_LOCK_FAT(&parent->lock));
1742 assert(IS_LOCK_FAT(&child->lock));
1743 assert(parent != child);
1744 Monitor* mon;
1745
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001746 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001747 assert(!expandObjHas(&mon->historyChildren, child));
1748 expandObjAddEntry(&mon->historyChildren, child);
1749
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001750 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001751 assert(!expandObjHas(&mon->historyParents, parent));
1752 expandObjAddEntry(&mon->historyParents, parent);
1753}
1754
1755
1756/*
1757 * Remove "child" from the list of children in "parent".
1758 */
1759static void unlinkParentFromChild(Object* parent, Object* child)
1760{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001761 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001762 assert(IS_LOCK_FAT(&parent->lock));
1763 assert(IS_LOCK_FAT(&child->lock));
1764 assert(parent != child);
1765 Monitor* mon;
1766
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001767 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001768 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1769 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1770 }
1771 assert(!expandObjHas(&mon->historyChildren, child));
1772 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1773
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001774 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001775 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1776 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1777 }
1778 assert(!expandObjHas(&mon->historyParents, parent));
1779 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1780}
1781
1782
1783/*
1784 * Log the monitors held by the current thread. This is done as part of
1785 * flagging an error.
1786 */
1787static void logHeldMonitors(Thread* self)
1788{
1789 char* name = NULL;
1790
1791 name = dvmGetThreadName(self);
1792 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1793 self->threadId, name);
1794 LOGW("(most-recently-acquired on top):\n");
1795 free(name);
1796
1797 LockedObjectData* lod = self->pLockedObjects;
1798 while (lod != NULL) {
1799 LOGW("--- object %p[%d] (%s)\n",
1800 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1801 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1802
1803 lod = lod->next;
1804 }
1805}
1806
1807/*
1808 * Recursively traverse the object hierarchy starting at "obj". We mark
1809 * ourselves on entry and clear the mark on exit. If we ever encounter
1810 * a marked object, we have a cycle.
1811 *
1812 * Returns "true" if all is well, "false" if we found a cycle.
1813 */
1814static bool traverseTree(Thread* self, const Object* obj)
1815{
1816 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001817 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001818
1819 /*
1820 * Have we been here before?
1821 */
1822 if (mon->historyMark) {
1823 int* rawStackTrace;
1824 int stackDepth;
1825
1826 LOGW("%s\n", kStartBanner);
1827 LOGW("Illegal lock attempt:\n");
1828 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1829
1830 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1831 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1832 free(rawStackTrace);
1833
1834 LOGW(" ");
1835 logHeldMonitors(self);
1836
1837 LOGW(" ");
1838 LOGW("Earlier, the following lock order (from last to first) was\n");
1839 LOGW("established -- stack trace is from first successful lock):\n");
1840 return false;
1841 }
1842 mon->historyMark = true;
1843
1844 /*
1845 * Examine the children. We do NOT hold these locks, so they might
1846 * very well transition from thin to fat or change ownership while
1847 * we work.
1848 *
1849 * NOTE: we rely on the fact that they cannot revert from fat to thin
1850 * while we work. This is currently a safe assumption.
1851 *
1852 * We can safely ignore thin-locked children, because by definition
1853 * they have no history and are leaf nodes. In the current
1854 * implementation we always fatten the locks to provide a place to
1855 * hang the stack trace.
1856 */
1857 ExpandingObjectList* pList = &mon->historyChildren;
1858 int i;
1859 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1860 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001861 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001862 if (!IS_LOCK_FAT(&lock))
1863 continue;
1864 if (!traverseTree(self, child)) {
1865 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1866 dvmLogRawStackTrace(mon->historyRawStackTrace,
1867 mon->historyStackDepth);
1868 mon->historyMark = false;
1869 return false;
1870 }
1871 }
1872
1873 mon->historyMark = false;
1874
1875 return true;
1876}
1877
1878/*
1879 * Update the deadlock prediction tree, based on the current thread
1880 * acquiring "acqObj". This must be called before the object is added to
1881 * the thread's list of held monitors.
1882 *
1883 * If the thread already holds the lock (recursion), or this is a known
1884 * lock configuration, we return without doing anything. Otherwise, we add
1885 * a link from the most-recently-acquired lock in this thread to "acqObj"
1886 * after ensuring that the parent lock is "fat".
1887 *
1888 * This MUST NOT be called while a GC is in progress in another thread,
1889 * because we assume exclusive access to history trees in owned monitors.
1890 */
1891static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1892{
1893 LockedObjectData* lod;
1894 LockedObjectData* mrl;
1895
1896 /*
1897 * Quick check for recursive access.
1898 */
1899 lod = dvmFindInMonitorList(self, acqObj);
1900 if (lod != NULL) {
1901 LOGV("+++ DP: recursive %p\n", acqObj);
1902 return;
1903 }
1904
1905 /*
1906 * Make the newly-acquired object's monitor "fat". In some ways this
1907 * isn't strictly necessary, but we need the GC to tell us when
1908 * "interesting" objects go away, and right now the only way to make
1909 * an object look interesting is to give it a monitor.
1910 *
1911 * This also gives us a place to hang a stack trace.
1912 *
1913 * Our thread holds the lock, so we're allowed to rewrite the lock
1914 * without worrying that something will change out from under us.
1915 */
1916 if (!IS_LOCK_FAT(&acqObj->lock)) {
1917 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001918 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001919 Monitor* newMon = dvmCreateMonitor(acqObj);
1920 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001921 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1922 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1923 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001924 }
1925
1926 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001927 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1928 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001929 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1930 &mon->historyStackDepth);
1931 }
1932
1933 /*
1934 * We need to examine and perhaps modify the most-recently-locked
1935 * monitor. We own that, so there's no risk of another thread
1936 * stepping on us.
1937 *
1938 * Retrieve the most-recently-locked entry from our thread.
1939 */
1940 mrl = self->pLockedObjects;
1941 if (mrl == NULL)
1942 return; /* no other locks held */
1943
1944 /*
1945 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1946 * this without holding the global lock because of our assertion that
1947 * a GC is not running in parallel -- nobody except the GC can
1948 * modify a history list in a Monitor they don't own, and we own "mrl".
1949 * (There might be concurrent *reads*, but no concurrent *writes.)
1950 *
1951 * If we find it, this is a known good configuration, and we're done.
1952 */
1953 if (objectInChildList(mrl->obj, acqObj))
1954 return;
1955
1956 /*
1957 * "mrl" is going to need to have a history tree. If it's currently
1958 * a thin lock, we make it fat now. The thin lock might have a
1959 * nonzero recursive lock count, which we need to carry over.
1960 *
1961 * Our thread holds the lock, so we're allowed to rewrite the lock
1962 * without worrying that something will change out from under us.
1963 */
1964 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1965 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001966 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001967 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1968 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001969 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1970 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1971 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001972 }
1973
1974 /*
1975 * We haven't seen this configuration before. We need to scan down
1976 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1977 * appear. We grab a global lock before traversing or updating the
1978 * history list.
1979 *
1980 * If we find a match for any of our held locks, we know that the lock
1981 * has previously been acquired *after* acqObj, and we throw an error.
1982 *
1983 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1984 * and do a recursive traversal, marking nodes as we cross them. If
1985 * we cross one a second time, we have a cycle and can throw an error.
1986 * (We do the flag-clearing traversal before adding the new link, so
1987 * that we're guaranteed to terminate.)
1988 *
1989 * If "acqObj" is a thin lock, it has no history, and we can create a
1990 * link to it without additional checks. [ We now guarantee that it's
1991 * always fat. ]
1992 */
1993 bool failed = false;
1994 dvmLockMutex(&gDvm.deadlockHistoryLock);
1995 linkParentToChild(mrl->obj, acqObj);
1996 if (!traverseTree(self, acqObj)) {
1997 LOGW("%s\n", kEndBanner);
1998 failed = true;
1999
2000 /* remove the entry so we're still okay when in "warning" mode */
2001 unlinkParentFromChild(mrl->obj, acqObj);
2002 }
2003 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
2004
2005 if (failed) {
2006 switch (gDvm.deadlockPredictMode) {
2007 case kDPErr:
2008 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
2009 break;
2010 case kDPAbort:
2011 LOGE("Aborting due to potential deadlock\n");
2012 dvmAbort();
2013 break;
2014 default:
2015 /* warn only */
2016 break;
2017 }
2018 }
2019}
2020
2021/*
2022 * We're removing "child" from existence. We want to pull all of
2023 * child's children into "parent", filtering out duplicates. This is
2024 * called during the GC.
2025 *
2026 * This does not modify "child", which might have multiple parents.
2027 */
2028static void mergeChildren(Object* parent, const Object* child)
2029{
2030 Monitor* mon;
2031 int i;
2032
2033 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002034 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002035 ExpandingObjectList* pList = &mon->historyChildren;
2036
2037 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2038 Object* grandChild = expandBufGetEntry(pList, i);
2039
2040 if (!objectInChildList(parent, grandChild)) {
2041 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
2042 linkParentToChild(parent, grandChild);
2043 } else {
2044 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
2045 }
2046 }
2047}
2048
2049/*
2050 * An object with a fat lock is being collected during a GC pass. We
2051 * want to remove it from any lock history trees that it is a part of.
2052 *
2053 * This may require updating the history trees in several monitors. The
2054 * monitor semantics guarantee that no other thread will be accessing
2055 * the history trees at the same time.
2056 */
2057static void removeCollectedObject(Object* obj)
2058{
2059 Monitor* mon;
2060
2061 LOGVV("+++ collecting %p\n", obj);
2062
2063#if 0
2064 /*
2065 * We're currently running through the entire set of known monitors.
2066 * This can be somewhat slow. We may want to keep lists of parents
2067 * in each child to speed up GC.
2068 */
2069 mon = gDvm.monitorList;
2070 while (mon != NULL) {
2071 Object* parent = mon->obj;
2072 if (parent != NULL) { /* value nulled for deleted entries */
2073 if (objectInChildList(parent, obj)) {
2074 LOGVV("removing child %p from parent %p\n", obj, parent);
2075 unlinkParentFromChild(parent, obj);
2076 mergeChildren(parent, obj);
2077 }
2078 }
2079 mon = mon->next;
2080 }
2081#endif
2082
2083 /*
2084 * For every parent of this object:
2085 * - merge all of our children into the parent's child list (creates
2086 * a two-way link between parent and child)
2087 * - remove ourselves from the parent's child list
2088 */
2089 ExpandingObjectList* pList;
2090 int i;
2091
2092 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002093 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002094 pList = &mon->historyParents;
2095 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2096 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002097 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002098
2099 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2100 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2101 }
2102 assert(!expandObjHas(&parentMon->historyChildren, obj));
2103
2104 mergeChildren(parent, obj);
2105 }
2106
2107 /*
2108 * For every child of this object:
2109 * - remove ourselves from the child's parent list
2110 */
2111 pList = &mon->historyChildren;
2112 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2113 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002114 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002115
2116 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2117 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2118 }
2119 assert(!expandObjHas(&childMon->historyParents, obj));
2120 }
2121}
2122
2123#endif /*WITH_DEADLOCK_PREDICTION*/