]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Fix problems with very long timeouts given when waiting on a mutex or
authorTom Hughes <tom@compton.nu>
Sun, 17 Oct 2004 15:18:22 +0000 (15:18 +0000)
committerTom Hughes <tom@compton.nu>
Sun, 17 Oct 2004 15:18:22 +0000 (15:18 +0000)
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

coregrind/vg_libpthread.c
coregrind/vg_scheduler.c

index df06d9cd5b605f66efcb5f194e7bdc67254c7ee4..2cbfe353cd51e04b901797ae657366e1daeafbfa 100644 (file)
@@ -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);
index 66d638f127c38e8307a4e9ad5ed3bd4d9aca59be..02d884d41b2f618ad96e6769c0a6bad73380f886 100644 (file)
@@ -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;