blob: 5380f3ed871b5a9d88d6520b3ad7d44c5b560121 [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);
336 prev = &handle;
337 prev->next = curr = *mon;
338 while (curr != NULL) {
339 obj = curr->obj;
340 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
341 prev->next = curr = curr->next;
342 freeObjectMonitor(obj);
343 } else {
344 prev = curr;
345 curr = curr->next;
346 }
347 }
348 *mon = handle.next;
349}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800350
Carl Shapirof0c514c2010-04-09 15:03:33 -0700351static char *logWriteInt(char *dst, int value)
352{
353 *dst++ = EVENT_TYPE_INT;
354 set4LE((u1 *)dst, value);
355 return dst + 4;
356}
357
358static char *logWriteString(char *dst, const char *value, size_t len)
359{
360 *dst++ = EVENT_TYPE_STRING;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700361 len = len < 32 ? len : 32;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700362 set4LE((u1 *)dst, len);
363 dst += 4;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700364 memcpy(dst, value, len);
365 return dst + len;
366}
367
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700368#define EVENT_LOG_TAG_dvm_lock_sample 20003
Carl Shapirof0c514c2010-04-09 15:03:33 -0700369
370static void logContentionEvent(Thread *self, u4 waitMs, u4 samplePercent)
371{
372 const StackSaveArea *saveArea;
373 const Method *meth;
374 u4 relativePc;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700375 char eventBuffer[132];
Carl Shapirof0c514c2010-04-09 15:03:33 -0700376 const char *fileName;
Carl Shapiroe3c01da2010-05-20 22:54:18 -0700377 char procName[33], *selfName;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700378 char *cp;
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700379 size_t len;
380 int fd;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700381
382 saveArea = SAVEAREA_FROM_FP(self->curFrame);
383 meth = saveArea->method;
384 cp = eventBuffer;
385
386 /* Emit the event list length, 1 byte. */
387 *cp++ = 7;
388
389 /* Emit the process name, <= 37 bytes. */
390 fd = open("/proc/self/cmdline", O_RDONLY);
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700391 memset(procName, 0, sizeof(procName));
392 read(fd, procName, sizeof(procName) - 1);
Carl Shapirof0c514c2010-04-09 15:03:33 -0700393 close(fd);
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700394 len = strlen(procName);
395 cp = logWriteString(cp, procName, len);
Carl Shapirof0c514c2010-04-09 15:03:33 -0700396
397 /* Emit the main thread status, 5 bytes. */
398 bool isMainThread = (self->systemTid == getpid());
399 cp = logWriteInt(cp, isMainThread);
400
401 /* Emit self thread name string, <= 37 bytes. */
402 selfName = dvmGetThreadName(self);
403 cp = logWriteString(cp, selfName, strlen(selfName));
404 free(selfName);
405
406 /* Emit the wait time, 5 bytes. */
407 cp = logWriteInt(cp, waitMs);
408
409 /* Emit the source code file name, <= 37 bytes. */
410 fileName = dvmGetMethodSourceFile(meth);
411 if (fileName == NULL) fileName = "";
412 cp = logWriteString(cp, fileName, strlen(fileName));
413
414 /* Emit the source code line number, 5 bytes. */
415 relativePc = saveArea->xtra.currentPc - saveArea->method->insns;
416 cp = logWriteInt(cp, dvmLineNumFromPC(meth, relativePc));
417
418 /* Emit the sample percentage, 5 bytes. */
419 cp = logWriteInt(cp, samplePercent);
420
421 assert((size_t)(cp - eventBuffer) <= sizeof(eventBuffer));
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700422 android_btWriteLog(EVENT_LOG_TAG_dvm_lock_sample,
Carl Shapirof0c514c2010-04-09 15:03:33 -0700423 EVENT_TYPE_LIST,
424 eventBuffer,
425 (size_t)(cp - eventBuffer));
426}
427
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800428/*
429 * Lock a monitor.
430 */
431static void lockMonitor(Thread* self, Monitor* mon)
432{
Carl Shapirof0c514c2010-04-09 15:03:33 -0700433 ThreadStatus oldStatus;
434 u4 waitThreshold, samplePercent;
435 u8 waitStart, waitEnd, waitMs;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800436
437 if (mon->owner == self) {
438 mon->lockCount++;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700439 return;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800440 }
Carl Shapiro045fdc92010-04-13 16:48:27 -0700441 if (dvmTryLockMutex(&mon->lock) != 0) {
Carl Shapirof0c514c2010-04-09 15:03:33 -0700442 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
443 waitThreshold = gDvm.lockProfThreshold;
444 if (waitThreshold) {
445 waitStart = dvmGetRelativeTimeUsec();
446 }
447 dvmLockMutex(&mon->lock);
448 if (waitThreshold) {
449 waitEnd = dvmGetRelativeTimeUsec();
450 }
451 dvmChangeStatus(self, oldStatus);
452 if (waitThreshold) {
453 waitMs = (waitEnd - waitStart) / 1000;
454 if (waitMs >= waitThreshold) {
455 samplePercent = 100;
456 } else {
Carl Shapiroaf69cf82010-04-16 17:33:15 -0700457 samplePercent = 100 * waitMs / waitThreshold;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700458 }
Carl Shapirob8fcf572010-04-16 17:33:15 -0700459 if (samplePercent != 0 && ((u4)rand() % 100 < samplePercent)) {
Carl Shapirof0c514c2010-04-09 15:03:33 -0700460 logContentionEvent(self, waitMs, samplePercent);
461 }
462 }
463 }
464 mon->owner = self;
465 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800466}
467
468/*
469 * Try to lock a monitor.
470 *
471 * Returns "true" on success.
472 */
Carl Shapirob31b3012010-05-25 18:35:37 -0700473#ifdef WITH_COPYING_GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800474static bool tryLockMonitor(Thread* self, Monitor* mon)
475{
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800476 if (mon->owner == self) {
477 mon->lockCount++;
478 return true;
479 } else {
Carl Shapiro980ffb02010-03-13 22:34:01 -0800480 if (dvmTryLockMutex(&mon->lock) == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800481 mon->owner = self;
482 assert(mon->lockCount == 0);
483 return true;
484 } else {
485 return false;
486 }
487 }
488}
Carl Shapirob31b3012010-05-25 18:35:37 -0700489#endif
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800490
491/*
492 * Unlock a monitor.
493 *
494 * Returns true if the unlock succeeded.
495 * If the unlock failed, an exception will be pending.
496 */
497static bool unlockMonitor(Thread* self, Monitor* mon)
498{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800499 assert(self != NULL);
Carl Shapiro92277082010-04-06 15:35:59 -0700500 assert(mon != NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800501 if (mon->owner == self) {
502 /*
503 * We own the monitor, so nobody else can be in here.
504 */
505 if (mon->lockCount == 0) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800506 mon->owner = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800507 dvmUnlockMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800508 } else {
509 mon->lockCount--;
510 }
511 } else {
512 /*
513 * We don't own this, so we're not allowed to unlock it.
514 * The JNI spec says that we should throw IllegalMonitorStateException
515 * in this case.
516 */
Carl Shapiro8782d7c2010-04-19 20:10:35 -0700517 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
518 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800519 return false;
520 }
521 return true;
522}
523
524/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800525 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800526 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800527 */
Carl Shapirob31b3012010-05-25 18:35:37 -0700528#ifndef NDEBUG
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800529static int waitSetCheck(Monitor *mon)
530{
531 Thread *fast, *slow;
532 size_t n;
533
534 assert(mon != NULL);
535 fast = slow = mon->waitSet;
536 n = 0;
537 for (;;) {
538 if (fast == NULL) return 0;
539 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800540 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800541 n += 2;
542 fast = fast->waitNext->waitNext;
543 slow = slow->waitNext;
544 }
545}
Carl Shapirob31b3012010-05-25 18:35:37 -0700546#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800547
548/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800549 * Links a thread into a monitor's wait set. The monitor lock must be
550 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800551 */
552static void waitSetAppend(Monitor *mon, Thread *thread)
553{
554 Thread *elt;
555
556 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800557 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800558 assert(thread != NULL);
559 assert(thread->waitNext == NULL);
560 assert(waitSetCheck(mon) == 0);
561 if (mon->waitSet == NULL) {
562 mon->waitSet = thread;
563 return;
564 }
565 elt = mon->waitSet;
566 while (elt->waitNext != NULL) {
567 elt = elt->waitNext;
568 }
569 elt->waitNext = thread;
570}
571
572/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800573 * Unlinks a thread from a monitor's wait set. The monitor lock must
574 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800575 */
576static void waitSetRemove(Monitor *mon, Thread *thread)
577{
578 Thread *elt;
579
580 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800581 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800582 assert(thread != NULL);
583 assert(waitSetCheck(mon) == 0);
584 if (mon->waitSet == NULL) {
585 return;
586 }
587 if (mon->waitSet == thread) {
588 mon->waitSet = thread->waitNext;
589 thread->waitNext = NULL;
590 return;
591 }
592 elt = mon->waitSet;
593 while (elt->waitNext != NULL) {
594 if (elt->waitNext == thread) {
595 elt->waitNext = thread->waitNext;
596 thread->waitNext = NULL;
597 return;
598 }
599 elt = elt->waitNext;
600 }
601}
602
Carl Shapirob4539192010-01-04 16:50:00 -0800603/*
604 * Converts the given relative waiting time into an absolute time.
605 */
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800606void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800607{
608 s8 endSec;
609
610#ifdef HAVE_TIMEDWAIT_MONOTONIC
611 clock_gettime(CLOCK_MONOTONIC, ts);
612#else
613 {
614 struct timeval tv;
615 gettimeofday(&tv, NULL);
616 ts->tv_sec = tv.tv_sec;
617 ts->tv_nsec = tv.tv_usec * 1000;
618 }
619#endif
620 endSec = ts->tv_sec + msec / 1000;
621 if (endSec >= 0x7fffffff) {
622 LOGV("NOTE: end time exceeds epoch\n");
623 endSec = 0x7ffffffe;
624 }
625 ts->tv_sec = endSec;
626 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
627
628 /* catch rollover */
629 if (ts->tv_nsec >= 1000000000L) {
630 ts->tv_sec++;
631 ts->tv_nsec -= 1000000000L;
632 }
633}
634
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800635int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
636 s8 msec, s4 nsec)
637{
638 int ret;
639 struct timespec ts;
640 absoluteTime(msec, nsec, &ts);
641#if defined(HAVE_TIMEDWAIT_MONOTONIC)
642 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
643#else
644 ret = pthread_cond_timedwait(cond, mutex, &ts);
645#endif
646 assert(ret == 0 || ret == ETIMEDOUT);
647 return ret;
648}
649
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800650/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800651 * Wait on a monitor until timeout, interrupt, or notification. Used for
652 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
653 *
654 * If another thread calls Thread.interrupt(), we throw InterruptedException
655 * and return immediately if one of the following are true:
656 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
657 * - blocked in join(), join(long), or join(long, int) methods of Thread
658 * - blocked in sleep(long), or sleep(long, int) methods of Thread
659 * Otherwise, we set the "interrupted" flag.
660 *
661 * Checks to make sure that "nsec" is in the range 0-999999
662 * (i.e. fractions of a millisecond) and throws the appropriate
663 * exception if it isn't.
664 *
665 * The spec allows "spurious wakeups", and recommends that all code using
666 * Object.wait() do so in a loop. This appears to derive from concerns
667 * about pthread_cond_wait() on multiprocessor systems. Some commentary
668 * on the web casts doubt on whether these can/should occur.
669 *
670 * Since we're allowed to wake up "early", we clamp extremely long durations
671 * to return at the end of the 32-bit time epoch.
672 */
673static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
674 bool interruptShouldThrow)
675{
676 struct timespec ts;
677 bool wasInterrupted = false;
678 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800679 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800680
Carl Shapiro71938022009-12-22 13:49:53 -0800681 assert(self != NULL);
682 assert(mon != NULL);
683
Carl Shapiro94338aa2009-12-21 11:42:59 -0800684 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800685 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800686 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
687 "object not locked by thread before wait()");
688 return;
689 }
690
691 /*
692 * Enforce the timeout range.
693 */
694 if (msec < 0 || nsec < 0 || nsec > 999999) {
695 dvmThrowException("Ljava/lang/IllegalArgumentException;",
696 "timeout arguments out of range");
697 return;
698 }
699
700 /*
701 * Compute absolute wakeup time, if necessary.
702 */
703 if (msec == 0 && nsec == 0) {
704 timed = false;
705 } else {
Bill Buzbeefccb31d2010-02-04 16:09:55 -0800706 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800707 timed = true;
708 }
709
710 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800711 * Add ourselves to the set of threads waiting on this monitor, and
712 * release our hold. We need to let it go even if we're a few levels
713 * deep in a recursive lock, and we need to restore that later.
714 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800715 * We append to the wait set ahead of clearing the count and owner
716 * fields so the subroutine can check that the calling thread owns
717 * the monitor. Aside from that, the order of member updates is
718 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800719 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800720 waitSetAppend(mon, self);
721 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800722 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800723 mon->owner = NULL;
724
725 /*
726 * Update thread status. If the GC wakes up, it'll ignore us, knowing
727 * that we won't touch any references in this state, and we'll check
728 * our suspend mode before we transition out.
729 */
730 if (timed)
731 dvmChangeStatus(self, THREAD_TIMED_WAIT);
732 else
733 dvmChangeStatus(self, THREAD_WAIT);
734
Carl Shapiro980ffb02010-03-13 22:34:01 -0800735 dvmLockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800736
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800737 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800738 * Set waitMonitor to the monitor object we will be waiting on.
739 * When waitMonitor is non-NULL a notifying or interrupting thread
740 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800741 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800742 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800743 self->waitMonitor = mon;
744
745 /*
746 * Handle the case where the thread was interrupted before we called
747 * wait().
748 */
749 if (self->interrupted) {
750 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800751 self->waitMonitor = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800752 dvmUnlockMutex(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800753 goto done;
754 }
755
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800756 /*
757 * Release the monitor lock and wait for a notification or
758 * a timeout to occur.
759 */
Carl Shapiro980ffb02010-03-13 22:34:01 -0800760 dvmUnlockMutex(&mon->lock);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800761
762 if (!timed) {
763 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
764 assert(ret == 0);
765 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800766#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800767 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800768#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800769 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800770#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800771 assert(ret == 0 || ret == ETIMEDOUT);
772 }
773 if (self->interrupted) {
774 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800775 }
776
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800777 self->interrupted = false;
778 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800779
Carl Shapiro980ffb02010-03-13 22:34:01 -0800780 dvmUnlockMutex(&self->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800781
Carl Shapiro30aa9972010-01-13 22:07:50 -0800782 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800783 lockMonitor(self, mon);
784
Carl Shapiro142ef272010-01-25 12:51:31 -0800785done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800786 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800787 * We remove our thread from wait set after restoring the count
788 * and owner fields so the subroutine can check that the calling
789 * thread owns the monitor. Aside from that, the order of member
790 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800791 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800792 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800793 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800794 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800795
796 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
797 dvmChangeStatus(self, THREAD_RUNNING);
798
799 if (wasInterrupted) {
800 /*
801 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800802 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800803 *
804 * The doc sayeth: "The interrupted status of the current thread is
805 * cleared when this exception is thrown."
806 */
807 self->interrupted = false;
808 if (interruptShouldThrow)
809 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
810 }
811}
812
813/*
814 * Notify one thread waiting on this monitor.
815 */
816static void notifyMonitor(Thread* self, Monitor* mon)
817{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800818 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800819
Carl Shapiro71938022009-12-22 13:49:53 -0800820 assert(self != NULL);
821 assert(mon != NULL);
822
Carl Shapiro94338aa2009-12-21 11:42:59 -0800823 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800824 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800825 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
826 "object not locked by thread before notify()");
827 return;
828 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800829 /* Signal the first waiting thread in the wait set. */
830 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800831 thread = mon->waitSet;
832 mon->waitSet = thread->waitNext;
833 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800834 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800835 /* Check to see if the thread is still waiting. */
836 if (thread->waitMonitor != NULL) {
837 pthread_cond_signal(&thread->waitCond);
Carl Shapiro980ffb02010-03-13 22:34:01 -0800838 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800839 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800840 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800841 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800842 }
843}
844
845/*
846 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800847 */
848static void notifyAllMonitor(Thread* self, Monitor* mon)
849{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800850 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800851
Carl Shapiro71938022009-12-22 13:49:53 -0800852 assert(self != NULL);
853 assert(mon != NULL);
854
Carl Shapiro94338aa2009-12-21 11:42:59 -0800855 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800856 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800857 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
858 "object not locked by thread before notifyAll()");
859 return;
860 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800861 /* Signal all threads in the wait set. */
862 while (mon->waitSet != NULL) {
863 thread = mon->waitSet;
864 mon->waitSet = thread->waitNext;
865 thread->waitNext = NULL;
Carl Shapiro980ffb02010-03-13 22:34:01 -0800866 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800867 /* Check to see if the thread is still waiting. */
868 if (thread->waitMonitor != NULL) {
869 pthread_cond_signal(&thread->waitCond);
870 }
Carl Shapiro980ffb02010-03-13 22:34:01 -0800871 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800872 }
873}
874
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800875/*
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800876 * Changes the shape of a monitor from thin to fat, preserving the
877 * internal lock state. The calling thread must own the lock.
878 */
879static void inflateMonitor(Thread *self, Object *obj)
880{
881 Monitor *mon;
882 u4 thin;
883
884 assert(self != NULL);
885 assert(obj != NULL);
886 assert(LW_SHAPE(obj->lock) == LW_SHAPE_THIN);
887 assert(LW_LOCK_OWNER(obj->lock) == self->threadId);
888 /* Allocate and acquire a new monitor. */
889 mon = dvmCreateMonitor(obj);
890 lockMonitor(self, mon);
891 /* Propagate the lock state. */
892 thin = obj->lock;
893 mon->lockCount = LW_LOCK_COUNT(thin);
894 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
895 thin |= (u4)mon | LW_SHAPE_FAT;
896 /* Publish the updated lock word. */
Andy McFadden6e10b9a2010-06-14 15:24:39 -0700897 ANDROID_MEMBAR_FULL();
Carl Shapiro66bb7df2010-03-12 15:25:37 -0800898 obj->lock = thin;
899}
900
901/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800902 * Implements monitorenter for "synchronized" stuff.
903 *
904 * This does not fail or throw an exception (unless deadlock prediction
905 * is enabled and set to "err" mode).
906 */
907void dvmLockObject(Thread* self, Object *obj)
908{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800909 volatile u4 *thinp;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800910 ThreadStatus oldStatus;
911 useconds_t sleepDelay;
912 const useconds_t maxSleepDelay = 1 << 20;
913 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800914
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800915 assert(self != NULL);
916 assert(obj != NULL);
917 threadId = self->threadId;
918 thinp = &obj->lock;
919retry:
920 thin = *thinp;
921 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
922 /*
923 * The lock is a thin lock. The owner field is used to
924 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800925 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800926 if (LW_LOCK_OWNER(thin) == threadId) {
927 /*
928 * The calling thread owns the lock. Increment the
929 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800930 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800931 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
932 } else if (LW_LOCK_OWNER(thin) == 0) {
933 /*
934 * The lock is unowned. Install the thread id of the
935 * calling thread into the owner field. This is the
936 * common case. In performance critical code the JIT
937 * will have tried this before calling out to the VM.
938 */
939 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
Andy McFadden6e10b9a2010-06-14 15:24:39 -0700940 if (android_atomic_release_cas(thin, newThin,
941 (int32_t*)thinp) != 0) {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800942 /*
943 * The acquire failed. Try again.
944 */
945 goto retry;
946 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800947 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800948 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
949 threadId, &obj->lock, 0, *thinp, thin);
950 /*
951 * The lock is owned by another thread. Notify the VM
952 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800953 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800954 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
955 /*
956 * Spin until the thin lock is released or inflated.
957 */
958 sleepDelay = 0;
959 for (;;) {
960 thin = *thinp;
961 /*
962 * Check the shape of the lock word. Another thread
963 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800964 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800965 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
966 if (LW_LOCK_OWNER(thin) == 0) {
967 /*
968 * The lock has been released. Install the
969 * thread id of the calling thread into the
970 * owner field.
971 */
972 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
Andy McFadden6e10b9a2010-06-14 15:24:39 -0700973 if (android_atomic_release_cas(thin, newThin,
974 (int32_t *)thinp) == 0) {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800975 /*
976 * The acquire succeed. Break out of the
977 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800978 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800979 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800980 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800981 } else {
982 /*
983 * The lock has not been released. Yield so
984 * the owning thread can run.
985 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800986 if (sleepDelay == 0) {
987 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800988 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800989 } else {
990 usleep(sleepDelay);
991 if (sleepDelay < maxSleepDelay / 2) {
992 sleepDelay *= 2;
993 }
994 }
995 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800996 } else {
997 /*
998 * The thin lock was inflated by another thread.
999 * Let the VM know we are no longer waiting and
1000 * try again.
1001 */
1002 LOG_THIN("(%d) lock %p surprise-fattened",
1003 threadId, &obj->lock);
1004 dvmChangeStatus(self, oldStatus);
1005 goto retry;
1006 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001007 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001008 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
1009 threadId, &obj->lock, 0, *thinp, thin);
1010 /*
1011 * We have acquired the thin lock. Let the VM know that
1012 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001013 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001014 dvmChangeStatus(self, oldStatus);
1015 /*
1016 * Fatten the lock.
1017 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001018 inflateMonitor(self, obj);
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001019 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001020 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001021 } else {
1022 /*
1023 * The lock is a fat lock.
1024 */
1025 assert(LW_MONITOR(obj->lock) != NULL);
1026 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001027 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001028#ifdef WITH_DEADLOCK_PREDICTION
1029 /*
1030 * See if we were allowed to grab the lock at this time. We do it
1031 * *after* acquiring the lock, rather than before, so that we can
1032 * freely update the Monitor struct. This seems counter-intuitive,
1033 * but our goal is deadlock *prediction* not deadlock *prevention*.
1034 * (If we actually deadlock, the situation is easy to diagnose from
1035 * a thread dump, so there's no point making a special effort to do
1036 * the checks before the lock is held.)
1037 *
1038 * This needs to happen before we add the object to the thread's
1039 * monitor list, so we can tell the difference between first-lock and
1040 * re-lock.
1041 *
1042 * It's also important that we do this while in THREAD_RUNNING, so
1043 * that we don't interfere with cleanup operations in the GC.
1044 */
1045 if (gDvm.deadlockPredictMode != kDPOff) {
1046 if (self->status != THREAD_RUNNING) {
1047 LOGE("Bad thread status (%d) in DP\n", self->status);
1048 dvmDumpThread(self, false);
1049 dvmAbort();
1050 }
1051 assert(!dvmCheckException(self));
1052 updateDeadlockPrediction(self, obj);
1053 if (dvmCheckException(self)) {
1054 /*
1055 * If we're throwing an exception here, we need to free the
1056 * lock. We add the object to the thread's monitor list so the
1057 * "unlock" code can remove it.
1058 */
1059 dvmAddToMonitorList(self, obj, false);
1060 dvmUnlockObject(self, obj);
1061 LOGV("--- unlocked, pending is '%s'\n",
1062 dvmGetException(self)->clazz->descriptor);
1063 }
1064 }
1065
1066 /*
1067 * Add the locked object, and the current stack trace, to the list
1068 * held by the Thread object. If deadlock prediction isn't on,
1069 * don't capture the stack trace.
1070 */
1071 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
1072#elif defined(WITH_MONITOR_TRACKING)
1073 /*
1074 * Add the locked object to the list held by the Thread object.
1075 */
1076 dvmAddToMonitorList(self, obj, false);
1077#endif
1078}
1079
1080/*
1081 * Implements monitorexit for "synchronized" stuff.
1082 *
1083 * On failure, throws an exception and returns "false".
1084 */
1085bool dvmUnlockObject(Thread* self, Object *obj)
1086{
Carl Shapiro94338aa2009-12-21 11:42:59 -08001087 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001088
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001089 assert(self != NULL);
1090 assert(self->status == THREAD_RUNNING);
1091 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001092 /*
1093 * Cache the lock word as its value can change while we are
1094 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001095 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001096 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001097 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
1098 /*
1099 * The lock is thin. We must ensure that the lock is owned
1100 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001101 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001102 if (LW_LOCK_OWNER(thin) == self->threadId) {
1103 /*
1104 * We are the lock owner. It is safe to update the lock
1105 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001106 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001107 if (LW_LOCK_COUNT(thin) == 0) {
1108 /*
1109 * The lock was not recursively acquired, the common
1110 * case. Unlock by clearing all bits except for the
1111 * hash state.
1112 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001113 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001114 } else {
1115 /*
1116 * The object was recursively acquired. Decrement the
1117 * lock recursion count field.
1118 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001119 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001120 }
1121 } else {
1122 /*
1123 * We do not own the lock. The JVM spec requires that we
1124 * throw an exception in this case.
1125 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001126 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001127 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001128 return false;
1129 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001130 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001131 /*
1132 * The lock is fat. We must check to see if unlockMonitor has
1133 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001134 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001135 assert(LW_MONITOR(obj->lock) != NULL);
1136 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001137 /*
1138 * An exception has been raised. Do not fall through.
1139 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001140 return false;
1141 }
1142 }
1143
1144#ifdef WITH_MONITOR_TRACKING
1145 /*
1146 * Remove the object from the Thread's list.
1147 */
1148 dvmRemoveFromMonitorList(self, obj);
1149#endif
1150
1151 return true;
1152}
1153
1154/*
1155 * Object.wait(). Also called for class init.
1156 */
1157void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1158 bool interruptShouldThrow)
1159{
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001160 Monitor* mon;
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001161 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001162
1163 /* If the lock is still thin, we need to fatten it.
1164 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001165 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001166 /* Make sure that 'self' holds the lock.
1167 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001168 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001169 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1170 "object not locked by thread before wait()");
1171 return;
1172 }
1173
1174 /* This thread holds the lock. We need to fatten the lock
1175 * so 'self' can block on it. Don't update the object lock
1176 * field yet, because 'self' needs to acquire the lock before
1177 * any other thread gets a chance.
1178 */
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001179 inflateMonitor(self, obj);
1180 LOG_THIN("(%d) lock %p fattened by wait() to count %d",
1181 self->threadId, &obj->lock, mon->lockCount);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001182 }
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001183 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001184 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1185}
1186
1187/*
1188 * Object.notify().
1189 */
1190void dvmObjectNotify(Thread* self, Object *obj)
1191{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001192 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001193
1194 /* If the lock is still thin, there aren't any waiters;
1195 * waiting on an object forces lock fattening.
1196 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001197 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001198 /* Make sure that 'self' holds the lock.
1199 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001200 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001201 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1202 "object not locked by thread before notify()");
1203 return;
1204 }
1205
1206 /* no-op; there are no waiters to notify.
1207 */
1208 } else {
1209 /* It's a fat lock.
1210 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001211 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001212 }
1213}
1214
1215/*
1216 * Object.notifyAll().
1217 */
1218void dvmObjectNotifyAll(Thread* self, Object *obj)
1219{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001220 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001221
1222 /* If the lock is still thin, there aren't any waiters;
1223 * waiting on an object forces lock fattening.
1224 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001225 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001226 /* Make sure that 'self' holds the lock.
1227 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001228 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001229 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1230 "object not locked by thread before notifyAll()");
1231 return;
1232 }
1233
1234 /* no-op; there are no waiters to notify.
1235 */
1236 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001237 /* It's a fat lock.
1238 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001239 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001240 }
1241}
1242
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001243/*
1244 * This implements java.lang.Thread.sleep(long msec, int nsec).
1245 *
1246 * The sleep is interruptible by other threads, which means we can't just
1247 * plop into an OS sleep call. (We probably could if we wanted to send
1248 * signals around and rely on EINTR, but that's inefficient and relies
1249 * on native code respecting our signal mask.)
1250 *
1251 * We have to do all of this stuff for Object.wait() as well, so it's
1252 * easiest to just sleep on a private Monitor.
1253 *
1254 * It appears that we want sleep(0,0) to go through the motions of sleeping
1255 * for a very short duration, rather than just returning.
1256 */
1257void dvmThreadSleep(u8 msec, u4 nsec)
1258{
1259 Thread* self = dvmThreadSelf();
1260 Monitor* mon = gDvm.threadSleepMon;
1261
1262 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1263 if (msec == 0 && nsec == 0)
1264 nsec++;
1265
1266 lockMonitor(self, mon);
1267 waitMonitor(self, mon, msec, nsec, true);
1268 unlockMonitor(self, mon);
1269}
1270
1271/*
1272 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001273 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001274void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001275{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001276 assert(thread != NULL);
1277
Carl Shapiro980ffb02010-03-13 22:34:01 -08001278 dvmLockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001279
1280 /*
1281 * If the interrupted flag is already set no additional action is
1282 * required.
1283 */
1284 if (thread->interrupted == true) {
Carl Shapiro980ffb02010-03-13 22:34:01 -08001285 dvmUnlockMutex(&thread->waitMutex);
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001286 return;
1287 }
1288
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001289 /*
1290 * Raise the "interrupted" flag. This will cause it to bail early out
1291 * of the next wait() attempt, if it's not currently waiting on
1292 * something.
1293 */
1294 thread->interrupted = true;
Andy McFadden6e10b9a2010-06-14 15:24:39 -07001295 ANDROID_MEMBAR_FULL();
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001296
1297 /*
1298 * Is the thread waiting?
1299 *
1300 * Note that fat vs. thin doesn't matter here; waitMonitor
1301 * is only set when a thread actually waits on a monitor,
1302 * which implies that the monitor has already been fattened.
1303 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001304 if (thread->waitMonitor != NULL) {
1305 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001306 }
1307
Carl Shapiro980ffb02010-03-13 22:34:01 -08001308 dvmUnlockMutex(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001309}
1310
Carl Shapiro30aa9972010-01-13 22:07:50 -08001311#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001312u4 dvmIdentityHashCode(Object *obj)
1313{
1314 return (u4)obj;
1315}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001316#else
Carl Shapiro30aa9972010-01-13 22:07:50 -08001317/*
1318 * Returns the identity hash code of the given object.
1319 */
1320u4 dvmIdentityHashCode(Object *obj)
1321{
1322 Thread *self, *thread;
1323 volatile u4 *lw;
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001324 size_t size;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001325 u4 lock, owner, hashState;
1326
1327 if (obj == NULL) {
1328 /*
1329 * Null is defined to have an identity hash code of 0.
1330 */
1331 return 0;
1332 }
1333 lw = &obj->lock;
1334retry:
1335 hashState = LW_HASH_STATE(*lw);
1336 if (hashState == LW_HASH_STATE_HASHED) {
1337 /*
1338 * The object has been hashed but has not had its hash code
1339 * relocated by the garbage collector. Use the raw object
1340 * address.
1341 */
1342 return (u4)obj >> 3;
1343 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1344 /*
1345 * The object has been hashed and its hash code has been
1346 * relocated by the collector. Use the value of the naturally
1347 * aligned word following the instance data.
1348 */
Carl Shapiroc48b6d02010-05-04 11:19:53 -07001349 assert(obj->clazz != gDvm.classJavaLangClass);
1350 assert(obj->clazz != gDvm.unlinkedJavaLangClass);
Carl Shapiro30aa9972010-01-13 22:07:50 -08001351 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001352 size = dvmArrayObjectSize((ArrayObject *)obj);
Carl Shapiroc48b6d02010-05-04 11:19:53 -07001353 size = (size + 2) & ~2;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001354 } else {
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001355 size = obj->clazz->objectSize;
Carl Shapiro30aa9972010-01-13 22:07:50 -08001356 }
Carl Shapirobfe4dcc2010-04-16 17:55:27 -07001357 return *(u4 *)(((char *)obj) + size);
Carl Shapiro30aa9972010-01-13 22:07:50 -08001358 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1359 /*
1360 * The object has never been hashed. Change the hash state to
1361 * hashed and use the raw object address.
1362 */
1363 self = dvmThreadSelf();
1364 if (self->threadId == lockOwner(obj)) {
1365 /*
1366 * We already own the lock so we can update the hash state
1367 * directly.
1368 */
1369 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1370 return (u4)obj >> 3;
1371 }
1372 /*
1373 * We do not own the lock. Try acquiring the lock. Should
1374 * this fail, we must suspend the owning thread.
1375 */
1376 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1377 /*
1378 * If the lock is thin assume it is unowned. We simulate
1379 * an acquire, update, and release with a single CAS.
1380 */
1381 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1382 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
Andy McFadden6e10b9a2010-06-14 15:24:39 -07001383 if (android_atomic_release_cas(
Carl Shapiro30aa9972010-01-13 22:07:50 -08001384 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
Andy McFadden6e10b9a2010-06-14 15:24:39 -07001385 (int32_t)lock,
1386 (int32_t *)lw) == 0) {
Carl Shapiro30aa9972010-01-13 22:07:50 -08001387 /*
1388 * A new lockword has been installed with a hash state
1389 * of hashed. Use the raw object address.
1390 */
1391 return (u4)obj >> 3;
1392 }
1393 } else {
1394 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1395 /*
1396 * The monitor lock has been acquired. Change the
1397 * hash state to hashed and use the raw object
1398 * address.
1399 */
1400 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1401 unlockMonitor(self, LW_MONITOR(*lw));
1402 return (u4)obj >> 3;
1403 }
1404 }
1405 /*
1406 * At this point we have failed to acquire the lock. We must
1407 * identify the owning thread and suspend it.
1408 */
1409 dvmLockThreadList(self);
1410 /*
1411 * Cache the lock word as its value can change between
1412 * determining its shape and retrieving its owner.
1413 */
1414 lock = *lw;
1415 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1416 /*
1417 * Find the thread with the corresponding thread id.
1418 */
1419 owner = LW_LOCK_OWNER(lock);
1420 assert(owner != self->threadId);
1421 /*
1422 * If the lock has no owner do not bother scanning the
1423 * thread list and fall through to the failure handler.
1424 */
1425 thread = owner ? gDvm.threadList : NULL;
1426 while (thread != NULL) {
1427 if (thread->threadId == owner) {
1428 break;
1429 }
1430 thread = thread->next;
1431 }
1432 } else {
1433 thread = LW_MONITOR(lock)->owner;
1434 }
1435 /*
1436 * If thread is NULL the object has been released since the
1437 * thread list lock was acquired. Try again.
1438 */
1439 if (thread == NULL) {
1440 dvmUnlockThreadList();
1441 goto retry;
1442 }
1443 /*
1444 * Wait for the owning thread to suspend.
1445 */
1446 dvmSuspendThread(thread);
1447 if (dvmHoldsLock(thread, obj)) {
1448 /*
1449 * The owning thread has been suspended. We can safely
1450 * change the hash state to hashed.
1451 */
1452 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1453 dvmResumeThread(thread);
1454 dvmUnlockThreadList();
1455 return (u4)obj >> 3;
1456 }
1457 /*
1458 * The wrong thread has been suspended. Try again.
1459 */
1460 dvmResumeThread(thread);
1461 dvmUnlockThreadList();
1462 goto retry;
1463 }
1464 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1465 dvmDumpThread(dvmThreadSelf(), false);
1466 dvmAbort();
1467 return 0; /* Quiet the compiler. */
1468}
1469#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001470
1471#ifdef WITH_DEADLOCK_PREDICTION
1472/*
1473 * ===========================================================================
1474 * Deadlock prediction
1475 * ===========================================================================
1476 */
1477/*
1478The idea is to predict the possibility of deadlock by recording the order
1479in which monitors are acquired. If we see an attempt to acquire a lock
1480out of order, we can identify the locks and offending code.
1481
1482To make this work, we need to keep track of the locks held by each thread,
1483and create history trees for each lock. When a thread tries to acquire
1484a new lock, we walk through the "history children" of the lock, looking
1485for a match with locks the thread already holds. If we find a match,
1486it means the thread has made a request that could result in a deadlock.
1487
1488To support recursive locks, we always allow re-locking a currently-held
1489lock, and maintain a recursion depth count.
1490
1491An ASCII-art example, where letters represent Objects:
1492
1493 A
1494 /|\
1495 / | \
1496 B | D
1497 \ |
1498 \|
1499 C
1500
1501The above is the tree we'd have after handling Object synchronization
1502sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1503a child of B. (The lines represent pointers between parent and child.
1504Every node can have multiple parents and multiple children.)
1505
1506If we hold AC, and want to lock B, we recursively search through B's
1507children to see if A or C appears. It does, so we reject the attempt.
1508(A straightforward way to implement it: add a link from C to B, then
1509determine whether the graph starting at B contains a cycle.)
1510
1511If we hold AC and want to lock D, we would succeed, creating a new link
1512from C to D.
1513
1514The lock history and a stack trace is attached to the Object's Monitor
1515struct, which means we need to fatten every Object we lock (thin locking
1516is effectively disabled). If we don't need the stack trace we can
1517avoid fattening the leaf nodes, only fattening objects that need to hold
1518history trees.
1519
1520Updates to Monitor structs are only allowed for the thread that holds
1521the Monitor, so we actually do most of our deadlock prediction work after
1522the lock has been acquired.
1523
1524When an object with a monitor is GCed, we need to remove it from the
1525history trees. There are two basic approaches:
1526 (1) For through the entire set of known monitors, search all child
1527 lists for the object in question. This is rather slow, resulting
1528 in GC passes that take upwards of 10 seconds to complete.
1529 (2) Maintain "parent" pointers in each node. Remove the entries as
1530 required. This requires additional storage and maintenance for
1531 every operation, but is significantly faster at GC time.
1532For each GCed object, we merge all of the object's children into each of
1533the object's parents.
1534*/
1535
1536#if !defined(WITH_MONITOR_TRACKING)
1537# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1538#endif
1539
1540/*
1541 * Clear out the contents of an ExpandingObjectList, freeing any
1542 * dynamic allocations.
1543 */
1544static void expandObjClear(ExpandingObjectList* pList)
1545{
1546 if (pList->list != NULL) {
1547 free(pList->list);
1548 pList->list = NULL;
1549 }
1550 pList->alloc = pList->count = 0;
1551}
1552
1553/*
1554 * Get the number of objects currently stored in the list.
1555 */
1556static inline int expandBufGetCount(const ExpandingObjectList* pList)
1557{
1558 return pList->count;
1559}
1560
1561/*
1562 * Get the Nth entry from the list.
1563 */
1564static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1565 int i)
1566{
1567 return pList->list[i];
1568}
1569
1570/*
1571 * Add a new entry to the list.
1572 *
1573 * We don't check for or try to enforce uniqueness. It's expected that
1574 * the higher-level code does this for us.
1575 */
1576static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1577{
1578 if (pList->count == pList->alloc) {
1579 /* time to expand */
1580 Object** newList;
1581
1582 if (pList->alloc == 0)
1583 pList->alloc = 4;
1584 else
1585 pList->alloc *= 2;
1586 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1587 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1588 if (newList == NULL) {
1589 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1590 dvmAbort();
1591 }
1592 pList->list = newList;
1593 }
1594
1595 pList->list[pList->count++] = obj;
1596}
1597
1598/*
1599 * Returns "true" if the element was successfully removed.
1600 */
1601static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1602{
1603 int i;
1604
1605 for (i = pList->count-1; i >= 0; i--) {
1606 if (pList->list[i] == obj)
1607 break;
1608 }
1609 if (i < 0)
1610 return false;
1611
1612 if (i != pList->count-1) {
1613 /*
1614 * The order of elements is not important, so we just copy the
1615 * last entry into the new slot.
1616 */
1617 //memmove(&pList->list[i], &pList->list[i+1],
1618 // (pList->count-1 - i) * sizeof(pList->list[0]));
1619 pList->list[i] = pList->list[pList->count-1];
1620 }
1621
1622 pList->count--;
1623 pList->list[pList->count] = (Object*) 0xdecadead;
1624 return true;
1625}
1626
1627/*
1628 * Returns "true" if "obj" appears in the list.
1629 */
1630static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1631{
1632 int i;
1633
1634 for (i = 0; i < pList->count; i++) {
1635 if (pList->list[i] == obj)
1636 return true;
1637 }
1638 return false;
1639}
1640
1641/*
1642 * Print the list contents to stdout. For debugging.
1643 */
1644static void expandObjDump(const ExpandingObjectList* pList)
1645{
1646 int i;
1647 for (i = 0; i < pList->count; i++)
1648 printf(" %p", pList->list[i]);
1649}
1650
1651/*
1652 * Check for duplicate entries. Returns the index of the first instance
1653 * of the duplicated value, or -1 if no duplicates were found.
1654 */
1655static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1656{
1657 int i, j;
1658 for (i = 0; i < pList->count-1; i++) {
1659 for (j = i + 1; j < pList->count; j++) {
1660 if (pList->list[i] == pList->list[j]) {
1661 return i;
1662 }
1663 }
1664 }
1665
1666 return -1;
1667}
1668
1669
1670/*
1671 * Determine whether "child" appears in the list of objects associated
1672 * with the Monitor in "parent". If "parent" is a thin lock, we return
1673 * false immediately.
1674 */
1675static bool objectInChildList(const Object* parent, Object* child)
1676{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001677 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001678 if (!IS_LOCK_FAT(&lock)) {
1679 //LOGI("on thin\n");
1680 return false;
1681 }
1682
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001683 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001684}
1685
1686/*
1687 * Print the child list.
1688 */
1689static void dumpKids(Object* parent)
1690{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001691 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001692
1693 printf("Children of %p:", parent);
1694 expandObjDump(&mon->historyChildren);
1695 printf("\n");
1696}
1697
1698/*
1699 * Add "child" to the list of children in "parent", and add "parent" to
1700 * the list of parents in "child".
1701 */
1702static void linkParentToChild(Object* parent, Object* child)
1703{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001704 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001705 assert(IS_LOCK_FAT(&parent->lock));
1706 assert(IS_LOCK_FAT(&child->lock));
1707 assert(parent != child);
1708 Monitor* mon;
1709
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001710 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001711 assert(!expandObjHas(&mon->historyChildren, child));
1712 expandObjAddEntry(&mon->historyChildren, child);
1713
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001714 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001715 assert(!expandObjHas(&mon->historyParents, parent));
1716 expandObjAddEntry(&mon->historyParents, parent);
1717}
1718
1719
1720/*
1721 * Remove "child" from the list of children in "parent".
1722 */
1723static void unlinkParentFromChild(Object* parent, Object* child)
1724{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001725 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001726 assert(IS_LOCK_FAT(&parent->lock));
1727 assert(IS_LOCK_FAT(&child->lock));
1728 assert(parent != child);
1729 Monitor* mon;
1730
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001731 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001732 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1733 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1734 }
1735 assert(!expandObjHas(&mon->historyChildren, child));
1736 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1737
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001738 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001739 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1740 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1741 }
1742 assert(!expandObjHas(&mon->historyParents, parent));
1743 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1744}
1745
1746
1747/*
1748 * Log the monitors held by the current thread. This is done as part of
1749 * flagging an error.
1750 */
1751static void logHeldMonitors(Thread* self)
1752{
1753 char* name = NULL;
1754
1755 name = dvmGetThreadName(self);
1756 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1757 self->threadId, name);
1758 LOGW("(most-recently-acquired on top):\n");
1759 free(name);
1760
1761 LockedObjectData* lod = self->pLockedObjects;
1762 while (lod != NULL) {
1763 LOGW("--- object %p[%d] (%s)\n",
1764 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1765 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1766
1767 lod = lod->next;
1768 }
1769}
1770
1771/*
1772 * Recursively traverse the object hierarchy starting at "obj". We mark
1773 * ourselves on entry and clear the mark on exit. If we ever encounter
1774 * a marked object, we have a cycle.
1775 *
1776 * Returns "true" if all is well, "false" if we found a cycle.
1777 */
1778static bool traverseTree(Thread* self, const Object* obj)
1779{
1780 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001781 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001782
1783 /*
1784 * Have we been here before?
1785 */
1786 if (mon->historyMark) {
1787 int* rawStackTrace;
1788 int stackDepth;
1789
1790 LOGW("%s\n", kStartBanner);
1791 LOGW("Illegal lock attempt:\n");
1792 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1793
1794 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1795 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1796 free(rawStackTrace);
1797
1798 LOGW(" ");
1799 logHeldMonitors(self);
1800
1801 LOGW(" ");
1802 LOGW("Earlier, the following lock order (from last to first) was\n");
1803 LOGW("established -- stack trace is from first successful lock):\n");
1804 return false;
1805 }
1806 mon->historyMark = true;
1807
1808 /*
1809 * Examine the children. We do NOT hold these locks, so they might
1810 * very well transition from thin to fat or change ownership while
1811 * we work.
1812 *
1813 * NOTE: we rely on the fact that they cannot revert from fat to thin
1814 * while we work. This is currently a safe assumption.
1815 *
1816 * We can safely ignore thin-locked children, because by definition
1817 * they have no history and are leaf nodes. In the current
1818 * implementation we always fatten the locks to provide a place to
1819 * hang the stack trace.
1820 */
1821 ExpandingObjectList* pList = &mon->historyChildren;
1822 int i;
1823 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1824 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001825 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001826 if (!IS_LOCK_FAT(&lock))
1827 continue;
1828 if (!traverseTree(self, child)) {
1829 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1830 dvmLogRawStackTrace(mon->historyRawStackTrace,
1831 mon->historyStackDepth);
1832 mon->historyMark = false;
1833 return false;
1834 }
1835 }
1836
1837 mon->historyMark = false;
1838
1839 return true;
1840}
1841
1842/*
1843 * Update the deadlock prediction tree, based on the current thread
1844 * acquiring "acqObj". This must be called before the object is added to
1845 * the thread's list of held monitors.
1846 *
1847 * If the thread already holds the lock (recursion), or this is a known
1848 * lock configuration, we return without doing anything. Otherwise, we add
1849 * a link from the most-recently-acquired lock in this thread to "acqObj"
1850 * after ensuring that the parent lock is "fat".
1851 *
1852 * This MUST NOT be called while a GC is in progress in another thread,
1853 * because we assume exclusive access to history trees in owned monitors.
1854 */
1855static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1856{
1857 LockedObjectData* lod;
1858 LockedObjectData* mrl;
1859
1860 /*
1861 * Quick check for recursive access.
1862 */
1863 lod = dvmFindInMonitorList(self, acqObj);
1864 if (lod != NULL) {
1865 LOGV("+++ DP: recursive %p\n", acqObj);
1866 return;
1867 }
1868
1869 /*
1870 * Make the newly-acquired object's monitor "fat". In some ways this
1871 * isn't strictly necessary, but we need the GC to tell us when
1872 * "interesting" objects go away, and right now the only way to make
1873 * an object look interesting is to give it a monitor.
1874 *
1875 * This also gives us a place to hang a stack trace.
1876 *
1877 * Our thread holds the lock, so we're allowed to rewrite the lock
1878 * without worrying that something will change out from under us.
1879 */
1880 if (!IS_LOCK_FAT(&acqObj->lock)) {
1881 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001882 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001883 inflateMonitor(self, acqObj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001884 }
1885
1886 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001887 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1888 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001889 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1890 &mon->historyStackDepth);
1891 }
1892
1893 /*
1894 * We need to examine and perhaps modify the most-recently-locked
1895 * monitor. We own that, so there's no risk of another thread
1896 * stepping on us.
1897 *
1898 * Retrieve the most-recently-locked entry from our thread.
1899 */
1900 mrl = self->pLockedObjects;
1901 if (mrl == NULL)
1902 return; /* no other locks held */
1903
1904 /*
1905 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1906 * this without holding the global lock because of our assertion that
1907 * a GC is not running in parallel -- nobody except the GC can
1908 * modify a history list in a Monitor they don't own, and we own "mrl".
1909 * (There might be concurrent *reads*, but no concurrent *writes.)
1910 *
1911 * If we find it, this is a known good configuration, and we're done.
1912 */
1913 if (objectInChildList(mrl->obj, acqObj))
1914 return;
1915
1916 /*
1917 * "mrl" is going to need to have a history tree. If it's currently
1918 * a thin lock, we make it fat now. The thin lock might have a
1919 * nonzero recursive lock count, which we need to carry over.
1920 *
1921 * Our thread holds the lock, so we're allowed to rewrite the lock
1922 * without worrying that something will change out from under us.
1923 */
1924 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1925 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001926 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
Carl Shapiro66bb7df2010-03-12 15:25:37 -08001927 inflateMonitor(self, mrl->obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001928 }
1929
1930 /*
1931 * We haven't seen this configuration before. We need to scan down
1932 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1933 * appear. We grab a global lock before traversing or updating the
1934 * history list.
1935 *
1936 * If we find a match for any of our held locks, we know that the lock
1937 * has previously been acquired *after* acqObj, and we throw an error.
1938 *
1939 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1940 * and do a recursive traversal, marking nodes as we cross them. If
1941 * we cross one a second time, we have a cycle and can throw an error.
1942 * (We do the flag-clearing traversal before adding the new link, so
1943 * that we're guaranteed to terminate.)
1944 *
1945 * If "acqObj" is a thin lock, it has no history, and we can create a
1946 * link to it without additional checks. [ We now guarantee that it's
1947 * always fat. ]
1948 */
1949 bool failed = false;
1950 dvmLockMutex(&gDvm.deadlockHistoryLock);
1951 linkParentToChild(mrl->obj, acqObj);
1952 if (!traverseTree(self, acqObj)) {
1953 LOGW("%s\n", kEndBanner);
1954 failed = true;
1955
1956 /* remove the entry so we're still okay when in "warning" mode */
1957 unlinkParentFromChild(mrl->obj, acqObj);
1958 }
1959 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1960
1961 if (failed) {
1962 switch (gDvm.deadlockPredictMode) {
1963 case kDPErr:
1964 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
1965 break;
1966 case kDPAbort:
1967 LOGE("Aborting due to potential deadlock\n");
1968 dvmAbort();
1969 break;
1970 default:
1971 /* warn only */
1972 break;
1973 }
1974 }
1975}
1976
1977/*
1978 * We're removing "child" from existence. We want to pull all of
1979 * child's children into "parent", filtering out duplicates. This is
1980 * called during the GC.
1981 *
1982 * This does not modify "child", which might have multiple parents.
1983 */
1984static void mergeChildren(Object* parent, const Object* child)
1985{
1986 Monitor* mon;
1987 int i;
1988
1989 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001990 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001991 ExpandingObjectList* pList = &mon->historyChildren;
1992
1993 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1994 Object* grandChild = expandBufGetEntry(pList, i);
1995
1996 if (!objectInChildList(parent, grandChild)) {
1997 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
1998 linkParentToChild(parent, grandChild);
1999 } else {
2000 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
2001 }
2002 }
2003}
2004
2005/*
2006 * An object with a fat lock is being collected during a GC pass. We
2007 * want to remove it from any lock history trees that it is a part of.
2008 *
2009 * This may require updating the history trees in several monitors. The
2010 * monitor semantics guarantee that no other thread will be accessing
2011 * the history trees at the same time.
2012 */
2013static void removeCollectedObject(Object* obj)
2014{
2015 Monitor* mon;
2016
2017 LOGVV("+++ collecting %p\n", obj);
2018
2019#if 0
2020 /*
2021 * We're currently running through the entire set of known monitors.
2022 * This can be somewhat slow. We may want to keep lists of parents
2023 * in each child to speed up GC.
2024 */
2025 mon = gDvm.monitorList;
2026 while (mon != NULL) {
2027 Object* parent = mon->obj;
2028 if (parent != NULL) { /* value nulled for deleted entries */
2029 if (objectInChildList(parent, obj)) {
2030 LOGVV("removing child %p from parent %p\n", obj, parent);
2031 unlinkParentFromChild(parent, obj);
2032 mergeChildren(parent, obj);
2033 }
2034 }
2035 mon = mon->next;
2036 }
2037#endif
2038
2039 /*
2040 * For every parent of this object:
2041 * - merge all of our children into the parent's child list (creates
2042 * a two-way link between parent and child)
2043 * - remove ourselves from the parent's child list
2044 */
2045 ExpandingObjectList* pList;
2046 int i;
2047
2048 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002049 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002050 pList = &mon->historyParents;
2051 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2052 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002053 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002054
2055 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2056 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2057 }
2058 assert(!expandObjHas(&parentMon->historyChildren, obj));
2059
2060 mergeChildren(parent, obj);
2061 }
2062
2063 /*
2064 * For every child of this object:
2065 * - remove ourselves from the child's parent list
2066 */
2067 pList = &mon->historyChildren;
2068 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2069 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002070 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002071
2072 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2073 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2074 }
2075 assert(!expandObjHas(&childMon->historyParents, obj));
2076 }
2077}
2078
2079#endif /*WITH_DEADLOCK_PREDICTION*/