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.

154 lines
4.0 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.
*/
#include <cstdio>
#include <cstdlib>
#include <unistd.h>
#include <sys/syscall.h>
#include "threadUtils.h"
/**************************************************
* Type definitions *
**************************************************/
typedef void *(*startfunc)(void*);
/**************************************************
* Global variables *
**************************************************/
volatile int numOfThreads = 0;
/**************************************************
* Global locks *
**************************************************/
pthread_mutex_t printLock; // This lock is used for synchronizing prints.
pthread_mutex_t numThreadsLock; // This lock is used for synchronizing access to numOfThreads.
/**************************************************
* Static functions declaration *
**************************************************/
void GetLock(pthread_mutex_t* mutex);
void ReleaseLock(pthread_mutex_t* mutex);
static void TimeoutHandler(int a);
/**************************************************
* External functions implementation *
**************************************************/
unsigned int GetTid() {
return (unsigned int)syscall(__NR_gettid);
}
void InitLocks() {
if (pthread_mutex_init(&printLock, NULL)) {
ErrorExit(RES_INIT_FAILED);
}
if (pthread_mutex_init(&numThreadsLock, NULL)) {
ErrorExit(RES_INIT_FAILED);
}
}
bool CreateNewThread(TidType* tid, void* func, void* info) {
return (pthread_create(tid, NULL, (startfunc)func, info) == 0);
}
// thread cancel is not supported in bionic.
void CancelThread(TidType tid) {
ErrorExit(RES_CANCEL_FAILED);
}
void WaitForThread(TidType tid) {
if (pthread_join(tid, NULL) != 0) {
ErrorExit(RES_JOIN_FAILED);
}
}
void ThreadExit() {
pthread_exit(NULL);
}
void IncThreads() {
GetLock(&numThreadsLock);
++numOfThreads;
ReleaseLock(&numThreadsLock);
}
void DecThreads() {
GetLock(&numThreadsLock);
--numOfThreads;
ReleaseLock(&numThreadsLock);
}
int NumOfThreads() {
return numOfThreads;
}
void Print(const string& str) {
GetLock(&printLock);
fprintf(stderr, "APP: <%d> %s\n", GetTid(), str.c_str());
ReleaseLock(&printLock);
}
void ErrorExit(Results res) {
GetLock(&printLock);
fprintf(stderr, "APP ERROR <%d>: %s\n", GetTid(), errorStrings[res].c_str());
ReleaseLock(&printLock);
exit(res);
}
void DoSleep(unsigned int seconds) {
sleep(seconds);
}
// thread cancel is not supported in bionic.
void EnterSafeCancellationPoint() {
ErrorExit(RES_CANCEL_FAILED);
}
void SetTimeout() {
struct sigaction sigact_timeout;
sigact_timeout.sa_handler = TimeoutHandler;
sigact_timeout.sa_flags = 0;
if (sigaction(SIGALRM, &sigact_timeout, 0) == -1) {
Print("Unable to set up timeout handler\n");
ErrorExit(RES_UNEXPECTED_EXIT);
}
alarm(TIMEOUT);
}
/**************************************************
* Static functions implementation *
**************************************************/
void GetLock(pthread_mutex_t* mutex) {
if (pthread_mutex_lock(mutex) != 0) {
ErrorExit(RES_LOCK_FAILED);
}
}
void ReleaseLock(pthread_mutex_t* mutex) {
if (pthread_mutex_unlock(mutex) != 0) {
ErrorExit(RES_UNLOCK_FAILED);
}
}
void DoYield() {
sched_yield();
}
void TimeoutHandler(int a) {
Print("Application is running more than 10 minutes. It might be hanged. Killing it");
ErrorExit(RES_EXIT_TIMEOUT);
}