From: Julian Seward Date: Sun, 21 Apr 2002 00:13:57 +0000 (+0000) Subject: Add pthread_mutex_trylock, and add various other hacks to try and make X-Git-Tag: svn/VALGRIND_1_0_3~344 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=51ab4971587dfc37489a808c45fba922c3a4ee6b;p=thirdparty%2Fvalgrind.git Add pthread_mutex_trylock, and add various other hacks to try and make Mozilla work. git-svn-id: svn://svn.valgrind.org/valgrind/trunk@107 --- diff --git a/coregrind/arch/x86-linux/vg_libpthread.c b/coregrind/arch/x86-linux/vg_libpthread.c index 33e72ab203..6bdf09affc 100644 --- a/coregrind/arch/x86-linux/vg_libpthread.c +++ b/coregrind/arch/x86-linux/vg_libpthread.c @@ -113,6 +113,17 @@ static void ignored ( char* msg ) } } +static void kludged ( char* msg ) +{ + if (get_pt_trace_level() >= 1) { + char* ig = "vg_libpthread.so: KLUDGED call to: "; + write(2, ig, strlen(ig)); + write(2, msg, strlen(msg)); + ig = "\n"; + write(2, ig, strlen(ig)); + } +} + /* --------------------------------------------------------------------- Pass pthread_ calls to Valgrind's request mechanism. @@ -138,7 +149,33 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) return 0; } +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) +{ + ignored("pthread_attr_setinheritsched"); + return 0; +} + +/* This is completely bogus. */ +int pthread_attr_getschedparam(const pthread_attr_t *attr, + struct sched_param *param) +{ + kludged("pthread_attr_getschedparam"); + if (param) param->__sched_priority = 0; /* who knows */ + return 0; +} + +int pthread_attr_setschedparam(pthread_attr_t *attr, + const struct sched_param *param) +{ + ignored("pthread_attr_setschedparam"); + return 0; +} +int pthread_attr_destroy(pthread_attr_t *attr) +{ + ignored("pthread_attr_destroy"); + return 0; +} /* --------------------------------------------------- THREADs @@ -268,6 +305,22 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) } } +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + int res; + static int moans = 3; + if (!(RUNNING_ON_VALGRIND) && moans-- > 0) { + char* str = "pthread_mutex_trylock-NOT-INSIDE-VALGRIND\n"; + write(2, str, strlen(str)); + return 0; + } else { + VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, + VG_USERREQ__PTHREAD_MUTEX_TRYLOCK, + mutex, 0, 0, 0); + return res; + } +} + int pthread_mutex_unlock(pthread_mutex_t *mutex) { int res; @@ -330,6 +383,7 @@ int pthread_getschedparam(pthread_t target_thread, int *policy, struct sched_param *param) { + kludged("pthread_getschedparam"); if (policy) *policy = SCHED_OTHER; if (param) param->__sched_priority = 0; /* who knows */ return 0; diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h index bdb60fc478..09bafb0318 100644 --- a/coregrind/vg_include.h +++ b/coregrind/vg_include.h @@ -398,12 +398,13 @@ extern Bool VG_(is_empty_arena) ( ArenaId aid ); #define VG_USERREQ__PTHREAD_JOIN 0x3002 #define VG_USERREQ__PTHREAD_GET_THREADID 0x3003 #define VG_USERREQ__PTHREAD_MUTEX_LOCK 0x3004 -#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK 0x3005 -#define VG_USERREQ__PTHREAD_CANCEL 0x3006 -#define VG_USERREQ__PTHREAD_EXIT 0x3007 -#define VG_USERREQ__PTHREAD_COND_WAIT 0x3008 -#define VG_USERREQ__PTHREAD_COND_SIGNAL 0x3009 -#define VG_USERREQ__PTHREAD_COND_BROADCAST 0x300A +#define VG_USERREQ__PTHREAD_MUTEX_TRYLOCK 0x3005 +#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK 0x3006 +#define VG_USERREQ__PTHREAD_CANCEL 0x3007 +#define VG_USERREQ__PTHREAD_EXIT 0x3008 +#define VG_USERREQ__PTHREAD_COND_WAIT 0x3009 +#define VG_USERREQ__PTHREAD_COND_SIGNAL 0x300A +#define VG_USERREQ__PTHREAD_COND_BROADCAST 0x300B /* Cosmetic ... */ #define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101 diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c index 33e72ab203..6bdf09affc 100644 --- a/coregrind/vg_libpthread.c +++ b/coregrind/vg_libpthread.c @@ -113,6 +113,17 @@ static void ignored ( char* msg ) } } +static void kludged ( char* msg ) +{ + if (get_pt_trace_level() >= 1) { + char* ig = "vg_libpthread.so: KLUDGED call to: "; + write(2, ig, strlen(ig)); + write(2, msg, strlen(msg)); + ig = "\n"; + write(2, ig, strlen(ig)); + } +} + /* --------------------------------------------------------------------- Pass pthread_ calls to Valgrind's request mechanism. @@ -138,7 +149,33 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) return 0; } +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) +{ + ignored("pthread_attr_setinheritsched"); + return 0; +} + +/* This is completely bogus. */ +int pthread_attr_getschedparam(const pthread_attr_t *attr, + struct sched_param *param) +{ + kludged("pthread_attr_getschedparam"); + if (param) param->__sched_priority = 0; /* who knows */ + return 0; +} + +int pthread_attr_setschedparam(pthread_attr_t *attr, + const struct sched_param *param) +{ + ignored("pthread_attr_setschedparam"); + return 0; +} +int pthread_attr_destroy(pthread_attr_t *attr) +{ + ignored("pthread_attr_destroy"); + return 0; +} /* --------------------------------------------------- THREADs @@ -268,6 +305,22 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) } } +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + int res; + static int moans = 3; + if (!(RUNNING_ON_VALGRIND) && moans-- > 0) { + char* str = "pthread_mutex_trylock-NOT-INSIDE-VALGRIND\n"; + write(2, str, strlen(str)); + return 0; + } else { + VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, + VG_USERREQ__PTHREAD_MUTEX_TRYLOCK, + mutex, 0, 0, 0); + return res; + } +} + int pthread_mutex_unlock(pthread_mutex_t *mutex) { int res; @@ -330,6 +383,7 @@ int pthread_getschedparam(pthread_t target_thread, int *policy, struct sched_param *param) { + kludged("pthread_getschedparam"); if (policy) *policy = SCHED_OTHER; if (param) param->__sched_priority = 0; /* who knows */ return 0; diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c index daf099b8ec..90a9d9bee8 100644 --- a/coregrind/vg_scheduler.c +++ b/coregrind/vg_scheduler.c @@ -1703,12 +1703,17 @@ void release_one_thread_waiting_on_mutex ( pthread_mutex_t* mutex, static -void do_pthread_mutex_lock( ThreadId tid, pthread_mutex_t *mutex ) +void do_pthread_mutex_lock( ThreadId tid, + Bool is_trylock, + pthread_mutex_t *mutex ) { - Char msg_buf[100]; + Char msg_buf[100]; + Char* caller + = is_trylock ? "pthread_mutex_lock " + : "pthread_mutex_trylock"; if (VG_(clo_trace_pthread_level) >= 2) { - VG_(sprintf)(msg_buf, "pthread_mutex_lock mx %p ...", mutex ); + VG_(sprintf)(msg_buf, "%s mx %p ...", caller, mutex ); print_pthread_event(tid, msg_buf); } @@ -1750,21 +1755,29 @@ void do_pthread_mutex_lock( ThreadId tid, pthread_mutex_t *mutex ) tid, mutex, mutex->__m_count); return; } else { - vg_threads[tid].m_edx = EDEADLK; + if (is_trylock) + vg_threads[tid].m_edx = EBUSY; + else + vg_threads[tid].m_edx = EDEADLK; return; } } else { /* Someone else has it; we have to wait. Mark ourselves thusly. */ /* GUARD: __m_count > 0 && __m_owner is valid */ - vg_threads[tid].status = VgTs_WaitMX; - vg_threads[tid].associated_mx = mutex; - /* No assignment to %EDX, since we're blocking. */ - if (VG_(clo_trace_pthread_level) >= 1) { - VG_(sprintf)(msg_buf, "pthread_mutex_lock mx %p: BLOCK", - mutex ); - print_pthread_event(tid, msg_buf); - } + if (is_trylock) { + /* caller is polling; so return immediately. */ + vg_threads[tid].m_edx = EBUSY; + } else { + vg_threads[tid].status = VgTs_WaitMX; + vg_threads[tid].associated_mx = mutex; + /* No assignment to %EDX, since we're blocking. */ + if (VG_(clo_trace_pthread_level) >= 1) { + VG_(sprintf)(msg_buf, "%s mx %p: BLOCK", + caller, mutex ); + print_pthread_event(tid, msg_buf); + } + } return; } @@ -2064,7 +2077,11 @@ void do_nontrivial_clientreq ( ThreadId tid ) break; case VG_USERREQ__PTHREAD_MUTEX_LOCK: - do_pthread_mutex_lock( tid, (pthread_mutex_t *)(arg[1]) ); + do_pthread_mutex_lock( tid, False, (pthread_mutex_t *)(arg[1]) ); + break; + + case VG_USERREQ__PTHREAD_MUTEX_TRYLOCK: + do_pthread_mutex_lock( tid, True, (pthread_mutex_t *)(arg[1]) ); break; case VG_USERREQ__PTHREAD_MUTEX_UNLOCK: diff --git a/vg_include.h b/vg_include.h index bdb60fc478..09bafb0318 100644 --- a/vg_include.h +++ b/vg_include.h @@ -398,12 +398,13 @@ extern Bool VG_(is_empty_arena) ( ArenaId aid ); #define VG_USERREQ__PTHREAD_JOIN 0x3002 #define VG_USERREQ__PTHREAD_GET_THREADID 0x3003 #define VG_USERREQ__PTHREAD_MUTEX_LOCK 0x3004 -#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK 0x3005 -#define VG_USERREQ__PTHREAD_CANCEL 0x3006 -#define VG_USERREQ__PTHREAD_EXIT 0x3007 -#define VG_USERREQ__PTHREAD_COND_WAIT 0x3008 -#define VG_USERREQ__PTHREAD_COND_SIGNAL 0x3009 -#define VG_USERREQ__PTHREAD_COND_BROADCAST 0x300A +#define VG_USERREQ__PTHREAD_MUTEX_TRYLOCK 0x3005 +#define VG_USERREQ__PTHREAD_MUTEX_UNLOCK 0x3006 +#define VG_USERREQ__PTHREAD_CANCEL 0x3007 +#define VG_USERREQ__PTHREAD_EXIT 0x3008 +#define VG_USERREQ__PTHREAD_COND_WAIT 0x3009 +#define VG_USERREQ__PTHREAD_COND_SIGNAL 0x300A +#define VG_USERREQ__PTHREAD_COND_BROADCAST 0x300B /* Cosmetic ... */ #define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101 diff --git a/vg_libpthread.c b/vg_libpthread.c index 33e72ab203..6bdf09affc 100644 --- a/vg_libpthread.c +++ b/vg_libpthread.c @@ -113,6 +113,17 @@ static void ignored ( char* msg ) } } +static void kludged ( char* msg ) +{ + if (get_pt_trace_level() >= 1) { + char* ig = "vg_libpthread.so: KLUDGED call to: "; + write(2, ig, strlen(ig)); + write(2, msg, strlen(msg)); + ig = "\n"; + write(2, ig, strlen(ig)); + } +} + /* --------------------------------------------------------------------- Pass pthread_ calls to Valgrind's request mechanism. @@ -138,7 +149,33 @@ int pthread_attr_setdetachstate(pthread_attr_t *attr, int detachstate) return 0; } +int pthread_attr_setinheritsched(pthread_attr_t *attr, int inherit) +{ + ignored("pthread_attr_setinheritsched"); + return 0; +} + +/* This is completely bogus. */ +int pthread_attr_getschedparam(const pthread_attr_t *attr, + struct sched_param *param) +{ + kludged("pthread_attr_getschedparam"); + if (param) param->__sched_priority = 0; /* who knows */ + return 0; +} + +int pthread_attr_setschedparam(pthread_attr_t *attr, + const struct sched_param *param) +{ + ignored("pthread_attr_setschedparam"); + return 0; +} +int pthread_attr_destroy(pthread_attr_t *attr) +{ + ignored("pthread_attr_destroy"); + return 0; +} /* --------------------------------------------------- THREADs @@ -268,6 +305,22 @@ int pthread_mutex_lock(pthread_mutex_t *mutex) } } +int pthread_mutex_trylock(pthread_mutex_t *mutex) +{ + int res; + static int moans = 3; + if (!(RUNNING_ON_VALGRIND) && moans-- > 0) { + char* str = "pthread_mutex_trylock-NOT-INSIDE-VALGRIND\n"; + write(2, str, strlen(str)); + return 0; + } else { + VALGRIND_MAGIC_SEQUENCE(res, 0 /* default */, + VG_USERREQ__PTHREAD_MUTEX_TRYLOCK, + mutex, 0, 0, 0); + return res; + } +} + int pthread_mutex_unlock(pthread_mutex_t *mutex) { int res; @@ -330,6 +383,7 @@ int pthread_getschedparam(pthread_t target_thread, int *policy, struct sched_param *param) { + kludged("pthread_getschedparam"); if (policy) *policy = SCHED_OTHER; if (param) param->__sched_priority = 0; /* who knows */ return 0; diff --git a/vg_scheduler.c b/vg_scheduler.c index daf099b8ec..90a9d9bee8 100644 --- a/vg_scheduler.c +++ b/vg_scheduler.c @@ -1703,12 +1703,17 @@ void release_one_thread_waiting_on_mutex ( pthread_mutex_t* mutex, static -void do_pthread_mutex_lock( ThreadId tid, pthread_mutex_t *mutex ) +void do_pthread_mutex_lock( ThreadId tid, + Bool is_trylock, + pthread_mutex_t *mutex ) { - Char msg_buf[100]; + Char msg_buf[100]; + Char* caller + = is_trylock ? "pthread_mutex_lock " + : "pthread_mutex_trylock"; if (VG_(clo_trace_pthread_level) >= 2) { - VG_(sprintf)(msg_buf, "pthread_mutex_lock mx %p ...", mutex ); + VG_(sprintf)(msg_buf, "%s mx %p ...", caller, mutex ); print_pthread_event(tid, msg_buf); } @@ -1750,21 +1755,29 @@ void do_pthread_mutex_lock( ThreadId tid, pthread_mutex_t *mutex ) tid, mutex, mutex->__m_count); return; } else { - vg_threads[tid].m_edx = EDEADLK; + if (is_trylock) + vg_threads[tid].m_edx = EBUSY; + else + vg_threads[tid].m_edx = EDEADLK; return; } } else { /* Someone else has it; we have to wait. Mark ourselves thusly. */ /* GUARD: __m_count > 0 && __m_owner is valid */ - vg_threads[tid].status = VgTs_WaitMX; - vg_threads[tid].associated_mx = mutex; - /* No assignment to %EDX, since we're blocking. */ - if (VG_(clo_trace_pthread_level) >= 1) { - VG_(sprintf)(msg_buf, "pthread_mutex_lock mx %p: BLOCK", - mutex ); - print_pthread_event(tid, msg_buf); - } + if (is_trylock) { + /* caller is polling; so return immediately. */ + vg_threads[tid].m_edx = EBUSY; + } else { + vg_threads[tid].status = VgTs_WaitMX; + vg_threads[tid].associated_mx = mutex; + /* No assignment to %EDX, since we're blocking. */ + if (VG_(clo_trace_pthread_level) >= 1) { + VG_(sprintf)(msg_buf, "%s mx %p: BLOCK", + caller, mutex ); + print_pthread_event(tid, msg_buf); + } + } return; } @@ -2064,7 +2077,11 @@ void do_nontrivial_clientreq ( ThreadId tid ) break; case VG_USERREQ__PTHREAD_MUTEX_LOCK: - do_pthread_mutex_lock( tid, (pthread_mutex_t *)(arg[1]) ); + do_pthread_mutex_lock( tid, False, (pthread_mutex_t *)(arg[1]) ); + break; + + case VG_USERREQ__PTHREAD_MUTEX_TRYLOCK: + do_pthread_mutex_lock( tid, True, (pthread_mutex_t *)(arg[1]) ); break; case VG_USERREQ__PTHREAD_MUTEX_UNLOCK: