Skip to content

Commit c00328f

Browse files
author
Scott Mertz
committed
libutils: fix deadlock in elapsedRealtimeNano
If n > 2 threads all lock the mutex awaiting the clock method to be set, the 1st thread will first set the method and unlock. The 2nd thread will then take the mutex, but never unlock because the clock_method has already been updated by the 1st thread. This causes a deadlock for threads 3-n. Solution is to ensure the calling thread always unlocks the mutex if it has previously locked it. Log: "main" prio=5 tid=1 Native | group="main" sCount=1 dsCount=0 obj=0x733313b0 self=0xb4cf6500 | sysTid=12786 nice=0 cgrp=default sched=0/0 handle=0xb6f86b44 | state=S schedstat=( 41990410 32985836 80 ) utm=3 stm=1 core=2 HZ=100 | stack=0xbe5fb000-0xbe5fd000 stackSize=8MB | held mutexes= native: #00 pc 00017638 /system/lib/libc.so (syscall+28) native: SlimRoms#1 pc 0003ffa5 /system/lib/libc.so (_ZL33__pthread_mutex_lock_with_timeoutP24pthread_mutex_internal_tPK8timespeci+504) native: SlimRoms#2 pc 000400a9 /system/lib/libc.so (pthread_mutex_lock+26) native: SlimRoms#3 pc 0000fa01 /system/lib/libutils.so (_ZN7android19elapsedRealtimeNanoEv+16) native: SlimRoms#4 pc 0000fb1f /system/lib/libutils.so (_ZN7android15elapsedRealtimeEv+2) native: #05 pc 00214d1d /data/dalvik-cache/arm/system@[email protected] (Java_android_os_SystemClock_elapsedRealtime__+72) "Thread-6372" prio=5 tid=9 Native | group="main" sCount=1 dsCount=0 obj=0x32c05120 self=0xacb58100 | sysTid=12829 nice=10 cgrp=bg_non_interactive sched=0/0 handle=0xb38c3930 | state=S schedstat=( 869427 8219115 17 ) utm=0 stm=0 core=2 HZ=100 | stack=0xb37c1000-0xb37c3000 stackSize=1038KB | held mutexes= native: #00 pc 00017638 /system/lib/libc.so (syscall+28) native: SlimRoms#1 pc 0003ffa5 /system/lib/libc.so (_ZL33__pthread_mutex_lock_with_timeoutP24pthread_mutex_internal_tPK8timespeci+504) native: SlimRoms#2 pc 000400a9 /system/lib/libc.so (pthread_mutex_lock+26) native: SlimRoms#3 pc 0000fa01 /system/lib/libutils.so (_ZN7android19elapsedRealtimeNanoEv+16) native: SlimRoms#4 pc 0000fb1f /system/lib/libutils.so (_ZN7android15elapsedRealtimeEv+2) native: #05 pc 00214d1d /data/dalvik-cache/arm/system@[email protected] (Java_android_os_SystemClock_elapsedRealtime__+72) HAM-1470 Change-Id: I41874d2b0ea034a35a74da030398231089c15cde
1 parent 4a978c6 commit c00328f

File tree

1 file changed

+8
-0
lines changed

1 file changed

+8
-0
lines changed

libutils/SystemClock.cpp

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -121,9 +121,11 @@ int64_t elapsedRealtimeNano()
121121
#endif
122122

123123
static int s_fd = -1;
124+
bool need_unlock = false;
124125

125126
if (clock_method < 0) {
126127
pthread_mutex_lock(&clock_lock);
128+
need_unlock = true;
127129
}
128130

129131
if (clock_method < 0 || clock_method == METHOD_IOCTL) {
@@ -143,6 +145,8 @@ int64_t elapsedRealtimeNano()
143145
checkTimeStamps(timestamp, &prevTimestamp, &prevMethod, METHOD_IOCTL);
144146
if (clock_method < 0) {
145147
clock_method = METHOD_IOCTL;
148+
}
149+
if (need_unlock) {
146150
pthread_mutex_unlock(&clock_lock);
147151
}
148152
return timestamp;
@@ -159,6 +163,8 @@ int64_t elapsedRealtimeNano()
159163
METHOD_CLOCK_GETTIME);
160164
if (clock_method < 0) {
161165
clock_method = METHOD_CLOCK_GETTIME;
166+
}
167+
if (need_unlock) {
162168
pthread_mutex_unlock(&clock_lock);
163169
}
164170
return timestamp;
@@ -173,6 +179,8 @@ int64_t elapsedRealtimeNano()
173179
METHOD_SYSTEMTIME);
174180
if (clock_method < 0) {
175181
clock_method = METHOD_SYSTEMTIME;
182+
}
183+
if (need_unlock) {
176184
pthread_mutex_unlock(&clock_lock);
177185
}
178186
return timestamp;

0 commit comments

Comments
 (0)