blob: 8fc4ac2c31ffc70dbee8ca9222d3578e66705828 [file] [log] [blame]
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001/*
2 * Copyright (C) 2008 The Android Open Source Project
3 *
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
7 *
8 * http://www.apache.org/licenses/LICENSE-2.0
9 *
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
15 */
Andy McFadden581bed72009-10-15 11:24:54 -070016
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080017/*
18 * Fundamental synchronization mechanisms.
19 *
20 * The top part of the file has operations on "monitor" structs; the
21 * next part has the native calls on objects.
22 *
23 * The current implementation uses "thin locking" to avoid allocating
24 * an Object's full Monitor struct until absolutely necessary (i.e.,
25 * during contention or a call to wait()).
26 *
27 * TODO: make improvements to thin locking
28 * We may be able to improve performance and reduce memory requirements by:
29 * - reverting to a thin lock once the Monitor is no longer necessary
30 * - using a pool of monitor objects, with some sort of recycling scheme
31 *
32 * TODO: recycle native-level monitors when objects are garbage collected.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080033 */
34#include "Dalvik.h"
35
Carl Shapirof0c514c2010-04-09 15:03:33 -070036#include <fcntl.h>
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080037#include <stdlib.h>
38#include <unistd.h>
39#include <pthread.h>
40#include <time.h>
41#include <sys/time.h>
42#include <errno.h>
43
44#define LOG_THIN LOGV
45
46#ifdef WITH_DEADLOCK_PREDICTION /* fwd */
47static const char* kStartBanner =
48 "<-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#";
49static const char* kEndBanner =
50 "#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#-#->";
51
52/*
53 * Unsorted, expanding list of objects.
54 *
55 * This is very similar to PointerSet (which came into existence after this),
56 * but these are unsorted, uniqueness is not enforced by the "add" function,
57 * and the base object isn't allocated on the heap.
58 */
59typedef struct ExpandingObjectList {
60 u2 alloc;
61 u2 count;
62 Object** list;
63} ExpandingObjectList;
64
65/* fwd */
66static void updateDeadlockPrediction(Thread* self, Object* obj);
67static void removeCollectedObject(Object* obj);
68static void expandObjClear(ExpandingObjectList* pList);
69#endif
70
71/*
72 * Every Object has a monitor associated with it, but not every Object is
73 * actually locked. Even the ones that are locked do not need a
74 * full-fledged monitor until a) there is actual contention or b) wait()
75 * is called on the Object.
76 *
77 * For Dalvik, we have implemented a scheme similar to the one described
78 * in Bacon et al.'s "Thin locks: featherweight synchronization for Java"
79 * (ACM 1998). Things are even easier for us, though, because we have
80 * a full 32 bits to work with.
81 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080082 * The two states of an Object's lock are referred to as "thin" and
83 * "fat". A lock may transition from the "thin" state to the "fat"
84 * state and this transition is referred to as inflation. Once a lock
85 * has been inflated it remains in the "fat" state indefinitely.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080086 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080087 * The lock value itself is stored in Object.lock. The LSB of the
88 * lock encodes its state. When cleared, the lock is in the "thin"
89 * state and its bits are formatted as follows:
Carl Shapiro71938022009-12-22 13:49:53 -080090 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080091 * [31 ---- 19] [18 ---- 3] [2 ---- 1] [0]
92 * lock count thread id hash state 0
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080093 *
Carl Shapiro77f52eb2009-12-24 19:56:53 -080094 * When set, the lock is in the "fat" state and its bits are formatted
Carl Shapiro94338aa2009-12-21 11:42:59 -080095 * as follows:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080096 *
Carl Shapiro94338aa2009-12-21 11:42:59 -080097 * [31 ---- 3] [2 ---- 1] [0]
98 * pointer hash state 1
The Android Open Source Projectf6c38712009-03-03 19:28:47 -080099 *
100 * For an in-depth description of the mechanics of thin-vs-fat locking,
101 * read the paper referred to above.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800102 */
103
104/*
105 * Monitors provide:
106 * - mutually exclusive access to resources
107 * - a way for multiple threads to wait for notification
108 *
109 * In effect, they fill the role of both mutexes and condition variables.
110 *
111 * Only one thread can own the monitor at any time. There may be several
112 * threads waiting on it (the wait call unlocks it). One or more waiting
113 * threads may be getting interrupted or notified at any given time.
114 */
115struct Monitor {
116 Thread* owner; /* which thread currently owns the lock? */
117 int lockCount; /* owner's recursive lock depth */
118 Object* obj; /* what object are we part of [debug only] */
119
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800120 Thread* waitSet; /* threads currently waiting on this monitor */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800121
122 pthread_mutex_t lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800123
124 Monitor* next;
125
126#ifdef WITH_DEADLOCK_PREDICTION
127 /*
128 * Objects that have been locked immediately after this one in the
129 * past. We use an expanding flat array, allocated on first use, to
130 * minimize allocations. Deletions from the list, expected to be
131 * infrequent, are crunched down.
132 */
133 ExpandingObjectList historyChildren;
134
135 /*
136 * We also track parents. This isn't strictly necessary, but it makes
137 * the cleanup at GC time significantly faster.
138 */
139 ExpandingObjectList historyParents;
140
141 /* used during cycle detection */
142 bool historyMark;
143
144 /* stack trace, established the first time we locked the object */
145 int historyStackDepth;
146 int* historyRawStackTrace;
147#endif
148};
149
150
151/*
152 * Create and initialize a monitor.
153 */
154Monitor* dvmCreateMonitor(Object* obj)
155{
156 Monitor* mon;
157
158 mon = (Monitor*) calloc(1, sizeof(Monitor));
159 if (mon == NULL) {
160 LOGE("Unable to allocate monitor\n");
161 dvmAbort();
162 }
Carl Shapiro94338aa2009-12-21 11:42:59 -0800163 if (((u4)mon & 7) != 0) {
164 LOGE("Misaligned monitor: %p\n", mon);
165 dvmAbort();
166 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800167 mon->obj = obj;
168 dvmInitMutex(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800169
170 /* replace the head of the list with the new monitor */
171 do {
172 mon->next = gDvm.monitorList;
173 } while (!ATOMIC_CMP_SWAP((int32_t*)(void*)&gDvm.monitorList,
174 (int32_t)mon->next, (int32_t)mon));
175
176 return mon;
177}
178
179/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800180 * Free the monitor list. Only used when shutting the VM down.
181 */
182void dvmFreeMonitorList(void)
183{
184 Monitor* mon;
185 Monitor* nextMon;
186
187 mon = gDvm.monitorList;
188 while (mon != NULL) {
189 nextMon = mon->next;
190
191#ifdef WITH_DEADLOCK_PREDICTION
192 expandObjClear(&mon->historyChildren);
193 expandObjClear(&mon->historyParents);
194 free(mon->historyRawStackTrace);
195#endif
196 free(mon);
197 mon = nextMon;
198 }
199}
200
201/*
202 * Log some info about our monitors.
203 */
204void dvmDumpMonitorInfo(const char* msg)
205{
206#if QUIET_ZYGOTE_MONITOR
207 if (gDvm.zygote) {
208 return;
209 }
210#endif
211
212 int totalCount;
213 int liveCount;
214
215 totalCount = liveCount = 0;
216 Monitor* mon = gDvm.monitorList;
217 while (mon != NULL) {
218 totalCount++;
219 if (mon->obj != NULL)
220 liveCount++;
221 mon = mon->next;
222 }
223
224 LOGD("%s: monitor list has %d entries (%d live)\n",
225 msg, totalCount, liveCount);
226}
227
228/*
229 * Get the object that a monitor is part of.
230 */
231Object* dvmGetMonitorObject(Monitor* mon)
232{
233 if (mon == NULL)
234 return NULL;
235 else
236 return mon->obj;
237}
238
239/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800240 * Returns the thread id of the thread owning the given lock.
241 */
242static u4 lockOwner(Object* obj)
243{
244 Thread *owner;
245 u4 lock;
246
247 assert(obj != NULL);
248 /*
249 * Since we're reading the lock value multiple times, latch it so
250 * that it doesn't change out from under us if we get preempted.
251 */
252 lock = obj->lock;
253 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
254 return LW_LOCK_OWNER(lock);
255 } else {
256 owner = LW_MONITOR(lock)->owner;
257 return owner ? owner->threadId : 0;
258 }
259}
260
261/*
Andy McFadden0a24ef92010-03-12 13:39:59 -0800262 * Get the thread that holds the lock on the specified object. The
263 * object may be unlocked, thin-locked, or fat-locked.
264 *
265 * The caller must lock the thread list before calling here.
266 */
267Thread* dvmGetObjectLockHolder(Object* obj)
268{
269 u4 threadId = lockOwner(obj);
270
271 if (threadId == 0)
272 return NULL;
273 return dvmGetThreadByThreadId(threadId);
274}
275
276/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800277 * Checks whether the given thread holds the given
278 * objects's lock.
279 */
280bool dvmHoldsLock(Thread* thread, Object* obj)
281{
282 if (thread == NULL || obj == NULL) {
283 return false;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800284 } else {
Carl Shapiro30aa9972010-01-13 22:07:50 -0800285 return thread->threadId == lockOwner(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800286 }
287}
288
289/*
290 * Free the monitor associated with an object and make the object's lock
291 * thin again. This is called during garbage collection.
292 */
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800293static void freeObjectMonitor(Object* obj)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800294{
295 Monitor *mon;
296
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800297 assert(LW_SHAPE(obj->lock) == LW_SHAPE_FAT);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800298
299#ifdef WITH_DEADLOCK_PREDICTION
300 if (gDvm.deadlockPredictMode != kDPOff)
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800301 removeCollectedObject(obj);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800302#endif
303
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800304 mon = LW_MONITOR(obj->lock);
305 obj->lock = DVM_LOCK_INITIAL_THIN_VALUE;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800306
307 /* This lock is associated with an object
308 * that's being swept. The only possible way
309 * anyone could be holding this lock would be
310 * if some JNI code locked but didn't unlock
311 * the object, in which case we've got some bad
312 * native code somewhere.
313 */
314 assert(pthread_mutex_trylock(&mon->lock) == 0);
315 pthread_mutex_destroy(&mon->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800316#ifdef WITH_DEADLOCK_PREDICTION
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800317 expandObjClear(&mon->historyChildren);
318 expandObjClear(&mon->historyParents);
319 free(mon->historyRawStackTrace);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800320#endif
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800321 free(mon);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800322}
323
Carl Shapiro5a6071b2010-01-07 21:35:50 -0800324/*
325 * Frees monitor objects belonging to unmarked objects.
326 */
327void dvmSweepMonitorList(Monitor** mon, int (*isUnmarkedObject)(void*))
328{
329 Monitor handle;
330 Monitor *prev, *curr;
331 Object *obj;
332
333 assert(mon != NULL);
334 assert(*mon != NULL);
335 assert(isUnmarkedObject != NULL);
336 prev = &handle;
337 prev->next = curr = *mon;
338 while (curr != NULL) {
339 obj = curr->obj;
340 if (obj != NULL && (*isUnmarkedObject)(obj) != 0) {
341 prev->next = curr = curr->next;
342 freeObjectMonitor(obj);
343 } else {
344 prev = curr;
345 curr = curr->next;
346 }
347 }
348 *mon = handle.next;
349}
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800350
Carl 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;
361 set4LE((u1 *)dst, len);
362 dst += 4;
363 len = len < 32 ? len : 32;
364 memcpy(dst, value, len);
365 return dst + len;
366}
367
368#define EVENT_LOG_TAG_dvm_lock_contention 20003
369
370static void logContentionEvent(Thread *self, u4 waitMs, u4 samplePercent)
371{
372 const StackSaveArea *saveArea;
373 const Method *meth;
374 u4 relativePc;
375 char eventBuffer[131];
376 const char *fileName;
377 char procName[32], *selfName, *ownerName;
378 char *cp;
379 int fd, len;
380
381 saveArea = SAVEAREA_FROM_FP(self->curFrame);
382 meth = saveArea->method;
383 cp = eventBuffer;
384
385 /* Emit the event list length, 1 byte. */
386 *cp++ = 7;
387
388 /* Emit the process name, <= 37 bytes. */
389 fd = open("/proc/self/cmdline", O_RDONLY);
390 len = read(fd, procName, sizeof(procName));
391 close(fd);
392 cp = logWriteString(cp, procName, (len > 0 ? len : 0));
393
394 /* Emit the main thread status, 5 bytes. */
395 bool isMainThread = (self->systemTid == getpid());
396 cp = logWriteInt(cp, isMainThread);
397
398 /* Emit self thread name string, <= 37 bytes. */
399 selfName = dvmGetThreadName(self);
400 cp = logWriteString(cp, selfName, strlen(selfName));
401 free(selfName);
402
403 /* Emit the wait time, 5 bytes. */
404 cp = logWriteInt(cp, waitMs);
405
406 /* Emit the source code file name, <= 37 bytes. */
407 fileName = dvmGetMethodSourceFile(meth);
408 if (fileName == NULL) fileName = "";
409 cp = logWriteString(cp, fileName, strlen(fileName));
410
411 /* Emit the source code line number, 5 bytes. */
412 relativePc = saveArea->xtra.currentPc - saveArea->method->insns;
413 cp = logWriteInt(cp, dvmLineNumFromPC(meth, relativePc));
414
415 /* Emit the sample percentage, 5 bytes. */
416 cp = logWriteInt(cp, samplePercent);
417
418 assert((size_t)(cp - eventBuffer) <= sizeof(eventBuffer));
419 android_btWriteLog(EVENT_LOG_TAG_dvm_lock_contention,
420 EVENT_TYPE_LIST,
421 eventBuffer,
422 (size_t)(cp - eventBuffer));
423}
424
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800425/*
426 * Lock a monitor.
427 */
428static void lockMonitor(Thread* self, Monitor* mon)
429{
Carl Shapirof0c514c2010-04-09 15:03:33 -0700430 Thread *owner;
431 ThreadStatus oldStatus;
432 u4 waitThreshold, samplePercent;
433 u8 waitStart, waitEnd, waitMs;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800434
435 if (mon->owner == self) {
436 mon->lockCount++;
Carl Shapirof0c514c2010-04-09 15:03:33 -0700437 return;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800438 }
Carl Shapirof0c514c2010-04-09 15:03:33 -0700439 if (pthread_mutex_trylock(&mon->lock) != 0) {
440 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
441 waitThreshold = gDvm.lockProfThreshold;
442 if (waitThreshold) {
443 waitStart = dvmGetRelativeTimeUsec();
444 }
445 dvmLockMutex(&mon->lock);
446 if (waitThreshold) {
447 waitEnd = dvmGetRelativeTimeUsec();
448 }
449 dvmChangeStatus(self, oldStatus);
450 if (waitThreshold) {
451 waitMs = (waitEnd - waitStart) / 1000;
452 if (waitMs >= waitThreshold) {
453 samplePercent = 100;
454 } else {
455 samplePercent = 1 + 100 * waitMs / gDvm.lockProfSample;
456 }
457 if ((u4)rand() % 100 < samplePercent) {
458 logContentionEvent(self, waitMs, samplePercent);
459 }
460 }
461 }
462 mon->owner = self;
463 assert(mon->lockCount == 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800464}
465
466/*
467 * Try to lock a monitor.
468 *
469 * Returns "true" on success.
470 */
471static bool tryLockMonitor(Thread* self, Monitor* mon)
472{
473 int cc;
474
475 if (mon->owner == self) {
476 mon->lockCount++;
477 return true;
478 } else {
479 cc = pthread_mutex_trylock(&mon->lock);
480 if (cc == 0) {
481 mon->owner = self;
482 assert(mon->lockCount == 0);
483 return true;
484 } else {
485 return false;
486 }
487 }
488}
489
490
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);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800500 assert(mon != NULL); // can this happen?
501
502 if (mon->owner == self) {
503 /*
504 * We own the monitor, so nobody else can be in here.
505 */
506 if (mon->lockCount == 0) {
507 int cc;
508 mon->owner = NULL;
509 cc = pthread_mutex_unlock(&mon->lock);
510 assert(cc == 0);
511 } else {
512 mon->lockCount--;
513 }
514 } else {
515 /*
516 * We don't own this, so we're not allowed to unlock it.
517 * The JNI spec says that we should throw IllegalMonitorStateException
518 * in this case.
519 */
Carl Shapiroe11f3fd2010-02-24 02:30:55 -0800520 dvmThrowExceptionFmt("Ljava/lang/IllegalMonitorStateException;",
521 "unlock of unowned monitor, self=%d owner=%d",
522 self->threadId,
523 mon->owner ? mon->owner->threadId : 0);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800524 return false;
525 }
526 return true;
527}
528
529/*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800530 * Checks the wait set for circular structure. Returns 0 if the list
Carl Shapirob4539192010-01-04 16:50:00 -0800531 * is not circular. Otherwise, returns 1. Used only by asserts.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800532 */
533static int waitSetCheck(Monitor *mon)
534{
535 Thread *fast, *slow;
536 size_t n;
537
538 assert(mon != NULL);
539 fast = slow = mon->waitSet;
540 n = 0;
541 for (;;) {
542 if (fast == NULL) return 0;
543 if (fast->waitNext == NULL) return 0;
Carl Shapiro5f56e672010-01-05 20:38:03 -0800544 if (fast == slow && n > 0) return 1;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800545 n += 2;
546 fast = fast->waitNext->waitNext;
547 slow = slow->waitNext;
548 }
549}
550
551/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800552 * Links a thread into a monitor's wait set. The monitor lock must be
553 * held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800554 */
555static void waitSetAppend(Monitor *mon, Thread *thread)
556{
557 Thread *elt;
558
559 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800560 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800561 assert(thread != NULL);
562 assert(thread->waitNext == NULL);
563 assert(waitSetCheck(mon) == 0);
564 if (mon->waitSet == NULL) {
565 mon->waitSet = thread;
566 return;
567 }
568 elt = mon->waitSet;
569 while (elt->waitNext != NULL) {
570 elt = elt->waitNext;
571 }
572 elt->waitNext = thread;
573}
574
575/*
Carl Shapiro30aa9972010-01-13 22:07:50 -0800576 * Unlinks a thread from a monitor's wait set. The monitor lock must
577 * be held by the caller of this routine.
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800578 */
579static void waitSetRemove(Monitor *mon, Thread *thread)
580{
581 Thread *elt;
582
583 assert(mon != NULL);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800584 assert(mon->owner == dvmThreadSelf());
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800585 assert(thread != NULL);
586 assert(waitSetCheck(mon) == 0);
587 if (mon->waitSet == NULL) {
588 return;
589 }
590 if (mon->waitSet == thread) {
591 mon->waitSet = thread->waitNext;
592 thread->waitNext = NULL;
593 return;
594 }
595 elt = mon->waitSet;
596 while (elt->waitNext != NULL) {
597 if (elt->waitNext == thread) {
598 elt->waitNext = thread->waitNext;
599 thread->waitNext = NULL;
600 return;
601 }
602 elt = elt->waitNext;
603 }
604}
605
Carl Shapirob4539192010-01-04 16:50:00 -0800606/*
607 * Converts the given relative waiting time into an absolute time.
608 */
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800609void absoluteTime(s8 msec, s4 nsec, struct timespec *ts)
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800610{
611 s8 endSec;
612
613#ifdef HAVE_TIMEDWAIT_MONOTONIC
614 clock_gettime(CLOCK_MONOTONIC, ts);
615#else
616 {
617 struct timeval tv;
618 gettimeofday(&tv, NULL);
619 ts->tv_sec = tv.tv_sec;
620 ts->tv_nsec = tv.tv_usec * 1000;
621 }
622#endif
623 endSec = ts->tv_sec + msec / 1000;
624 if (endSec >= 0x7fffffff) {
625 LOGV("NOTE: end time exceeds epoch\n");
626 endSec = 0x7ffffffe;
627 }
628 ts->tv_sec = endSec;
629 ts->tv_nsec = (ts->tv_nsec + (msec % 1000) * 1000000) + nsec;
630
631 /* catch rollover */
632 if (ts->tv_nsec >= 1000000000L) {
633 ts->tv_sec++;
634 ts->tv_nsec -= 1000000000L;
635 }
636}
637
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800638int dvmRelativeCondWait(pthread_cond_t* cond, pthread_mutex_t* mutex,
639 s8 msec, s4 nsec)
640{
641 int ret;
642 struct timespec ts;
643 absoluteTime(msec, nsec, &ts);
644#if defined(HAVE_TIMEDWAIT_MONOTONIC)
645 ret = pthread_cond_timedwait_monotonic(cond, mutex, &ts);
646#else
647 ret = pthread_cond_timedwait(cond, mutex, &ts);
648#endif
649 assert(ret == 0 || ret == ETIMEDOUT);
650 return ret;
651}
652
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800653/*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800654 * Wait on a monitor until timeout, interrupt, or notification. Used for
655 * Object.wait() and (somewhat indirectly) Thread.sleep() and Thread.join().
656 *
657 * If another thread calls Thread.interrupt(), we throw InterruptedException
658 * and return immediately if one of the following are true:
659 * - blocked in wait(), wait(long), or wait(long, int) methods of Object
660 * - blocked in join(), join(long), or join(long, int) methods of Thread
661 * - blocked in sleep(long), or sleep(long, int) methods of Thread
662 * Otherwise, we set the "interrupted" flag.
663 *
664 * Checks to make sure that "nsec" is in the range 0-999999
665 * (i.e. fractions of a millisecond) and throws the appropriate
666 * exception if it isn't.
667 *
668 * The spec allows "spurious wakeups", and recommends that all code using
669 * Object.wait() do so in a loop. This appears to derive from concerns
670 * about pthread_cond_wait() on multiprocessor systems. Some commentary
671 * on the web casts doubt on whether these can/should occur.
672 *
673 * Since we're allowed to wake up "early", we clamp extremely long durations
674 * to return at the end of the 32-bit time epoch.
675 */
676static void waitMonitor(Thread* self, Monitor* mon, s8 msec, s4 nsec,
677 bool interruptShouldThrow)
678{
679 struct timespec ts;
680 bool wasInterrupted = false;
681 bool timed;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800682 int ret;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800683
Carl Shapiro71938022009-12-22 13:49:53 -0800684 assert(self != NULL);
685 assert(mon != NULL);
686
Carl Shapiro94338aa2009-12-21 11:42:59 -0800687 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800688 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800689 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
690 "object not locked by thread before wait()");
691 return;
692 }
693
694 /*
695 * Enforce the timeout range.
696 */
697 if (msec < 0 || nsec < 0 || nsec > 999999) {
698 dvmThrowException("Ljava/lang/IllegalArgumentException;",
699 "timeout arguments out of range");
700 return;
701 }
702
703 /*
704 * Compute absolute wakeup time, if necessary.
705 */
706 if (msec == 0 && nsec == 0) {
707 timed = false;
708 } else {
Bill Buzbeeeb695c62010-02-04 16:09:55 -0800709 absoluteTime(msec, nsec, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800710 timed = true;
711 }
712
713 /*
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800714 * Add ourselves to the set of threads waiting on this monitor, and
715 * release our hold. We need to let it go even if we're a few levels
716 * deep in a recursive lock, and we need to restore that later.
717 *
Carl Shapiro142ef272010-01-25 12:51:31 -0800718 * We append to the wait set ahead of clearing the count and owner
719 * fields so the subroutine can check that the calling thread owns
720 * the monitor. Aside from that, the order of member updates is
721 * not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800722 */
Carl Shapiro142ef272010-01-25 12:51:31 -0800723 waitSetAppend(mon, self);
724 int prevLockCount = mon->lockCount;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800725 mon->lockCount = 0;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800726 mon->owner = NULL;
727
728 /*
729 * Update thread status. If the GC wakes up, it'll ignore us, knowing
730 * that we won't touch any references in this state, and we'll check
731 * our suspend mode before we transition out.
732 */
733 if (timed)
734 dvmChangeStatus(self, THREAD_TIMED_WAIT);
735 else
736 dvmChangeStatus(self, THREAD_WAIT);
737
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800738 ret = pthread_mutex_lock(&self->waitMutex);
739 assert(ret == 0);
740
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800741 /*
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800742 * Set waitMonitor to the monitor object we will be waiting on.
743 * When waitMonitor is non-NULL a notifying or interrupting thread
744 * must signal the thread's waitCond to wake it up.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800745 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800746 assert(self->waitMonitor == NULL);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800747 self->waitMonitor = mon;
748
749 /*
750 * Handle the case where the thread was interrupted before we called
751 * wait().
752 */
753 if (self->interrupted) {
754 wasInterrupted = true;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800755 self->waitMonitor = NULL;
756 pthread_mutex_unlock(&self->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800757 goto done;
758 }
759
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800760 /*
761 * Release the monitor lock and wait for a notification or
762 * a timeout to occur.
763 */
764 pthread_mutex_unlock(&mon->lock);
765
766 if (!timed) {
767 ret = pthread_cond_wait(&self->waitCond, &self->waitMutex);
768 assert(ret == 0);
769 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800770#ifdef HAVE_TIMEDWAIT_MONOTONIC
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800771 ret = pthread_cond_timedwait_monotonic(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800772#else
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800773 ret = pthread_cond_timedwait(&self->waitCond, &self->waitMutex, &ts);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800774#endif
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800775 assert(ret == 0 || ret == ETIMEDOUT);
776 }
777 if (self->interrupted) {
778 wasInterrupted = true;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800779 }
780
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800781 self->interrupted = false;
782 self->waitMonitor = NULL;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800783
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800784 pthread_mutex_unlock(&self->waitMutex);
785
Carl Shapiro30aa9972010-01-13 22:07:50 -0800786 /* Reacquire the monitor lock. */
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800787 lockMonitor(self, mon);
788
Carl Shapiro142ef272010-01-25 12:51:31 -0800789done:
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800790 /*
Carl Shapiro07b35922010-01-25 14:48:30 -0800791 * We remove our thread from wait set after restoring the count
792 * and owner fields so the subroutine can check that the calling
793 * thread owns the monitor. Aside from that, the order of member
794 * updates is not order sensitive as we hold the pthread mutex.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800795 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800796 mon->owner = self;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800797 mon->lockCount = prevLockCount;
Carl Shapiro07b35922010-01-25 14:48:30 -0800798 waitSetRemove(mon, self);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800799
800 /* set self->status back to THREAD_RUNNING, and self-suspend if needed */
801 dvmChangeStatus(self, THREAD_RUNNING);
802
803 if (wasInterrupted) {
804 /*
805 * We were interrupted while waiting, or somebody interrupted an
Carl Shapiro30aa9972010-01-13 22:07:50 -0800806 * un-interruptible thread earlier and we're bailing out immediately.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800807 *
808 * The doc sayeth: "The interrupted status of the current thread is
809 * cleared when this exception is thrown."
810 */
811 self->interrupted = false;
812 if (interruptShouldThrow)
813 dvmThrowException("Ljava/lang/InterruptedException;", NULL);
814 }
815}
816
817/*
818 * Notify one thread waiting on this monitor.
819 */
820static void notifyMonitor(Thread* self, Monitor* mon)
821{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800822 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800823
Carl Shapiro71938022009-12-22 13:49:53 -0800824 assert(self != NULL);
825 assert(mon != NULL);
826
Carl Shapiro94338aa2009-12-21 11:42:59 -0800827 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800828 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800829 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
830 "object not locked by thread before notify()");
831 return;
832 }
Carl Shapiro30aa9972010-01-13 22:07:50 -0800833 /* Signal the first waiting thread in the wait set. */
834 while (mon->waitSet != NULL) {
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800835 thread = mon->waitSet;
836 mon->waitSet = thread->waitNext;
837 thread->waitNext = NULL;
838 pthread_mutex_lock(&thread->waitMutex);
839 /* Check to see if the thread is still waiting. */
840 if (thread->waitMonitor != NULL) {
841 pthread_cond_signal(&thread->waitCond);
Carl Shapiro30aa9972010-01-13 22:07:50 -0800842 pthread_mutex_unlock(&thread->waitMutex);
843 return;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800844 }
845 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800846 }
847}
848
849/*
850 * Notify all threads waiting on this monitor.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800851 */
852static void notifyAllMonitor(Thread* self, Monitor* mon)
853{
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800854 Thread* thread;
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800855
Carl Shapiro71938022009-12-22 13:49:53 -0800856 assert(self != NULL);
857 assert(mon != NULL);
858
Carl Shapiro94338aa2009-12-21 11:42:59 -0800859 /* Make sure that we hold the lock. */
Carl Shapiro71938022009-12-22 13:49:53 -0800860 if (mon->owner != self) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800861 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
862 "object not locked by thread before notifyAll()");
863 return;
864 }
Carl Shapiro77f52eb2009-12-24 19:56:53 -0800865 /* Signal all threads in the wait set. */
866 while (mon->waitSet != NULL) {
867 thread = mon->waitSet;
868 mon->waitSet = thread->waitNext;
869 thread->waitNext = NULL;
870 pthread_mutex_lock(&thread->waitMutex);
871 /* Check to see if the thread is still waiting. */
872 if (thread->waitMonitor != NULL) {
873 pthread_cond_signal(&thread->waitCond);
874 }
875 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800876 }
877}
878
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800879/*
880 * Implements monitorenter for "synchronized" stuff.
881 *
882 * This does not fail or throw an exception (unless deadlock prediction
883 * is enabled and set to "err" mode).
884 */
885void dvmLockObject(Thread* self, Object *obj)
886{
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800887 volatile u4 *thinp;
Carl Shapiro94338aa2009-12-21 11:42:59 -0800888 Monitor *mon;
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800889 ThreadStatus oldStatus;
890 useconds_t sleepDelay;
891 const useconds_t maxSleepDelay = 1 << 20;
892 u4 thin, newThin, threadId;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800893
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800894 assert(self != NULL);
895 assert(obj != NULL);
896 threadId = self->threadId;
897 thinp = &obj->lock;
898retry:
899 thin = *thinp;
900 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
901 /*
902 * The lock is a thin lock. The owner field is used to
903 * determine the acquire method, ordered by cost.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800904 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800905 if (LW_LOCK_OWNER(thin) == threadId) {
906 /*
907 * The calling thread owns the lock. Increment the
908 * value of the recursion count field.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800909 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800910 obj->lock += 1 << LW_LOCK_COUNT_SHIFT;
911 } else if (LW_LOCK_OWNER(thin) == 0) {
912 /*
913 * The lock is unowned. Install the thread id of the
914 * calling thread into the owner field. This is the
915 * common case. In performance critical code the JIT
916 * will have tried this before calling out to the VM.
917 */
918 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
919 if (!ATOMIC_CMP_SWAP((int32_t *)thinp, thin, newThin)) {
920 /*
921 * The acquire failed. Try again.
922 */
923 goto retry;
924 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800925 } else {
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800926 LOG_THIN("(%d) spin on lock %p: %#x (%#x) %#x",
927 threadId, &obj->lock, 0, *thinp, thin);
928 /*
929 * The lock is owned by another thread. Notify the VM
930 * that we are about to wait.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800931 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800932 oldStatus = dvmChangeStatus(self, THREAD_MONITOR);
933 /*
934 * Spin until the thin lock is released or inflated.
935 */
936 sleepDelay = 0;
937 for (;;) {
938 thin = *thinp;
939 /*
940 * Check the shape of the lock word. Another thread
941 * may have inflated the lock while we were waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800942 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800943 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
944 if (LW_LOCK_OWNER(thin) == 0) {
945 /*
946 * The lock has been released. Install the
947 * thread id of the calling thread into the
948 * owner field.
949 */
950 newThin = thin | (threadId << LW_LOCK_OWNER_SHIFT);
951 if (ATOMIC_CMP_SWAP((int32_t *)thinp,
952 thin, newThin)) {
953 /*
954 * The acquire succeed. Break out of the
955 * loop and proceed to inflate the lock.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800956 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800957 break;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800958 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800959 } else {
960 /*
961 * The lock has not been released. Yield so
962 * the owning thread can run.
963 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800964 if (sleepDelay == 0) {
965 sched_yield();
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800966 sleepDelay = 1000;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800967 } else {
968 usleep(sleepDelay);
969 if (sleepDelay < maxSleepDelay / 2) {
970 sleepDelay *= 2;
971 }
972 }
973 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800974 } else {
975 /*
976 * The thin lock was inflated by another thread.
977 * Let the VM know we are no longer waiting and
978 * try again.
979 */
980 LOG_THIN("(%d) lock %p surprise-fattened",
981 threadId, &obj->lock);
982 dvmChangeStatus(self, oldStatus);
983 goto retry;
984 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800985 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800986 LOG_THIN("(%d) spin on lock done %p: %#x (%#x) %#x",
987 threadId, &obj->lock, 0, *thinp, thin);
988 /*
989 * We have acquired the thin lock. Let the VM know that
990 * we are no longer waiting.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -0800991 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -0800992 dvmChangeStatus(self, oldStatus);
993 /*
994 * Fatten the lock.
995 */
996 mon = dvmCreateMonitor(obj);
997 lockMonitor(self, mon);
998 thin = *thinp;
999 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
1000 thin |= (u4)mon | LW_SHAPE_FAT;
1001 MEM_BARRIER();
1002 obj->lock = thin;
1003 LOG_THIN("(%d) lock %p fattened", threadId, &obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001004 }
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001005 } else {
1006 /*
1007 * The lock is a fat lock.
1008 */
1009 assert(LW_MONITOR(obj->lock) != NULL);
1010 lockMonitor(self, LW_MONITOR(obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001011 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001012#ifdef WITH_DEADLOCK_PREDICTION
1013 /*
1014 * See if we were allowed to grab the lock at this time. We do it
1015 * *after* acquiring the lock, rather than before, so that we can
1016 * freely update the Monitor struct. This seems counter-intuitive,
1017 * but our goal is deadlock *prediction* not deadlock *prevention*.
1018 * (If we actually deadlock, the situation is easy to diagnose from
1019 * a thread dump, so there's no point making a special effort to do
1020 * the checks before the lock is held.)
1021 *
1022 * This needs to happen before we add the object to the thread's
1023 * monitor list, so we can tell the difference between first-lock and
1024 * re-lock.
1025 *
1026 * It's also important that we do this while in THREAD_RUNNING, so
1027 * that we don't interfere with cleanup operations in the GC.
1028 */
1029 if (gDvm.deadlockPredictMode != kDPOff) {
1030 if (self->status != THREAD_RUNNING) {
1031 LOGE("Bad thread status (%d) in DP\n", self->status);
1032 dvmDumpThread(self, false);
1033 dvmAbort();
1034 }
1035 assert(!dvmCheckException(self));
1036 updateDeadlockPrediction(self, obj);
1037 if (dvmCheckException(self)) {
1038 /*
1039 * If we're throwing an exception here, we need to free the
1040 * lock. We add the object to the thread's monitor list so the
1041 * "unlock" code can remove it.
1042 */
1043 dvmAddToMonitorList(self, obj, false);
1044 dvmUnlockObject(self, obj);
1045 LOGV("--- unlocked, pending is '%s'\n",
1046 dvmGetException(self)->clazz->descriptor);
1047 }
1048 }
1049
1050 /*
1051 * Add the locked object, and the current stack trace, to the list
1052 * held by the Thread object. If deadlock prediction isn't on,
1053 * don't capture the stack trace.
1054 */
1055 dvmAddToMonitorList(self, obj, gDvm.deadlockPredictMode != kDPOff);
1056#elif defined(WITH_MONITOR_TRACKING)
1057 /*
1058 * Add the locked object to the list held by the Thread object.
1059 */
1060 dvmAddToMonitorList(self, obj, false);
1061#endif
1062}
1063
1064/*
1065 * Implements monitorexit for "synchronized" stuff.
1066 *
1067 * On failure, throws an exception and returns "false".
1068 */
1069bool dvmUnlockObject(Thread* self, Object *obj)
1070{
Carl Shapiro94338aa2009-12-21 11:42:59 -08001071 u4 thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001072
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001073 assert(self != NULL);
1074 assert(self->status == THREAD_RUNNING);
1075 assert(obj != NULL);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001076 /*
1077 * Cache the lock word as its value can change while we are
1078 * examining its state.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001079 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001080 thin = obj->lock;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001081 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
1082 /*
1083 * The lock is thin. We must ensure that the lock is owned
1084 * by the given thread before unlocking it.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001085 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001086 if (LW_LOCK_OWNER(thin) == self->threadId) {
1087 /*
1088 * We are the lock owner. It is safe to update the lock
1089 * without CAS as lock ownership guards the lock itself.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001090 */
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001091 if (LW_LOCK_COUNT(thin) == 0) {
1092 /*
1093 * The lock was not recursively acquired, the common
1094 * case. Unlock by clearing all bits except for the
1095 * hash state.
1096 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001097 obj->lock &= (LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT);
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001098 } else {
1099 /*
1100 * The object was recursively acquired. Decrement the
1101 * lock recursion count field.
1102 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001103 obj->lock -= 1 << LW_LOCK_COUNT_SHIFT;
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001104 }
1105 } else {
1106 /*
1107 * We do not own the lock. The JVM spec requires that we
1108 * throw an exception in this case.
1109 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001110 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001111 "unlock of unowned monitor");
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001112 return false;
1113 }
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001114 } else {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001115 /*
1116 * The lock is fat. We must check to see if unlockMonitor has
1117 * raised any exceptions before continuing.
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001118 */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001119 assert(LW_MONITOR(obj->lock) != NULL);
1120 if (!unlockMonitor(self, LW_MONITOR(obj->lock))) {
Carl Shapiroef5b4d32010-01-26 13:22:04 -08001121 /*
1122 * An exception has been raised. Do not fall through.
1123 */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001124 return false;
1125 }
1126 }
1127
1128#ifdef WITH_MONITOR_TRACKING
1129 /*
1130 * Remove the object from the Thread's list.
1131 */
1132 dvmRemoveFromMonitorList(self, obj);
1133#endif
1134
1135 return true;
1136}
1137
1138/*
1139 * Object.wait(). Also called for class init.
1140 */
1141void dvmObjectWait(Thread* self, Object *obj, s8 msec, s4 nsec,
1142 bool interruptShouldThrow)
1143{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001144 Monitor* mon = LW_MONITOR(obj->lock);
1145 u4 hashState;
1146 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001147
1148 /* If the lock is still thin, we need to fatten it.
1149 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001150 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001151 /* Make sure that 'self' holds the lock.
1152 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001153 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001154 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1155 "object not locked by thread before wait()");
1156 return;
1157 }
1158
1159 /* This thread holds the lock. We need to fatten the lock
1160 * so 'self' can block on it. Don't update the object lock
1161 * field yet, because 'self' needs to acquire the lock before
1162 * any other thread gets a chance.
1163 */
1164 mon = dvmCreateMonitor(obj);
1165
1166 /* 'self' has actually locked the object one or more times;
1167 * make sure that the monitor reflects this.
1168 */
1169 lockMonitor(self, mon);
Carl Shapiro94338aa2009-12-21 11:42:59 -08001170 mon->lockCount = LW_LOCK_COUNT(thin);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001171 LOG_THIN("(%d) lock 0x%08x fattened by wait() to count %d\n",
1172 self->threadId, (uint)&obj->lock, mon->lockCount);
1173
Andy McFadden581bed72009-10-15 11:24:54 -07001174
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001175 /* Make the monitor public now that it's in the right state.
1176 */
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001177 thin &= LW_HASH_STATE_MASK << LW_HASH_STATE_SHIFT;
1178 thin |= (u4)mon | LW_SHAPE_FAT;
Andy McFadden581bed72009-10-15 11:24:54 -07001179 MEM_BARRIER();
Carl Shapiro147dd3f2010-03-08 14:38:42 -08001180 obj->lock = thin;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001181 }
1182
1183 waitMonitor(self, mon, msec, nsec, interruptShouldThrow);
1184}
1185
1186/*
1187 * Object.notify().
1188 */
1189void dvmObjectNotify(Thread* self, Object *obj)
1190{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001191 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001192
1193 /* If the lock is still thin, there aren't any waiters;
1194 * waiting on an object forces lock fattening.
1195 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001196 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001197 /* Make sure that 'self' holds the lock.
1198 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001199 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001200 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1201 "object not locked by thread before notify()");
1202 return;
1203 }
1204
1205 /* no-op; there are no waiters to notify.
1206 */
1207 } else {
1208 /* It's a fat lock.
1209 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001210 notifyMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001211 }
1212}
1213
1214/*
1215 * Object.notifyAll().
1216 */
1217void dvmObjectNotifyAll(Thread* self, Object *obj)
1218{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001219 u4 thin = obj->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001220
1221 /* If the lock is still thin, there aren't any waiters;
1222 * waiting on an object forces lock fattening.
1223 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001224 if (LW_SHAPE(thin) == LW_SHAPE_THIN) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001225 /* Make sure that 'self' holds the lock.
1226 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001227 if (LW_LOCK_OWNER(thin) != self->threadId) {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001228 dvmThrowException("Ljava/lang/IllegalMonitorStateException;",
1229 "object not locked by thread before notifyAll()");
1230 return;
1231 }
1232
1233 /* no-op; there are no waiters to notify.
1234 */
1235 } else {
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001236 /* It's a fat lock.
1237 */
Carl Shapiro94338aa2009-12-21 11:42:59 -08001238 notifyAllMonitor(self, LW_MONITOR(thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001239 }
1240}
1241
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001242/*
1243 * This implements java.lang.Thread.sleep(long msec, int nsec).
1244 *
1245 * The sleep is interruptible by other threads, which means we can't just
1246 * plop into an OS sleep call. (We probably could if we wanted to send
1247 * signals around and rely on EINTR, but that's inefficient and relies
1248 * on native code respecting our signal mask.)
1249 *
1250 * We have to do all of this stuff for Object.wait() as well, so it's
1251 * easiest to just sleep on a private Monitor.
1252 *
1253 * It appears that we want sleep(0,0) to go through the motions of sleeping
1254 * for a very short duration, rather than just returning.
1255 */
1256void dvmThreadSleep(u8 msec, u4 nsec)
1257{
1258 Thread* self = dvmThreadSelf();
1259 Monitor* mon = gDvm.threadSleepMon;
1260
1261 /* sleep(0,0) wakes up immediately, wait(0,0) means wait forever; adjust */
1262 if (msec == 0 && nsec == 0)
1263 nsec++;
1264
1265 lockMonitor(self, mon);
1266 waitMonitor(self, mon, msec, nsec, true);
1267 unlockMonitor(self, mon);
1268}
1269
1270/*
1271 * Implement java.lang.Thread.interrupt().
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001272 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001273void dvmThreadInterrupt(Thread* thread)
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001274{
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001275 assert(thread != NULL);
1276
1277 pthread_mutex_lock(&thread->waitMutex);
1278
1279 /*
1280 * If the interrupted flag is already set no additional action is
1281 * required.
1282 */
1283 if (thread->interrupted == true) {
1284 pthread_mutex_unlock(&thread->waitMutex);
1285 return;
1286 }
1287
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001288 /*
1289 * Raise the "interrupted" flag. This will cause it to bail early out
1290 * of the next wait() attempt, if it's not currently waiting on
1291 * something.
1292 */
1293 thread->interrupted = true;
1294 MEM_BARRIER();
1295
1296 /*
1297 * Is the thread waiting?
1298 *
1299 * Note that fat vs. thin doesn't matter here; waitMonitor
1300 * is only set when a thread actually waits on a monitor,
1301 * which implies that the monitor has already been fattened.
1302 */
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001303 if (thread->waitMonitor != NULL) {
1304 pthread_cond_signal(&thread->waitCond);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001305 }
1306
Carl Shapiro77f52eb2009-12-24 19:56:53 -08001307 pthread_mutex_unlock(&thread->waitMutex);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001308}
1309
Carl Shapiro30aa9972010-01-13 22:07:50 -08001310#ifndef WITH_COPYING_GC
Carl Shapiro94338aa2009-12-21 11:42:59 -08001311u4 dvmIdentityHashCode(Object *obj)
1312{
1313 return (u4)obj;
1314}
Carl Shapiro30aa9972010-01-13 22:07:50 -08001315#else
1316static size_t arrayElementWidth(const ArrayObject *array)
1317{
1318 const char *descriptor;
1319
1320 if (dvmIsObjectArray(array)) {
1321 return sizeof(Object *);
1322 } else {
1323 descriptor = array->obj.clazz->descriptor;
1324 switch (descriptor[1]) {
1325 case 'B': return 1; /* byte */
1326 case 'C': return 2; /* char */
1327 case 'D': return 8; /* double */
1328 case 'F': return 4; /* float */
1329 case 'I': return 4; /* int */
1330 case 'J': return 8; /* long */
1331 case 'S': return 2; /* short */
1332 case 'Z': return 1; /* boolean */
1333 }
1334 }
1335 LOGE("object %p has an unhandled descriptor '%s'", array, descriptor);
1336 dvmDumpThread(dvmThreadSelf(), false);
1337 dvmAbort();
1338 return 0; /* Quiet the compiler. */
1339}
1340
1341static size_t arrayObjectLength(const ArrayObject *array)
1342{
1343 size_t length;
1344
1345 length = offsetof(ArrayObject, contents);
1346 length += array->length * arrayElementWidth(array);
1347 return length;
1348}
1349
1350/*
1351 * Returns the identity hash code of the given object.
1352 */
1353u4 dvmIdentityHashCode(Object *obj)
1354{
1355 Thread *self, *thread;
1356 volatile u4 *lw;
1357 size_t length;
1358 u4 lock, owner, hashState;
1359
1360 if (obj == NULL) {
1361 /*
1362 * Null is defined to have an identity hash code of 0.
1363 */
1364 return 0;
1365 }
1366 lw = &obj->lock;
1367retry:
1368 hashState = LW_HASH_STATE(*lw);
1369 if (hashState == LW_HASH_STATE_HASHED) {
1370 /*
1371 * The object has been hashed but has not had its hash code
1372 * relocated by the garbage collector. Use the raw object
1373 * address.
1374 */
1375 return (u4)obj >> 3;
1376 } else if (hashState == LW_HASH_STATE_HASHED_AND_MOVED) {
1377 /*
1378 * The object has been hashed and its hash code has been
1379 * relocated by the collector. Use the value of the naturally
1380 * aligned word following the instance data.
1381 */
1382 if (IS_CLASS_FLAG_SET(obj->clazz, CLASS_ISARRAY)) {
1383 length = arrayObjectLength((ArrayObject *)obj);
1384 length = (length + 3) & ~3;
1385 } else {
1386 length = obj->clazz->objectSize;
1387 }
1388 return *(u4 *)(((char *)obj) + length);
1389 } else if (hashState == LW_HASH_STATE_UNHASHED) {
1390 /*
1391 * The object has never been hashed. Change the hash state to
1392 * hashed and use the raw object address.
1393 */
1394 self = dvmThreadSelf();
1395 if (self->threadId == lockOwner(obj)) {
1396 /*
1397 * We already own the lock so we can update the hash state
1398 * directly.
1399 */
1400 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1401 return (u4)obj >> 3;
1402 }
1403 /*
1404 * We do not own the lock. Try acquiring the lock. Should
1405 * this fail, we must suspend the owning thread.
1406 */
1407 if (LW_SHAPE(*lw) == LW_SHAPE_THIN) {
1408 /*
1409 * If the lock is thin assume it is unowned. We simulate
1410 * an acquire, update, and release with a single CAS.
1411 */
1412 lock = DVM_LOCK_INITIAL_THIN_VALUE;
1413 lock |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1414 if (ATOMIC_CMP_SWAP((int32_t *)lw,
1415 (int32_t)DVM_LOCK_INITIAL_THIN_VALUE,
1416 (int32_t)lock)) {
1417 /*
1418 * A new lockword has been installed with a hash state
1419 * of hashed. Use the raw object address.
1420 */
1421 return (u4)obj >> 3;
1422 }
1423 } else {
1424 if (tryLockMonitor(self, LW_MONITOR(*lw))) {
1425 /*
1426 * The monitor lock has been acquired. Change the
1427 * hash state to hashed and use the raw object
1428 * address.
1429 */
1430 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1431 unlockMonitor(self, LW_MONITOR(*lw));
1432 return (u4)obj >> 3;
1433 }
1434 }
1435 /*
1436 * At this point we have failed to acquire the lock. We must
1437 * identify the owning thread and suspend it.
1438 */
1439 dvmLockThreadList(self);
1440 /*
1441 * Cache the lock word as its value can change between
1442 * determining its shape and retrieving its owner.
1443 */
1444 lock = *lw;
1445 if (LW_SHAPE(lock) == LW_SHAPE_THIN) {
1446 /*
1447 * Find the thread with the corresponding thread id.
1448 */
1449 owner = LW_LOCK_OWNER(lock);
1450 assert(owner != self->threadId);
1451 /*
1452 * If the lock has no owner do not bother scanning the
1453 * thread list and fall through to the failure handler.
1454 */
1455 thread = owner ? gDvm.threadList : NULL;
1456 while (thread != NULL) {
1457 if (thread->threadId == owner) {
1458 break;
1459 }
1460 thread = thread->next;
1461 }
1462 } else {
1463 thread = LW_MONITOR(lock)->owner;
1464 }
1465 /*
1466 * If thread is NULL the object has been released since the
1467 * thread list lock was acquired. Try again.
1468 */
1469 if (thread == NULL) {
1470 dvmUnlockThreadList();
1471 goto retry;
1472 }
1473 /*
1474 * Wait for the owning thread to suspend.
1475 */
1476 dvmSuspendThread(thread);
1477 if (dvmHoldsLock(thread, obj)) {
1478 /*
1479 * The owning thread has been suspended. We can safely
1480 * change the hash state to hashed.
1481 */
1482 *lw |= (LW_HASH_STATE_HASHED << LW_HASH_STATE_SHIFT);
1483 dvmResumeThread(thread);
1484 dvmUnlockThreadList();
1485 return (u4)obj >> 3;
1486 }
1487 /*
1488 * The wrong thread has been suspended. Try again.
1489 */
1490 dvmResumeThread(thread);
1491 dvmUnlockThreadList();
1492 goto retry;
1493 }
1494 LOGE("object %p has an unknown hash state %#x", obj, hashState);
1495 dvmDumpThread(dvmThreadSelf(), false);
1496 dvmAbort();
1497 return 0; /* Quiet the compiler. */
1498}
1499#endif /* WITH_COPYING_GC */
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001500
1501#ifdef WITH_DEADLOCK_PREDICTION
1502/*
1503 * ===========================================================================
1504 * Deadlock prediction
1505 * ===========================================================================
1506 */
1507/*
1508The idea is to predict the possibility of deadlock by recording the order
1509in which monitors are acquired. If we see an attempt to acquire a lock
1510out of order, we can identify the locks and offending code.
1511
1512To make this work, we need to keep track of the locks held by each thread,
1513and create history trees for each lock. When a thread tries to acquire
1514a new lock, we walk through the "history children" of the lock, looking
1515for a match with locks the thread already holds. If we find a match,
1516it means the thread has made a request that could result in a deadlock.
1517
1518To support recursive locks, we always allow re-locking a currently-held
1519lock, and maintain a recursion depth count.
1520
1521An ASCII-art example, where letters represent Objects:
1522
1523 A
1524 /|\
1525 / | \
1526 B | D
1527 \ |
1528 \|
1529 C
1530
1531The above is the tree we'd have after handling Object synchronization
1532sequences "ABC", "AC", "AD". A has three children, {B, C, D}. C is also
1533a child of B. (The lines represent pointers between parent and child.
1534Every node can have multiple parents and multiple children.)
1535
1536If we hold AC, and want to lock B, we recursively search through B's
1537children to see if A or C appears. It does, so we reject the attempt.
1538(A straightforward way to implement it: add a link from C to B, then
1539determine whether the graph starting at B contains a cycle.)
1540
1541If we hold AC and want to lock D, we would succeed, creating a new link
1542from C to D.
1543
1544The lock history and a stack trace is attached to the Object's Monitor
1545struct, which means we need to fatten every Object we lock (thin locking
1546is effectively disabled). If we don't need the stack trace we can
1547avoid fattening the leaf nodes, only fattening objects that need to hold
1548history trees.
1549
1550Updates to Monitor structs are only allowed for the thread that holds
1551the Monitor, so we actually do most of our deadlock prediction work after
1552the lock has been acquired.
1553
1554When an object with a monitor is GCed, we need to remove it from the
1555history trees. There are two basic approaches:
1556 (1) For through the entire set of known monitors, search all child
1557 lists for the object in question. This is rather slow, resulting
1558 in GC passes that take upwards of 10 seconds to complete.
1559 (2) Maintain "parent" pointers in each node. Remove the entries as
1560 required. This requires additional storage and maintenance for
1561 every operation, but is significantly faster at GC time.
1562For each GCed object, we merge all of the object's children into each of
1563the object's parents.
1564*/
1565
1566#if !defined(WITH_MONITOR_TRACKING)
1567# error "WITH_DEADLOCK_PREDICTION requires WITH_MONITOR_TRACKING"
1568#endif
1569
1570/*
1571 * Clear out the contents of an ExpandingObjectList, freeing any
1572 * dynamic allocations.
1573 */
1574static void expandObjClear(ExpandingObjectList* pList)
1575{
1576 if (pList->list != NULL) {
1577 free(pList->list);
1578 pList->list = NULL;
1579 }
1580 pList->alloc = pList->count = 0;
1581}
1582
1583/*
1584 * Get the number of objects currently stored in the list.
1585 */
1586static inline int expandBufGetCount(const ExpandingObjectList* pList)
1587{
1588 return pList->count;
1589}
1590
1591/*
1592 * Get the Nth entry from the list.
1593 */
1594static inline Object* expandBufGetEntry(const ExpandingObjectList* pList,
1595 int i)
1596{
1597 return pList->list[i];
1598}
1599
1600/*
1601 * Add a new entry to the list.
1602 *
1603 * We don't check for or try to enforce uniqueness. It's expected that
1604 * the higher-level code does this for us.
1605 */
1606static void expandObjAddEntry(ExpandingObjectList* pList, Object* obj)
1607{
1608 if (pList->count == pList->alloc) {
1609 /* time to expand */
1610 Object** newList;
1611
1612 if (pList->alloc == 0)
1613 pList->alloc = 4;
1614 else
1615 pList->alloc *= 2;
1616 LOGVV("expanding %p to %d\n", pList, pList->alloc);
1617 newList = realloc(pList->list, pList->alloc * sizeof(Object*));
1618 if (newList == NULL) {
1619 LOGE("Failed expanding DP object list (alloc=%d)\n", pList->alloc);
1620 dvmAbort();
1621 }
1622 pList->list = newList;
1623 }
1624
1625 pList->list[pList->count++] = obj;
1626}
1627
1628/*
1629 * Returns "true" if the element was successfully removed.
1630 */
1631static bool expandObjRemoveEntry(ExpandingObjectList* pList, Object* obj)
1632{
1633 int i;
1634
1635 for (i = pList->count-1; i >= 0; i--) {
1636 if (pList->list[i] == obj)
1637 break;
1638 }
1639 if (i < 0)
1640 return false;
1641
1642 if (i != pList->count-1) {
1643 /*
1644 * The order of elements is not important, so we just copy the
1645 * last entry into the new slot.
1646 */
1647 //memmove(&pList->list[i], &pList->list[i+1],
1648 // (pList->count-1 - i) * sizeof(pList->list[0]));
1649 pList->list[i] = pList->list[pList->count-1];
1650 }
1651
1652 pList->count--;
1653 pList->list[pList->count] = (Object*) 0xdecadead;
1654 return true;
1655}
1656
1657/*
1658 * Returns "true" if "obj" appears in the list.
1659 */
1660static bool expandObjHas(const ExpandingObjectList* pList, Object* obj)
1661{
1662 int i;
1663
1664 for (i = 0; i < pList->count; i++) {
1665 if (pList->list[i] == obj)
1666 return true;
1667 }
1668 return false;
1669}
1670
1671/*
1672 * Print the list contents to stdout. For debugging.
1673 */
1674static void expandObjDump(const ExpandingObjectList* pList)
1675{
1676 int i;
1677 for (i = 0; i < pList->count; i++)
1678 printf(" %p", pList->list[i]);
1679}
1680
1681/*
1682 * Check for duplicate entries. Returns the index of the first instance
1683 * of the duplicated value, or -1 if no duplicates were found.
1684 */
1685static int expandObjCheckForDuplicates(const ExpandingObjectList* pList)
1686{
1687 int i, j;
1688 for (i = 0; i < pList->count-1; i++) {
1689 for (j = i + 1; j < pList->count; j++) {
1690 if (pList->list[i] == pList->list[j]) {
1691 return i;
1692 }
1693 }
1694 }
1695
1696 return -1;
1697}
1698
1699
1700/*
1701 * Determine whether "child" appears in the list of objects associated
1702 * with the Monitor in "parent". If "parent" is a thin lock, we return
1703 * false immediately.
1704 */
1705static bool objectInChildList(const Object* parent, Object* child)
1706{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001707 u4 lock = parent->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001708 if (!IS_LOCK_FAT(&lock)) {
1709 //LOGI("on thin\n");
1710 return false;
1711 }
1712
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001713 return expandObjHas(&LW_MONITOR(lock)->historyChildren, child);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001714}
1715
1716/*
1717 * Print the child list.
1718 */
1719static void dumpKids(Object* parent)
1720{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001721 Monitor* mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001722
1723 printf("Children of %p:", parent);
1724 expandObjDump(&mon->historyChildren);
1725 printf("\n");
1726}
1727
1728/*
1729 * Add "child" to the list of children in "parent", and add "parent" to
1730 * the list of parents in "child".
1731 */
1732static void linkParentToChild(Object* parent, Object* child)
1733{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001734 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for merge
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001735 assert(IS_LOCK_FAT(&parent->lock));
1736 assert(IS_LOCK_FAT(&child->lock));
1737 assert(parent != child);
1738 Monitor* mon;
1739
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001740 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001741 assert(!expandObjHas(&mon->historyChildren, child));
1742 expandObjAddEntry(&mon->historyChildren, child);
1743
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001744 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001745 assert(!expandObjHas(&mon->historyParents, parent));
1746 expandObjAddEntry(&mon->historyParents, parent);
1747}
1748
1749
1750/*
1751 * Remove "child" from the list of children in "parent".
1752 */
1753static void unlinkParentFromChild(Object* parent, Object* child)
1754{
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001755 //assert(LW_MONITOR(parent->lock)->owner == dvmThreadSelf()); // !owned for GC
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001756 assert(IS_LOCK_FAT(&parent->lock));
1757 assert(IS_LOCK_FAT(&child->lock));
1758 assert(parent != child);
1759 Monitor* mon;
1760
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001761 mon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001762 if (!expandObjRemoveEntry(&mon->historyChildren, child)) {
1763 LOGW("WARNING: child %p not found in parent %p\n", child, parent);
1764 }
1765 assert(!expandObjHas(&mon->historyChildren, child));
1766 assert(expandObjCheckForDuplicates(&mon->historyChildren) < 0);
1767
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001768 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001769 if (!expandObjRemoveEntry(&mon->historyParents, parent)) {
1770 LOGW("WARNING: parent %p not found in child %p\n", parent, child);
1771 }
1772 assert(!expandObjHas(&mon->historyParents, parent));
1773 assert(expandObjCheckForDuplicates(&mon->historyParents) < 0);
1774}
1775
1776
1777/*
1778 * Log the monitors held by the current thread. This is done as part of
1779 * flagging an error.
1780 */
1781static void logHeldMonitors(Thread* self)
1782{
1783 char* name = NULL;
1784
1785 name = dvmGetThreadName(self);
1786 LOGW("Monitors currently held by thread (threadid=%d '%s')\n",
1787 self->threadId, name);
1788 LOGW("(most-recently-acquired on top):\n");
1789 free(name);
1790
1791 LockedObjectData* lod = self->pLockedObjects;
1792 while (lod != NULL) {
1793 LOGW("--- object %p[%d] (%s)\n",
1794 lod->obj, lod->recursionCount, lod->obj->clazz->descriptor);
1795 dvmLogRawStackTrace(lod->rawStackTrace, lod->stackDepth);
1796
1797 lod = lod->next;
1798 }
1799}
1800
1801/*
1802 * Recursively traverse the object hierarchy starting at "obj". We mark
1803 * ourselves on entry and clear the mark on exit. If we ever encounter
1804 * a marked object, we have a cycle.
1805 *
1806 * Returns "true" if all is well, "false" if we found a cycle.
1807 */
1808static bool traverseTree(Thread* self, const Object* obj)
1809{
1810 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001811 Monitor* mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001812
1813 /*
1814 * Have we been here before?
1815 */
1816 if (mon->historyMark) {
1817 int* rawStackTrace;
1818 int stackDepth;
1819
1820 LOGW("%s\n", kStartBanner);
1821 LOGW("Illegal lock attempt:\n");
1822 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1823
1824 rawStackTrace = dvmFillInStackTraceRaw(self, &stackDepth);
1825 dvmLogRawStackTrace(rawStackTrace, stackDepth);
1826 free(rawStackTrace);
1827
1828 LOGW(" ");
1829 logHeldMonitors(self);
1830
1831 LOGW(" ");
1832 LOGW("Earlier, the following lock order (from last to first) was\n");
1833 LOGW("established -- stack trace is from first successful lock):\n");
1834 return false;
1835 }
1836 mon->historyMark = true;
1837
1838 /*
1839 * Examine the children. We do NOT hold these locks, so they might
1840 * very well transition from thin to fat or change ownership while
1841 * we work.
1842 *
1843 * NOTE: we rely on the fact that they cannot revert from fat to thin
1844 * while we work. This is currently a safe assumption.
1845 *
1846 * We can safely ignore thin-locked children, because by definition
1847 * they have no history and are leaf nodes. In the current
1848 * implementation we always fatten the locks to provide a place to
1849 * hang the stack trace.
1850 */
1851 ExpandingObjectList* pList = &mon->historyChildren;
1852 int i;
1853 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
1854 const Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001855 u4 lock = child->lock;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001856 if (!IS_LOCK_FAT(&lock))
1857 continue;
1858 if (!traverseTree(self, child)) {
1859 LOGW("--- object %p (%s)\n", obj, obj->clazz->descriptor);
1860 dvmLogRawStackTrace(mon->historyRawStackTrace,
1861 mon->historyStackDepth);
1862 mon->historyMark = false;
1863 return false;
1864 }
1865 }
1866
1867 mon->historyMark = false;
1868
1869 return true;
1870}
1871
1872/*
1873 * Update the deadlock prediction tree, based on the current thread
1874 * acquiring "acqObj". This must be called before the object is added to
1875 * the thread's list of held monitors.
1876 *
1877 * If the thread already holds the lock (recursion), or this is a known
1878 * lock configuration, we return without doing anything. Otherwise, we add
1879 * a link from the most-recently-acquired lock in this thread to "acqObj"
1880 * after ensuring that the parent lock is "fat".
1881 *
1882 * This MUST NOT be called while a GC is in progress in another thread,
1883 * because we assume exclusive access to history trees in owned monitors.
1884 */
1885static void updateDeadlockPrediction(Thread* self, Object* acqObj)
1886{
1887 LockedObjectData* lod;
1888 LockedObjectData* mrl;
1889
1890 /*
1891 * Quick check for recursive access.
1892 */
1893 lod = dvmFindInMonitorList(self, acqObj);
1894 if (lod != NULL) {
1895 LOGV("+++ DP: recursive %p\n", acqObj);
1896 return;
1897 }
1898
1899 /*
1900 * Make the newly-acquired object's monitor "fat". In some ways this
1901 * isn't strictly necessary, but we need the GC to tell us when
1902 * "interesting" objects go away, and right now the only way to make
1903 * an object look interesting is to give it a monitor.
1904 *
1905 * This also gives us a place to hang a stack trace.
1906 *
1907 * Our thread holds the lock, so we're allowed to rewrite the lock
1908 * without worrying that something will change out from under us.
1909 */
1910 if (!IS_LOCK_FAT(&acqObj->lock)) {
1911 LOGVV("fattening lockee %p (recur=%d)\n",
Carl Shapiro94338aa2009-12-21 11:42:59 -08001912 acqObj, LW_LOCK_COUNT(acqObj->lock.thin));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001913 Monitor* newMon = dvmCreateMonitor(acqObj);
1914 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001915 newMon->lockCount += LW_LOCK_COUNT(acqObj->lock);
1916 u4 hashState = LW_HASH_STATE(acqObj->lock) << LW_HASH_STATE_SHIFT;
1917 acqObj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001918 }
1919
1920 /* if we don't have a stack trace for this monitor, establish one */
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001921 if (LW_MONITOR(acqObj->lock)->historyRawStackTrace == NULL) {
1922 Monitor* mon = LW_MONITOR(acqObj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001923 mon->historyRawStackTrace = dvmFillInStackTraceRaw(self,
1924 &mon->historyStackDepth);
1925 }
1926
1927 /*
1928 * We need to examine and perhaps modify the most-recently-locked
1929 * monitor. We own that, so there's no risk of another thread
1930 * stepping on us.
1931 *
1932 * Retrieve the most-recently-locked entry from our thread.
1933 */
1934 mrl = self->pLockedObjects;
1935 if (mrl == NULL)
1936 return; /* no other locks held */
1937
1938 /*
1939 * Do a quick check to see if "acqObj" is a direct descendant. We can do
1940 * this without holding the global lock because of our assertion that
1941 * a GC is not running in parallel -- nobody except the GC can
1942 * modify a history list in a Monitor they don't own, and we own "mrl".
1943 * (There might be concurrent *reads*, but no concurrent *writes.)
1944 *
1945 * If we find it, this is a known good configuration, and we're done.
1946 */
1947 if (objectInChildList(mrl->obj, acqObj))
1948 return;
1949
1950 /*
1951 * "mrl" is going to need to have a history tree. If it's currently
1952 * a thin lock, we make it fat now. The thin lock might have a
1953 * nonzero recursive lock count, which we need to carry over.
1954 *
1955 * Our thread holds the lock, so we're allowed to rewrite the lock
1956 * without worrying that something will change out from under us.
1957 */
1958 if (!IS_LOCK_FAT(&mrl->obj->lock)) {
1959 LOGVV("fattening parent %p f/b/o child %p (recur=%d)\n",
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001960 mrl->obj, acqObj, LW_LOCK_COUNT(mrl->obj->lock));
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001961 Monitor* newMon = dvmCreateMonitor(mrl->obj);
1962 lockMonitor(self, newMon); // can't stall, don't need VMWAIT
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08001963 newMon->lockCount += LW_LOCK_COUNT(mrl->obj->lock);
1964 u4 hashState = LW_HASH_STATE(mrl->obj->lock) << LW_HASH_STATE_SHIFT;
1965 mrl->obj->lock = (u4)newMon | hashState | LW_SHAPE_FAT;
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08001966 }
1967
1968 /*
1969 * We haven't seen this configuration before. We need to scan down
1970 * acqObj's tree to see if any of the monitors in self->pLockedObjects
1971 * appear. We grab a global lock before traversing or updating the
1972 * history list.
1973 *
1974 * If we find a match for any of our held locks, we know that the lock
1975 * has previously been acquired *after* acqObj, and we throw an error.
1976 *
1977 * The easiest way to do this is to create a link from "mrl" to "acqObj"
1978 * and do a recursive traversal, marking nodes as we cross them. If
1979 * we cross one a second time, we have a cycle and can throw an error.
1980 * (We do the flag-clearing traversal before adding the new link, so
1981 * that we're guaranteed to terminate.)
1982 *
1983 * If "acqObj" is a thin lock, it has no history, and we can create a
1984 * link to it without additional checks. [ We now guarantee that it's
1985 * always fat. ]
1986 */
1987 bool failed = false;
1988 dvmLockMutex(&gDvm.deadlockHistoryLock);
1989 linkParentToChild(mrl->obj, acqObj);
1990 if (!traverseTree(self, acqObj)) {
1991 LOGW("%s\n", kEndBanner);
1992 failed = true;
1993
1994 /* remove the entry so we're still okay when in "warning" mode */
1995 unlinkParentFromChild(mrl->obj, acqObj);
1996 }
1997 dvmUnlockMutex(&gDvm.deadlockHistoryLock);
1998
1999 if (failed) {
2000 switch (gDvm.deadlockPredictMode) {
2001 case kDPErr:
2002 dvmThrowException("Ldalvik/system/PotentialDeadlockError;", NULL);
2003 break;
2004 case kDPAbort:
2005 LOGE("Aborting due to potential deadlock\n");
2006 dvmAbort();
2007 break;
2008 default:
2009 /* warn only */
2010 break;
2011 }
2012 }
2013}
2014
2015/*
2016 * We're removing "child" from existence. We want to pull all of
2017 * child's children into "parent", filtering out duplicates. This is
2018 * called during the GC.
2019 *
2020 * This does not modify "child", which might have multiple parents.
2021 */
2022static void mergeChildren(Object* parent, const Object* child)
2023{
2024 Monitor* mon;
2025 int i;
2026
2027 assert(IS_LOCK_FAT(&child->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002028 mon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002029 ExpandingObjectList* pList = &mon->historyChildren;
2030
2031 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2032 Object* grandChild = expandBufGetEntry(pList, i);
2033
2034 if (!objectInChildList(parent, grandChild)) {
2035 LOGVV("+++ migrating %p link to %p\n", grandChild, parent);
2036 linkParentToChild(parent, grandChild);
2037 } else {
2038 LOGVV("+++ parent %p already links to %p\n", parent, grandChild);
2039 }
2040 }
2041}
2042
2043/*
2044 * An object with a fat lock is being collected during a GC pass. We
2045 * want to remove it from any lock history trees that it is a part of.
2046 *
2047 * This may require updating the history trees in several monitors. The
2048 * monitor semantics guarantee that no other thread will be accessing
2049 * the history trees at the same time.
2050 */
2051static void removeCollectedObject(Object* obj)
2052{
2053 Monitor* mon;
2054
2055 LOGVV("+++ collecting %p\n", obj);
2056
2057#if 0
2058 /*
2059 * We're currently running through the entire set of known monitors.
2060 * This can be somewhat slow. We may want to keep lists of parents
2061 * in each child to speed up GC.
2062 */
2063 mon = gDvm.monitorList;
2064 while (mon != NULL) {
2065 Object* parent = mon->obj;
2066 if (parent != NULL) { /* value nulled for deleted entries */
2067 if (objectInChildList(parent, obj)) {
2068 LOGVV("removing child %p from parent %p\n", obj, parent);
2069 unlinkParentFromChild(parent, obj);
2070 mergeChildren(parent, obj);
2071 }
2072 }
2073 mon = mon->next;
2074 }
2075#endif
2076
2077 /*
2078 * For every parent of this object:
2079 * - merge all of our children into the parent's child list (creates
2080 * a two-way link between parent and child)
2081 * - remove ourselves from the parent's child list
2082 */
2083 ExpandingObjectList* pList;
2084 int i;
2085
2086 assert(IS_LOCK_FAT(&obj->lock));
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002087 mon = LW_MONITOR(obj->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002088 pList = &mon->historyParents;
2089 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2090 Object* parent = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002091 Monitor* parentMon = LW_MONITOR(parent->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002092
2093 if (!expandObjRemoveEntry(&parentMon->historyChildren, obj)) {
2094 LOGW("WARNING: child %p not found in parent %p\n", obj, parent);
2095 }
2096 assert(!expandObjHas(&parentMon->historyChildren, obj));
2097
2098 mergeChildren(parent, obj);
2099 }
2100
2101 /*
2102 * For every child of this object:
2103 * - remove ourselves from the child's parent list
2104 */
2105 pList = &mon->historyChildren;
2106 for (i = expandBufGetCount(pList)-1; i >= 0; i--) {
2107 Object* child = expandBufGetEntry(pList, i);
Carl Shapiro8d7f9b22009-12-21 20:23:45 -08002108 Monitor* childMon = LW_MONITOR(child->lock);
The Android Open Source Projectf6c38712009-03-03 19:28:47 -08002109
2110 if (!expandObjRemoveEntry(&childMon->historyParents, obj)) {
2111 LOGW("WARNING: parent %p not found in child %p\n", obj, child);
2112 }
2113 assert(!expandObjHas(&childMon->historyParents, obj));
2114 }
2115}
2116
2117#endif /*WITH_DEADLOCK_PREDICTION*/