blob: 1405315f6c9cecc3470af638f9c6469cd28b67bd [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
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 Shapiro6b4ba582010-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 Shapiro6b4ba582010-04-09 15:03:33 -0700433 Thread *owner;
434 ThreadStatus oldStatus;
435 u4 waitThreshold, samplePercent;
436 u8 waitStart, waitEnd, waitMs;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800437
438 if (mon->owner == self) {
439 mon->lockCount++;
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700440 return;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800441 }
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700442 if (pthread_mutex_trylock(&mon->lock) != 0) {
443 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
444 waitThreshold = gDvm.lockProfThreshold;
445 if (waitThreshold) {
446 waitStart = dvmGetRelativeTimeUsec();
447 }
448 dvmLockMutex(&mon->lock);
449 if (waitThreshold) {
450 waitEnd = dvmGetRelativeTimeUsec();
451 }
452 dvmChangeStatus(self, oldStatus);
453 if (waitThreshold) {
454 waitMs = (waitEnd - waitStart) / 1000;
455 if (waitMs >= waitThreshold) {
456 samplePercent = 100;
457 } else {
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700458 samplePercent = 100 * waitMs / waitThreshold;
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700459 }
Carl Shapirob8fcf572010-04-16 17:33:15 -0700460 if (samplePercent != 0 && ((u4)rand() % 100 < samplePercent)) {
Carl Shapiro6b4ba582010-04-09 15:03:33 -0700461 logContentionEvent(self, waitMs, samplePercent);
462 }
463 }
464 }
465 mon->owner = self;
466 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800467}
468
469/*
470 * Try to lock a monitor.
471 *
472 * Returns "true" on success.
473 */
474static bool tryLockMonitor(Thread* self, Monitor* mon)
475{
476 int cc;
477
478 if (mon->owner == self) {
479 mon->lockCount++;
480 return true;
481 } else {
482 cc = pthread_mutex_trylock(&mon->lock);
483 if (cc == 0) {
484 mon->owner = self;
485 assert(mon->lockCount == 0);
486 return true;
487 } else {
488 return false;
489 }
490 }
491}
492
493
494/*
495 * Unlock a monitor.
496 *
497 * Returns true if the unlock succeeded.
498 * If the unlock failed, an exception will be pending.
499 */
500static bool unlockMonitor(Thread* self, Monitor* mon)
501{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800502 assert(self != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800503 assert(mon != NULL); // can this happen?
504
505 if (mon->owner == self) {
506 /*
507 * We own the monitor, so nobody else can be in here.
508 */
509 if (mon->lockCount == 0) {
510 int cc;
511 mon->owner = NULL;
512 cc = pthread_mutex_unlock(&mon->lock);
513 assert(cc == 0);
514 } else {
515 mon->lockCount--;
516 }
517 } else {
518 /*
519 * We don't own this, so we're not allowed to unlock it.
520 * The JNI spec says that we should throw IllegalMonitorStateException
521 * in this case.
522 */
Carl Shapiroe11f3fd2010-02-24 02:30:55 -0800523 dvmThrowExceptionFmt("Ljava/lang/IllegalMonitorStateException;",
524 "unlock of unowned monitor, self=%d owner=%d",
Carl Shapirob8fcf572010-04-16 17:33:15 -0700525 self->threadId,
Carl Shapiroe11f3fd2010-02-24 02:30:55 -0800526 mon->owner ? mon->owner->threadId : 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800527 return false;
528 }
529 return true;
530}
531
532/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800533 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800534 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800535 */
536static int waitSetCheck(Monitor *mon)
537{
538 Thread *fast, *slow;
539 size_t n;
540
541 assert(mon != NULL);
542 fast = slow = mon->waitSet;
543 n = 0;
544 for (;;) {
545 if (fast == NULL) return 0;
546 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800547 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800548 n += 2;
549 fast = fast->waitNext->waitNext;
550 slow = slow->waitNext;
551 }
552}
553
554/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800555 * Links a thread into a monitor's wait set. The monitor lock must be
556 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800557 */
558static void waitSetAppend(Monitor *mon, Thread *thread)
559{
560 Thread *elt;
561
562 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800563 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800564 assert(thread != NULL);
565 assert(thread->waitNext == NULL);
566 assert(waitSetCheck(mon) == 0);
567 if (mon->waitSet == NULL) {
568 mon->waitSet = thread;
569 return;
570 }
571 elt = mon->waitSet;
572 while (elt->waitNext != NULL) {
573 elt = elt->waitNext;
574 }
575 elt->waitNext = thread;
576}
577
578/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800579 * Unlinks a thread from a monitor's wait set. The monitor lock must
580 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800581 */
582static void waitSetRemove(Monitor *mon, Thread *thread)
583{
584 Thread *elt;
585
586 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800587 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800588 assert(thread != NULL);
589 assert(waitSetCheck(mon) == 0);
590 if (mon->waitSet == NULL) {
591 return;
592 }
593 if (mon->waitSet == thread) {
594 mon->waitSet = thread->waitNext;
595 thread->waitNext = NULL;
596 return;
597 }
598 elt = mon->waitSet;
599 while (elt->waitNext != NULL) {
600 if (elt->waitNext == thread) {
601 elt->waitNext = thread->waitNext;
602 thread->waitNext = NULL;
603 return;
604 }
605 elt = elt->waitNext;
606 }
607}
608
Carl Shapirob4539192010-01-04 16:50:00 -0800609/*
610 * Converts the given relative waiting time into an absolute time.
611 */
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800612void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800613{
614 s8 endSec;
615
616#ifdef HAVE_TIMEDWAIT_MONOTONIC
617 clock_gettime(CLOCK_MONOTONIC, ts);
618#else
619 {
620 struct timeval tv;
621 gettimeofday(&tv, NULL);
622 ts->tv_sec = tv.tv_sec;
623 ts->tv_nsec = tv.tv_usec * 1000;
624 }
625#endif
626 endSec = ts->tv_sec + msec / 1000;
627 if (endSec >= 0x7fffffff) {
628 LOGV("NOTE: end time exceeds epoch\n");
629 endSec = 0x7ffffffe;
630 }
631 ts->tv_sec = endSec;
632 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
633
634 /* catch rollover */
635 if (ts->tv_nsec >= 1000000000L) {
636 ts->tv_sec++;
637 ts->tv_nsec -= 1000000000L;
638 }
639}
640
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800641int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
642 s8 msec, s4 nsec)
643{
644 int ret;
645 struct timespec ts;
646 absoluteTime(msec, nsec, &ts);
647#if defined(HAVE_TIMEDWAIT_MONOTONIC)
648 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
649#else
650 ret = pthread_cond_timedwait(cond, mutex, &ts);
651#endif
652 assert(ret == 0 || ret == ETIMEDOUT);
653 return ret;
654}
655
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800656/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800657 * Wait on a monitor until timeout, interrupt, or notification. Used for
658 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
659 *
660 * If another thread calls Thread.interrupt(), we throw InterruptedException
661 * and return immediately if one of the following are true:
662 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
663 * - blocked in join(), join(long), or join(long, int) methods of Thread
664 * - blocked in sleep(long), or sleep(long, int) methods of Thread
665 * Otherwise, we set the "interrupted" flag.
666 *
667 * Checks to make sure that "nsec" is in the range 0-999999
668 * (i.e. fractions of a millisecond) and throws the appropriate
669 * exception if it isn't.
670 *
671 * The spec allows "spurious wakeups", and recommends that all code using
672 * Object.wait() do so in a loop. This appears to derive from concerns
673 * about pthread_cond_wait() on multiprocessor systems. Some commentary
674 * on the web casts doubt on whether these can/should occur.
675 *
676 * Since we're allowed to wake up "early", we clamp extremely long durations
677 * to return at the end of the 32-bit time epoch.
678 */
679static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
680 bool interruptShouldThrow)
681{
682 struct timespec ts;
683 bool wasInterrupted = false;
684 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800685 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800686
Carl Shapiro71938022009-12-22 13:49:53 -0800687 assert(self != NULL);
688 assert(mon != NULL);
689
Carl Shapiro94338aa2009-12-21 11:42:59 -0800690 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800691 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800692 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
693 "object not locked by thread before wait()");
694 return;
695 }
696
697 /*
698 * Enforce the timeout range.
699 */
700 if (msec < 0 || nsec < 0 || nsec > 999999) {
701 dvmThrowException("Ljava/lang/IllegalArgumentException;",
702 "timeout arguments out of range");
703 return;
704 }
705
706 /*
707 * Compute absolute wakeup time, if necessary.
708 */
709 if (msec == 0 && nsec == 0) {
710 timed = false;
711 } else {
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800712 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800713 timed = true;
714 }
715
716 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800717 * Add ourselves to the set of threads waiting on this monitor, and
718 * release our hold. We need to let it go even if we're a few levels
719 * deep in a recursive lock, and we need to restore that later.
720 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800721 * We append to the wait set ahead of clearing the count and owner
722 * fields so the subroutine can check that the calling thread owns
723 * the monitor. Aside from that, the order of member updates is
724 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800725 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800726 waitSetAppend(mon, self);
727 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800728 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800729 mon->owner = NULL;
730
731 /*
732 * Update thread status. If the GC wakes up, it'll ignore us, knowing
733 * that we won't touch any references in this state, and we'll check
734 * our suspend mode before we transition out.
735 */
736 if (timed)
737 dvmChangeStatus(self, THREAD_TIMED_WAIT);
738 else
739 dvmChangeStatus(self, THREAD_WAIT);
740
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800741 ret = pthread_mutex_lock(&self->waitMutex);
742 assert(ret == 0);
743
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800744 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800745 * Set waitMonitor to the monitor object we will be waiting on.
746 * When waitMonitor is non-NULL a notifying or interrupting thread
747 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800748 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800749 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800750 self->waitMonitor = mon;
751
752 /*
753 * Handle the case where the thread was interrupted before we called
754 * wait().
755 */
756 if (self->interrupted) {
757 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800758 self->waitMonitor = NULL;
759 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800760 goto done;
761 }
762
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800763 /*
764 * Release the monitor lock and wait for a notification or
765 * a timeout to occur.
766 */
767 pthread_mutex_unlock(&mon->lock);
768
769 if (!timed) {
770 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
771 assert(ret == 0);
772 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800773#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800774 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800775#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800776 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800777#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800778 assert(ret == 0 || ret == ETIMEDOUT);
779 }
780 if (self->interrupted) {
781 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800782 }
783
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800784 self->interrupted = false;
785 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800786
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800787 pthread_mutex_unlock(&self->waitMutex);
788
Carl Shapiro30aa9972010-01-13 22:07:50 -0800789 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800790 lockMonitor(self, mon);
791
Carl Shapiro142ef272010-01-25 12:51:31 -0800792done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800793 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800794 * We remove our thread from wait set after restoring the count
795 * and owner fields so the subroutine can check that the calling
796 * thread owns the monitor. Aside from that, the order of member
797 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800798 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800799 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800800 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800801 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800802
803 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
804 dvmChangeStatus(self, THREAD_RUNNING);
805
806 if (wasInterrupted) {
807 /*
808 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800809 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800810 *
811 * The doc sayeth: "The interrupted status of the current thread is
812 * cleared when this exception is thrown."
813 */
814 self->interrupted = false;
815 if (interruptShouldThrow)
816 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
817 }
818}
819
820/*
821 * Notify one thread waiting on this monitor.
822 */
823static void notifyMonitor(Thread* self, Monitor* mon)
824{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800825 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800826
Carl Shapiro71938022009-12-22 13:49:53 -0800827 assert(self != NULL);
828 assert(mon != NULL);
829
Carl Shapiro94338aa2009-12-21 11:42:59 -0800830 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800831 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800832 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
833 "object not locked by thread before notify()");
834 return;
835 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800836 /* Signal the first waiting thread in the wait set. */
837 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800838 thread = mon->waitSet;
839 mon->waitSet = thread->waitNext;
840 thread->waitNext = NULL;
841 pthread_mutex_lock(&thread->waitMutex);
842 /* Check to see if the thread is still waiting. */
843 if (thread->waitMonitor != NULL) {
844 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800845 pthread_mutex_unlock(&thread->waitMutex);
846 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800847 }
848 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800849 }
850}
851
852/*
853 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800854 */
855static void notifyAllMonitor(Thread* self, Monitor* mon)
856{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800857 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800858
Carl Shapiro71938022009-12-22 13:49:53 -0800859 assert(self != NULL);
860 assert(mon != NULL);
861
Carl Shapiro94338aa2009-12-21 11:42:59 -0800862 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800863 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800864 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
865 "object not locked by thread before notifyAll()");
866 return;
867 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800868 /* Signal all threads in the wait set. */
869 while (mon->waitSet != NULL) {
870 thread = mon->waitSet;
871 mon->waitSet = thread->waitNext;
872 thread->waitNext = NULL;
873 pthread_mutex_lock(&thread->waitMutex);
874 /* Check to see if the thread is still waiting. */
875 if (thread->waitMonitor != NULL) {
876 pthread_cond_signal(&thread->waitCond);
877 }
878 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800879 }
880}
881
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800882/*
883 * Implements monitorenter for "synchronized" stuff.
884 *
885 * This does not fail or throw an exception (unless deadlock prediction
886 * is enabled and set to "err" mode).
887 */
888void dvmLockObject(Thread* self, Object *obj)
889{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800890 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800891 Monitor *mon;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800892 ThreadStatus oldStatus;
893 useconds_t sleepDelay;
894 const useconds_t maxSleepDelay = 1 << 20;
895 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800896
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800897 assert(self != NULL);
898 assert(obj != NULL);
899 threadId = self->threadId;
900 thinp = &obj->lock;
901retry:
902 thin = *thinp;
903 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
904 /*
905 * The lock is a thin lock. The owner field is used to
906 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800907 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800908 if (LW_LOCK_OWNER(thin) == threadId) {
909 /*
910 * The calling thread owns the lock. Increment the
911 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800912 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800913 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
914 } else if (LW_LOCK_OWNER(thin) == 0) {
915 /*
916 * The lock is unowned. Install the thread id of the
917 * calling thread into the owner field. This is the
918 * common case. In performance critical code the JIT
919 * will have tried this before calling out to the VM.
920 */
921 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
922 if (!ATOMIC_CMP_SWAP((int32_t *)thinp, thin, newThin)) {
923 /*
924 * The acquire failed. Try again.
925 */
926 goto retry;
927 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800928 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800929 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
930 threadId, &obj->lock, 0, *thinp, thin);
931 /*
932 * The lock is owned by another thread. Notify the VM
933 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800934 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800935 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
936 /*
937 * Spin until the thin lock is released or inflated.
938 */
939 sleepDelay = 0;
940 for (;;) {
941 thin = *thinp;
942 /*
943 * Check the shape of the lock word. Another thread
944 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800945 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800946 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
947 if (LW_LOCK_OWNER(thin) == 0) {
948 /*
949 * The lock has been released. Install the
950 * thread id of the calling thread into the
951 * owner field.
952 */
953 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
954 if (ATOMIC_CMP_SWAP((int32_t *)thinp,
955 thin, newThin)) {
956 /*
957 * The acquire succeed. Break out of the
958 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800959 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800960 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800961 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800962 } else {
963 /*
964 * The lock has not been released. Yield so
965 * the owning thread can run.
966 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800967 if (sleepDelay == 0) {
968 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800969 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800970 } else {
971 usleep(sleepDelay);
972 if (sleepDelay < maxSleepDelay / 2) {
973 sleepDelay *= 2;
974 }
975 }
976 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800977 } else {
978 /*
979 * The thin lock was inflated by another thread.
980 * Let the VM know we are no longer waiting and
981 * try again.
982 */
983 LOG_THIN("(%d) lock %p surprise-fattened",
984 threadId, &obj->lock);
985 dvmChangeStatus(self, oldStatus);
986 goto retry;
987 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800988 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800989 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
990 threadId, &obj->lock, 0, *thinp, thin);
991 /*
992 * We have acquired the thin lock. Let the VM know that
993 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800994 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800995 dvmChangeStatus(self, oldStatus);
996 /*
997 * Fatten the lock.
998 */
999 mon = dvmCreateMonitor(obj);
1000 lockMonitor(self, mon);
1001 thin = *thinp;
1002 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
1003 thin |= (u4)mon | LW_SHAPE_FAT;
1004 MEM_BARRIER();
1005 obj->lock = thin;
1006 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001007 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001008 } else {
1009 /*
1010 * The lock is a fat lock.
1011 */
1012 assert(LW_MONITOR(obj->lock) != NULL);
1013 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001014 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001015#ifdef WITH_DEADLOCK_PREDICTION
1016 /*
1017 * See if we were allowed to grab the lock at this time. We do it
1018 * *after* acquiring the lock, rather than before, so that we can
1019 * freely update the Monitor struct. This seems counter-intuitive,
1020 * but our goal is deadlock *prediction* not deadlock *prevention*.
1021 * (If we actually deadlock, the situation is easy to diagnose from
1022 * a thread dump, so there's no point making a special effort to do
1023 * the checks before the lock is held.)
1024 *
1025 * This needs to happen before we add the object to the thread's
1026 * monitor list, so we can tell the difference between first-lock and
1027 * re-lock.
1028 *
1029 * It's also important that we do this while in THREAD_RUNNING, so
1030 * that we don't interfere with cleanup operations in the GC.
1031 */
1032 if (gDvm.deadlockPredictMode != kDPOff) {
1033 if (self->status != THREAD_RUNNING) {
1034 LOGE("Bad thread status (%d) in DP\n", self->status);
1035 dvmDumpThread(self, false);
1036 dvmAbort();
1037 }
1038 assert(!dvmCheckException(self));
1039 updateDeadlockPrediction(self, obj);
1040 if (dvmCheckException(self)) {
1041 /*
1042 * If we're throwing an exception here, we need to free the
1043 * lock. We add the object to the thread's monitor list so the
1044 * "unlock" code can remove it.
1045 */
1046 dvmAddToMonitorList(self, obj, false);
1047 dvmUnlockObject(self, obj);
1048 LOGV("--- unlocked, pending is '%s'\n",
1049 dvmGetException(self)->clazz->descriptor);
1050 }
1051 }
1052
1053 /*
1054 * Add the locked object, and the current stack trace, to the list
1055 * held by the Thread object. If deadlock prediction isn't on,
1056 * don't capture the stack trace.
1057 */
1058 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
1059#elif defined(WITH_MONITOR_TRACKING)
1060 /*
1061 * Add the locked object to the list held by the Thread object.
1062 */
1063 dvmAddToMonitorList(self, obj, false);
1064#endif
1065}
1066
1067/*
1068 * Implements monitorexit for "synchronized" stuff.
1069 *
1070 * On failure, throws an exception and returns "false".
1071 */
1072bool dvmUnlockObject(Thread* self, Object *obj)
1073{
Carl Shapiro94338aa2009-12-21 11:42:59 -08001074 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001075
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001076 assert(self != NULL);
1077 assert(self->status == THREAD_RUNNING);
1078 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001079 /*
1080 * Cache the lock word as its value can change while we are
1081 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001082 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001083 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001084 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
1085 /*
1086 * The lock is thin. We must ensure that the lock is owned
1087 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001088 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001089 if (LW_LOCK_OWNER(thin) == self->threadId) {
1090 /*
1091 * We are the lock owner. It is safe to update the lock
1092 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001093 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001094 if (LW_LOCK_COUNT(thin) == 0) {
1095 /*
1096 * The lock was not recursively acquired, the common
1097 * case. Unlock by clearing all bits except for the
1098 * hash state.
1099 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001100 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001101 } else {
1102 /*
1103 * The object was recursively acquired. Decrement the
1104 * lock recursion count field.
1105 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001106 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001107 }
1108 } else {
1109 /*
1110 * We do not own the lock. The JVM spec requires that we
1111 * throw an exception in this case.
1112 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001113 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001114 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001115 return false;
1116 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001117 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001118 /*
1119 * The lock is fat. We must check to see if unlockMonitor has
1120 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001121 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001122 assert(LW_MONITOR(obj->lock) != NULL);
1123 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001124 /*
1125 * An exception has been raised. Do not fall through.
1126 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001127 return false;
1128 }
1129 }
1130
1131#ifdef WITH_MONITOR_TRACKING
1132 /*
1133 * Remove the object from the Thread's list.
1134 */
1135 dvmRemoveFromMonitorList(self, obj);
1136#endif
1137
1138 return true;
1139}
1140
1141/*
1142 * Object.wait(). Also called for class init.
1143 */
1144void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1145 bool interruptShouldThrow)
1146{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001147 Monitor* mon = LW_MONITOR(obj->lock);
1148 u4 hashState;
1149 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001150
1151 /* If the lock is still thin, we need to fatten it.
1152 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001153 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001154 /* Make sure that 'self' holds the lock.
1155 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001156 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001157 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1158 "object not locked by thread before wait()");
1159 return;
1160 }
1161
1162 /* This thread holds the lock. We need to fatten the lock
1163 * so 'self' can block on it. Don't update the object lock
1164 * field yet, because 'self' needs to acquire the lock before
1165 * any other thread gets a chance.
1166 */
1167 mon = dvmCreateMonitor(obj);
1168
1169 /* 'self' has actually locked the object one or more times;
1170 * make sure that the monitor reflects this.
1171 */
1172 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001173 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001174 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1175 self->threadId, (uint)&obj->lock, mon->lockCount);
1176
Andy McFadden581bed72009-10-15 11:24:54 -07001177
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001178 /* Make the monitor public now that it's in the right state.
1179 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001180 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
1181 thin |= (u4)mon | LW_SHAPE_FAT;
Andy McFadden581bed72009-10-15 11:24:54 -07001182 MEM_BARRIER();
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001183 obj->lock = thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001184 }
1185
1186 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1187}
1188
1189/*
1190 * Object.notify().
1191 */
1192void dvmObjectNotify(Thread* self, Object *obj)
1193{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001194 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001195
1196 /* If the lock is still thin, there aren't any waiters;
1197 * waiting on an object forces lock fattening.
1198 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001199 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001200 /* Make sure that 'self' holds the lock.
1201 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001202 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001203 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1204 "object not locked by thread before notify()");
1205 return;
1206 }
1207
1208 /* no-op; there are no waiters to notify.
1209 */
1210 } else {
1211 /* It's a fat lock.
1212 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001213 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001214 }
1215}
1216
1217/*
1218 * Object.notifyAll().
1219 */
1220void dvmObjectNotifyAll(Thread* self, Object *obj)
1221{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001222 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001223
1224 /* If the lock is still thin, there aren't any waiters;
1225 * waiting on an object forces lock fattening.
1226 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001227 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001228 /* Make sure that 'self' holds the lock.
1229 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001230 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001231 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1232 "object not locked by thread before notifyAll()");
1233 return;
1234 }
1235
1236 /* no-op; there are no waiters to notify.
1237 */
1238 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001239 /* It's a fat lock.
1240 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001241 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001242 }
1243}
1244
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001245/*
1246 * This implements java.lang.Thread.sleep(long msec, int nsec).
1247 *
1248 * The sleep is interruptible by other threads, which means we can't just
1249 * plop into an OS sleep call. (We probably could if we wanted to send
1250 * signals around and rely on EINTR, but that's inefficient and relies
1251 * on native code respecting our signal mask.)
1252 *
1253 * We have to do all of this stuff for Object.wait() as well, so it's
1254 * easiest to just sleep on a private Monitor.
1255 *
1256 * It appears that we want sleep(0,0) to go through the motions of sleeping
1257 * for a very short duration, rather than just returning.
1258 */
1259void dvmThreadSleep(u8 msec, u4 nsec)
1260{
1261 Thread* self = dvmThreadSelf();
1262 Monitor* mon = gDvm.threadSleepMon;
1263
1264 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1265 if (msec == 0 && nsec == 0)
1266 nsec++;
1267
1268 lockMonitor(self, mon);
1269 waitMonitor(self, mon, msec, nsec, true);
1270 unlockMonitor(self, mon);
1271}
1272
1273/*
1274 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001275 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001276void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001277{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001278 assert(thread != NULL);
1279
1280 pthread_mutex_lock(&thread->waitMutex);
1281
1282 /*
1283 * If the interrupted flag is already set no additional action is
1284 * required.
1285 */
1286 if (thread->interrupted == true) {
1287 pthread_mutex_unlock(&thread->waitMutex);
1288 return;
1289 }
1290
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001291 /*
1292 * Raise the "interrupted" flag. This will cause it to bail early out
1293 * of the next wait() attempt, if it's not currently waiting on
1294 * something.
1295 */
1296 thread->interrupted = true;
1297 MEM_BARRIER();
1298
1299 /*
1300 * Is the thread waiting?
1301 *
1302 * Note that fat vs. thin doesn't matter here; waitMonitor
1303 * is only set when a thread actually waits on a monitor,
1304 * which implies that the monitor has already been fattened.
1305 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001306 if (thread->waitMonitor != NULL) {
1307 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001308 }
1309
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001310 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001311}
1312
Carl Shapiro30aa9972010-01-13 22:07:50 -08001313#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001314u4 dvmIdentityHashCode(Object *obj)
1315{
1316 return (u4)obj;
1317}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001318#else
1319static size_t arrayElementWidth(const ArrayObject *array)
1320{
1321 const char *descriptor;
1322
1323 if (dvmIsObjectArray(array)) {
1324 return sizeof(Object *);
1325 } else {
1326 descriptor = array->obj.clazz->descriptor;
1327 switch (descriptor[1]) {
1328 case 'B': return 1; /* byte */
1329 case 'C': return 2; /* char */
1330 case 'D': return 8; /* double */
1331 case 'F': return 4; /* float */
1332 case 'I': return 4; /* int */
1333 case 'J': return 8; /* long */
1334 case 'S': return 2; /* short */
1335 case 'Z': return 1; /* boolean */
1336 }
1337 }
1338 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1339 dvmDumpThread(dvmThreadSelf(), false);
1340 dvmAbort();
1341 return 0; /* Quiet the compiler. */
1342}
1343
1344static size_t arrayObjectLength(const ArrayObject *array)
1345{
1346 size_t length;
1347
1348 length = offsetof(ArrayObject, contents);
1349 length += array->length * arrayElementWidth(array);
1350 return length;
1351}
1352
1353/*
1354 * Returns the identity hash code of the given object.
1355 */
1356u4 dvmIdentityHashCode(Object *obj)
1357{
1358 Thread *self, *thread;
1359 volatile u4 *lw;
1360 size_t length;
1361 u4 lock, owner, hashState;
1362
1363 if (obj == NULL) {
1364 /*
1365 * Null is defined to have an identity hash code of 0.
1366 */
1367 return 0;
1368 }
1369 lw = &obj->lock;
1370retry:
1371 hashState = LW_HASH_STATE(*lw);
1372 if (hashState == LW_HASH_STATE_HASHED) {
1373 /*
1374 * The object has been hashed but has not had its hash code
1375 * relocated by the garbage collector. Use the raw object
1376 * address.
1377 */
1378 return (u4)obj >> 3;
1379 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1380 /*
1381 * The object has been hashed and its hash code has been
1382 * relocated by the collector. Use the value of the naturally
1383 * aligned word following the instance data.
1384 */
1385 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1386 length = arrayObjectLength((ArrayObject *)obj);
1387 length = (length + 3) & ~3;
1388 } else {
1389 length = obj->clazz->objectSize;
1390 }
1391 return *(u4 *)(((char *)obj) + length);
1392 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1393 /*
1394 * The object has never been hashed. Change the hash state to
1395 * hashed and use the raw object address.
1396 */
1397 self = dvmThreadSelf();
1398 if (self->threadId == lockOwner(obj)) {
1399 /*
1400 * We already own the lock so we can update the hash state
1401 * directly.
1402 */
1403 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1404 return (u4)obj >> 3;
1405 }
1406 /*
1407 * We do not own the lock. Try acquiring the lock. Should
1408 * this fail, we must suspend the owning thread.
1409 */
1410 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1411 /*
1412 * If the lock is thin assume it is unowned. We simulate
1413 * an acquire, update, and release with a single CAS.
1414 */
1415 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1416 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1417 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1418 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1419 (int32_t)lock)) {
1420 /*
1421 * A new lockword has been installed with a hash state
1422 * of hashed. Use the raw object address.
1423 */
1424 return (u4)obj >> 3;
1425 }
1426 } else {
1427 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1428 /*
1429 * The monitor lock has been acquired. Change the
1430 * hash state to hashed and use the raw object
1431 * address.
1432 */
1433 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1434 unlockMonitor(self, LW_MONITOR(*lw));
1435 return (u4)obj >> 3;
1436 }
1437 }
1438 /*
1439 * At this point we have failed to acquire the lock. We must
1440 * identify the owning thread and suspend it.
1441 */
1442 dvmLockThreadList(self);
1443 /*
1444 * Cache the lock word as its value can change between
1445 * determining its shape and retrieving its owner.
1446 */
1447 lock = *lw;
1448 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1449 /*
1450 * Find the thread with the corresponding thread id.
1451 */
1452 owner = LW_LOCK_OWNER(lock);
1453 assert(owner != self->threadId);
1454 /*
1455 * If the lock has no owner do not bother scanning the
1456 * thread list and fall through to the failure handler.
1457 */
1458 thread = owner ? gDvm.threadList : NULL;
1459 while (thread != NULL) {
1460 if (thread->threadId == owner) {
1461 break;
1462 }
1463 thread = thread->next;
1464 }
1465 } else {
1466 thread = LW_MONITOR(lock)->owner;
1467 }
1468 /*
1469 * If thread is NULL the object has been released since the
1470 * thread list lock was acquired. Try again.
1471 */
1472 if (thread == NULL) {
1473 dvmUnlockThreadList();
1474 goto retry;
1475 }
1476 /*
1477 * Wait for the owning thread to suspend.
1478 */
1479 dvmSuspendThread(thread);
1480 if (dvmHoldsLock(thread, obj)) {
1481 /*
1482 * The owning thread has been suspended. We can safely
1483 * change the hash state to hashed.
1484 */
1485 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1486 dvmResumeThread(thread);
1487 dvmUnlockThreadList();
1488 return (u4)obj >> 3;
1489 }
1490 /*
1491 * The wrong thread has been suspended. Try again.
1492 */
1493 dvmResumeThread(thread);
1494 dvmUnlockThreadList();
1495 goto retry;
1496 }
1497 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1498 dvmDumpThread(dvmThreadSelf(), false);
1499 dvmAbort();
1500 return 0; /* Quiet the compiler. */
1501}
1502#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001503
1504#ifdef WITH_DEADLOCK_PREDICTION
1505/*
1506 * ===========================================================================
1507 * Deadlock prediction
1508 * ===========================================================================
1509 */
1510/*
1511The idea is to predict the possibility of deadlock by recording the order
1512in which monitors are acquired. If we see an attempt to acquire a lock
1513out of order, we can identify the locks and offending code.
1514
1515To make this work, we need to keep track of the locks held by each thread,
1516and create history trees for each lock. When a thread tries to acquire
1517a new lock, we walk through the "history children" of the lock, looking
1518for a match with locks the thread already holds. If we find a match,
1519it means the thread has made a request that could result in a deadlock.
1520
1521To support recursive locks, we always allow re-locking a currently-held
1522lock, and maintain a recursion depth count.
1523
1524An ASCII-art example, where letters represent Objects:
1525
1526 A
1527 /|\
1528 / | \
1529 B | D
1530 \ |
1531 \|
1532 C
1533
1534The above is the tree we'd have after handling Object synchronization
1535sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1536a child of B. (The lines represent pointers between parent and child.
1537Every node can have multiple parents and multiple children.)
1538
1539If we hold AC, and want to lock B, we recursively search through B's
1540children to see if A or C appears. It does, so we reject the attempt.
1541(A straightforward way to implement it: add a link from C to B, then
1542determine whether the graph starting at B contains a cycle.)
1543
1544If we hold AC and want to lock D, we would succeed, creating a new link
1545from C to D.
1546
1547The lock history and a stack trace is attached to the Object's Monitor
1548struct, which means we need to fatten every Object we lock (thin locking
1549is effectively disabled). If we don't need the stack trace we can
1550avoid fattening the leaf nodes, only fattening objects that need to hold
1551history trees.
1552
1553Updates to Monitor structs are only allowed for the thread that holds
1554the Monitor, so we actually do most of our deadlock prediction work after
1555the lock has been acquired.
1556
1557When an object with a monitor is GCed, we need to remove it from the
1558history trees. There are two basic approaches:
1559 (1) For through the entire set of known monitors, search all child
1560 lists for the object in question. This is rather slow, resulting
1561 in GC passes that take upwards of 10 seconds to complete.
1562 (2) Maintain "parent" pointers in each node. Remove the entries as
1563 required. This requires additional storage and maintenance for
1564 every operation, but is significantly faster at GC time.
1565For each GCed object, we merge all of the object's children into each of
1566the object's parents.
1567*/
1568
1569#if !defined(WITH_MONITOR_TRACKING)
1570# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1571#endif
1572
1573/*
1574 * Clear out the contents of an ExpandingObjectList, freeing any
1575 * dynamic allocations.
1576 */
1577static void expandObjClear(ExpandingObjectList* pList)
1578{
1579 if (pList->list != NULL) {
1580 free(pList->list);
1581 pList->list = NULL;
1582 }
1583 pList->alloc = pList->count = 0;
1584}
1585
1586/*
1587 * Get the number of objects currently stored in the list.
1588 */
1589static inline int expandBufGetCount(const ExpandingObjectList* pList)
1590{
1591 return pList->count;
1592}
1593
1594/*
1595 * Get the Nth entry from the list.
1596 */
1597static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1598 int i)
1599{
1600 return pList->list[i];
1601}
1602
1603/*
1604 * Add a new entry to the list.
1605 *
1606 * We don't check for or try to enforce uniqueness. It's expected that
1607 * the higher-level code does this for us.
1608 */
1609static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1610{
1611 if (pList->count == pList->alloc) {
1612 /* time to expand */
1613 Object** newList;
1614
1615 if (pList->alloc == 0)
1616 pList->alloc = 4;
1617 else
1618 pList->alloc *= 2;
1619 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1620 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1621 if (newList == NULL) {
1622 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1623 dvmAbort();
1624 }
1625 pList->list = newList;
1626 }
1627
1628 pList->list[pList->count++] = obj;
1629}
1630
1631/*
1632 * Returns "true" if the element was successfully removed.
1633 */
1634static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1635{
1636 int i;
1637
1638 for (i = pList->count-1; i >= 0; i--) {
1639 if (pList->list[i] == obj)
1640 break;
1641 }
1642 if (i < 0)
1643 return false;
1644
1645 if (i != pList->count-1) {
1646 /*
1647 * The order of elements is not important, so we just copy the
1648 * last entry into the new slot.
1649 */
1650 //memmove(&pList->list[i], &pList->list[i+1],
1651 // (pList->count-1 - i) * sizeof(pList->list[0]));
1652 pList->list[i] = pList->list[pList->count-1];
1653 }
1654
1655 pList->count--;
1656 pList->list[pList->count] = (Object*) 0xdecadead;
1657 return true;
1658}
1659
1660/*
1661 * Returns "true" if "obj" appears in the list.
1662 */
1663static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1664{
1665 int i;
1666
1667 for (i = 0; i < pList->count; i++) {
1668 if (pList->list[i] == obj)
1669 return true;
1670 }
1671 return false;
1672}
1673
1674/*
1675 * Print the list contents to stdout. For debugging.
1676 */
1677static void expandObjDump(const ExpandingObjectList* pList)
1678{
1679 int i;
1680 for (i = 0; i < pList->count; i++)
1681 printf(" %p", pList->list[i]);
1682}
1683
1684/*
1685 * Check for duplicate entries. Returns the index of the first instance
1686 * of the duplicated value, or -1 if no duplicates were found.
1687 */
1688static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1689{
1690 int i, j;
1691 for (i = 0; i < pList->count-1; i++) {
1692 for (j = i + 1; j < pList->count; j++) {
1693 if (pList->list[i] == pList->list[j]) {
1694 return i;
1695 }
1696 }
1697 }
1698
1699 return -1;
1700}
1701
1702
1703/*
1704 * Determine whether "child" appears in the list of objects associated
1705 * with the Monitor in "parent". If "parent" is a thin lock, we return
1706 * false immediately.
1707 */
1708static bool objectInChildList(const Object* parent, Object* child)
1709{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001710 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001711 if (!IS_LOCK_FAT(&lock)) {
1712 //LOGI("on thin\n");
1713 return false;
1714 }
1715
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001716 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001717}
1718
1719/*
1720 * Print the child list.
1721 */
1722static void dumpKids(Object* parent)
1723{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001724 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001725
1726 printf("Children of %p:", parent);
1727 expandObjDump(&mon->historyChildren);
1728 printf("\n");
1729}
1730
1731/*
1732 * Add "child" to the list of children in "parent", and add "parent" to
1733 * the list of parents in "child".
1734 */
1735static void linkParentToChild(Object* parent, Object* child)
1736{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001737 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001738 assert(IS_LOCK_FAT(&parent->lock));
1739 assert(IS_LOCK_FAT(&child->lock));
1740 assert(parent != child);
1741 Monitor* mon;
1742
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001743 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001744 assert(!expandObjHas(&mon->historyChildren, child));
1745 expandObjAddEntry(&mon->historyChildren, child);
1746
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001747 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001748 assert(!expandObjHas(&mon->historyParents, parent));
1749 expandObjAddEntry(&mon->historyParents, parent);
1750}
1751
1752
1753/*
1754 * Remove "child" from the list of children in "parent".
1755 */
1756static void unlinkParentFromChild(Object* parent, Object* child)
1757{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001758 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001759 assert(IS_LOCK_FAT(&parent->lock));
1760 assert(IS_LOCK_FAT(&child->lock));
1761 assert(parent != child);
1762 Monitor* mon;
1763
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001764 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001765 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1766 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1767 }
1768 assert(!expandObjHas(&mon->historyChildren, child));
1769 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1770
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001771 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001772 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1773 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1774 }
1775 assert(!expandObjHas(&mon->historyParents, parent));
1776 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1777}
1778
1779
1780/*
1781 * Log the monitors held by the current thread. This is done as part of
1782 * flagging an error.
1783 */
1784static void logHeldMonitors(Thread* self)
1785{
1786 char* name = NULL;
1787
1788 name = dvmGetThreadName(self);
1789 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1790 self->threadId, name);
1791 LOGW("(most-recently-acquired on top):\n");
1792 free(name);
1793
1794 LockedObjectData* lod = self->pLockedObjects;
1795 while (lod != NULL) {
1796 LOGW("--- object %p[%d] (%s)\n",
1797 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1798 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1799
1800 lod = lod->next;
1801 }
1802}
1803
1804/*
1805 * Recursively traverse the object hierarchy starting at "obj". We mark
1806 * ourselves on entry and clear the mark on exit. If we ever encounter
1807 * a marked object, we have a cycle.
1808 *
1809 * Returns "true" if all is well, "false" if we found a cycle.
1810 */
1811static bool traverseTree(Thread* self, const Object* obj)
1812{
1813 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001814 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001815
1816 /*
1817 * Have we been here before?
1818 */
1819 if (mon->historyMark) {
1820 int* rawStackTrace;
1821 int stackDepth;
1822
1823 LOGW("%s\n", kStartBanner);
1824 LOGW("Illegal lock attempt:\n");
1825 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1826
1827 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1828 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1829 free(rawStackTrace);
1830
1831 LOGW(" ");
1832 logHeldMonitors(self);
1833
1834 LOGW(" ");
1835 LOGW("Earlier, the following lock order (from last to first) was\n");
1836 LOGW("established -- stack trace is from first successful lock):\n");
1837 return false;
1838 }
1839 mon->historyMark = true;
1840
1841 /*
1842 * Examine the children. We do NOT hold these locks, so they might
1843 * very well transition from thin to fat or change ownership while
1844 * we work.
1845 *
1846 * NOTE: we rely on the fact that they cannot revert from fat to thin
1847 * while we work. This is currently a safe assumption.
1848 *
1849 * We can safely ignore thin-locked children, because by definition
1850 * they have no history and are leaf nodes. In the current
1851 * implementation we always fatten the locks to provide a place to
1852 * hang the stack trace.
1853 */
1854 ExpandingObjectList* pList = &mon->historyChildren;
1855 int i;
1856 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1857 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001858 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001859 if (!IS_LOCK_FAT(&lock))
1860 continue;
1861 if (!traverseTree(self, child)) {
1862 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1863 dvmLogRawStackTrace(mon->historyRawStackTrace,
1864 mon->historyStackDepth);
1865 mon->historyMark = false;
1866 return false;
1867 }
1868 }
1869
1870 mon->historyMark = false;
1871
1872 return true;
1873}
1874
1875/*
1876 * Update the deadlock prediction tree, based on the current thread
1877 * acquiring "acqObj". This must be called before the object is added to
1878 * the thread's list of held monitors.
1879 *
1880 * If the thread already holds the lock (recursion), or this is a known
1881 * lock configuration, we return without doing anything. Otherwise, we add
1882 * a link from the most-recently-acquired lock in this thread to "acqObj"
1883 * after ensuring that the parent lock is "fat".
1884 *
1885 * This MUST NOT be called while a GC is in progress in another thread,
1886 * because we assume exclusive access to history trees in owned monitors.
1887 */
1888static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1889{
1890 LockedObjectData* lod;
1891 LockedObjectData* mrl;
1892
1893 /*
1894 * Quick check for recursive access.
1895 */
1896 lod = dvmFindInMonitorList(self, acqObj);
1897 if (lod != NULL) {
1898 LOGV("+++ DP: recursive %p\n", acqObj);
1899 return;
1900 }
1901
1902 /*
1903 * Make the newly-acquired object's monitor "fat". In some ways this
1904 * isn't strictly necessary, but we need the GC to tell us when
1905 * "interesting" objects go away, and right now the only way to make
1906 * an object look interesting is to give it a monitor.
1907 *
1908 * This also gives us a place to hang a stack trace.
1909 *
1910 * Our thread holds the lock, so we're allowed to rewrite the lock
1911 * without worrying that something will change out from under us.
1912 */
1913 if (!IS_LOCK_FAT(&acqObj->lock)) {
1914 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001915 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001916 Monitor* newMon = dvmCreateMonitor(acqObj);
1917 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001918 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1919 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1920 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001921 }
1922
1923 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001924 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1925 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001926 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1927 &mon->historyStackDepth);
1928 }
1929
1930 /*
1931 * We need to examine and perhaps modify the most-recently-locked
1932 * monitor. We own that, so there's no risk of another thread
1933 * stepping on us.
1934 *
1935 * Retrieve the most-recently-locked entry from our thread.
1936 */
1937 mrl = self->pLockedObjects;
1938 if (mrl == NULL)
1939 return; /* no other locks held */
1940
1941 /*
1942 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1943 * this without holding the global lock because of our assertion that
1944 * a GC is not running in parallel -- nobody except the GC can
1945 * modify a history list in a Monitor they don't own, and we own "mrl".
1946 * (There might be concurrent *reads*, but no concurrent *writes.)
1947 *
1948 * If we find it, this is a known good configuration, and we're done.
1949 */
1950 if (objectInChildList(mrl->obj, acqObj))
1951 return;
1952
1953 /*
1954 * "mrl" is going to need to have a history tree. If it's currently
1955 * a thin lock, we make it fat now. The thin lock might have a
1956 * nonzero recursive lock count, which we need to carry over.
1957 *
1958 * Our thread holds the lock, so we're allowed to rewrite the lock
1959 * without worrying that something will change out from under us.
1960 */
1961 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1962 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001963 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001964 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1965 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001966 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1967 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1968 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001969 }
1970
1971 /*
1972 * We haven't seen this configuration before. We need to scan down
1973 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1974 * appear. We grab a global lock before traversing or updating the
1975 * history list.
1976 *
1977 * If we find a match for any of our held locks, we know that the lock
1978 * has previously been acquired *after* acqObj, and we throw an error.
1979 *
1980 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1981 * and do a recursive traversal, marking nodes as we cross them. If
1982 * we cross one a second time, we have a cycle and can throw an error.
1983 * (We do the flag-clearing traversal before adding the new link, so
1984 * that we're guaranteed to terminate.)
1985 *
1986 * If "acqObj" is a thin lock, it has no history, and we can create a
1987 * link to it without additional checks. [ We now guarantee that it's
1988 * always fat. ]
1989 */
1990 bool failed = false;
1991 dvmLockMutex(&gDvm.deadlockHistoryLock);
1992 linkParentToChild(mrl->obj, acqObj);
1993 if (!traverseTree(self, acqObj)) {
1994 LOGW("%s\n", kEndBanner);
1995 failed = true;
1996
1997 /* remove the entry so we're still okay when in "warning" mode */
1998 unlinkParentFromChild(mrl->obj, acqObj);
1999 }
2000 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
2001
2002 if (failed) {
2003 switch (gDvm.deadlockPredictMode) {
2004 case kDPErr:
2005 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
2006 break;
2007 case kDPAbort:
2008 LOGE("Aborting due to potential deadlock\n");
2009 dvmAbort();
2010 break;
2011 default:
2012 /* warn only */
2013 break;
2014 }
2015 }
2016}
2017
2018/*
2019 * We're removing "child" from existence. We want to pull all of
2020 * child's children into "parent", filtering out duplicates. This is
2021 * called during the GC.
2022 *
2023 * This does not modify "child", which might have multiple parents.
2024 */
2025static void mergeChildren(Object* parent, const Object* child)
2026{
2027 Monitor* mon;
2028 int i;
2029
2030 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002031 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002032 ExpandingObjectList* pList = &mon->historyChildren;
2033
2034 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2035 Object* grandChild = expandBufGetEntry(pList, i);
2036
2037 if (!objectInChildList(parent, grandChild)) {
2038 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
2039 linkParentToChild(parent, grandChild);
2040 } else {
2041 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
2042 }
2043 }
2044}
2045
2046/*
2047 * An object with a fat lock is being collected during a GC pass. We
2048 * want to remove it from any lock history trees that it is a part of.
2049 *
2050 * This may require updating the history trees in several monitors. The
2051 * monitor semantics guarantee that no other thread will be accessing
2052 * the history trees at the same time.
2053 */
2054static void removeCollectedObject(Object* obj)
2055{
2056 Monitor* mon;
2057
2058 LOGVV("+++ collecting %p\n", obj);
2059
2060#if 0
2061 /*
2062 * We're currently running through the entire set of known monitors.
2063 * This can be somewhat slow. We may want to keep lists of parents
2064 * in each child to speed up GC.
2065 */
2066 mon = gDvm.monitorList;
2067 while (mon != NULL) {
2068 Object* parent = mon->obj;
2069 if (parent != NULL) { /* value nulled for deleted entries */
2070 if (objectInChildList(parent, obj)) {
2071 LOGVV("removing child %p from parent %p\n", obj, parent);
2072 unlinkParentFromChild(parent, obj);
2073 mergeChildren(parent, obj);
2074 }
2075 }
2076 mon = mon->next;
2077 }
2078#endif
2079
2080 /*
2081 * For every parent of this object:
2082 * - merge all of our children into the parent's child list (creates
2083 * a two-way link between parent and child)
2084 * - remove ourselves from the parent's child list
2085 */
2086 ExpandingObjectList* pList;
2087 int i;
2088
2089 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002090 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002091 pList = &mon->historyParents;
2092 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2093 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002094 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002095
2096 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2097 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2098 }
2099 assert(!expandObjHas(&parentMon->historyChildren, obj));
2100
2101 mergeChildren(parent, obj);
2102 }
2103
2104 /*
2105 * For every child of this object:
2106 * - remove ourselves from the child's parent list
2107 */
2108 pList = &mon->historyChildren;
2109 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2110 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002111 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002112
2113 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2114 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2115 }
2116 assert(!expandObjHas(&childMon->historyParents, obj));
2117 }
2118}
2119
2120#endif /*WITH_DEADLOCK_PREDICTION*/