diff --git a/libs/main/io_devices/pibinarylog.cpp b/libs/main/io_devices/pibinarylog.cpp index 973a4d5e..207c4008 100644 --- a/libs/main/io_devices/pibinarylog.cpp +++ b/libs/main/io_devices/pibinarylog.cpp @@ -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); diff --git a/libs/main/io_devices/piethernet.cpp b/libs/main/io_devices/piethernet.cpp index 5fd3d057..cf29729c 100644 --- a/libs/main/io_devices/piethernet.cpp +++ b/libs/main/io_devices/piethernet.cpp @@ -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; diff --git a/libs/main/io_devices/pigpio.cpp b/libs/main/io_devices/pigpio.cpp index 40692346..679b0423 100644 --- a/libs/main/io_devices/pigpio.cpp +++ b/libs/main/io_devices/pigpio.cpp @@ -28,6 +28,7 @@ # include # include #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 ids = gpio_.keys(); diff --git a/libs/main/io_devices/piiodevice.cpp b/libs/main/io_devices/piiodevice.cpp index 0195e8ea..b517bbdb 100644 --- a/libs/main/io_devices/piiodevice.cpp +++ b/libs/main/io_devices/piiodevice.cpp @@ -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; } diff --git a/libs/main/io_devices/pisharedmemory.cpp b/libs/main/io_devices/pisharedmemory.cpp index a11e3912..8c2a4aae 100644 --- a/libs/main/io_devices/pisharedmemory.cpp +++ b/libs/main/io_devices/pisharedmemory.cpp @@ -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; } diff --git a/libs/main/io_utils/pipacketextractor.cpp b/libs/main/io_utils/pipacketextractor.cpp index 171adb05..a0de975b 100644 --- a/libs/main/io_utils/pipacketextractor.cpp +++ b/libs/main/io_utils/pipacketextractor.cpp @@ -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); diff --git a/libs/main/literals/piliterals.h b/libs/main/literals/piliterals.h new file mode 100644 index 00000000..845d4ab6 --- /dev/null +++ b/libs/main/literals/piliterals.h @@ -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 . +*/ + +#ifndef PILITERALS_H +#define PILITERALS_H + +#include "piliterals_bytearray.h" +#include "piliterals_bytes.h" +#include "piliterals_string.h" +#include "piliterals_time.h" + +#endif diff --git a/libs/main/literals/piliterals_bytearray.h b/libs/main/literals/piliterals_bytearray.h new file mode 100644 index 00000000..33cfafe8 --- /dev/null +++ b/libs/main/literals/piliterals_bytearray.h @@ -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 . +*/ + +#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 diff --git a/libs/main/core/piliterals.h b/libs/main/literals/piliterals_bytes.h similarity index 73% rename from libs/main/core/piliterals.h rename to libs/main/literals/piliterals_bytes.h index 2e87d319..5e3c93dd 100644 --- a/libs/main/core/piliterals.h +++ b/libs/main/literals/piliterals_bytes.h @@ -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 . */ -#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; } diff --git a/libs/main/literals/piliterals_string.h b/libs/main/literals/piliterals_string.h new file mode 100644 index 00000000..136f0aae --- /dev/null +++ b/libs/main/literals/piliterals_string.h @@ -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 . +*/ + +#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 diff --git a/libs/main/literals/piliterals_time.h b/libs/main/literals/piliterals_time.h new file mode 100644 index 00000000..c6f1f670 --- /dev/null +++ b/libs/main/literals/piliterals_time.h @@ -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 . +*/ + +#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 diff --git a/libs/main/system/pisingleapplication.cpp b/libs/main/system/pisingleapplication.cpp index 7243de86..d0c67af5 100644 --- a/libs/main/system/pisingleapplication.cpp +++ b/libs/main/system/pisingleapplication.cpp @@ -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; } diff --git a/libs/main/thread/pithread.cpp b/libs/main/thread/pithread.cpp index 19396336..14dd5061 100644 --- a/libs/main/thread/pithread.cpp +++ b/libs/main/thread/pithread.cpp @@ -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 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 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(); +} diff --git a/libs/main/thread/pithread.h b/libs/main/thread/pithread.h index e0a7baed..6b043679 100644 --- a/libs/main/thread/pithread.h +++ b/libs/main/thread/pithread.h @@ -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() diff --git a/main.cpp b/main.cpp index 8418d880..f46f22a9 100644 --- a/main.cpp +++ b/main.cpp @@ -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;