Implement __pthread_kill_other_threads_np properly. It does seem to
be needed after all.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@342 a5019735-40e9-0310-863c-91ae7b9d1cf9
diff --git a/coregrind/arch/x86-linux/vg_libpthread.c b/coregrind/arch/x86-linux/vg_libpthread.c
index c92d54c..6f51b04 100644
--- a/coregrind/arch/x86-linux/vg_libpthread.c
+++ b/coregrind/arch/x86-linux/vg_libpthread.c
@@ -897,28 +897,19 @@
}
-/*-------------------*/
-/* If this is indeed used by LinuxThreads to implement thread nuking
- post fork and pre exec, we should really nuke em, not do
- pthread_cancel. */
-static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER;
-
+/* Not really sure what this is for. I suspect for doing the POSIX
+ requirements for fork() and exec(). We do this internally anyway
+ whenever those syscalls are observed, so this could be superfluous,
+ but hey ...
+*/
void __pthread_kill_other_threads_np ( void )
{
- /* If we need this, implement it properly! */
- vgPlain_unimp("__pthread_kill_other_threads_np");
-#if 0
- int i, res, me;
- __pthread_mutex_lock(&massacre_mx);
- me = pthread_self();
- for (i = 1; i < VG_N_THREADS; i++) {
- if (i == me) continue;
- res = pthread_cancel(i);
- if (0 && res == 0)
- printf("----------- NUKED %d\n", i);
- }
- __pthread_mutex_unlock(&massacre_mx);
-#endif
+ int res;
+ ensure_valgrind("__pthread_kill_other_threads_np");
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__NUKE_OTHER_THREADS,
+ 0, 0, 0, 0);
+ assert(res == 0);
}
diff --git a/coregrind/vg_include.h b/coregrind/vg_include.h
index 840282b..f5e6658 100644
--- a/coregrind/vg_include.h
+++ b/coregrind/vg_include.h
@@ -478,6 +478,8 @@
#define VG_USERREQ__CLEANUP_POP 0x3021
#define VG_USERREQ__GET_KEY_D_AND_S 0x3022
+#define VG_USERREQ__NUKE_OTHER_THREADS 0x3023
+
/* Cosmetic ... */
#define VG_USERREQ__GET_PTHREAD_TRACE_LEVEL 0x3101
diff --git a/coregrind/vg_libpthread.c b/coregrind/vg_libpthread.c
index c92d54c..6f51b04 100644
--- a/coregrind/vg_libpthread.c
+++ b/coregrind/vg_libpthread.c
@@ -897,28 +897,19 @@
}
-/*-------------------*/
-/* If this is indeed used by LinuxThreads to implement thread nuking
- post fork and pre exec, we should really nuke em, not do
- pthread_cancel. */
-static pthread_mutex_t massacre_mx = PTHREAD_MUTEX_INITIALIZER;
-
+/* Not really sure what this is for. I suspect for doing the POSIX
+ requirements for fork() and exec(). We do this internally anyway
+ whenever those syscalls are observed, so this could be superfluous,
+ but hey ...
+*/
void __pthread_kill_other_threads_np ( void )
{
- /* If we need this, implement it properly! */
- vgPlain_unimp("__pthread_kill_other_threads_np");
-#if 0
- int i, res, me;
- __pthread_mutex_lock(&massacre_mx);
- me = pthread_self();
- for (i = 1; i < VG_N_THREADS; i++) {
- if (i == me) continue;
- res = pthread_cancel(i);
- if (0 && res == 0)
- printf("----------- NUKED %d\n", i);
- }
- __pthread_mutex_unlock(&massacre_mx);
-#endif
+ int res;
+ ensure_valgrind("__pthread_kill_other_threads_np");
+ VALGRIND_MAGIC_SEQUENCE(res, (-1) /* default */,
+ VG_USERREQ__NUKE_OTHER_THREADS,
+ 0, 0, 0, 0);
+ assert(res == 0);
}
diff --git a/coregrind/vg_scheduler.c b/coregrind/vg_scheduler.c
index 9db5021..228a8a3 100644
--- a/coregrind/vg_scheduler.c
+++ b/coregrind/vg_scheduler.c
@@ -1706,8 +1706,9 @@
if (tid == me
|| VG_(threads)[tid].status == VgTs_Empty)
continue;
- VG_(printf)(
- "VG_(nuke_all_threads_except): nuking tid %d\n", tid);
+ if (0)
+ VG_(printf)(
+ "VG_(nuke_all_threads_except): nuking tid %d\n", tid);
VG_(threads)[tid].status = VgTs_Empty;
cleanup_after_thread_exited( tid );
}
@@ -3044,6 +3045,11 @@
(CleanupEntry*)arg[2] );
break;
+ case VG_USERREQ__NUKE_OTHER_THREADS:
+ VG_(nuke_all_threads_except) ( tid );
+ SET_EDX(tid, 0);
+ break;
+
case VG_USERREQ__MAKE_NOACCESS:
case VG_USERREQ__MAKE_WRITABLE:
case VG_USERREQ__MAKE_READABLE: