From: Tom Hughes Date: Sun, 17 Oct 2004 15:18:22 +0000 (+0000) Subject: Fix problems with very long timeouts given when waiting on a mutex or X-Git-Tag: svn/VALGRIND_3_0_0~1513 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=2d7c989f9a3d4b5372f3202f1a3a5d59b8091d8b;p=thirdparty%2Fvalgrind.git 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. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@2781 --- diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c index df06d9cd5b..2cbfe353cd 100644 --- a/coregrind/vg_libpthread.c +++ b/coregrind/vg_libpthread.c @@ -1355,6 +1355,8 @@ int __pthread_mutex_timedlock(pthread_mutex_t *mutex, struct timeval timeval_now; 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); @@ -1373,8 +1375,15 @@ int __pthread_mutex_timedlock(pthread_mutex_t *mutex, + ((unsigned long long int)(abstime->tv_nsec / 1000000)); 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, vg_mutex, ms_end, 0, 0); @@ -1518,6 +1527,8 @@ int pthread_cond_timedwait ( pthread_cond_t *cond, struct timeval timeval_now; 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); @@ -1537,8 +1548,17 @@ int pthread_cond_timedwait ( pthread_cond_t *cond, + ((unsigned long long int)(abstime->tv_nsec / 1000000)); 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, cond, vg_mutex, ms_end, 0); diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index 66d638f127..02d884d41b 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -614,8 +614,13 @@ void idle ( void ) } if (tp != NULL) { - delta = tp->time - now; - vg_assert(delta >= 0); + vg_assert(tp->time >= now); + /* limit the signed int delta to INT_MAX */ + if ((tp->time - now) <= 0x7FFFFFFFU) { + delta = tp->time - now; + } else { + delta = 0x7FFFFFFF; + } } if (wicked) delta = 0;