more literals, use some in PIP, small refactor PIThread::start (clang-format mistakes)

This commit is contained in:
2023-07-02 14:02:10 +03:00
parent 54d0ba1876
commit ccae1a7311
15 changed files with 530 additions and 294 deletions

View File

@@ -693,7 +693,34 @@ int PIThread::priority2System(PIThread::Priority p) {
bool PIThread::_startThread(void * func) {
terminating = false;
running_ = true;
#if !defined(WINDOWS) && !defined(FREERTOS)
#ifdef FREERTOS
if (xTaskCreate((__THREAD_FUNC_RET__(*)(void *))func,
((PIString &)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii(), // A name just for humans
128, // This stack size can be checked & adjusted by reading the Stack Highwater
this,
priority_,
&PRIVATE->thread) == pdPASS) {
tid_ = (llong)PRIVATE->thread;
return true;
}
#elif defined(WINDOWS)
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
# ifdef CC_GCC
PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void *))func, this, 0, 0);
# else
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
# endif
if (PRIVATE->thread != 0) {
setPriority(priority_);
return true;
}
#else
pthread_attr_t attr;
pthread_attr_init(&attr);
pthread_attr_setdetachstate(&attr, PTHREAD_CREATE_DETACHED);
@@ -707,44 +734,24 @@ bool PIThread::_startThread(void * func) {
# else
pthread_setname_np(PRIVATE->thread, ((PIString &)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii());
# endif
setPriority(priority_);
return true;
}
#endif
#ifdef WINDOWS
if (PRIVATE->thread) CloseHandle(PRIVATE->thread);
# ifdef CC_GCC
PRIVATE->thread = (void *)_beginthreadex(0, 0, (__THREAD_FUNC_RET__(*)(void *))func, this, 0, 0);
# else
PRIVATE->thread = CreateThread(0, 0, (LPTHREAD_START_ROUTINE)func, this, 0, 0);
# endif
if (PRIVATE->thread != 0) {
#endif
#ifdef FREERTOS
if (xTaskCreate((__THREAD_FUNC_RET__(*)(void *))func,
((PIString &)name().elided(15, 0.4f).resize(15, PIChar('\0'))).dataAscii(), // A name just for humans
128, // This stack size can be checked & adjusted by reading the Stack Highwater
this,
priority_,
&PRIVATE->thread) == pdPASS) {
tid_ = (llong)PRIVATE->thread;
#endif
#ifndef FREERTOS
setPriority(priority_);
#endif
return true;
} else {
running_ = false;
PRIVATE->thread = 0;
piCoutObj << "Error: Can`t start new thread:" << errorString();
}
running_ = false;
return false;
}
running_ = false;
PRIVATE->thread = 0;
piCoutObj << "Error: Can`t start new thread:" << errorString();
return false;
}
void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior;
if (!running_ || (PRIVATE->thread == 0)) return;
void PIThread::setPriority(PIThread::Priority prior) {
priority_ = prior;
if (!running_ || (PRIVATE->thread == 0)) return;
#ifdef FREERTOS
vTaskPrioritySet(PRIVATE->thread, priority2System(priority_));
vTaskPrioritySet(PRIVATE->thread, priority2System(priority_));
#else
# ifndef WINDOWS
// PICout(PICoutManipulators::DefaultControls) << "setPriority" << PRIVATE->thread;
@@ -764,134 +771,144 @@ bool PIThread::_startThread(void * func) {
SetThreadPriority(PRIVATE->thread, priority2System(priority_));
# endif
#endif // FREERTOS
}
}
bool PIThread::waitForStart(PISystemTime timeout) {
return waitForStart(timeout.toMilliseconds());
}
bool PIThread::waitForFinish(PISystemTime timeout) {
return waitForFinish(timeout.toMilliseconds());
}
#ifdef WINDOWS
bool isExists(HANDLE hThread) {
// errorClear();
// piCout << "isExists" << hThread;
DWORD dw = 0;
GetExitCodeThread(hThread, &dw);
// piCout << ret << dw << errorString();
if (dw == STILL_ACTIVE) return true;
// piCout << errorString();
return false;
}
bool isExists(HANDLE hThread) {
// errorClear();
// piCout << "isExists" << hThread;
DWORD dw = 0;
GetExitCodeThread(hThread, &dw);
// piCout << ret << dw << errorString();
if (dw == STILL_ACTIVE) return true;
// piCout << errorString();
return false;
}
#endif
bool PIThread::waitForFinish(int timeout_msecs) {
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "PIThread::waitForFinish" << running_ << terminating <<
// timeout_msecs;
if (!running_) return true;
if (timeout_msecs < 0) {
while (running_) {
piMinSleep();
bool PIThread::waitForFinish(int timeout_msecs) {
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "PIThread::waitForFinish" << running_ << terminating <<
// timeout_msecs;
if (!running_) return true;
if (timeout_msecs < 0) {
while (running_) {
piMinSleep();
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
}
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
tmf_.reset();
while (running_ && tmf_.elapsed_m() < timeout_msecs) {
piMinSleep();
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
}
return tmf_.elapsed_m() < timeout_msecs;
}
bool PIThread::waitForStart(int timeout_msecs) {
if (running_) return true;
if (timeout_msecs < 0) {
while (!running_)
piMinSleep();
return true;
}
tms_.reset();
while (!running_ && tms_.elapsed_m() < timeout_msecs)
piMinSleep();
return tms_.elapsed_m() < timeout_msecs;
return true;
}
tmf_.reset();
while (running_ && tmf_.elapsed_m() < timeout_msecs) {
piMinSleep();
#ifdef WINDOWS
if (!isExists(PRIVATE->thread)) {
unlock();
return true;
}
#endif
}
return tmf_.elapsed_m() < timeout_msecs;
}
void PIThread::_beginThread() {
bool PIThread::waitForStart(int timeout_msecs) {
if (running_) return true;
if (timeout_msecs < 0) {
while (!running_)
piMinSleep();
return true;
}
tms_.reset();
while (!running_ && tms_.elapsed_m() < timeout_msecs)
piMinSleep();
return tms_.elapsed_m() < timeout_msecs;
}
void PIThread::_beginThread() {
#ifndef WINDOWS
# if !defined(ANDROID) && !defined(FREERTOS)
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, 0);
pthread_setcanceltype(PTHREAD_CANCEL_DEFERRED, 0);
# endif
#endif
#ifdef WINDOWS
tid_ = GetCurrentThreadId();
tid_ = GetCurrentThreadId();
#endif
#ifdef LINUX
tid_ = gettid();
tid_ = gettid();
#endif
PIINTROSPECTION_THREAD_START(this);
REGISTER_THREAD(this);
running_ = true;
if (lockRun) thread_mutex.lock();
begin();
if (lockRun) thread_mutex.unlock();
started();
}
PIINTROSPECTION_THREAD_START(this);
REGISTER_THREAD(this);
running_ = true;
if (lockRun) thread_mutex.lock();
begin();
if (lockRun) thread_mutex.unlock();
started();
}
void PIThread::_runThread() {
PIINTROSPECTION_THREAD_RUN(this);
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) thread_mutex.lock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
void PIThread::_runThread() {
PIINTROSPECTION_THREAD_RUN(this);
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "...";
if (lockRun) thread_mutex.lock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "lock" << "ok";
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "run" << "...";
#ifdef PIP_INTROSPECTION
PITimeMeasurer _tm;
PITimeMeasurer _tm;
#endif
run();
run();
#ifdef PIP_INTROSPECTION
PIINTROSPECTION_THREAD_RUN_DONE(this, ullong(_tm.elapsed_u()));
PIINTROSPECTION_THREAD_RUN_DONE(this, ullong(_tm.elapsed_u()));
#endif
// 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) thread_mutex.unlock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "unlock" << "ok";
}
// 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) thread_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";
if (lockRun) thread_mutex.lock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
end();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.unlock();
terminating = running_ = false;
tid_ = -1;
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
// cout << "thread " << t << " exiting ... " << endl;
// PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_THREAD_STOP(this);
void PIThread::_endThread() {
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "...";
stopped();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.lock();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "end" << "...";
end();
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "stop" << "ok";
if (lockRun) thread_mutex.unlock();
terminating = running_ = false;
tid_ = -1;
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "exit";
// cout << "thread " << t << " exiting ... " << endl;
// PICout(PICoutManipulators::DefaultControls) << "pthread_exit" << (__privateinitializer__.p)->thread;
UNREGISTER_THREAD(this);
PIINTROSPECTION_THREAD_STOP(this);
#if defined(WINDOWS)
# ifdef CC_GCC
_endthreadex(0);
_endthreadex(0);
# else
ExitThread(0);
ExitThread(0);
# endif
#elif defined(FREERTOS)
PRIVATE->thread = 0;
@@ -900,115 +917,115 @@ bool PIThread::_startThread(void * func) {
PRIVATE->thread = 0;
pthread_exit(0);
#endif
}
}
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";
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);
}
_endThread();
}
// PICout(PICoutManipulators::DefaultControls) << "thread" << this << "wait" << "ok";
}
_endThread();
}
void PIThread::__thread_func_once__() {
_beginThread();
_runThread();
_endThread();
}
void PIThread::__thread_func_once__() {
_beginThread();
_runThread();
_endThread();
}
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! event handler "handler" of object "object" in this thread.\n
//! This %PIThread automatically delete on function finish.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! обработчик "handler" объекта "object" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения обработчика.
//!
//! \~\code
//! class MyObj: public PIObject {
//! PIOBJECT(MyObj)
//! public:
//! EVENT_HANDLER(void, threadRun) {
//! piForTimes (5) {
//! piCout << "threadRun";
//! piMSleep(100);
//! }
//! };
//! };
//!
//! int main(int argc, char * argv[]) {
//! MyObj mo;
//! PIThread::runOnce(&mo, "threadRun");
//! piMSleep(1000); // wait for thread finish
//! return 0;
//! }
//! \endcode
void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
if (!PIObject::piConnectU(t, PIStringAscii("started"), object, object, PIStringAscii(handler), "PIThread::runOnce").isValid()) {
delete t;
return;
}
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! event handler "handler" of object "object" in this thread.\n
//! This %PIThread automatically delete on function finish.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! обработчик "handler" объекта "object" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения обработчика.
//!
//! \~\code
//! class MyObj: public PIObject {
//! PIOBJECT(MyObj)
//! public:
//! EVENT_HANDLER(void, threadRun) {
//! piForTimes (5) {
//! piCout << "threadRun";
//! piMSleep(100);
//! }
//! };
//! };
//!
//! int main(int argc, char * argv[]) {
//! MyObj mo;
//! PIThread::runOnce(&mo, "threadRun");
//! piMSleep(1000); // wait for thread finish
//! return 0;
//! }
//! \endcode
void PIThread::runOnce(PIObject * object, const char * handler, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
if (!PIObject::piConnectU(t, PIStringAscii("started"), object, object, PIStringAscii(handler), "PIThread::runOnce").isValid()) {
delete t;
return;
}
#ifndef MICRO_PIP
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
#endif
t->startOnce();
}
t->startOnce();
}
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) "func" in this thread.\n
//! This %PIThread automatically delete on function finish.\n
//! "func" shouldn`t have arguments.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) "func" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения функции.\n
//! "func" не должна иметь аргументов.
//!
//! \~\code
//! PIThread::runOnce([](){
//! piForTimes(5) {
//! piCout << "thread func";
//! piMSleep(100);
//! }
//! });
//! piMSleep(1000);
//! \endcode
void PIThread::runOnce(std::function<void()> func, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
t->setSlot(func);
//! \~\details
//! \~english
//! This method create %PIThread with name "name" and execute
//! [lambda expression](https://en.cppreference.com/w/cpp/language/lambda) "func" in this thread.\n
//! This %PIThread automatically delete on function finish.\n
//! "func" shouldn`t have arguments.
//!
//! \~russian
//! Этот метод создает %PIThread с именем "name" и выполняет
//! [лямбда-выражение](https://ru.cppreference.com/w/cpp/language/lambda) "func" в этом потоке.\n
//! %PIThread автоматически удаляется после завершения функции.\n
//! "func" не должна иметь аргументов.
//!
//! \~\code
//! PIThread::runOnce([](){
//! piForTimes(5) {
//! piCout << "thread func";
//! piMSleep(100);
//! }
//! });
//! piMSleep(1000);
//! \endcode
void PIThread::runOnce(std::function<void()> func, const PIString & name) {
PIThread * t = new PIThread();
t->setName(name);
t->setSlot(func);
#ifndef MICRO_PIP
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
__PIThreadCollection::instance()->startedAuto(t);
CONNECT0(void, t, stopped, __PIThreadCollection::instance(), stoppedAuto);
#endif
t->startOnce();
}
t->startOnce();
}