You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
178 lines
3.8 KiB
178 lines
3.8 KiB
/*
|
|
* Copyright 2002-2019 Intel Corporation.
|
|
*
|
|
* This software is provided to you as Sample Source Code as defined in the accompanying
|
|
* End User License Agreement for the Intel(R) Software Development Products ("Agreement")
|
|
* section 1.L.
|
|
*
|
|
* This software and the related documents are provided as is, with no express or implied
|
|
* warranties, other than those that are expressly stated in the License.
|
|
*/
|
|
|
|
/*! @file
|
|
* Test detaching - reattach Pin on Linux
|
|
* The application verifies that signal mask is preserved during attach - detach.
|
|
*/
|
|
#include <assert.h>
|
|
#include <stdio.h>
|
|
#include <dlfcn.h>
|
|
#include <signal.h>
|
|
#include <sys/types.h>
|
|
#include <unistd.h>
|
|
#include <pthread.h>
|
|
#include <sys/wait.h>
|
|
#include <sched.h>
|
|
#include <stdlib.h>
|
|
#include <string>
|
|
#include <list>
|
|
#include <stdint.h>
|
|
#include "../Utils/threadlib.h"
|
|
|
|
|
|
|
|
volatile unsigned int unblockedUsr1Tid = 0;
|
|
volatile unsigned int unblockedUsr2Tid = 0;
|
|
volatile bool usr1Tested = false;
|
|
volatile bool usr2Tested = false;
|
|
|
|
pthread_mutex_t mutex;
|
|
|
|
extern "C" int AppShouldExit()
|
|
{
|
|
return 0;
|
|
}
|
|
|
|
|
|
void SigUsrHandler(int sig)
|
|
{
|
|
pthread_mutex_lock(&mutex);
|
|
|
|
if (sig == SIGUSR1)
|
|
{
|
|
if (unblockedUsr1Tid == GetTid())
|
|
{
|
|
usr1Tested = true;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "The signal mask is incorrect, SIGUSR1 is caught by %d, expected %d\n",
|
|
GetTid(), unblockedUsr1Tid);
|
|
exit(-1);
|
|
}
|
|
}
|
|
if (sig == SIGUSR2)
|
|
{
|
|
if (unblockedUsr2Tid == GetTid())
|
|
{
|
|
usr2Tested = true;
|
|
}
|
|
else
|
|
{
|
|
fprintf(stderr, "The signal mask is incorrect, SIGUSR2 is caught by %d, expected %d\n",
|
|
GetTid(), unblockedUsr2Tid);
|
|
exit(-1);
|
|
}
|
|
}
|
|
pthread_mutex_unlock(&mutex);
|
|
}
|
|
|
|
|
|
sigset_t sigSet;
|
|
|
|
void BlockSignal(int sigNo)
|
|
{
|
|
sigset_t mask;
|
|
sigemptyset(&mask);
|
|
sigaddset(&mask, sigNo);
|
|
pthread_sigmask(SIG_BLOCK, &mask, 0);
|
|
}
|
|
|
|
void UnblockSignal(int sigNo)
|
|
{
|
|
sigset_t mask;
|
|
sigemptyset(&mask);
|
|
sigaddset(&mask, sigNo);
|
|
pthread_sigmask(SIG_UNBLOCK, &mask, 0);
|
|
}
|
|
void UnblockAllSignals()
|
|
{
|
|
sigset_t mask;
|
|
sigemptyset(&mask);
|
|
pthread_sigmask(SIG_SETMASK, &mask, 0);
|
|
}
|
|
|
|
void * ThreadFunc(void * arg)
|
|
{
|
|
unsigned int thread_no = *(unsigned int *)&arg;
|
|
|
|
if (thread_no == 1)
|
|
{
|
|
unblockedUsr1Tid = GetTid();
|
|
UnblockSignal(SIGUSR1);
|
|
}
|
|
else if (thread_no == 2)
|
|
{
|
|
unblockedUsr2Tid = GetTid();
|
|
UnblockSignal(SIGUSR2);
|
|
}
|
|
|
|
while (!usr1Tested || !usr2Tested)
|
|
{
|
|
sleep(1);
|
|
}
|
|
return 0;
|
|
}
|
|
|
|
|
|
#define NUM_OF_THREADS 7
|
|
pthread_t threads[NUM_OF_THREADS];
|
|
|
|
|
|
int main(int argc, char *argv[])
|
|
{
|
|
// Set the same signal handler for USR1 and USR2 signals
|
|
signal(SIGUSR1, SigUsrHandler);
|
|
signal(SIGUSR2, SigUsrHandler);
|
|
|
|
// initialize a mutex that will be used by threads
|
|
pthread_mutex_init(&mutex, 0);
|
|
|
|
/* Block signals in all threads */
|
|
BlockSignal(SIGUSR1);
|
|
BlockSignal(SIGUSR2);
|
|
/*****************/
|
|
|
|
while (!AppShouldExit())
|
|
{
|
|
// launch threads
|
|
usr1Tested = false;
|
|
usr2Tested = false;
|
|
for (uintptr_t i = 0; i < NUM_OF_THREADS; i++)
|
|
{
|
|
pthread_create(&threads[i], 0, ThreadFunc, (void *)i);
|
|
}
|
|
|
|
while ((unblockedUsr1Tid == 0) || (unblockedUsr2Tid == 0))
|
|
{
|
|
sched_yield();
|
|
}
|
|
|
|
while (!usr1Tested || !usr2Tested)
|
|
{
|
|
kill(getpid(), SIGUSR1);
|
|
kill(getpid(), SIGUSR2);
|
|
}
|
|
|
|
for (unsigned int i = 0; i < NUM_OF_THREADS; i++)
|
|
{
|
|
pthread_join(threads[i], 0);
|
|
}
|
|
unblockedUsr1Tid = 0;
|
|
unblockedUsr2Tid = 0;
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|
|
|