|
From: Tom H. <th...@cy...> - 2004-10-17 15:18:26
|
CVS commit by thughes:
Fix problems with very long timeouts given when waiting on a mutex or
condition variable. The pthread routines now use a timeout of 0xfffffffe
if the user asks for something longer than that otherwise we will wrap
around and actually get a much shorter timeout.
The scheduler has also been changed so that it it now limits itself to
a timeout of 0x7fffffff when working how how long to poll for. This won't
affect how long a thread actually sleeps for as we'll just wind up waiting
a bit more on the next pass round the loop.
This fixes bug 76845.
M +24 -4 vg_libpthread.c 1.169
M +7 -2 vg_scheduler.c 1.191
--- valgrind/coregrind/vg_libpthread.c #1.168:1.169
@@ -1356,4 +1356,6 @@ int __pthread_mutex_timedlock(pthread_mu
unsigned long long int ull_ms_now_after_1970;
unsigned long long int ull_ms_end_after_1970;
+ unsigned long long int ull_ms_now;
+ unsigned long long int ull_ms_end;
vg_pthread_mutex_t* vg_mutex;
CONVERT(mutex, mutex, vg_mutex);
@@ -1374,6 +1376,13 @@ int __pthread_mutex_timedlock(pthread_mu
if (ull_ms_end_after_1970 < ull_ms_now_after_1970)
ull_ms_end_after_1970 = ull_ms_now_after_1970;
- ms_end
- = ms_now + (unsigned int)(ull_ms_end_after_1970 - ull_ms_now_after_1970);
+ if (ull_ms_end >= (unsigned long long int)(0xFFFFFFFFUL)) {
+ /* use 0xFFFFFFFEUL because 0xFFFFFFFFUL is reserved for no timeout
+ (the fine difference between a long wait and a possible abort
+ due to a detected deadlock).
+ */
+ ms_end = 0xFFFFFFFEUL;
+ } else {
+ ms_end = (unsigned int)(ull_ms_end);
+ }
VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
VG_USERREQ__PTHREAD_MUTEX_TIMEDLOCK,
@@ -1519,4 +1528,6 @@ int pthread_cond_timedwait ( pthread_con
unsigned long long int ull_ms_now_after_1970;
unsigned long long int ull_ms_end_after_1970;
+ unsigned long long int ull_ms_now;
+ unsigned long long int ull_ms_end;
vg_pthread_mutex_t* vg_mutex;
CONVERT(mutex, mutex, vg_mutex);
@@ -1538,6 +1549,15 @@ int pthread_cond_timedwait ( pthread_con
if (ull_ms_end_after_1970 < ull_ms_now_after_1970)
ull_ms_end_after_1970 = ull_ms_now_after_1970;
- ms_end
- = ms_now + (unsigned int)(ull_ms_end_after_1970 - ull_ms_now_after_1970);
+ ull_ms_now = ((unsigned long long int)(ms_now));
+ ull_ms_end = ull_ms_now + (ull_ms_end_after_1970 - ull_ms_now_after_1970);
+ if (ull_ms_end >= (unsigned long long int)(0xFFFFFFFFUL)) {
+ /* use 0xFFFFFFFEUL because 0xFFFFFFFFUL is reserved for no timeout
+ (the fine difference between a long wait and a possible abort
+ due to a detected deadlock).
+ */
+ ms_end = 0xFFFFFFFEUL;
+ } else {
+ ms_end = (unsigned int)(ull_ms_end);
+ }
VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */,
VG_USERREQ__PTHREAD_COND_TIMEDWAIT,
--- valgrind/coregrind/vg_scheduler.c #1.190:1.191
@@ -615,6 +615,11 @@ void idle ( void )
if (tp != NULL) {
+ vg_assert(tp->time >= now);
+ /* limit the signed int delta to INT_MAX */
+ if ((tp->time - now) <= 0x7FFFFFFFU) {
delta = tp->time - now;
- vg_assert(delta >= 0);
+ } else {
+ delta = 0x7FFFFFFF;
+ }
}
if (wicked)
|