]> git.ipfire.org Git - thirdparty/valgrind.git/commitdiff
Illumos helgrind: fix for pthread_rwlock_timedrdlock and pthread_rwlock_timedrwlock
authorPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 3 Apr 2025 17:56:51 +0000 (19:56 +0200)
committerPaul Floyd <pjfloyd@wanadoo.fr>
Thu, 3 Apr 2025 17:56:51 +0000 (19:56 +0200)
On Illumos these two functions are implemented by calling
pthread_rwlock_clockrdlock and pthread_rwlock_clockwrlock respectively.
Since we intercept both it was appearing as though the lock was being
taken recursively when it wasn't. Fixed it by using a static flag for each
and not callinng the client requests if already in a call to the timed
functions.

I think that musl also does this but, ho-hum, Helgrind has never worked on musl.

helgrind/hg_intercepts.c

index 661ab1a0935c77fa7b2f40ac2bc5d3ed4e3f9c1e..54711d8f26517b66fa641dca3dcd7a32b420f35b 100644 (file)
@@ -2750,6 +2750,7 @@ static int pthread_rwlock_tryrdlock_WRK(pthread_rwlock_t* rwlock)
 #  error "Unsupported OS"
 #endif
 
+static Bool in_pthread_rwlock_timedrdlock_WRK = False;
 
 //-----------------------------------------------------------
 // glibc:   pthread_rwlock_timedrdlock
@@ -2773,7 +2774,9 @@ static int pthread_rwlock_timedrdlock_WRK(pthread_rwlock_t *rwlock,
                  pthread_rwlock_t *, rwlock,
                  long, 0/*isW*/, long, 0/*isTryLock*/);
 
+   in_pthread_rwlock_timedrdlock_WRK = True;
    CALL_FN_W_WW(ret, fn, rwlock, timeout);
+   in_pthread_rwlock_timedrdlock_WRK = False;
 
    DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST,
                  pthread_rwlock_t *, rwlock, long, 0/*isW*/,
@@ -2831,15 +2834,19 @@ static int pthread_rwlock_clockrdlock_WRK(pthread_rwlock_t *rwlock,
       fprintf(stderr, "<< pthread_rwl_clockrdl %p", rwlock); fflush(stderr);
    }
 
-   DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE,
-                 pthread_rwlock_t *, rwlock,
-                 long, 0/*isW*/, long, 0/*isTryLock*/);
+   if (!in_pthread_rwlock_timedrdlock_WRK) {
+      DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE,
+                    pthread_rwlock_t *, rwlock,
+                    long, 0/*isW*/, long, 0/*isTryLock*/);
+   }
 
    CALL_FN_W_WWW(ret, fn, rwlock, clockid, timeout);
 
-   DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST,
-                 pthread_rwlock_t *, rwlock, long, 0/*isW*/,
-                 long, (ret == 0) ? True : False);
+   if (!in_pthread_rwlock_timedrdlock_WRK) {
+      DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST,
+                    pthread_rwlock_t *, rwlock, long, 0/*isW*/,
+                   long, (ret == 0) ? True : False);
+   }
    if (ret != 0) {
       DO_PthAPIerror("pthread_rwlock_clockrdlock", ret);
    }
@@ -2858,6 +2865,7 @@ PTH_FUNC(int, pthreadZurwlockZuclockrdlock, // pthread_rwlock_clockrdlock
 }
 #endif
 
+static Bool in_pthread_rwlock_timedwrlock_WRK = False;
 
 //-----------------------------------------------------------
 // glibc:   pthread_rwlock_timedwrlock
@@ -2880,7 +2888,9 @@ static int pthread_rwlock_timedwrlock_WRK(pthread_rwlock_t *rwlock,
                  pthread_rwlock_t *, rwlock,
                  long, 1/*isW*/, long, 0/*isTryLock*/);
 
+   in_pthread_rwlock_timedwrlock_WRK = True;
    CALL_FN_W_WW(ret, fn, rwlock, timeout);
+   in_pthread_rwlock_timedwrlock_WRK = False;
 
    DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST,
                  pthread_rwlock_t *, rwlock, long, 1/*isW*/,
@@ -2925,6 +2935,7 @@ PTH_FUNC(int, pthreadZurwlockZutimedwrlock, // pthread_rwlock_timedwrlock
 #if defined(VGO_linux) || defined(VGO_solaris)
 //-----------------------------------------------------------
 // glibc:   pthread_rwlock_clockwrlock
+// Illumos: pthread_rwlock_clockwrlock
 //
 __attribute__((noinline)) __attribute__((unused))
 static int pthread_rwlock_clockwrlock_WRK(pthread_rwlock_t *rwlock,
@@ -2938,15 +2949,19 @@ static int pthread_rwlock_clockwrlock_WRK(pthread_rwlock_t *rwlock,
       fprintf(stderr, "<< pthread_rwl_clockwrl %p", rwlock); fflush(stderr);
    }
 
-   DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE,
-                 pthread_rwlock_t *, rwlock,
-                 long, 1/*isW*/, long, 0/*isTryLock*/);
+   if (!in_pthread_rwlock_timedwrlock_WRK) {
+      DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_PRE,
+                    pthread_rwlock_t *, rwlock,
+                    long, 1/*isW*/, long, 0/*isTryLock*/);
+   }
 
    CALL_FN_W_WWW(ret, fn, rwlock, clockid, timeout);
 
-   DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST,
-                 pthread_rwlock_t *, rwlock, long, 1/*isW*/,
-                 long, (ret == 0) ? True : False);
+   if (!in_pthread_rwlock_timedwrlock_WRK) {
+      DO_CREQ_v_WWW(_VG_USERREQ__HG_PTHREAD_RWLOCK_LOCK_POST,
+                    pthread_rwlock_t *, rwlock, long, 1/*isW*/,
+                    long, (ret == 0) ? True : False);
+   }
    if (ret != 0) {
       DO_PthAPIerror("pthread_rwlock_clockwrlock", ret);
    }