OSDN Git Service

Use relative futex timeout in SuspendAllInternal.
authorrock.yeh <app1_test@weckout.com>
Fri, 23 Dec 2016 07:11:13 +0000 (15:11 +0800)
committerrock.yeh <app1_test@weckout.com>
Mon, 9 Jan 2017 01:48:01 +0000 (01:48 +0000)
This erroneously used an absolute timeout for FUTEX_WAIT, potentially
causing it to block for MUCH longer than 10 seconds.
http://man7.org/linux/man-pages/man2/futex.2.html
Note: for FUTEX_WAIT, timeout is interpreted as a relative value.

Error case:
kernel time: 15842.476344
nsec: 31694950164731
12-22 20:25:48.020043     0     0 F [15842.476344][HeapTaskDaemon:3008]
futex_wait 00000070fcdf8980 1 1 31694950164731

Normal case:
kernel time: 15842.476344
nsec: 15842476344

Block backtrace:
"HeapTaskDaemon" sysTid=3008
  #00 pc 000000000001bcac  /system/lib64/libc.so (syscall+28)
  #01 pc 0000000000461db0  /system/lib64/libart.so
(_ZN3art10ThreadList18SuspendAllInternalEPNS_6ThreadES2_S2_b+720)
  #02 pc 000000000046249c  /system/lib64/libart.so
(_ZN3art10ThreadList10SuspendAllEPKcb+532)
  #03 pc 00000000001e8fc8  /system/lib64/libart.so
(_ZN3art2gc9collector9MarkSweep9RunPhasesEv+232)
  #04 pc 00000000001e1694  /system/lib64/libart.so
(_ZN3art2gc9collector16GarbageCollector3RunENS0_7GcCauseEb+332)
  #05 pc 0000000000211500  /system/lib64/libart.so
(_ZN3art2gc4Heap22CollectGarbageInternalENS0_9collector6GcTypeENS0_7Gc
CauseEb+3048)
  #06 pc 0000000000218acc  /system/lib64/libart.so
(_ZN3art2gc4Heap12ConcurrentGCEPNS_6ThreadEb+124)
  #07 pc 000000000021fbf4  /system/lib64/libart.so
(_ZN3art2gc4Heap16ConcurrentGCTask3RunEPNS_6ThreadE+36)

This is a fix patch log and each timeout log interval of 10 seconds:
12-27 03:27:46.153744 1631 1713 E art : Unexpected time out during
suspend all.
12-27 03:27:56.154401 1631 1713 E art : Unexpected time out during
suspend all.
12-27 03:28:06.154956 1631 1713 E art : Unexpected time out during
suspend all.

runtime/thread_list.cc

index bf9eef8..34f9043 100644 (file)
@@ -653,7 +653,7 @@ void ThreadList::SuspendAllInternal(Thread* self,
   // is done with a timeout so that we can detect problems.
 #if ART_USE_FUTEXES
   timespec wait_timeout;
-  InitTimeSpec(true, CLOCK_MONOTONIC, 10000, 0, &wait_timeout);
+  InitTimeSpec(false, CLOCK_MONOTONIC, 10000, 0, &wait_timeout);
 #endif
   while (true) {
     int32_t cur_val = pending_threads.LoadRelaxed();