blob: 8603455156e341daa498fda262860623121aef51 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andy McFadden581bed72009-10-15 11:24:54 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Fundamental synchronization mechanisms.
19 *
20 * The top part of the file has operations on "monitor" structs; the
21 * next part has the native calls on objects.
22 *
23 * The current implementation uses "thin locking" to avoid allocating
24 * an Object's full Monitor struct until absolutely necessary (i.e.,
25 * during contention or a call to wait()).
26 *
27 * TODO: make improvements to thin locking
28 * We may be able to improve performance and reduce memory requirements by:
29 * - reverting to a thin lock once the Monitor is no longer necessary
30 * - using a pool of monitor objects, with some sort of recycling scheme
31 *
32 * TODO: recycle native-level monitors when objects are garbage collected.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080033 */
34#include "Dalvik.h"
35
Carl Shapirof0c514c2010-04-09 15:03:33 -070036#include <fcntl.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080037#include <stdlib.h>
38#include <unistd.h>
39#include <pthread.h>
40#include <time.h>
41#include <sys/time.h>
42#include <errno.h>
43
44#define LOG_THIN LOGV
45
46#ifdef WITH_DEADLOCK_PREDICTION /* fwd */
47static const char* kStartBanner =
48 "<-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#";
49static const char* kEndBanner =
50 "#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#->";
51
52/*
53 * Unsorted, expanding list of objects.
54 *
55 * This is very similar to PointerSet (which came into existence after this),
56 * but these are unsorted, uniqueness is not enforced by the "add" function,
57 * and the base object isn't allocated on the heap.
58 */
59typedef struct ExpandingObjectList {
60 u2 alloc;
61 u2 count;
62 Object** list;
63} ExpandingObjectList;
64
65/* fwd */
66static void updateDeadlockPrediction(Thread* self, Object* obj);
67static void removeCollectedObject(Object* obj);
68static void expandObjClear(ExpandingObjectList* pList);
69#endif
70
71/*
72 * Every Object has a monitor associated with it, but not every Object is
73 * actually locked. Even the ones that are locked do not need a
74 * full-fledged monitor until a) there is actual contention or b) wait()
75 * is called on the Object.
76 *
77 * For Dalvik, we have implemented a scheme similar to the one described
78 * in Bacon et al.'s "Thin locks: featherweight synchronization for Java"
79 * (ACM 1998). Things are even easier for us, though, because we have
80 * a full 32 bits to work with.
81 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080082 * The two states of an Object's lock are referred to as "thin" and
83 * "fat". A lock may transition from the "thin" state to the "fat"
84 * state and this transition is referred to as inflation. Once a lock
85 * has been inflated it remains in the "fat" state indefinitely.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080086 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080087 * The lock value itself is stored in Object.lock. The LSB of the
88 * lock encodes its state. When cleared, the lock is in the "thin"
89 * state and its bits are formatted as follows:
Carl Shapiro71938022009-12-22 13:49:53 -080090 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080091 * [31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
92 * lock count thread id hash state 0
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080093 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080094 * When set, the lock is in the "fat" state and its bits are formatted
Carl Shapiro94338aa2009-12-21 11:42:59 -080095 * as follows:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080096 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080097 * [31 ---- 3] [2 ---- 1] [0]
98 * pointer hash state 1
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080099 *
100 * For an in-depth description of the mechanics of thin-vs-fat locking,
101 * read the paper referred to above.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800102 */
103
104/*
105 * Monitors provide:
106 * - mutually exclusive access to resources
107 * - a way for multiple threads to wait for notification
108 *
109 * In effect, they fill the role of both mutexes and condition variables.
110 *
111 * Only one thread can own the monitor at any time. There may be several
112 * threads waiting on it (the wait call unlocks it). One or more waiting
113 * threads may be getting interrupted or notified at any given time.
114 */
115struct Monitor {
116 Thread* owner; /* which thread currently owns the lock? */
117 int lockCount; /* owner's recursive lock depth */
118 Object* obj; /* what object are we part of [debug only] */
119
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800120 Thread* waitSet; /* threads currently waiting on this monitor */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800121
122 pthread_mutex_t lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800123
124 Monitor* next;
125
126#ifdef WITH_DEADLOCK_PREDICTION
127 /*
128 * Objects that have been locked immediately after this one in the
129 * past. We use an expanding flat array, allocated on first use, to
130 * minimize allocations. Deletions from the list, expected to be
131 * infrequent, are crunched down.
132 */
133 ExpandingObjectList historyChildren;
134
135 /*
136 * We also track parents. This isn't strictly necessary, but it makes
137 * the cleanup at GC time significantly faster.
138 */
139 ExpandingObjectList historyParents;
140
141 /* used during cycle detection */
142 bool historyMark;
143
144 /* stack trace, established the first time we locked the object */
145 int historyStackDepth;
146 int* historyRawStackTrace;
147#endif
148};
149
150
151/*
152 * Create and initialize a monitor.
153 */
154Monitor* dvmCreateMonitor(Object* obj)
155{
156 Monitor* mon;
157
158 mon = (Monitor*) calloc(1, sizeof(Monitor));
159 if (mon == NULL) {
160 LOGE("Unable to allocate monitor\n");
161 dvmAbort();
162 }
Carl Shapiro94338aa2009-12-21 11:42:59 -0800163 if (((u4)mon & 7) != 0) {
164 LOGE("Misaligned monitor: %p\n", mon);
165 dvmAbort();
166 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800167 mon->obj = obj;
168 dvmInitMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800169
170 /* replace the head of the list with the new monitor */
171 do {
172 mon->next = gDvm.monitorList;
Andy McFadden6e10b9a2010-06-14 15:24:39 -0700173 } while (android_atomic_release_cas((int32_t)mon->next, (int32_t)mon,
174 (int32_t*)(void*)&gDvm.monitorList) != 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800175
176 return mon;
177}
178
179/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800180 * Free the monitor list. Only used when shutting the VM down.
181 */
182void dvmFreeMonitorList(void)
183{
184 Monitor* mon;
185 Monitor* nextMon;
186
187 mon = gDvm.monitorList;
188 while (mon != NULL) {
189 nextMon = mon->next;
190
191#ifdef WITH_DEADLOCK_PREDICTION
192 expandObjClear(&mon->historyChildren);
193 expandObjClear(&mon->historyParents);
194 free(mon->historyRawStackTrace);
195#endif
196 free(mon);
197 mon = nextMon;
198 }
199}
200
201/*
202 * Log some info about our monitors.
203 */
204void dvmDumpMonitorInfo(const char* msg)
205{
206#if QUIET_ZYGOTE_MONITOR
207 if (gDvm.zygote) {
208 return;
209 }
210#endif
211
212 int totalCount;
213 int liveCount;
214
215 totalCount = liveCount = 0;
216 Monitor* mon = gDvm.monitorList;
217 while (mon != NULL) {
218 totalCount++;
219 if (mon->obj != NULL)
220 liveCount++;
221 mon = mon->next;
222 }
223
224 LOGD("%s: monitor list has %d entries (%d live)\n",
225 msg, totalCount, liveCount);
226}
227
228/*
229 * Get the object that a monitor is part of.
230 */
231Object* dvmGetMonitorObject(Monitor* mon)
232{
233 if (mon == NULL)
234 return NULL;
235 else
236 return mon->obj;
237}
238
239/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800240 * Returns the thread id of the thread owning the given lock.
241 */
242static u4 lockOwner(Object* obj)
243{
244 Thread *owner;
245 u4 lock;
246
247 assert(obj != NULL);
248 /*
249 * Since we're reading the lock value multiple times, latch it so
250 * that it doesn't change out from under us if we get preempted.
251 */
252 lock = obj->lock;
253 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
254 return LW_LOCK_OWNER(lock);
255 } else {
256 owner = LW_MONITOR(lock)->owner;
257 return owner ? owner->threadId : 0;
258 }
259}
260
261/*
Andy McFaddenfd542662010-03-12 13:39:59 -0800262 * Get the thread that holds the lock on the specified object. The
263 * object may be unlocked, thin-locked, or fat-locked.
264 *
265 * The caller must lock the thread list before calling here.
266 */
267Thread* dvmGetObjectLockHolder(Object* obj)
268{
269 u4 threadId = lockOwner(obj);
270
271 if (threadId == 0)
272 return NULL;
273 return dvmGetThreadByThreadId(threadId);
274}
275
276/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800277 * Checks whether the given thread holds the given
278 * objects's lock.
279 */
280bool dvmHoldsLock(Thread* thread, Object* obj)
281{
282 if (thread == NULL || obj == NULL) {
283 return false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800284 } else {
Carl Shapiro30aa9972010-01-13 22:07:50 -0800285 return thread->threadId == lockOwner(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800286 }
287}
288
289/*
290 * Free the monitor associated with an object and make the object's lock
291 * thin again. This is called during garbage collection.
292 */
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800293static void freeObjectMonitor(Object* obj)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800294{
295 Monitor *mon;
296
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800297 assert(LW_SHAPE(obj->lock) == LW_SHAPE_FAT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800298
299#ifdef WITH_DEADLOCK_PREDICTION
300 if (gDvm.deadlockPredictMode != kDPOff)
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800301 removeCollectedObject(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800302#endif
303
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800304 mon = LW_MONITOR(obj->lock);
305 obj->lock = DVM_LOCK_INITIAL_THIN_VALUE;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800306
307 /* This lock is associated with an object
308 * that's being swept. The only possible way
309 * anyone could be holding this lock would be
310 * if some JNI code locked but didn't unlock
311 * the object, in which case we've got some bad
312 * native code somewhere.
313 */
Carl Shapiro1ff876d2010-04-04 01:56:48 -0700314 assert(pthread_mutex_trylock(&mon->lock) == 0);
315 assert(pthread_mutex_unlock(&mon->lock) == 0);
Carl Shapiro980ffb02010-03-13 22:34:01 -0800316 dvmDestroyMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800317#ifdef WITH_DEADLOCK_PREDICTION
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800318 expandObjClear(&mon->historyChildren);
319 expandObjClear(&mon->historyParents);
320 free(mon->historyRawStackTrace);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800321#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800322 free(mon);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800323}
324
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800325/*
326 * Frees monitor objects belonging to unmarked objects.
327 */
328void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
329{
330 Monitor handle;
331 Monitor *prev, *curr;
332 Object *obj;
333
334 assert(mon != NULL);
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800335 assert(isUnmarkedObject != NULL);
Carl Shapiro8881a802010-08-10 15:55:45 -0700336#ifdef WITH_DEADLOCK_PREDICTION
337 dvmDumpMonitorInfo("before monitor sweep");
338#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800339 prev = &handle;
340 prev->next = curr = *mon;
341 while (curr != NULL) {
342 obj = curr->obj;
343 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
344 prev->next = curr = curr->next;
345 freeObjectMonitor(obj);
346 } else {
347 prev = curr;
348 curr = curr->next;
349 }
350 }
351 *mon = handle.next;
Carl Shapiro8881a802010-08-10 15:55:45 -0700352#ifdef WITH_DEADLOCK_PREDICTION
353 dvmDumpMonitorInfo("after monitor sweep");
354#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800355}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800356
Carl Shapirof0c514c2010-04-09 15:03:33 -0700357static char *logWriteInt(char *dst, int value)
358{
359 *dst++ = EVENT_TYPE_INT;
360 set4LE((u1 *)dst, value);
361 return dst + 4;
362}
363
364static char *logWriteString(char *dst, const char *value, size_t len)
365{
366 *dst++ = EVENT_TYPE_STRING;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700367 len = len < 32 ? len : 32;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700368 set4LE((u1 *)dst, len);
369 dst += 4;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700370 memcpy(dst, value, len);
371 return dst + len;
372}
373
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700374#define EVENT_LOG_TAG_dvm_lock_sample 20003
Carl Shapirof0c514c2010-04-09 15:03:33 -0700375
376static void logContentionEvent(Thread *self, u4 waitMs, u4 samplePercent)
377{
378 const StackSaveArea *saveArea;
379 const Method *meth;
380 u4 relativePc;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700381 char eventBuffer[132];
Carl Shapirof0c514c2010-04-09 15:03:33 -0700382 const char *fileName;
Carl Shapiroe3c01da2010-05-20 22:54:18 -0700383 char procName[33], *selfName;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700384 char *cp;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700385 size_t len;
386 int fd;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700387
388 saveArea = SAVEAREA_FROM_FP(self->curFrame);
389 meth = saveArea->method;
390 cp = eventBuffer;
391
392 /* Emit the event list length, 1 byte. */
393 *cp++ = 7;
394
395 /* Emit the process name, <= 37 bytes. */
396 fd = open("/proc/self/cmdline", O_RDONLY);
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700397 memset(procName, 0, sizeof(procName));
398 read(fd, procName, sizeof(procName) - 1);
Carl Shapirof0c514c2010-04-09 15:03:33 -0700399 close(fd);
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700400 len = strlen(procName);
401 cp = logWriteString(cp, procName, len);
Carl Shapirof0c514c2010-04-09 15:03:33 -0700402
403 /* Emit the main thread status, 5 bytes. */
404 bool isMainThread = (self->systemTid == getpid());
405 cp = logWriteInt(cp, isMainThread);
406
407 /* Emit self thread name string, <= 37 bytes. */
408 selfName = dvmGetThreadName(self);
409 cp = logWriteString(cp, selfName, strlen(selfName));
410 free(selfName);
411
412 /* Emit the wait time, 5 bytes. */
413 cp = logWriteInt(cp, waitMs);
414
415 /* Emit the source code file name, <= 37 bytes. */
416 fileName = dvmGetMethodSourceFile(meth);
417 if (fileName == NULL) fileName = "";
418 cp = logWriteString(cp, fileName, strlen(fileName));
419
420 /* Emit the source code line number, 5 bytes. */
421 relativePc = saveArea->xtra.currentPc - saveArea->method->insns;
422 cp = logWriteInt(cp, dvmLineNumFromPC(meth, relativePc));
423
424 /* Emit the sample percentage, 5 bytes. */
425 cp = logWriteInt(cp, samplePercent);
426
427 assert((size_t)(cp - eventBuffer) <= sizeof(eventBuffer));
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700428 android_btWriteLog(EVENT_LOG_TAG_dvm_lock_sample,
Carl Shapirof0c514c2010-04-09 15:03:33 -0700429 EVENT_TYPE_LIST,
430 eventBuffer,
431 (size_t)(cp - eventBuffer));
432}
433
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800434/*
435 * Lock a monitor.
436 */
437static void lockMonitor(Thread* self, Monitor* mon)
438{
Carl Shapirof0c514c2010-04-09 15:03:33 -0700439 ThreadStatus oldStatus;
440 u4 waitThreshold, samplePercent;
441 u8 waitStart, waitEnd, waitMs;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800442
443 if (mon->owner == self) {
444 mon->lockCount++;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700445 return;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800446 }
Carl Shapiro045fdc92010-04-13 16:48:27 -0700447 if (dvmTryLockMutex(&mon->lock) != 0) {
Carl Shapirof0c514c2010-04-09 15:03:33 -0700448 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
449 waitThreshold = gDvm.lockProfThreshold;
450 if (waitThreshold) {
451 waitStart = dvmGetRelativeTimeUsec();
452 }
453 dvmLockMutex(&mon->lock);
454 if (waitThreshold) {
455 waitEnd = dvmGetRelativeTimeUsec();
456 }
457 dvmChangeStatus(self, oldStatus);
458 if (waitThreshold) {
459 waitMs = (waitEnd - waitStart) / 1000;
460 if (waitMs >= waitThreshold) {
461 samplePercent = 100;
462 } else {
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700463 samplePercent = 100 * waitMs / waitThreshold;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700464 }
Carl Shapirob8fcf572010-04-16 17:33:15 -0700465 if (samplePercent != 0 && ((u4)rand() % 100 < samplePercent)) {
Carl Shapirof0c514c2010-04-09 15:03:33 -0700466 logContentionEvent(self, waitMs, samplePercent);
467 }
468 }
469 }
470 mon->owner = self;
471 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800472}
473
474/*
475 * Try to lock a monitor.
476 *
477 * Returns "true" on success.
478 */
Carl Shapirob31b3012010-05-25 18:35:37 -0700479#ifdef WITH_COPYING_GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800480static bool tryLockMonitor(Thread* self, Monitor* mon)
481{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800482 if (mon->owner == self) {
483 mon->lockCount++;
484 return true;
485 } else {
Carl Shapiro980ffb02010-03-13 22:34:01 -0800486 if (dvmTryLockMutex(&mon->lock) == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800487 mon->owner = self;
488 assert(mon->lockCount == 0);
489 return true;
490 } else {
491 return false;
492 }
493 }
494}
Carl Shapirob31b3012010-05-25 18:35:37 -0700495#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800496
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);
Carl Shapiro92277082010-04-06 15:35:59 -0700506 assert(mon != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800507 if (mon->owner == self) {
508 /*
509 * We own the monitor, so nobody else can be in here.
510 */
511 if (mon->lockCount == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800512 mon->owner = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800513 dvmUnlockMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800514 } 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 Shapiro8782d7c2010-04-19 20:10:35 -0700523 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
524 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800525 return false;
526 }
527 return true;
528}
529
530/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800531 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800532 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800533 */
Carl Shapirob31b3012010-05-25 18:35:37 -0700534#ifndef NDEBUG
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800535static int waitSetCheck(Monitor *mon)
536{
537 Thread *fast, *slow;
538 size_t n;
539
540 assert(mon != NULL);
541 fast = slow = mon->waitSet;
542 n = 0;
543 for (;;) {
544 if (fast == NULL) return 0;
545 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800546 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800547 n += 2;
548 fast = fast->waitNext->waitNext;
549 slow = slow->waitNext;
550 }
551}
Carl Shapirob31b3012010-05-25 18:35:37 -0700552#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800553
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 Buzbeefccb31d2010-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 Buzbeefccb31d2010-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 Buzbeefccb31d2010-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 Shapiro980ffb02010-03-13 22:34:01 -0800741 dvmLockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800742
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800743 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800744 * Set waitMonitor to the monitor object we will be waiting on.
745 * When waitMonitor is non-NULL a notifying or interrupting thread
746 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800747 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800748 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800749 self->waitMonitor = mon;
750
751 /*
752 * Handle the case where the thread was interrupted before we called
753 * wait().
754 */
755 if (self->interrupted) {
756 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800757 self->waitMonitor = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800758 dvmUnlockMutex(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800759 goto done;
760 }
761
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800762 /*
763 * Release the monitor lock and wait for a notification or
764 * a timeout to occur.
765 */
Carl Shapiro980ffb02010-03-13 22:34:01 -0800766 dvmUnlockMutex(&mon->lock);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800767
768 if (!timed) {
769 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
770 assert(ret == 0);
771 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800772#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800773 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800774#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800775 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800776#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800777 assert(ret == 0 || ret == ETIMEDOUT);
778 }
779 if (self->interrupted) {
780 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800781 }
782
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800783 self->interrupted = false;
784 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800785
Carl Shapiro980ffb02010-03-13 22:34:01 -0800786 dvmUnlockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800787
Carl Shapiro30aa9972010-01-13 22:07:50 -0800788 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800789 lockMonitor(self, mon);
790
Carl Shapiro142ef272010-01-25 12:51:31 -0800791done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800792 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800793 * We remove our thread from wait set after restoring the count
794 * and owner fields so the subroutine can check that the calling
795 * thread owns the monitor. Aside from that, the order of member
796 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800797 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800798 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800799 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800800 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800801
802 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
803 dvmChangeStatus(self, THREAD_RUNNING);
804
805 if (wasInterrupted) {
806 /*
807 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800808 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800809 *
810 * The doc sayeth: "The interrupted status of the current thread is
811 * cleared when this exception is thrown."
812 */
813 self->interrupted = false;
814 if (interruptShouldThrow)
815 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
816 }
817}
818
819/*
820 * Notify one thread waiting on this monitor.
821 */
822static void notifyMonitor(Thread* self, Monitor* mon)
823{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800824 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800825
Carl Shapiro71938022009-12-22 13:49:53 -0800826 assert(self != NULL);
827 assert(mon != NULL);
828
Carl Shapiro94338aa2009-12-21 11:42:59 -0800829 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800830 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800831 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
832 "object not locked by thread before notify()");
833 return;
834 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800835 /* Signal the first waiting thread in the wait set. */
836 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800837 thread = mon->waitSet;
838 mon->waitSet = thread->waitNext;
839 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800840 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800841 /* Check to see if the thread is still waiting. */
842 if (thread->waitMonitor != NULL) {
843 pthread_cond_signal(&thread->waitCond);
Carl Shapiro980ffb02010-03-13 22:34:01 -0800844 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800845 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800846 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800847 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800848 }
849}
850
851/*
852 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800853 */
854static void notifyAllMonitor(Thread* self, Monitor* mon)
855{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800856 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800857
Carl Shapiro71938022009-12-22 13:49:53 -0800858 assert(self != NULL);
859 assert(mon != NULL);
860
Carl Shapiro94338aa2009-12-21 11:42:59 -0800861 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800862 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800863 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
864 "object not locked by thread before notifyAll()");
865 return;
866 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800867 /* Signal all threads in the wait set. */
868 while (mon->waitSet != NULL) {
869 thread = mon->waitSet;
870 mon->waitSet = thread->waitNext;
871 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800872 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800873 /* Check to see if the thread is still waiting. */
874 if (thread->waitMonitor != NULL) {
875 pthread_cond_signal(&thread->waitCond);
876 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800877 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800878 }
879}
880
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800881/*
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800882 * Changes the shape of a monitor from thin to fat, preserving the
883 * internal lock state. The calling thread must own the lock.
884 */
885static void inflateMonitor(Thread *self, Object *obj)
886{
887 Monitor *mon;
888 u4 thin;
889
890 assert(self != NULL);
891 assert(obj != NULL);
892 assert(LW_SHAPE(obj->lock) == LW_SHAPE_THIN);
893 assert(LW_LOCK_OWNER(obj->lock) == self->threadId);
894 /* Allocate and acquire a new monitor. */
895 mon = dvmCreateMonitor(obj);
896 lockMonitor(self, mon);
897 /* Propagate the lock state. */
898 thin = obj->lock;
899 mon->lockCount = LW_LOCK_COUNT(thin);
900 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
901 thin |= (u4)mon | LW_SHAPE_FAT;
902 /* Publish the updated lock word. */
Carl Shapiro4ba56722010-06-21 11:04:33 -0700903 android_atomic_release_store(thin, (int32_t *)&obj->lock);
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800904}
905
906/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800907 * Implements monitorenter for "synchronized" stuff.
908 *
909 * This does not fail or throw an exception (unless deadlock prediction
910 * is enabled and set to "err" mode).
911 */
912void dvmLockObject(Thread* self, Object *obj)
913{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800914 volatile u4 *thinp;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800915 ThreadStatus oldStatus;
916 useconds_t sleepDelay;
917 const useconds_t maxSleepDelay = 1 << 20;
918 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800919
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800920 assert(self != NULL);
921 assert(obj != NULL);
922 threadId = self->threadId;
923 thinp = &obj->lock;
924retry:
925 thin = *thinp;
926 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
927 /*
928 * The lock is a thin lock. The owner field is used to
929 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800930 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800931 if (LW_LOCK_OWNER(thin) == threadId) {
932 /*
933 * The calling thread owns the lock. Increment the
934 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800935 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800936 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapirof3cfbbf2010-07-23 16:30:12 -0700937 if (LW_LOCK_COUNT(obj->lock) == LW_LOCK_COUNT_MASK) {
938 /*
939 * The reacquisition limit has been reached. Inflate
940 * the lock so the next acquire will not overflow the
941 * recursion count field.
942 */
943 inflateMonitor(self, obj);
944 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800945 } else if (LW_LOCK_OWNER(thin) == 0) {
946 /*
947 * The lock is unowned. Install the thread id of the
948 * calling thread into the owner field. This is the
949 * common case. In performance critical code the JIT
950 * will have tried this before calling out to the VM.
951 */
952 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
Andy McFadden6e10b9a2010-06-14 15:24:39 -0700953 if (android_atomic_release_cas(thin, newThin,
954 (int32_t*)thinp) != 0) {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800955 /*
956 * The acquire failed. Try again.
957 */
958 goto retry;
959 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800960 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800961 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
962 threadId, &obj->lock, 0, *thinp, thin);
963 /*
964 * The lock is owned by another thread. Notify the VM
965 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800966 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800967 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
968 /*
969 * Spin until the thin lock is released or inflated.
970 */
971 sleepDelay = 0;
972 for (;;) {
973 thin = *thinp;
974 /*
975 * Check the shape of the lock word. Another thread
976 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800977 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800978 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
979 if (LW_LOCK_OWNER(thin) == 0) {
980 /*
981 * The lock has been released. Install the
982 * thread id of the calling thread into the
983 * owner field.
984 */
985 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
Andy McFadden6e10b9a2010-06-14 15:24:39 -0700986 if (android_atomic_release_cas(thin, newThin,
987 (int32_t *)thinp) == 0) {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800988 /*
989 * The acquire succeed. Break out of the
990 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800991 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800992 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800993 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800994 } else {
995 /*
996 * The lock has not been released. Yield so
997 * the owning thread can run.
998 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800999 if (sleepDelay == 0) {
1000 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001001 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001002 } else {
1003 usleep(sleepDelay);
1004 if (sleepDelay < maxSleepDelay / 2) {
1005 sleepDelay *= 2;
1006 }
1007 }
1008 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001009 } else {
1010 /*
1011 * The thin lock was inflated by another thread.
1012 * Let the VM know we are no longer waiting and
1013 * try again.
1014 */
1015 LOG_THIN("(%d) lock %p surprise-fattened",
1016 threadId, &obj->lock);
1017 dvmChangeStatus(self, oldStatus);
1018 goto retry;
1019 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001020 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001021 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
1022 threadId, &obj->lock, 0, *thinp, thin);
1023 /*
1024 * We have acquired the thin lock. Let the VM know that
1025 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001026 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001027 dvmChangeStatus(self, oldStatus);
1028 /*
1029 * Fatten the lock.
1030 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001031 inflateMonitor(self, obj);
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001032 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001033 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001034 } else {
1035 /*
1036 * The lock is a fat lock.
1037 */
1038 assert(LW_MONITOR(obj->lock) != NULL);
1039 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001040 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001041#ifdef WITH_DEADLOCK_PREDICTION
1042 /*
1043 * See if we were allowed to grab the lock at this time. We do it
1044 * *after* acquiring the lock, rather than before, so that we can
1045 * freely update the Monitor struct. This seems counter-intuitive,
1046 * but our goal is deadlock *prediction* not deadlock *prevention*.
1047 * (If we actually deadlock, the situation is easy to diagnose from
1048 * a thread dump, so there's no point making a special effort to do
1049 * the checks before the lock is held.)
1050 *
1051 * This needs to happen before we add the object to the thread's
1052 * monitor list, so we can tell the difference between first-lock and
1053 * re-lock.
1054 *
1055 * It's also important that we do this while in THREAD_RUNNING, so
1056 * that we don't interfere with cleanup operations in the GC.
1057 */
1058 if (gDvm.deadlockPredictMode != kDPOff) {
1059 if (self->status != THREAD_RUNNING) {
1060 LOGE("Bad thread status (%d) in DP\n", self->status);
1061 dvmDumpThread(self, false);
1062 dvmAbort();
1063 }
1064 assert(!dvmCheckException(self));
1065 updateDeadlockPrediction(self, obj);
1066 if (dvmCheckException(self)) {
1067 /*
1068 * If we're throwing an exception here, we need to free the
1069 * lock. We add the object to the thread's monitor list so the
1070 * "unlock" code can remove it.
1071 */
1072 dvmAddToMonitorList(self, obj, false);
1073 dvmUnlockObject(self, obj);
1074 LOGV("--- unlocked, pending is '%s'\n",
1075 dvmGetException(self)->clazz->descriptor);
1076 }
1077 }
1078
1079 /*
1080 * Add the locked object, and the current stack trace, to the list
1081 * held by the Thread object. If deadlock prediction isn't on,
1082 * don't capture the stack trace.
1083 */
1084 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
1085#elif defined(WITH_MONITOR_TRACKING)
1086 /*
1087 * Add the locked object to the list held by the Thread object.
1088 */
1089 dvmAddToMonitorList(self, obj, false);
1090#endif
1091}
1092
1093/*
1094 * Implements monitorexit for "synchronized" stuff.
1095 *
1096 * On failure, throws an exception and returns "false".
1097 */
1098bool dvmUnlockObject(Thread* self, Object *obj)
1099{
Carl Shapiro94338aa2009-12-21 11:42:59 -08001100 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001101
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001102 assert(self != NULL);
1103 assert(self->status == THREAD_RUNNING);
1104 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001105 /*
1106 * Cache the lock word as its value can change while we are
1107 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001108 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001109 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001110 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
1111 /*
1112 * The lock is thin. We must ensure that the lock is owned
1113 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001114 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001115 if (LW_LOCK_OWNER(thin) == self->threadId) {
1116 /*
1117 * We are the lock owner. It is safe to update the lock
1118 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001119 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001120 if (LW_LOCK_COUNT(thin) == 0) {
1121 /*
1122 * The lock was not recursively acquired, the common
1123 * case. Unlock by clearing all bits except for the
1124 * hash state.
1125 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001126 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001127 } else {
1128 /*
1129 * The object was recursively acquired. Decrement the
1130 * lock recursion count field.
1131 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001132 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001133 }
1134 } else {
1135 /*
1136 * We do not own the lock. The JVM spec requires that we
1137 * throw an exception in this case.
1138 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001139 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001140 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001141 return false;
1142 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001143 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001144 /*
1145 * The lock is fat. We must check to see if unlockMonitor has
1146 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001147 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001148 assert(LW_MONITOR(obj->lock) != NULL);
1149 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001150 /*
1151 * An exception has been raised. Do not fall through.
1152 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001153 return false;
1154 }
1155 }
1156
1157#ifdef WITH_MONITOR_TRACKING
1158 /*
1159 * Remove the object from the Thread's list.
1160 */
1161 dvmRemoveFromMonitorList(self, obj);
1162#endif
1163
1164 return true;
1165}
1166
1167/*
1168 * Object.wait(). Also called for class init.
1169 */
1170void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1171 bool interruptShouldThrow)
1172{
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001173 Monitor* mon;
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001174 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001175
1176 /* If the lock is still thin, we need to fatten it.
1177 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001178 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001179 /* Make sure that 'self' holds the lock.
1180 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001181 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001182 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1183 "object not locked by thread before wait()");
1184 return;
1185 }
1186
1187 /* This thread holds the lock. We need to fatten the lock
1188 * so 'self' can block on it. Don't update the object lock
1189 * field yet, because 'self' needs to acquire the lock before
1190 * any other thread gets a chance.
1191 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001192 inflateMonitor(self, obj);
1193 LOG_THIN("(%d) lock %p fattened by wait() to count %d",
1194 self->threadId, &obj->lock, mon->lockCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001195 }
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001196 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001197 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1198}
1199
1200/*
1201 * Object.notify().
1202 */
1203void dvmObjectNotify(Thread* self, Object *obj)
1204{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001205 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001206
1207 /* If the lock is still thin, there aren't any waiters;
1208 * waiting on an object forces lock fattening.
1209 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001210 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001211 /* Make sure that 'self' holds the lock.
1212 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001213 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001214 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1215 "object not locked by thread before notify()");
1216 return;
1217 }
1218
1219 /* no-op; there are no waiters to notify.
1220 */
1221 } else {
1222 /* It's a fat lock.
1223 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001224 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001225 }
1226}
1227
1228/*
1229 * Object.notifyAll().
1230 */
1231void dvmObjectNotifyAll(Thread* self, Object *obj)
1232{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001233 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001234
1235 /* If the lock is still thin, there aren't any waiters;
1236 * waiting on an object forces lock fattening.
1237 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001238 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001239 /* Make sure that 'self' holds the lock.
1240 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001241 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001242 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1243 "object not locked by thread before notifyAll()");
1244 return;
1245 }
1246
1247 /* no-op; there are no waiters to notify.
1248 */
1249 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001250 /* It's a fat lock.
1251 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001252 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001253 }
1254}
1255
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001256/*
1257 * This implements java.lang.Thread.sleep(long msec, int nsec).
1258 *
1259 * The sleep is interruptible by other threads, which means we can't just
1260 * plop into an OS sleep call. (We probably could if we wanted to send
1261 * signals around and rely on EINTR, but that's inefficient and relies
1262 * on native code respecting our signal mask.)
1263 *
1264 * We have to do all of this stuff for Object.wait() as well, so it's
1265 * easiest to just sleep on a private Monitor.
1266 *
1267 * It appears that we want sleep(0,0) to go through the motions of sleeping
1268 * for a very short duration, rather than just returning.
1269 */
1270void dvmThreadSleep(u8 msec, u4 nsec)
1271{
1272 Thread* self = dvmThreadSelf();
1273 Monitor* mon = gDvm.threadSleepMon;
1274
1275 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1276 if (msec == 0 && nsec == 0)
1277 nsec++;
1278
1279 lockMonitor(self, mon);
1280 waitMonitor(self, mon, msec, nsec, true);
1281 unlockMonitor(self, mon);
1282}
1283
1284/*
1285 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001286 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001287void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001288{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001289 assert(thread != NULL);
1290
Carl Shapiro980ffb02010-03-13 22:34:01 -08001291 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001292
1293 /*
1294 * If the interrupted flag is already set no additional action is
1295 * required.
1296 */
1297 if (thread->interrupted == true) {
Carl Shapiro980ffb02010-03-13 22:34:01 -08001298 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001299 return;
1300 }
1301
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001302 /*
1303 * Raise the "interrupted" flag. This will cause it to bail early out
1304 * of the next wait() attempt, if it's not currently waiting on
1305 * something.
1306 */
1307 thread->interrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001308
1309 /*
1310 * Is the thread waiting?
1311 *
1312 * Note that fat vs. thin doesn't matter here; waitMonitor
1313 * is only set when a thread actually waits on a monitor,
1314 * which implies that the monitor has already been fattened.
1315 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001316 if (thread->waitMonitor != NULL) {
1317 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001318 }
1319
Carl Shapiro980ffb02010-03-13 22:34:01 -08001320 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001321}
1322
Carl Shapiro30aa9972010-01-13 22:07:50 -08001323#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001324u4 dvmIdentityHashCode(Object *obj)
1325{
1326 return (u4)obj;
1327}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001328#else
Carl Shapiro30aa9972010-01-13 22:07:50 -08001329/*
1330 * Returns the identity hash code of the given object.
1331 */
1332u4 dvmIdentityHashCode(Object *obj)
1333{
1334 Thread *self, *thread;
1335 volatile u4 *lw;
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001336 size_t size;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001337 u4 lock, owner, hashState;
1338
1339 if (obj == NULL) {
1340 /*
1341 * Null is defined to have an identity hash code of 0.
1342 */
1343 return 0;
1344 }
1345 lw = &obj->lock;
1346retry:
1347 hashState = LW_HASH_STATE(*lw);
1348 if (hashState == LW_HASH_STATE_HASHED) {
1349 /*
1350 * The object has been hashed but has not had its hash code
1351 * relocated by the garbage collector. Use the raw object
1352 * address.
1353 */
1354 return (u4)obj >> 3;
1355 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1356 /*
1357 * The object has been hashed and its hash code has been
1358 * relocated by the collector. Use the value of the naturally
1359 * aligned word following the instance data.
1360 */
Carl Shapiroc48b6d02010-05-04 11:19:53 -07001361 assert(obj->clazz != gDvm.classJavaLangClass);
Carl Shapiro30aa9972010-01-13 22:07:50 -08001362 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001363 size = dvmArrayObjectSize((ArrayObject *)obj);
Carl Shapiroc48b6d02010-05-04 11:19:53 -07001364 size = (size + 2) & ~2;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001365 } else {
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001366 size = obj->clazz->objectSize;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001367 }
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001368 return *(u4 *)(((char *)obj) + size);
Carl Shapiro30aa9972010-01-13 22:07:50 -08001369 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1370 /*
1371 * The object has never been hashed. Change the hash state to
1372 * hashed and use the raw object address.
1373 */
1374 self = dvmThreadSelf();
1375 if (self->threadId == lockOwner(obj)) {
1376 /*
1377 * We already own the lock so we can update the hash state
1378 * directly.
1379 */
1380 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1381 return (u4)obj >> 3;
1382 }
1383 /*
1384 * We do not own the lock. Try acquiring the lock. Should
1385 * this fail, we must suspend the owning thread.
1386 */
1387 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1388 /*
1389 * If the lock is thin assume it is unowned. We simulate
1390 * an acquire, update, and release with a single CAS.
1391 */
1392 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1393 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
Andy McFadden6e10b9a2010-06-14 15:24:39 -07001394 if (android_atomic_release_cas(
Carl Shapiro30aa9972010-01-13 22:07:50 -08001395 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
Andy McFadden6e10b9a2010-06-14 15:24:39 -07001396 (int32_t)lock,
1397 (int32_t *)lw) == 0) {
Carl Shapiro30aa9972010-01-13 22:07:50 -08001398 /*
1399 * A new lockword has been installed with a hash state
1400 * of hashed. Use the raw object address.
1401 */
1402 return (u4)obj >> 3;
1403 }
1404 } else {
1405 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1406 /*
1407 * The monitor lock has been acquired. Change the
1408 * hash state to hashed and use the raw object
1409 * address.
1410 */
1411 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1412 unlockMonitor(self, LW_MONITOR(*lw));
1413 return (u4)obj >> 3;
1414 }
1415 }
1416 /*
1417 * At this point we have failed to acquire the lock. We must
1418 * identify the owning thread and suspend it.
1419 */
1420 dvmLockThreadList(self);
1421 /*
1422 * Cache the lock word as its value can change between
1423 * determining its shape and retrieving its owner.
1424 */
1425 lock = *lw;
1426 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1427 /*
1428 * Find the thread with the corresponding thread id.
1429 */
1430 owner = LW_LOCK_OWNER(lock);
1431 assert(owner != self->threadId);
1432 /*
1433 * If the lock has no owner do not bother scanning the
1434 * thread list and fall through to the failure handler.
1435 */
1436 thread = owner ? gDvm.threadList : NULL;
1437 while (thread != NULL) {
1438 if (thread->threadId == owner) {
1439 break;
1440 }
1441 thread = thread->next;
1442 }
1443 } else {
1444 thread = LW_MONITOR(lock)->owner;
1445 }
1446 /*
1447 * If thread is NULL the object has been released since the
1448 * thread list lock was acquired. Try again.
1449 */
1450 if (thread == NULL) {
1451 dvmUnlockThreadList();
1452 goto retry;
1453 }
1454 /*
1455 * Wait for the owning thread to suspend.
1456 */
1457 dvmSuspendThread(thread);
1458 if (dvmHoldsLock(thread, obj)) {
1459 /*
1460 * The owning thread has been suspended. We can safely
1461 * change the hash state to hashed.
1462 */
1463 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1464 dvmResumeThread(thread);
1465 dvmUnlockThreadList();
1466 return (u4)obj >> 3;
1467 }
1468 /*
1469 * The wrong thread has been suspended. Try again.
1470 */
1471 dvmResumeThread(thread);
1472 dvmUnlockThreadList();
1473 goto retry;
1474 }
1475 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1476 dvmDumpThread(dvmThreadSelf(), false);
1477 dvmAbort();
1478 return 0; /* Quiet the compiler. */
1479}
1480#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001481
1482#ifdef WITH_DEADLOCK_PREDICTION
1483/*
1484 * ===========================================================================
1485 * Deadlock prediction
1486 * ===========================================================================
1487 */
1488/*
1489The idea is to predict the possibility of deadlock by recording the order
1490in which monitors are acquired. If we see an attempt to acquire a lock
1491out of order, we can identify the locks and offending code.
1492
1493To make this work, we need to keep track of the locks held by each thread,
1494and create history trees for each lock. When a thread tries to acquire
1495a new lock, we walk through the "history children" of the lock, looking
1496for a match with locks the thread already holds. If we find a match,
1497it means the thread has made a request that could result in a deadlock.
1498
1499To support recursive locks, we always allow re-locking a currently-held
1500lock, and maintain a recursion depth count.
1501
1502An ASCII-art example, where letters represent Objects:
1503
1504 A
1505 /|\
1506 / | \
1507 B | D
1508 \ |
1509 \|
1510 C
1511
1512The above is the tree we'd have after handling Object synchronization
1513sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1514a child of B. (The lines represent pointers between parent and child.
1515Every node can have multiple parents and multiple children.)
1516
1517If we hold AC, and want to lock B, we recursively search through B's
1518children to see if A or C appears. It does, so we reject the attempt.
1519(A straightforward way to implement it: add a link from C to B, then
1520determine whether the graph starting at B contains a cycle.)
1521
1522If we hold AC and want to lock D, we would succeed, creating a new link
1523from C to D.
1524
1525The lock history and a stack trace is attached to the Object's Monitor
1526struct, which means we need to fatten every Object we lock (thin locking
1527is effectively disabled). If we don't need the stack trace we can
1528avoid fattening the leaf nodes, only fattening objects that need to hold
1529history trees.
1530
1531Updates to Monitor structs are only allowed for the thread that holds
1532the Monitor, so we actually do most of our deadlock prediction work after
1533the lock has been acquired.
1534
1535When an object with a monitor is GCed, we need to remove it from the
1536history trees. There are two basic approaches:
1537 (1) For through the entire set of known monitors, search all child
1538 lists for the object in question. This is rather slow, resulting
1539 in GC passes that take upwards of 10 seconds to complete.
1540 (2) Maintain "parent" pointers in each node. Remove the entries as
1541 required. This requires additional storage and maintenance for
1542 every operation, but is significantly faster at GC time.
1543For each GCed object, we merge all of the object's children into each of
1544the object's parents.
1545*/
1546
1547#if !defined(WITH_MONITOR_TRACKING)
1548# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1549#endif
1550
1551/*
1552 * Clear out the contents of an ExpandingObjectList, freeing any
1553 * dynamic allocations.
1554 */
1555static void expandObjClear(ExpandingObjectList* pList)
1556{
1557 if (pList->list != NULL) {
1558 free(pList->list);
1559 pList->list = NULL;
1560 }
1561 pList->alloc = pList->count = 0;
1562}
1563
1564/*
1565 * Get the number of objects currently stored in the list.
1566 */
1567static inline int expandBufGetCount(const ExpandingObjectList* pList)
1568{
1569 return pList->count;
1570}
1571
1572/*
1573 * Get the Nth entry from the list.
1574 */
1575static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1576 int i)
1577{
1578 return pList->list[i];
1579}
1580
1581/*
1582 * Add a new entry to the list.
1583 *
1584 * We don't check for or try to enforce uniqueness. It's expected that
1585 * the higher-level code does this for us.
1586 */
1587static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1588{
1589 if (pList->count == pList->alloc) {
1590 /* time to expand */
1591 Object** newList;
1592
1593 if (pList->alloc == 0)
1594 pList->alloc = 4;
1595 else
1596 pList->alloc *= 2;
1597 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1598 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1599 if (newList == NULL) {
1600 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1601 dvmAbort();
1602 }
1603 pList->list = newList;
1604 }
1605
1606 pList->list[pList->count++] = obj;
1607}
1608
1609/*
1610 * Returns "true" if the element was successfully removed.
1611 */
1612static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1613{
1614 int i;
1615
1616 for (i = pList->count-1; i >= 0; i--) {
1617 if (pList->list[i] == obj)
1618 break;
1619 }
1620 if (i < 0)
1621 return false;
1622
1623 if (i != pList->count-1) {
1624 /*
1625 * The order of elements is not important, so we just copy the
1626 * last entry into the new slot.
1627 */
1628 //memmove(&pList->list[i], &pList->list[i+1],
1629 // (pList->count-1 - i) * sizeof(pList->list[0]));
1630 pList->list[i] = pList->list[pList->count-1];
1631 }
1632
1633 pList->count--;
1634 pList->list[pList->count] = (Object*) 0xdecadead;
1635 return true;
1636}
1637
1638/*
1639 * Returns "true" if "obj" appears in the list.
1640 */
1641static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1642{
1643 int i;
1644
1645 for (i = 0; i < pList->count; i++) {
1646 if (pList->list[i] == obj)
1647 return true;
1648 }
1649 return false;
1650}
1651
1652/*
1653 * Print the list contents to stdout. For debugging.
1654 */
1655static void expandObjDump(const ExpandingObjectList* pList)
1656{
1657 int i;
1658 for (i = 0; i < pList->count; i++)
1659 printf(" %p", pList->list[i]);
1660}
1661
1662/*
1663 * Check for duplicate entries. Returns the index of the first instance
1664 * of the duplicated value, or -1 if no duplicates were found.
1665 */
1666static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1667{
1668 int i, j;
1669 for (i = 0; i < pList->count-1; i++) {
1670 for (j = i + 1; j < pList->count; j++) {
1671 if (pList->list[i] == pList->list[j]) {
1672 return i;
1673 }
1674 }
1675 }
1676
1677 return -1;
1678}
1679
1680
1681/*
1682 * Determine whether "child" appears in the list of objects associated
1683 * with the Monitor in "parent". If "parent" is a thin lock, we return
1684 * false immediately.
1685 */
1686static bool objectInChildList(const Object* parent, Object* child)
1687{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001688 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001689 if (!IS_LOCK_FAT(&lock)) {
1690 //LOGI("on thin\n");
1691 return false;
1692 }
1693
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001694 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001695}
1696
1697/*
1698 * Print the child list.
1699 */
1700static void dumpKids(Object* parent)
1701{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001702 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001703
1704 printf("Children of %p:", parent);
1705 expandObjDump(&mon->historyChildren);
1706 printf("\n");
1707}
1708
1709/*
1710 * Add "child" to the list of children in "parent", and add "parent" to
1711 * the list of parents in "child".
1712 */
1713static void linkParentToChild(Object* parent, Object* child)
1714{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001715 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001716 assert(IS_LOCK_FAT(&parent->lock));
1717 assert(IS_LOCK_FAT(&child->lock));
1718 assert(parent != child);
1719 Monitor* mon;
1720
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001721 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001722 assert(!expandObjHas(&mon->historyChildren, child));
1723 expandObjAddEntry(&mon->historyChildren, child);
1724
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001725 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001726 assert(!expandObjHas(&mon->historyParents, parent));
1727 expandObjAddEntry(&mon->historyParents, parent);
1728}
1729
1730
1731/*
1732 * Remove "child" from the list of children in "parent".
1733 */
1734static void unlinkParentFromChild(Object* parent, Object* child)
1735{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001736 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001737 assert(IS_LOCK_FAT(&parent->lock));
1738 assert(IS_LOCK_FAT(&child->lock));
1739 assert(parent != child);
1740 Monitor* mon;
1741
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001742 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001743 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1744 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1745 }
1746 assert(!expandObjHas(&mon->historyChildren, child));
1747 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1748
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001749 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001750 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1751 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1752 }
1753 assert(!expandObjHas(&mon->historyParents, parent));
1754 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1755}
1756
1757
1758/*
1759 * Log the monitors held by the current thread. This is done as part of
1760 * flagging an error.
1761 */
1762static void logHeldMonitors(Thread* self)
1763{
1764 char* name = NULL;
1765
1766 name = dvmGetThreadName(self);
1767 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1768 self->threadId, name);
1769 LOGW("(most-recently-acquired on top):\n");
1770 free(name);
1771
1772 LockedObjectData* lod = self->pLockedObjects;
1773 while (lod != NULL) {
1774 LOGW("--- object %p[%d] (%s)\n",
1775 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1776 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1777
1778 lod = lod->next;
1779 }
1780}
1781
1782/*
1783 * Recursively traverse the object hierarchy starting at "obj". We mark
1784 * ourselves on entry and clear the mark on exit. If we ever encounter
1785 * a marked object, we have a cycle.
1786 *
1787 * Returns "true" if all is well, "false" if we found a cycle.
1788 */
1789static bool traverseTree(Thread* self, const Object* obj)
1790{
1791 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001792 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001793
1794 /*
1795 * Have we been here before?
1796 */
1797 if (mon->historyMark) {
1798 int* rawStackTrace;
1799 int stackDepth;
1800
1801 LOGW("%s\n", kStartBanner);
1802 LOGW("Illegal lock attempt:\n");
1803 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1804
1805 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1806 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1807 free(rawStackTrace);
1808
1809 LOGW(" ");
1810 logHeldMonitors(self);
1811
1812 LOGW(" ");
1813 LOGW("Earlier, the following lock order (from last to first) was\n");
1814 LOGW("established -- stack trace is from first successful lock):\n");
1815 return false;
1816 }
1817 mon->historyMark = true;
1818
1819 /*
1820 * Examine the children. We do NOT hold these locks, so they might
1821 * very well transition from thin to fat or change ownership while
1822 * we work.
1823 *
1824 * NOTE: we rely on the fact that they cannot revert from fat to thin
1825 * while we work. This is currently a safe assumption.
1826 *
1827 * We can safely ignore thin-locked children, because by definition
1828 * they have no history and are leaf nodes. In the current
1829 * implementation we always fatten the locks to provide a place to
1830 * hang the stack trace.
1831 */
1832 ExpandingObjectList* pList = &mon->historyChildren;
1833 int i;
1834 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1835 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001836 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001837 if (!IS_LOCK_FAT(&lock))
1838 continue;
1839 if (!traverseTree(self, child)) {
1840 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1841 dvmLogRawStackTrace(mon->historyRawStackTrace,
1842 mon->historyStackDepth);
1843 mon->historyMark = false;
1844 return false;
1845 }
1846 }
1847
1848 mon->historyMark = false;
1849
1850 return true;
1851}
1852
1853/*
1854 * Update the deadlock prediction tree, based on the current thread
1855 * acquiring "acqObj". This must be called before the object is added to
1856 * the thread's list of held monitors.
1857 *
1858 * If the thread already holds the lock (recursion), or this is a known
1859 * lock configuration, we return without doing anything. Otherwise, we add
1860 * a link from the most-recently-acquired lock in this thread to "acqObj"
1861 * after ensuring that the parent lock is "fat".
1862 *
1863 * This MUST NOT be called while a GC is in progress in another thread,
1864 * because we assume exclusive access to history trees in owned monitors.
1865 */
1866static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1867{
1868 LockedObjectData* lod;
1869 LockedObjectData* mrl;
1870
1871 /*
1872 * Quick check for recursive access.
1873 */
1874 lod = dvmFindInMonitorList(self, acqObj);
1875 if (lod != NULL) {
1876 LOGV("+++ DP: recursive %p\n", acqObj);
1877 return;
1878 }
1879
1880 /*
1881 * Make the newly-acquired object's monitor "fat". In some ways this
1882 * isn't strictly necessary, but we need the GC to tell us when
1883 * "interesting" objects go away, and right now the only way to make
1884 * an object look interesting is to give it a monitor.
1885 *
1886 * This also gives us a place to hang a stack trace.
1887 *
1888 * Our thread holds the lock, so we're allowed to rewrite the lock
1889 * without worrying that something will change out from under us.
1890 */
1891 if (!IS_LOCK_FAT(&acqObj->lock)) {
1892 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001893 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001894 inflateMonitor(self, acqObj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001895 }
1896
1897 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001898 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1899 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001900 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1901 &mon->historyStackDepth);
1902 }
1903
1904 /*
1905 * We need to examine and perhaps modify the most-recently-locked
1906 * monitor. We own that, so there's no risk of another thread
1907 * stepping on us.
1908 *
1909 * Retrieve the most-recently-locked entry from our thread.
1910 */
1911 mrl = self->pLockedObjects;
1912 if (mrl == NULL)
1913 return; /* no other locks held */
1914
1915 /*
1916 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1917 * this without holding the global lock because of our assertion that
1918 * a GC is not running in parallel -- nobody except the GC can
1919 * modify a history list in a Monitor they don't own, and we own "mrl".
1920 * (There might be concurrent *reads*, but no concurrent *writes.)
1921 *
1922 * If we find it, this is a known good configuration, and we're done.
1923 */
1924 if (objectInChildList(mrl->obj, acqObj))
1925 return;
1926
1927 /*
1928 * "mrl" is going to need to have a history tree. If it's currently
1929 * a thin lock, we make it fat now. The thin lock might have a
1930 * nonzero recursive lock count, which we need to carry over.
1931 *
1932 * Our thread holds the lock, so we're allowed to rewrite the lock
1933 * without worrying that something will change out from under us.
1934 */
1935 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1936 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001937 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001938 inflateMonitor(self, mrl->obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001939 }
1940
1941 /*
1942 * We haven't seen this configuration before. We need to scan down
1943 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1944 * appear. We grab a global lock before traversing or updating the
1945 * history list.
1946 *
1947 * If we find a match for any of our held locks, we know that the lock
1948 * has previously been acquired *after* acqObj, and we throw an error.
1949 *
1950 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1951 * and do a recursive traversal, marking nodes as we cross them. If
1952 * we cross one a second time, we have a cycle and can throw an error.
1953 * (We do the flag-clearing traversal before adding the new link, so
1954 * that we're guaranteed to terminate.)
1955 *
1956 * If "acqObj" is a thin lock, it has no history, and we can create a
1957 * link to it without additional checks. [ We now guarantee that it's
1958 * always fat. ]
1959 */
1960 bool failed = false;
1961 dvmLockMutex(&gDvm.deadlockHistoryLock);
1962 linkParentToChild(mrl->obj, acqObj);
1963 if (!traverseTree(self, acqObj)) {
1964 LOGW("%s\n", kEndBanner);
1965 failed = true;
1966
1967 /* remove the entry so we're still okay when in "warning" mode */
1968 unlinkParentFromChild(mrl->obj, acqObj);
1969 }
1970 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1971
1972 if (failed) {
1973 switch (gDvm.deadlockPredictMode) {
1974 case kDPErr:
1975 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1976 break;
1977 case kDPAbort:
1978 LOGE("Aborting due to potential deadlock\n");
1979 dvmAbort();
1980 break;
1981 default:
1982 /* warn only */
1983 break;
1984 }
1985 }
1986}
1987
1988/*
1989 * We're removing "child" from existence. We want to pull all of
1990 * child's children into "parent", filtering out duplicates. This is
1991 * called during the GC.
1992 *
1993 * This does not modify "child", which might have multiple parents.
1994 */
1995static void mergeChildren(Object* parent, const Object* child)
1996{
1997 Monitor* mon;
1998 int i;
1999
2000 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002001 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002002 ExpandingObjectList* pList = &mon->historyChildren;
2003
2004 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2005 Object* grandChild = expandBufGetEntry(pList, i);
2006
2007 if (!objectInChildList(parent, grandChild)) {
2008 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
2009 linkParentToChild(parent, grandChild);
2010 } else {
2011 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
2012 }
2013 }
2014}
2015
2016/*
2017 * An object with a fat lock is being collected during a GC pass. We
2018 * want to remove it from any lock history trees that it is a part of.
2019 *
2020 * This may require updating the history trees in several monitors. The
2021 * monitor semantics guarantee that no other thread will be accessing
2022 * the history trees at the same time.
2023 */
2024static void removeCollectedObject(Object* obj)
2025{
2026 Monitor* mon;
2027
2028 LOGVV("+++ collecting %p\n", obj);
2029
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002030 /*
2031 * For every parent of this object:
2032 * - merge all of our children into the parent's child list (creates
2033 * a two-way link between parent and child)
2034 * - remove ourselves from the parent's child list
2035 */
2036 ExpandingObjectList* pList;
2037 int i;
2038
2039 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002040 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002041 pList = &mon->historyParents;
2042 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2043 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002044 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002045
2046 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2047 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2048 }
2049 assert(!expandObjHas(&parentMon->historyChildren, obj));
2050
2051 mergeChildren(parent, obj);
2052 }
2053
2054 /*
2055 * For every child of this object:
2056 * - remove ourselves from the child's parent list
2057 */
2058 pList = &mon->historyChildren;
2059 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2060 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002061 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002062
2063 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2064 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2065 }
2066 assert(!expandObjHas(&childMon->historyParents, obj));
2067 }
2068}
2069
2070#endif /*WITH_DEADLOCK_PREDICTION*/