be needed after all.
git-svn-id: svn://svn.valgrind.org/valgrind/trunk@342
}
-/*-------------------*/
-/* 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);
}
#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
}
-/*-------------------*/
-/* 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);
}
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 );
}
(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:
#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
}
-/*-------------------*/
-/* 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);
}
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 );
}
(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: