mirror of
https://github.com/MariaDB/server.git
synced 2025-01-17 12:32:27 +01:00
91 lines
2.5 KiB
C
91 lines
2.5 KiB
C
|
/* $Header$ */
|
||
|
|
||
|
/*
|
||
|
* LinuxThreads specific stuff.
|
||
|
*/
|
||
|
|
||
|
#include <sys/types.h>
|
||
|
|
||
|
#include <assert.h>
|
||
|
#include <limits.h> /* PTHREAD_THREADS_MAX */
|
||
|
#include <pthread.h>
|
||
|
#include <stdio.h>
|
||
|
#include <unistd.h>
|
||
|
#include <signal.h>
|
||
|
#include <sched.h>
|
||
|
|
||
|
#include "linuxthreads.h"
|
||
|
|
||
|
#define AT_INT(intval) *((int32_t*)(intval))
|
||
|
|
||
|
/*
|
||
|
* Internal LinuxThreads variables.
|
||
|
* Official interface exposed to GDB.
|
||
|
*/
|
||
|
#if 1
|
||
|
extern volatile int __pthread_threads_debug;
|
||
|
extern volatile char __pthread_handles;
|
||
|
extern char __pthread_initial_thread;
|
||
|
/*extern volatile Elf32_Sym* __pthread_manager_thread;*/
|
||
|
extern const int __pthread_sizeof_handle;
|
||
|
extern const int __pthread_offsetof_descr;
|
||
|
extern const int __pthread_offsetof_pid;
|
||
|
extern volatile int __pthread_handles_num;
|
||
|
#endif /* 0 */
|
||
|
|
||
|
/*
|
||
|
* Notify others.
|
||
|
*/
|
||
|
int
|
||
|
linuxthreads_notify_others( const int signotify)
|
||
|
{
|
||
|
const pid_t mypid = getpid();
|
||
|
//const pthread_t mytid = pthread_self();
|
||
|
int i;
|
||
|
int threadcount = 0;
|
||
|
int threads[PTHREAD_THREADS_MAX];
|
||
|
int pid;
|
||
|
|
||
|
TRACE_FPRINTF((stderr, "theadcount:%d\n", __pthread_handles_num));
|
||
|
if (__pthread_handles_num==2) {
|
||
|
/* no threads beside the initial thread */
|
||
|
return 0;
|
||
|
}
|
||
|
/*assert(maxthreads>=3);
|
||
|
assert(maxthreads>=__pthread_handles_num+2);*/
|
||
|
|
||
|
// take the initial thread with us
|
||
|
pid = AT_INT(&__pthread_initial_thread + __pthread_offsetof_pid);
|
||
|
if (pid!=mypid && pid!=0)
|
||
|
threads[threadcount++] = pid;
|
||
|
// don't know why, but always handles[0]==handles[1]
|
||
|
for (i=1; i<__pthread_handles_num; ++i) {
|
||
|
const int descr = AT_INT(&__pthread_handles+i*__pthread_sizeof_handle+__pthread_offsetof_descr);
|
||
|
assert(descr!=0);
|
||
|
pid = AT_INT(descr+__pthread_offsetof_pid);
|
||
|
if (pid!=mypid && pid!=0)
|
||
|
threads[threadcount++] = pid;
|
||
|
}
|
||
|
/* TRACE_FPRINTF((stderr, "Stopping threads...")); */
|
||
|
//for (i=0; i<threadcount; ++i) {
|
||
|
// /* TRACE_FPRINTF((stderr, "%d ", threads[i])); */
|
||
|
// fflush(stdout);
|
||
|
// kill(threads[i], SIGSTOP); /* Tell thread to stop */
|
||
|
//}
|
||
|
/* TRACE_FPRINTF((stderr, " done!\n")); */
|
||
|
for (i=0; i<threadcount; ++i) {
|
||
|
TRACE_FPRINTF((stderr, "--- NOTIFYING %d\n", threads[i]));
|
||
|
kill(threads[i], signotify); /* Tell to print stack trace */
|
||
|
/* TRACE_FPRINTF((stderr, "--- WAITING FOR %d\n", threads[i])); */
|
||
|
/*pause(); Wait for confirmation. */
|
||
|
}
|
||
|
for (i=0; i<threadcount; ++i)
|
||
|
sched_yield();
|
||
|
for (i=0; i<threadcount; ++i) {
|
||
|
TRACE_FPRINTF((stderr, "--- KILLING %d\n", threads[i]));
|
||
|
kill(threads[i], SIGKILL); /* Tell thread die :) */
|
||
|
}
|
||
|
return __pthread_handles_num;
|
||
|
}
|
||
|
|