git-svn-id: svn://db.shs.com.ru/pip@802 12ceb7fc-bf1f-11e4-8940-5bc7170c53b5

This commit is contained in:
2019-06-17 18:32:02 +00:00
parent 6812b645d9
commit 71128017dd
24 changed files with 904 additions and 547 deletions

View File

@@ -20,7 +20,7 @@
#include "piincludes_p.h"
#include "pithread.h"
#include "pisystemtests.h"
#include "piintrospection_proxy.h"
#include "piintrospection_threads.h"
#include <signal.h>
#ifdef WINDOWS
# define __THREAD_FUNC_RET__ uint __stdcall
@@ -160,6 +160,7 @@ PRIVATE_DEFINITION_END(PIThread)
PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay): PIObject() {
PIINTROSPECTION_THREAD_NEW(this);
piMonitor.threads++;
tid_ = -1;
PRIVATE->thread = 0;
@@ -173,6 +174,7 @@ PIThread::PIThread(void * data, ThreadFunc func, bool startNow, int timer_delay)
PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
PIINTROSPECTION_THREAD_NEW(this);
piMonitor.threads++;
tid_ = -1;
PRIVATE->thread = 0;
@@ -185,6 +187,7 @@ PIThread::PIThread(bool startNow, int timer_delay): PIObject() {
PIThread::~PIThread() {
PIINTROSPECTION_THREAD_DELETE(this);
piMonitor.threads--;
if (!running_ || PRIVATE->thread == 0) return;
#ifdef FREERTOS
@@ -220,91 +223,15 @@ void PIThread::stop(bool wait) {
bool PIThread::start(int timer_delay) {
if (running_) return false;
//if (terminating) waitForFinish();
terminating = false;
running_ = true;
delay_ = timer_delay;
#ifndef WINDOWS
pthread_attr_t attr;
pthread_attr_init(&attr);
# ifndef ANDROID
//pthread_attr_setschedparam(&attr, &(PRIVATE->sparam));
# endif
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&PRIVATE->thread, &attr, thread_function, this);
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
pthread_setname_np(PRIVATE->thread, ((PIString&)name().resize(15, '\0')).dataAscii());
# ifdef MAC_OS
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
# else
# ifdef FREERTOS
tid_ = PRIVATE->thread;
# endif
# endif
#else
if (PRIVATE->thread != 0) CloseHandle(PRIVATE->thread);
# ifdef CC_GCC
PRIVATE->thread = (void *)_beginthreadex(0, 0, thread_function, this, 0, 0);
# else
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function, this, 0, 0);
# endif
if (PRIVATE->thread != 0) {
#endif
setPriority(priority_);
return true;
} else {
running_ = false;
PRIVATE->thread = 0;
piCoutObj << "Error: Can`t start new thread:" << errorString();
}
running_ = false;
return false;
return _startThread((void*)thread_function);
}
bool PIThread::startOnce() {
if (terminating) waitForFinish();
if (running_) return false;
terminating = false;
running_ = true;
#ifndef WINDOWS
pthread_attr_t attr;
pthread_attr_init(&attr);
# ifndef ANDROID
//pthread_attr_setschedparam(&attr, &(PRIVATE->sparam));
# endif
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&(PRIVATE->thread), &attr, thread_function_once, this);
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
pthread_setname_np(PRIVATE->thread, ((PIString&)name().resize(15, '\0')).dataAscii());
# ifdef MAC_OS
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
# else
# ifdef FREERTOS
tid_ = PRIVATE->thread;
# endif
# endif
#else
if (PRIVATE->thread != 0) CloseHandle(PRIVATE->thread);
# ifdef CC_GCC
PRIVATE->thread = (void *)_beginthreadex(0, 0, thread_function_once, this, 0, 0);
# else
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)thread_function_once, this, 0, 0);
# endif
if (PRIVATE->thread != 0) {
#endif
setPriority(priority_);
return true;
} else {
running_ = false;
PRIVATE->thread = 0;
piCoutObj << "Error: Can`t start new thread:" << errorString();
}
running_ = false;
return false;
return _startThread((void*)thread_function_once);
}
@@ -317,7 +244,6 @@ void PIThread::terminate() {
#else
if (PRIVATE->thread == 0) return;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
terminating = running_ = false;
tid_ = -1;
//PICout(PICoutManipulators::DefaultControls) << "terminate" << PRIVATE->thread;
@@ -337,6 +263,7 @@ void PIThread::terminate() {
PRIVATE->thread = 0;
end();
#endif
PIINTROSPECTION_THREAD_STOP(this);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "terminate ok" << running_;
}
@@ -370,6 +297,50 @@ int PIThread::priority2System(PIThread::Priority p) {
}
bool PIThread::_startThread(void * func) {
//if (terminating) waitForFinish();
terminating = false;
running_ = true;
#ifndef WINDOWS
pthread_attr_t attr;
pthread_attr_init(&attr);
# ifndef ANDROID
//pthread_attr_setschedparam(&attr, &(PRIVATE->sparam));
# endif
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
int ret = pthread_create(&PRIVATE->thread, &attr, (void*(*)(void*))func, this);
//PICout(PICoutManipulators::DefaultControls) << "pthread_create" << PRIVATE->thread;
pthread_attr_destroy(&attr);
if (ret == 0) {
pthread_setname_np(PRIVATE->thread, ((PIString&)name().resize(15, '\0')).dataAscii());
# ifdef MAC_OS
pthread_threadid_np(PRIVATE->thread, (__uint64_t*)&tid_);
# else
# ifdef FREERTOS
tid_ = PRIVATE->thread;
# endif
# endif
#else
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
# ifdef CC_GCC
PRIVATE->thread = (void *)_beginthreadex(0, 0, (unsigned(__stdcall*)(void*))func, this, 0, 0);
# else
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
# endif
if (PRIVATE->thread != 0) {
#endif
setPriority(priority_);
return true;
} else {
running_ = false;
PRIVATE->thread = 0;
piCoutObj << "Error: Can`t start new thread:" << errorString();
}
running_ = false;
return false;
}
void PIThread::setPriority(PIThread::Priority prior) {
#ifndef FREERTOS // FreeRTOS can't change priority runtime
priority_ = prior;
@@ -451,7 +422,7 @@ bool PIThread::waitForStart(int timeout_msecs) {
}
void PIThread::__thread_func__() {
void PIThread::_beginThread() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
@@ -466,50 +437,35 @@ void PIThread::__thread_func__() {
#ifdef LINUX
tid_ = gettid();
#endif
PIINTROSPECTION_REGISTER_THREAD(tid(), priority(), name());
PIINTROSPECTION_THREAD_START(this);
REGISTER_THREAD(this);
running_ = true;
if (lockRun) mutex_.lock();
begin();
if (lockRun) mutex_.unlock();
started();
while (!terminating) {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "...";
maybeCallQueuedEvents();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) mutex_.lock();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
run();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "ok";
//printf("thread %p tick\n", this);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "...";
if (ret_func != 0) ret_func(data_);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "...";
if (lockRun) mutex_.unlock();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "...";
if (delay_ > 0) {
tmr_.reset();
double sl(0.);
while (1) {
sl = piMind(delay_ - tmr_.elapsed_m(), PIP_MIN_MSLEEP);
#ifdef WINDOWS
/*if (sl <= 1. && sl >= 0.) {
piMSleep(PIP_MIN_MSLEEP);
continue;
}*/
#endif
//printf("%f %f %f\n", double(delay_), tmr_.elapsed_m(), sl);
if (terminating) break;
if (sl <= 0.) break;
piMSleep(sl);
}
}
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
}
}
void PIThread::_runThread() {
PIINTROSPECTION_THREAD_RUN(this);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) mutex_.lock();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
run();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "ok";
//printf("thread %p tick\n", this);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "...";
if (ret_func != 0) ret_func(data_);
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "ret_func" << "ok";
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "...";
if (lockRun) mutex_.unlock();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
}
void PIThread::_endThread() {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
stopped();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
@@ -524,10 +480,10 @@ void PIThread::__thread_func__() {
//cout << "thread " << t << " exiting ... " << endl;
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
PIINTROSPECTION_THREAD_STOP(this);
#ifndef WINDOWS
pthread_detach((__privateinitializer__.p)->thread);
(__privateinitializer__.p)->thread = 0;
pthread_detach(PRIVATE->thread);
PRIVATE->thread = 0;
#endif
#ifndef WINDOWS
pthread_exit(0);
@@ -541,50 +497,34 @@ void PIThread::__thread_func__() {
}
void PIThread::__thread_func__() {
_beginThread();
while (!terminating) {
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "...";
maybeCallQueuedEvents();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "queued" << "ok";
_runThread();
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "...";
PIINTROSPECTION_THREAD_WAIT(this);
if (delay_ > 0) {
tmr_.reset();
double sl(0.);
while (1) {
sl = piMind(delay_ - tmr_.elapsed_m(), PIP_MIN_MSLEEP);
if (terminating) break;
if (sl <= 0.) break;
piMSleep(sl);
}
}
//PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
}
_endThread();
}
void PIThread::__thread_func_once__() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, 0);
# endif
#else
//__PISetTimerResolution();
#endif
#ifdef WINDOWS
tid_ = GetCurrentThreadId();
#endif
#ifdef LINUX
tid_ = gettid();
#endif
PIINTROSPECTION_REGISTER_THREAD(tid(), priority(), name());
REGISTER_THREAD(this);
running_ = true;
begin();
started();
if (lockRun) mutex_.lock();
run();
if (ret_func != 0) ret_func(data_);
if (lockRun) mutex_.unlock();
stopped();
end();
terminating = running_ = false;
tid_ = -1;
//cout << "thread " << t << " exiting ... " << endl;
//PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_UNREGISTER_THREAD(tid());
#ifndef WINDOWS
pthread_detach((__privateinitializer__.p)->thread);
(__privateinitializer__.p)->thread = 0;
#endif
#ifndef WINDOWS
pthread_exit(0);
#else
# ifdef CC_GCC
_endthreadex(0);
# else
ExitThread(0);
# endif
#endif
_beginThread();
_runThread();
_endThread();
}