1ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "../../config.h" 2ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <assert.h> 3ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <errno.h> 4ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <pthread.h> 5ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <signal.h> 6ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdio.h> 7ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <stdlib.h> 8ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <string.h> 9ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <time.h> 10ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <unistd.h> 11ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef HAVE_ASM_UNISTD_H 12ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include <asm/unistd.h> // __NR_gettid 13ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 14ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#include "../drd.h" 15ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 16ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 17ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int s_debug = 0; 18ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 19ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 20ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic int getktid() 21ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 22ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#ifdef __NR_gettid 23ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return syscall(__NR_gettid); 24ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#else 25ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return -1; 26ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown#endif 27ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 28ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 29ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void print_thread_id(const char* const label) 30ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 31ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (s_debug) 32ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 33ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown char msg[256]; 34ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown snprintf(msg, sizeof(msg), 35ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown "%spid %d / kernel thread ID %d / Valgrind thread ID %d\n", 36ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown label, getpid(), getktid(), DRD_GET_VALGRIND_THREADID); 37ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown write(STDOUT_FILENO, msg, strlen(msg)); 38ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 39ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 40ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 41ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownstatic void SignalHandler(const int iSignal) 42ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 43ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_thread_id("Signal was delivered to "); 44ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 45ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 46ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownvoid* thread_func(void* thread_arg) 47ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 48ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_thread_id("thread: "); 49ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 50ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sleep(10); 51ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown //assert(result < 0 && errno == EINTR); 52ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 53ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 54ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 55ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 56ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brownint main(int argc, char** argv) 57ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown{ 58ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_t threadid; 59ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct timespec tsDelay; 60ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 61ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Primitive argument parsing. 62ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown if (argc > 1) 63ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown s_debug = 1; 64ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 65ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown print_thread_id("main: "); 66ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 67ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown { 68ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown struct sigaction sa; 69ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown memset(&sa, 0, sizeof(sa)); 70ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sa.sa_handler = &SignalHandler; 71ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sigemptyset(&sa.sa_mask); 72ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown sigaction(SIGALRM, &sa, 0); 73ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown } 74ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 75ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_create(&threadid, 0, thread_func, 0); 76ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // Wait until the thread is inside clock_nanosleep(). 77ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tsDelay.tv_sec = 0; 78ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown tsDelay.tv_nsec = 20 * 1000 * 1000; 79ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown nanosleep(&tsDelay, 0); 80ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown // And send SIGALRM to the thread. 81ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_kill(threadid, SIGALRM); 82ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown pthread_join(threadid, 0); 83ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown 84ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown return 0; 85ed07e00d438c74b7a23c01bfffde77e3968305e4Jeff Brown} 86