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

@@ -20,6 +20,7 @@
#include "pibinarylog.h"
#include "pidir.h"
#include "piliterals.h"
#include "pipropertystorage.h"
#define PIBINARYLOG_VERSION_OLD 0x31
@@ -57,7 +58,7 @@ PIBinaryLog::PIBinaryLog() {
#ifdef MICRO_PIP
setThreadedReadBufferSize(512);
#else
setThreadedReadBufferSize(65536);
setThreadedReadBufferSize(64_KiB);
#endif
is_started = is_indexed = is_pause = false;
create_index_on_fly = false;
@@ -67,9 +68,9 @@ PIBinaryLog::PIBinaryLog() {
setPlaySpeed(1.);
setDefaultID(1);
setPlaySpeed(1.0);
setPlayDelay(PISystemTime::fromSeconds(1.0));
setPlayDelay(1_s);
setPlayRealTime();
setSplitTime(PISystemTime(600, 0));
setSplitTime(600_s);
setSplitRecordCount(1000);
setSplitFileSize(0xFFFFFF);
setSplitMode(SplitNone);

View File

@@ -21,6 +21,7 @@
#include "piconfig.h"
#include "piconstchars.h"
#include "piincludes_p.h"
#include "piliterals.h"
#include "pipropertystorage.h"
#include "pisysteminfo.h"
// clang-format off
@@ -167,11 +168,11 @@ void PIEthernet::construct() {
setTTL(64);
setMulticastTTL(1);
server_thread_.setData(this);
server_thread_.setName("__S__server_thread");
server_thread_.setName("__S__server_thread"_a);
#ifdef MICRO_PIP
setThreadedReadBufferSize(512);
#else
setThreadedReadBufferSize(65536);
setThreadedReadBufferSize(64_KiB);
#endif
// setPriority(piHigh);
}
@@ -305,7 +306,7 @@ bool PIEthernet::closeDevice() {
server_thread_.stop();
PRIVATE->event.interrupt();
if (server_thread_.isRunning()) {
if (!server_thread_.waitForFinish(1000)) server_thread_.terminate();
if (!server_thread_.waitForFinish(1_s)) server_thread_.terminate();
}
PRIVATE->event.destroy();
if (sock_s == sock) sock_s = -1;
@@ -487,7 +488,7 @@ bool PIEthernet::listen(bool threaded) {
if (server_thread_.isRunning()) {
if (!server_bounded) return true;
server_thread_.stop();
if (!server_thread_.waitForFinish(100)) server_thread_.terminate();
if (!server_thread_.waitForFinish(100_ms)) server_thread_.terminate();
}
listen_threaded = true;
server_bounded = false;

View File

@@ -28,6 +28,7 @@
# include <fcntl.h>
# include <unistd.h>
#endif
#include "piliterals.h"
//! \class PIGPIO pigpio.h
@@ -71,7 +72,7 @@ PIGPIO::PIGPIO(): PIThread() {}
PIGPIO::~PIGPIO() {
stop();
waitForFinish(100);
waitForFinish(100_ms);
PIMutexLocker ml(mutex);
#ifdef GPIO_SYS_CLASS
PIVector<int> ids = gpio_.keys();

View File

@@ -21,6 +21,7 @@
#include "piconfig.h"
#include "piconnection.h"
#include "piliterals.h"
#include "pipropertystorage.h"
@@ -311,7 +312,7 @@ void PIIODevice::_init() {
#ifdef MICRO_PIP
threaded_read_buffer_size = 512;
#else
threaded_read_buffer_size = 4096;
threaded_read_buffer_size = 4_KiB;
#endif
read_thread.setName("__S__.PIIODevice.read_thread");
write_thread.setName("__S__.PIIODevice.write_thread");
@@ -471,7 +472,7 @@ bool PIIODevice::configure(const PIString & config_file, const PIString & sectio
PIString PIIODevice::constructFullPath() const {
return fullPathPrefix().toString() + PIStringAscii("://") + constructFullPathDevice() + fullPathOptions();
return fullPathPrefix().toString() + "://"_a + constructFullPathDevice() + fullPathOptions();
}
@@ -511,18 +512,12 @@ void PIIODevice::splitFullPath(PIString fpwm, PIString * full_path, DeviceMode *
PIStringList opts(dms.split(","));
piForeachC(PIString & o, opts) {
// piCout << dms;
if (o == PIStringAscii("r") || o == PIStringAscii("ro") || o == PIStringAscii("read") || o == PIStringAscii("readonly"))
dm |= ReadOnly;
if (o == PIStringAscii("w") || o == PIStringAscii("wo") || o == PIStringAscii("write") || o == PIStringAscii("writeonly"))
dm |= WriteOnly;
if (o == PIStringAscii("br") || o == PIStringAscii("blockr") || o == PIStringAscii("blockread") ||
o == PIStringAscii("blockingread"))
op |= BlockingRead;
if (o == PIStringAscii("bw") || o == PIStringAscii("blockw") || o == PIStringAscii("blockwrite") ||
o == PIStringAscii("blockingwrite"))
op |= BlockingWrite;
if (o == PIStringAscii("brw") || o == PIStringAscii("bwr") || o == PIStringAscii("blockrw") || o == PIStringAscii("blockwr") ||
o == PIStringAscii("blockreadrite") || o == PIStringAscii("blockingreadwrite"))
if (o == "r"_a || o == "ro"_a || o == "read"_a || o == "readonly"_a) dm |= ReadOnly;
if (o == "w"_a || o == "wo"_a || o == "write"_a || o == "writeonly"_a) dm |= WriteOnly;
if (o == "br"_a || o == "blockr"_a || o == "blockread"_a || o == "blockingread"_a) op |= BlockingRead;
if (o == "bw"_a || o == "blockw"_a || o == "blockwrite"_a || o == "blockingwrite"_a) op |= BlockingWrite;
if (o == "brw"_a || o == "bwr"_a || o == "blockrw"_a || o == "blockwr"_a || o == "blockreadrite"_a ||
o == "blockingreadwrite"_a)
op |= BlockingRead | BlockingWrite;
}
fpwm.cutRight(fpwm.length() - fpwm.findLast('(')).trim();
@@ -565,29 +560,29 @@ void PIIODevice::registerDevice(PIConstChars prefix, PIConstChars classname, PII
PIString PIIODevice::fullPathOptions() const {
if (mode_ == ReadWrite && options_ == 0) return PIString();
PIString ret(" (");
PIString ret(" ("_a);
bool f = true;
if (mode_ == ReadOnly) {
if (!f) ret += ",";
if (!f) ret += ","_a;
f = false;
ret += "ro";
ret += "ro"_a;
}
if (mode_ == WriteOnly) {
if (!f) ret += ",";
if (!f) ret += ","_a;
f = false;
ret += "wo";
ret += "wo"_a;
}
if (options_[BlockingRead]) {
if (!f) ret += ",";
if (!f) ret += ","_a;
f = false;
ret += "br";
ret += "br"_a;
}
if (options_[BlockingWrite]) {
if (!f) ret += ",";
if (!f) ret += ","_a;
f = false;
ret += "bw";
ret += "bw"_a;
}
return ret + ")";
return ret + ")"_a;
}

View File

@@ -20,6 +20,7 @@
#include "pisharedmemory.h"
#include "piincludes_p.h"
#include "piliterals.h"
#include "pipropertystorage.h"
#if defined(LINUX) || defined(MAC_OS)
# define SHM_POSIX
@@ -77,7 +78,7 @@ PRIVATE_DEFINITION_END(PISharedMemory)
PISharedMemory::PISharedMemory(): PIIODevice() {
initPrivate();
dsize = 65536;
dsize = 64_KiB;
}

View File

@@ -19,6 +19,8 @@
#include "pipacketextractor.h"
#include "piliterals.h"
/** \class PIPacketExtractor
* \brief Packets extractor
@@ -99,7 +101,7 @@ void PIPacketExtractor::construct() {
#ifdef MICRO_PIP
setThreadedReadBufferSize(512);
#else
setThreadedReadBufferSize(65536);
setThreadedReadBufferSize(64_KiB);
#endif
setDevice(nullptr);
setSplitMode(None);

View File

@@ -0,0 +1,40 @@
/*! \file piliterals.h
* \ingroup Core
* \~\brief
* \~english C++11 literals
* \~russian C++11 суффиксы
*
* \~\details
* \~english
* Include all literals_*.h files
* \~russian
* Включает все файлы literals_*.h
*/
/*
PIP - Platform Independent Primitives
C++11 literals
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PILITERALS_H
#define PILITERALS_H
#include "piliterals_bytearray.h"
#include "piliterals_bytes.h"
#include "piliterals_string.h"
#include "piliterals_time.h"
#endif

View File

@@ -0,0 +1,46 @@
/*! \file piliterals_bytearray.h
* \ingroup Core
* \~\brief
* \~english PIByteArray C++11 literals
* \~russian C++11 суффиксы PIByteArray
*/
/*
PIP - Platform Independent Primitives
PIByteArray C++11 literals
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PILITERALS_BYTEARRAY_H
#define PILITERALS_BYTEARRAY_H
#include "pibytearray.h"
//! \~\brief
//! \~english PIByteArray from hex string (e.g. "1a2e3f")
//! \~russian PIByteArray из hex строки (например "1a2e3f")
inline PIByteArray operator""_hex(const char * v, size_t sz) {
return PIByteArray::fromHex(PIStringAscii(v, sz));
}
//! \~\brief
//! \~english PIByteArray from base64 string (e.g. "aGVsbG8=")
//! \~russian PIByteArray из base64 строки (например "aGVsbG8=")
inline PIByteArray operator""_base64(const char * v, size_t sz) {
return PIByteArray::fromBase64(PIStringAscii(v, sz));
}
#endif

View File

@@ -1,7 +1,7 @@
/*! \file piliterals.h
/*! \file piliterals_bytes.h
* \ingroup Core
* \~\brief
* \~english Bytes C++11 literals
* \~english Bytes C++11 literals for bytes
* \~russian C++11 байтовые суффиксы
*
* \~\details
@@ -16,7 +16,7 @@
*/
/*
PIP - Platform Independent Primitives
Bytes C++11 literals
Bytes C++11 literals for bytes
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
@@ -33,35 +33,35 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PILITERALS_H
#define PILITERALS_H
#ifndef PILITERALS_BYTES_H
#define PILITERALS_BYTES_H
//! \~\brief
//! \~english Kilobytes, x1000
//! \~russian Килобайт, x1000
unsigned long long operator""_KB(long double v) {
constexpr unsigned long long operator""_KB(long double v) {
return v * 1000.;
}
//! \~\brief
//! \~english Kilobytes, x1000
//! \~russian Килобайт, x1000
unsigned long long operator""_KB(unsigned long long v) {
constexpr unsigned long long operator""_KB(unsigned long long v) {
return v * 1000;
}
//! \~\brief
//! \~english Kibibytes, x1024 (2^10)
//! \~russian Кибибайт, x1024 (2^10)
unsigned long long operator""_KiB(long double v) {
constexpr unsigned long long operator""_KiB(long double v) {
return v * 1024.;
}
//! \~\brief
//! \~english Kibibytes, x1024 (2^10)
//! \~russian Кибибайт, x1024 (2^10)
unsigned long long operator""_KiB(unsigned long long v) {
constexpr unsigned long long operator""_KiB(unsigned long long v) {
return v * 1024;
}
@@ -69,28 +69,28 @@ unsigned long long operator""_KiB(unsigned long long v) {
//! \~\brief
//! \~english Megabytes, x1000.000
//! \~russian Мегабайт, x1000.000
unsigned long long operator""_MB(long double v) {
constexpr unsigned long long operator""_MB(long double v) {
return v * 1000. * 1000.;
}
//! \~\brief
//! \~english Megabytes, x1000.000
//! \~russian Мегабайт, x1000.000
unsigned long long operator""_MB(unsigned long long v) {
constexpr unsigned long long operator""_MB(unsigned long long v) {
return v * 1000 * 1000;
}
//! \~\brief
//! \~english Mebibytes, x1.048.576 (2^20)
//! \~russian Мебибайт, x1.048.576 (2^20)
unsigned long long operator""_MiB(long double v) {
constexpr unsigned long long operator""_MiB(long double v) {
return v * 1024. * 1024.;
}
//! \~\brief
//! \~english Mebibytes, x1.048.576 (2^20)
//! \~russian Мебибайт, x1.048.576 (2^20)
unsigned long long operator""_MiB(unsigned long long v) {
constexpr unsigned long long operator""_MiB(unsigned long long v) {
return v * 1024 * 1024;
}
@@ -98,28 +98,28 @@ unsigned long long operator""_MiB(unsigned long long v) {
//! \~\brief
//! \~english Gigabytes, x1000.000.000
//! \~russian Гигабайт, x1000.000.000
unsigned long long operator""_GB(long double v) {
constexpr unsigned long long operator""_GB(long double v) {
return v * 1000. * 1000. * 1000.;
}
//! \~\brief
//! \~english Gigabytes, x1000.000.000
//! \~russian Гигабайт, x1000.000.000
unsigned long long operator""_GB(unsigned long long v) {
constexpr unsigned long long operator""_GB(unsigned long long v) {
return v * 1000 * 1000 * 1000;
}
//! \~\brief
//! \~english Gibibytes, x1.073.741.824 (2^30)
//! \~russian Гибибайт, x1.073.741.824 (2^30)
unsigned long long operator""_GiB(long double v) {
constexpr unsigned long long operator""_GiB(long double v) {
return v * 1024. * 1024. * 1024.;
}
//! \~\brief
//! \~english Gibibytes, x1.073.741.824 (2^30)
//! \~russian Гибибайт, x1.073.741.824 (2^30)
unsigned long long operator""_GiB(unsigned long long v) {
constexpr unsigned long long operator""_GiB(unsigned long long v) {
return v * 1024 * 1024 * 1024;
}
@@ -127,28 +127,28 @@ unsigned long long operator""_GiB(unsigned long long v) {
//! \~\brief
//! \~english Terabytes, x1000.000.000.000
//! \~russian Терабайт, x1000.000.000.000
unsigned long long operator""_TB(long double v) {
constexpr unsigned long long operator""_TB(long double v) {
return v * 1000. * 1000. * 1000. * 1000.;
}
//! \~\brief
//! \~english Terabytes, x1000.000.000.000
//! \~russian Терабайт, x1000.000.000.000
unsigned long long operator""_TB(unsigned long long v) {
constexpr unsigned long long operator""_TB(unsigned long long v) {
return v * 1000 * 1000 * 1000 * 1000;
}
//! \~\brief
//! \~english Tebibytes, x1.099.511.627.776 (2^40)
//! \~russian Тебибайт, x1.099.511.627.776 (2^40)
unsigned long long operator""_TiB(long double v) {
constexpr unsigned long long operator""_TiB(long double v) {
return v * 1024. * 1024. * 1024. * 1024.;
}
//! \~\brief
//! \~english Tebibytes, x1.099.511.627.776 (2^40)
//! \~russian Тебибайт, x1.099.511.627.776 (2^40)
unsigned long long operator""_TiB(unsigned long long v) {
constexpr unsigned long long operator""_TiB(unsigned long long v) {
return v * 1024 * 1024 * 1024 * 1024;
}
@@ -156,28 +156,28 @@ unsigned long long operator""_TiB(unsigned long long v) {
//! \~\brief
//! \~english Petabytes, x1000.000.000.000.000
//! \~russian Петабайт, x1000.000.000.000.000
unsigned long long operator""_PB(long double v) {
constexpr unsigned long long operator""_PB(long double v) {
return v * 1000. * 1000. * 1000. * 1000. * 1000.;
}
//! \~\brief
//! \~english Petabytes, x1000.000.000.000.000
//! \~russian Петабайт, x1000.000.000.000.000
unsigned long long operator""_PB(unsigned long long v) {
constexpr unsigned long long operator""_PB(unsigned long long v) {
return v * 1000 * 1000 * 1000 * 1000 * 1000;
}
//! \~\brief
//! \~english Pebibytes, x1.125.899.906.842.624 (2^50)
//! \~russian Пебибайт, x1.125.899.906.842.624 (2^50)
unsigned long long operator""_PiB(long double v) {
constexpr unsigned long long operator""_PiB(long double v) {
return v * 1024. * 1024. * 1024. * 1024. * 1024.;
}
//! \~\brief
//! \~english Pebibytes, x1.125.899.906.842.624 (2^50)
//! \~russian Пебибайт, x1.125.899.906.842.624 (2^50)
unsigned long long operator""_PiB(unsigned long long v) {
constexpr unsigned long long operator""_PiB(unsigned long long v) {
return v * 1024 * 1024 * 1024 * 1024 * 1024;
}

View File

@@ -0,0 +1,46 @@
/*! \file piliterals_string.h
* \ingroup Core
* \~\brief
* \~english PIString C++11 literals
* \~russian C++11 суффиксы PIString
*/
/*
PIP - Platform Independent Primitives
PIString C++11 literals
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PILITERALS_STRING_H
#define PILITERALS_STRING_H
#include "pistring.h"
//! \~\brief
//! \~english PIString from ASCII
//! \~russian PIString из ASCII
inline PIString operator""_a(const char * v, size_t sz) {
return PIString::fromAscii(v, sz);
}
//! \~\brief
//! \~english PIString from UTF-8
//! \~russian PIString из UTF-8
inline PIString operator""_u8(const char * v, size_t sz) {
return PIString::fromUTF8(v, sz);
}
#endif

View File

@@ -0,0 +1,85 @@
/*! \file piliterals_time.h
* \ingroup Core
* \~\brief
* \~english PISystemTime C++11 literals
* \~russian C++11 суффиксы PISystemTime
*/
/*
PIP - Platform Independent Primitives
PISystemTime C++11 literals
Ivan Pelipenko peri4ko@yandex.ru
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef PILITERALS_TIME_H
#define PILITERALS_TIME_H
#include "pisystemtime.h"
//! \~\brief
//! \~english PISystemTime from seconds
//! \~russian PISystemTime из секунд
inline PISystemTime operator""_s(long double v) {
return PISystemTime::fromSeconds(v);
}
//! \~\brief
//! \~english PISystemTime from seconds
//! \~russian PISystemTime из секунд
inline PISystemTime operator""_s(unsigned long long v) {
return PISystemTime::fromSeconds(v);
}
//! \~\brief
//! \~english PISystemTime from milliseconds
//! \~russian PISystemTime из милисекунд
inline PISystemTime operator""_ms(long double v) {
return PISystemTime::fromMilliseconds(v);
}
//! \~\brief
//! \~english PISystemTime from milliseconds
//! \~russian PISystemTime из милисекунд
inline PISystemTime operator""_ms(unsigned long long v) {
return PISystemTime::fromMilliseconds(v);
}
//! \~\brief
//! \~english PISystemTime from microseconds
//! \~russian PISystemTime из микросекунд
inline PISystemTime operator""_us(long double v) {
return PISystemTime::fromMicroseconds(v);
}
//! \~\brief
//! \~english PISystemTime from microseconds
//! \~russian PISystemTime из микросекунд
inline PISystemTime operator""_us(unsigned long long v) {
return PISystemTime::fromMicroseconds(v);
}
//! \~\brief
//! \~english PISystemTime from nanoseconds
//! \~russian PISystemTime из наносекунд
inline PISystemTime operator""_ns(unsigned long long v) {
return PISystemTime::fromNanoseconds(v);
}
#endif

View File

@@ -19,6 +19,7 @@
#include "pisingleapplication.h"
#include "piliterals.h"
#include "pisharedmemory.h"
@@ -61,7 +62,7 @@
//!
#define SHM_SIZE 1024 * 32
#define SHM_SIZE 32_KiB
PISingleApplication::PISingleApplication(const PIString & app_name): PIThread() {
@@ -75,7 +76,7 @@ PISingleApplication::PISingleApplication(const PIString & app_name): PIThread()
PISingleApplication::~PISingleApplication() {
stop();
if (!waitForFinish(5000)) terminate();
if (!waitForFinish(5_s)) terminate();
delete shm;
}

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();
}

View File

@@ -163,8 +163,10 @@ public:
EVENT_HANDLER0(bool, waitForStart) { return waitForStart(-1); }
EVENT_HANDLER1(bool, waitForStart, int, timeout_msecs);
bool waitForStart(PISystemTime timeout);
EVENT_HANDLER0(bool, waitForFinish) { return waitForFinish(-1); }
EVENT_HANDLER1(bool, waitForFinish, int, timeout_msecs);
bool waitForFinish(PISystemTime timeout);
//! \~english Set necessity of lock every \a run() with internal mutex
//! \~russian Устанавливает необходимость блокировки внутреннего мьютекса каждый \a run()

View File

@@ -26,12 +26,10 @@ REGISTER_VARIANT_CAST(PIString, SomeType) {
return SomeType{sl[0].toInt(), sl[1].toFloat()};
}
#include "piliterals.h"
int main(int argc, char * argv[]) {
// clang-format off
piCout << 2_MB;
piCout << 2.1_MB;
piCout << 2_MiB;
piCout << 2.1_MiB;
piCout << 0.5_s;
// clang-format on
return 0;
/*PIValueTree root;