/* * 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 #include #include #include #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); }