diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d731562..5e7e49d1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -66,7 +66,6 @@ set(PIP_SRC_USB "lib/usb") set(PIP_SRC_FFTW "lib/fftw") set(PIP_SRC_OPENCL "lib/opencl") set(PIP_SRC_IO_UTILS "lib/io_utils") -set(PIP_SRC_CONCURRENT "lib/concurrent") set(PIP_SRC_CLOUD "lib/cloud") set(PIP_SRC_LUA "lib/lua") set(PIP_SRC_DIRS ${PIP_SRC_MAIN} @@ -77,8 +76,8 @@ set(PIP_SRC_DIRS ${PIP_SRC_MAIN} ${PIP_SRC_FFTW} ${PIP_SRC_OPENCL} ${PIP_SRC_IO_UTILS} - ${PIP_SRC_CONCURRENT} - ${PIP_SRC_CLOUD} + ${PIP_SRC_CLOUD} + ${PIP_SRC_LUA} ) set(PIP_LIBS_TARGETS pip) set(LIBS_MAIN) @@ -192,7 +191,7 @@ get_filename_component(C_COMPILER "${CMAKE_C_COMPILER}" NAME) # Sources # Main lib -set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "concurrent" "cloud" "lua") +set(PIP_FOLDERS "." "core" "containers" "thread" "system" "io_devices" "io_utils" "console" "math" "code" "geo" "resources" "opencl" "crypt" "introspection" "cloud" "lua") include_directories("${PIP_SRC_MAIN}") set(PIP_MAIN_FOLDERS) foreach(F ${PIP_FOLDERS}) @@ -221,17 +220,17 @@ gather_src("${PIP_SRC_OPENCL}" CPP_LIB_OPENCL HDRS PHDRS) # IO Utils lib gather_src("${PIP_SRC_IO_UTILS}" CPP_LIB_IO_UTILS HDRS PHDRS) -# Concurrent lib -gather_src("${PIP_SRC_CONCURRENT}" CPP_LIB_CONCURRENT HDRS PHDRS) - -gather_src("${PIP_CONCURRENT_TEST}" CPP_CONCURRENT_TEST HDRS PHDRS) - # Cloud lib gather_src("${PIP_SRC_CLOUD}" CPP_LIB_CLOUD HDRS PHDRS) # LUA lib gather_src("${PIP_SRC_LUA}" CPP_LIB_LUA HDRS PHDRS) +if (TESTS) + # Concurrent lib tests + gather_src("${PIP_CONCURRENT_TEST}" CPP_CONCURRENT_TEST HDRS PHDRS) +endif() + if(PIP_FREERTOS) add_definitions(-DPIP_FREERTOS) set(ICU OFF) @@ -580,24 +579,10 @@ if (NOT CROSSTOOLS) list(APPEND PIP_LIBS_TARGETS pip_io_utils) - # Concurrent module - set(CONCURRENT_LIBS pip) - import_version(pip_concurrent pip) - set_deploy_property(pip_concurrent ${PIP_LIB_TYPE} - LABEL "PIP concurrent support" - FULLNAME "${_PIP_DOMAIN}.pip_concurrent" - COMPANY "${_PIP_COMPANY}" - INFO "Platform-Independent Primitives") - make_rc(pip_concurrent _RC) - add_library(pip_concurrent ${PIP_LIB_TYPE} ${CPP_LIB_CONCURRENT} ${_RC}) - target_link_libraries(pip_concurrent ${CONCURRENT_LIBS}) - set_property(TARGET pip_concurrent PROPERTY CXX_STANDARD 11) - list(APPEND PIP_LIBS_TARGETS pip_concurrent) - # Enable build tests for concurrent module if(PIP_CONCURRENT_TEST) add_executable(pip_concurrent_test ${CPP_CONCURRENT_TEST}) - target_link_libraries(pip_concurrent_test gtest_main gmock_main pip_concurrent) + target_link_libraries(pip_concurrent_test pip gtest_main gmock_main) add_test(NAME pip_concurrent_test COMMAND tests) add_custom_target(pip_concurrent_test_perform ALL COMMAND pip_concurrent_test) endif() @@ -813,7 +798,6 @@ message(" Compress : ${PIP_COMPRESS}") message(" FFTW : ${PIP_FFTW}") message(" OpenCL : ${PIP_OPENCL}") message(" IOUtils : ${PIP_IOUTILS}") -message(" Concurrent: yes") message(" Cloud : ${PIP_CLOUD}") message(" Lua : ${PIP_LUA}") message("") diff --git a/cmake/FindPIP.cmake b/cmake/FindPIP.cmake index 48b4b47f..06292c0d 100644 --- a/cmake/FindPIP.cmake +++ b/cmake/FindPIP.cmake @@ -9,7 +9,6 @@ Also create imported targets: * PIP::FFTW * PIP::OpenCL * PIP::IOUtils - * PIP::Concurrent * PIP::Cloud * PIP::Lua @@ -67,7 +66,6 @@ find_library(PIP_FFTW_LIBRARY pip_fftw${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_COMPRESS_LIBRARY pip_compress${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_OPENCL_LIBRARY pip_opencl${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_IO_UTILS_LIBRARY pip_io_utils${_pip_suffix} HINTS ${_PIP_LIBDIR}) -find_library(PIP_CONCURRENT_LIBRARY pip_concurrent${_pip_suffix} HINTS ${_PIP_LIBDIR}) find_library(PIP_CLOUD_LIBRARY pip_cloud HINTS${_pip_suffix} ${_PIP_LIBDIR}) find_library(PIP_LUA_LIBRARY pip_lua HINTS${_pip_suffix} ${_PIP_LIBDIR}) find_file(PIP_H_INCLUDE "pip.h" HINTS ${_PIP_INCDIR} $ENV{SMSDK_DIR}/include/pip) @@ -134,15 +132,14 @@ if(PIP_FIND_VERSION VERSION_GREATER PIP_VERSION) message(FATAL_ERROR "PIP version ${PIP_VERSION} is available, but ${PIP_FIND_VERSION} requested!") endif() -set(__modules "USB;Crypt;Console;FFTW;Compress;IOUtils;Concurrent;Cloud;Lua") +set(__modules "USB;Crypt;Console;FFTW;Compress;IOUtils;Cloud;Lua") set(__module_USB "${PIP_USB_LIBRARY}" ) set(__module_Console "${PIP_CONSOLE_LIBRARY}" ) set(__module_Crypt "${PIP_CRYPT_LIBRARY}" ) set(__module_FFTW "${PIP_FFTW_LIBRARY}" ) set(__module_Compress "${PIP_COMPRESS_LIBRARY}" ) -set(__module_OpenCL "${PIP_OPENCL_LIBRARY}" ) +set(__module_OpenCL "${PIP_OPENCL_LIBRARY}" ) set(__module_IOUtils "${PIP_IO_UTILS_LIBRARY}" ) -set(__module_Concurrent "${PIP_CONCURRENT_LIBRARY}") set(__module_Cloud "${PIP_CLOUD_LIBRARY}" ) set(__module_Lua "${PIP_LUA_LIBRARY}" ) if((NOT TARGET PIP) AND PIP_LIBRARY) diff --git a/lib/concurrent/piconditionlock.cpp b/lib/concurrent/piconditionlock.cpp deleted file mode 100644 index 35dee0c4..00000000 --- a/lib/concurrent/piconditionlock.cpp +++ /dev/null @@ -1,95 +0,0 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 . -*/ - -#include "piconditionlock.h" -#ifdef WINDOWS -# include -#else -# include -#endif - - -PRIVATE_DEFINITION_START(PIConditionLock) -#ifdef WINDOWS - CRITICAL_SECTION -#else - pthread_mutex_t -#endif - nativeHandle; -PRIVATE_DEFINITION_END(PIConditionLock) - - -PIConditionLock::PIConditionLock() { -#ifdef WINDOWS - InitializeCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutexattr_t attr; - memset(&attr, 0, sizeof(attr)); - pthread_mutexattr_init(&attr); - pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); - memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); - pthread_mutex_init(&(PRIVATE->nativeHandle), &attr); - pthread_mutexattr_destroy(&attr); -#endif -} - - -PIConditionLock::~PIConditionLock() { -#ifdef WINDOWS - DeleteCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutex_destroy(&(PRIVATE->nativeHandle)); -#endif -} - - -void PIConditionLock::lock() { -#ifdef WINDOWS - EnterCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutex_lock(&(PRIVATE->nativeHandle)); -#endif -} - - -void PIConditionLock::unlock() { -#ifdef WINDOWS - LeaveCriticalSection(&PRIVATE->nativeHandle); -#else - pthread_mutex_unlock(&(PRIVATE->nativeHandle)); -#endif -} - - -void *PIConditionLock::handle() { -#ifdef WINDOWS - return &PRIVATE->nativeHandle; -#else - return &PRIVATE->nativeHandle; -#endif -} - - -bool PIConditionLock::tryLock() { -#ifdef WINDOWS - return TryEnterCriticalSection(&PRIVATE->nativeHandle) != 0; -#else - return (pthread_mutex_trylock(&(PRIVATE->nativeHandle)) == 0); -#endif -} diff --git a/lib/concurrent/test/BlockingDequeueUnitTest.cpp b/lib/concurrent/test/BlockingDequeueUnitTest.cpp index e0d4dd46..fb673059 100644 --- a/lib/concurrent/test/BlockingDequeueUnitTest.cpp +++ b/lib/concurrent/test/BlockingDequeueUnitTest.cpp @@ -8,24 +8,24 @@ public: bool isTrueCondition = false; int timeout = -1; - void wait(PIConditionLock& lk) override { + void wait(PIMutex& lk) override { isWaitCalled = true; } - void wait(PIConditionLock& lk, const std::function& condition) override { + void wait(PIMutex& lk, const std::function& condition) override { isWaitCalled = true; lk.lock(); isTrueCondition = condition(); lk.unlock(); } - bool waitFor(PIConditionLock& lk, int timeoutMs) override { + bool waitFor(PIMutex& lk, int timeoutMs) override { isWaitForCalled = true; timeout = timeoutMs; return false; } - bool waitFor(PIConditionLock& lk, int timeoutMs, const std::function& condition) override { + bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition) override { isWaitForCalled = true; lk.lock(); isTrueCondition = condition(); diff --git a/lib/concurrent/test/ConditionLockIntegrationTest.cpp b/lib/concurrent/test/ConditionLockIntegrationTest.cpp index 8d42a597..13a6c6f6 100644 --- a/lib/concurrent/test/ConditionLockIntegrationTest.cpp +++ b/lib/concurrent/test/ConditionLockIntegrationTest.cpp @@ -2,12 +2,12 @@ #include "gmock/gmock.h" #include "piconditionvar.h" -#include +#include "pithread.h" #include "testutil.h" class ConditionLock : public ::testing::Test, public TestUtil { public: - PIConditionLock* m = new PIConditionLock(); + PIMutex* m = new PIMutex(); }; TEST_F(ConditionLock, lock_is_protect) { @@ -50,4 +50,4 @@ TEST_F(ConditionLock, tryLock_is_true_when_unlocked) { TEST_F(ConditionLock, tryLock_is_recursive_lock_enable) { m->lock(); ASSERT_TRUE(m->tryLock()); -} \ No newline at end of file +} diff --git a/lib/concurrent/test/ConditionVariableIntegrationTest.cpp b/lib/concurrent/test/ConditionVariableIntegrationTest.cpp index 6a2609fa..a9d26cec 100644 --- a/lib/concurrent/test/ConditionVariableIntegrationTest.cpp +++ b/lib/concurrent/test/ConditionVariableIntegrationTest.cpp @@ -5,7 +5,7 @@ class ConditionVariable : public ::testing::Test, public TestUtil { public: - PIConditionLock m; + PIMutex m; PIConditionVariable* variable; protected: @@ -197,4 +197,4 @@ TEST_F(ConditionVariable, waitFor_is_unblock_when_condition_and_notifyOne) { variable->notifyOne(); msleep(WAIT_THREAD_TIME_MS); ASSERT_FALSE(thread->isRunning()); -} \ No newline at end of file +} diff --git a/lib/concurrent/test/ExecutorIntegrationTest.cpp b/lib/concurrent/test/ExecutorIntegrationTest.cpp index 099c5a8e..8e58a48c 100644 --- a/lib/concurrent/test/ExecutorIntegrationTest.cpp +++ b/lib/concurrent/test/ExecutorIntegrationTest.cpp @@ -1,5 +1,5 @@ #include "gtest/gtest.h" -#include "executor.h" +#include "pithreadpoolexecutor.h" #include "pimutex.h" const int WAIT_THREAD_TIME_MS = 30; @@ -51,4 +51,4 @@ TEST(ExcutorIntegrationTest, execute_is_awaitTermination_wait) { double waitTime = measurer.elapsed_m(); ASSERT_GE(waitTime, WAIT_THREAD_TIME_MS); ASSERT_LE(waitTime, 4 * WAIT_THREAD_TIME_MS); -} \ No newline at end of file +} diff --git a/lib/console/piconsole.cpp b/lib/console/piconsole.cpp deleted file mode 100644 index 8202826b..00000000 --- a/lib/console/piconsole.cpp +++ /dev/null @@ -1,1168 +0,0 @@ -/* - PIP - Platform Independent Primitives - Console output/input - 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 . -*/ -#include "piconsole.h" -#include "piincludes_p.h" -#include "pipeer.h" -#include "pidiagnostics.h" -#include "pisystemmonitor.h" -#ifndef WINDOWS -# include -# include -# include -#else -# include -# define COMMON_LVB_UNDERSCORE 0x8000 -#endif - - -/** \class PIConsole - * \brief Console output class - * \details - * \section PIConsole_sec0 Synopsis - * This class provides output to console with automatic alignment and update. - * It supports tabs, keyboard listening, formats and colors. - * - * \section PIConsole_sec1 Layout - * %PIConsole works with variable pointers. You should add your variables with - * functions \a addVariable() which receives label name, pointer to variable - * and optional column and format. Columns count is dynamically increased if - * new column used. E.g. if you add variable to empty tab to column 3, columns - * count will be increased to 3, but two firsts columns will be empty. Each column - * filled from top to bottom, but you can add just string with function - * \a addString() or add empty line with function \a addEmptyLine(). Layout scheme: - * \image html piconsole_layout.png - * - * \section PIConsole_sec2 Keyboard usage - * %PIConsole should to be single in application. %PIConsole aggregate PIKbdListener - * which grab keyboard and automatic switch tabs by theirs bind keys. If there is no - * tab binded to pressed key external function "slot" will be called - * - **/ - - -PRIVATE_DEFINITION_START(PIConsole) -#ifdef WINDOWS -void getWinCurCoord() {GetConsoleScreenBufferInfo(hOut, &csbi); ccoord = csbi.dwCursorPosition;} -COORD & getWinCoord(int dx = 0, int dy = 0) {getWinCurCoord(); ccoord.X += dx; ccoord.Y += dy; return ccoord;} -void * hOut; -CONSOLE_SCREEN_BUFFER_INFO sbi, csbi; -CONSOLE_CURSOR_INFO curinfo; -COORD ccoord, ulcoord; -WORD dattr; -DWORD smode, written; -#endif -PRIVATE_DEFINITION_END(PIConsole) - - -PIConsole::PIConsole(bool startNow, PIKbdListener::KBFunc slot): PIThread() { - setName("console"); - setPriority(piLow); - needLockRun(true); - ret_func = slot; - num_format = systime_format = 0; - vid = 0; - cur_tab = width = height = pwidth = pheight = max_y = 0; - def_align = Nothing; - tabs.reserve(16); -#ifdef WINDOWS - PRIVATE->ulcoord.X = 0; - PRIVATE->hOut = GetStdHandle(STD_OUTPUT_HANDLE); - GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); - PRIVATE->dattr = PRIVATE->sbi.wAttributes; - width = PRIVATE->sbi.srWindow.Right - PRIVATE->sbi.srWindow.Left; - height = PRIVATE->sbi.srWindow.Bottom - PRIVATE->sbi.srWindow.Top; - PRIVATE->ulcoord.Y = PRIVATE->sbi.srWindow.Top; - GetConsoleMode(PRIVATE->hOut, &PRIVATE->smode); - GetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); -#else -# ifdef FREERTOS - width = 80; - height = 24; -# else - winsize ws; - ioctl(0, TIOCGWINSZ, &ws); - width = ws.ws_col; - height = ws.ws_row; -# endif -#endif - addTab("main"); - listener = new PIKbdListener(key_event, this); - peer_timer = new PITimer(); - peer_timer->setName("__S__.PIConsole.peer_timer"); - peer = 0; - server_mode = pause_ = false; - state = Disconnected; - peer_timer->addDelimiter(20); - peer_timer->setName("__S__PIConsole::peer_timer"); - CONNECT2(void, void * , int, peer_timer, tickEvent, this, peerTimer); - if (startNow) start(); -} - - -PIConsole::~PIConsole() { - stopPeer(); - if (isRunning()) - stop(); - clearTabs(false); - delete listener; - delete peer_timer; -#ifdef WINDOWS - SetConsoleMode(PRIVATE->hOut, PRIVATE->smode); - SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); -#endif -} - - -int PIConsole::addTab(const PIString & name, char bind_key) { - if (isRunning()) lock(); - tabs.push_back(Tab(name, bind_key)); - cur_tab = tabs.size() - 1; - if (isRunning()) unlock(); - return tabs.size(); -} - - -void PIConsole::removeTab(uint index) { - if (index >= tabs.size()) return; - if (isRunning()) lock(); - tabs.remove(index); - if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1; - if (isRunning()) unlock(); -} - - -void PIConsole::removeTab(const PIString & name) { - uint index = tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - removeTab(index); -} - - -void PIConsole::clearTab(uint index) { - if (index >= tabs.size()) return; - lock(); - tabs[index].columns.clear(); - if (cur_tab == index) { - clearScreen(); - fillLabels(); - } - if (cur_tab >= tabs.size()) cur_tab = tabs.size() - 1; - unlock(); -} - - -void PIConsole::clearTab(const PIString & name) { - uint index = tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - clearTab(index); -} - - -void PIConsole::update() { - lock(); - fillLabels(); - unlock(); -} - - -bool PIConsole::setTab(uint index) { - if (index >= tabs.size()) - return false; - if (!isRunning()) { - cur_tab = index; - return true; - } - lock(); - PICout::__mutex__().lock(); - cur_tab = index; - clearScreen(); - fillLabels(); - PICout::__mutex__().unlock(); - unlock(); - return true; -} - - -bool PIConsole::setTab(const PIString & name) { - uint index = tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - return setTab(index); -} - - -bool PIConsole::setTabBindKey(uint index, char bind_key) { - if (index >= tabs.size()) - return false; - tabs[index].key = bind_key; - return true; -} - - -bool PIConsole::setTabBindKey(const PIString & name, char bind_key) { - uint index =tabs.size() + 1; - for (uint i = 0; i < tabs.size(); ++i) { - if (tabs[i].name == name) { - index = i; - break; - } - } - return setTabBindKey(index, bind_key); -} - - -void PIConsole::key_event(PIKbdListener::KeyEvent key, void * t) { - PIConsole * p = (PIConsole * )t; - int ct = p->cur_tab; - if (key.key == PIKbdListener::LeftArrow) { - do { - ct--; - if (ct < 0) return; - } while (p->tabs[ct].key == 0); - p->setTab(ct); - return; - } - if (key.key == PIKbdListener::RightArrow) { - do { - ct++; - if (ct >= p->tabs.size_s()) return; - } while (p->tabs[ct].key == 0); - p->setTab(ct); - return; - } - for (uint i = 0; i < p->tabsCount(); ++i) { - if (p->tabs[i].key == key.key) { - p->setTab(i); - return; - } - } - if (p->ret_func != 0) p->ret_func(key, t); - p->keyPressed(key, t); -} - - -int PIConsole::couts(const PIString & v) { - return printf("%s", v.data()); -} - - -int PIConsole::couts(const char * v) { - return printf("%s", v); -} - - -void PIConsole::clearVariables(bool clearScreen) { - if (isRunning()) lock(); - if (clearScreen && isRunning()) { - toUpperLeft(); - clearScreenLower(); - } - columns().clear(); - if (isRunning()) unlock(); -} - - -void PIConsole::stop(bool clear) { - PIThread::stop(true); - if (clear) clearScreen(); - moveTo(0, max_y + 4); - showCursor(); - couts(fstr(Normal)); -#ifdef WINDOWS - SetConsoleMode(PRIVATE->hOut, PRIVATE->smode); - SetConsoleTextAttribute(PRIVATE->hOut, PRIVATE->dattr); -#endif - fflush(0); -} - - -PIString PIConsole::fstr(FormatFlags f) { - num_format = systime_format = 0; - if (f[PIConsole::Dec]) num_format = 0; - if (f[PIConsole::Hex]) num_format = 1; - if (f[PIConsole::Oct]) num_format = 2; - if (f[PIConsole::Bin]) num_format = 4; - if (f[PIConsole::Scientific]) num_format = 3; - if (f[PIConsole::SystemTimeSplit]) systime_format = 0; - if (f[PIConsole::SystemTimeSeconds]) systime_format = 1; - -#ifdef WINDOWS - WORD attr = 0; - - if (f[PIConsole::Inverse]) { - if (f[PIConsole::Red]) attr |= BACKGROUND_RED; - if (f[PIConsole::Green]) attr |= BACKGROUND_GREEN; - if (f[PIConsole::Blue]) attr |= BACKGROUND_BLUE; - if (f[PIConsole::Yellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN); - if (f[PIConsole::Magenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE); - if (f[PIConsole::Cyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE); - if (f[PIConsole::White]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); - if (f[PIConsole::BackRed]) attr |= FOREGROUND_RED; - if (f[PIConsole::BackGreen]) attr |= FOREGROUND_GREEN; - if (f[PIConsole::BackBlue]) attr |= FOREGROUND_BLUE; - if (f[PIConsole::BackYellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN); - if (f[PIConsole::BackMagenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE); - if (f[PIConsole::BackCyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE); - if (f[PIConsole::BackWhite]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - if ((attr & BACKGROUND_RED) + (attr & BACKGROUND_GREEN) + (attr & BACKGROUND_BLUE) == 0) - attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - } else { - if (f[PIConsole::Red]) attr |= FOREGROUND_RED; - if (f[PIConsole::Green]) attr |= FOREGROUND_GREEN; - if (f[PIConsole::Blue]) attr |= FOREGROUND_BLUE; - if (f[PIConsole::Yellow]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN); - if (f[PIConsole::Magenta]) attr |= (FOREGROUND_RED | FOREGROUND_BLUE); - if (f[PIConsole::Cyan]) attr |= (FOREGROUND_GREEN | FOREGROUND_BLUE); - if (f[PIConsole::White]) attr |= (FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE); - if (f[PIConsole::BackRed]) attr |= BACKGROUND_RED; - if (f[PIConsole::BackGreen]) attr |= BACKGROUND_GREEN; - if (f[PIConsole::BackBlue]) attr |= BACKGROUND_BLUE; - if (f[PIConsole::BackYellow]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN); - if (f[PIConsole::BackMagenta]) attr |= (BACKGROUND_RED | BACKGROUND_BLUE); - if (f[PIConsole::BackCyan]) attr |= (BACKGROUND_GREEN | BACKGROUND_BLUE); - if (f[PIConsole::BackWhite]) attr |= (BACKGROUND_RED | BACKGROUND_GREEN | BACKGROUND_BLUE); - if ((attr & FOREGROUND_RED) + (attr & FOREGROUND_GREEN) + (attr & FOREGROUND_BLUE) == 0) - attr |= FOREGROUND_RED | FOREGROUND_GREEN | FOREGROUND_BLUE; - } - if (f[PIConsole::Bold]) attr |= FOREGROUND_INTENSITY; - if (f[PIConsole::Underline]) attr |= COMMON_LVB_UNDERSCORE; - - SetConsoleTextAttribute(PRIVATE->hOut, attr); - return PIString(); -#else - PIString ts("\e[0"); - - if (f[PIConsole::Bold]) ts += ";1"; - if (f[PIConsole::Faint]) ts += ";2"; - if (f[PIConsole::Italic]) ts += ";3"; - if (f[PIConsole::Underline]) ts += ";4"; - if (f[PIConsole::Blink]) ts += ";5"; - if (f[PIConsole::Inverse]) ts += ";7"; - - if (f[PIConsole::Black]) ts += ";30"; - if (f[PIConsole::Red]) ts += ";31"; - if (f[PIConsole::Green]) ts += ";32"; - if (f[PIConsole::Yellow]) ts += ";33"; - if (f[PIConsole::Blue]) ts += ";34"; - if (f[PIConsole::Magenta]) ts += ";35"; - if (f[PIConsole::Cyan]) ts += ";36"; - if (f[PIConsole::White]) ts += ";37"; - - if (f[PIConsole::BackBlack]) ts += ";40"; - if (f[PIConsole::BackRed]) ts += ";41"; - if (f[PIConsole::BackGreen]) ts += ";42"; - if (f[PIConsole::BackYellow]) ts += ";43"; - if (f[PIConsole::BackBlue]) ts += ";44"; - if (f[PIConsole::BackMagenta]) ts += ";45"; - if (f[PIConsole::BackCyan]) ts += ";46"; - if (f[PIConsole::BackWhite]) ts += ";47"; - - return ts + "m"; -#endif -} - - -inline int PIConsole::couts(const bool v) {return (v ? printf("true") : printf("false"));} -inline int PIConsole::couts(const char v) {return printf("%c", v);} -inline int PIConsole::couts(const short v) { - switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hd", v); break;} -} -inline int PIConsole::couts(const int v) { - switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%d", v); break;} -} -inline int PIConsole::couts(const long v) { - switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%ld", v); break;} -} -inline int PIConsole::couts(const llong v) { - switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lld", v); break;} -} -inline int PIConsole::couts(const uchar v) { - switch (num_format) {case (1): return printf("0x%.2X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 1)); break; default: return printf("%u", v); break;} -} -inline int PIConsole::couts(const ushort v) { - switch (num_format) {case (1): return printf("0x%.4hX", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 2)); break; default: return printf("%hu", v); break;} -} -inline int PIConsole::couts(const uint v) { - switch (num_format) {case (1): return printf("0x%.8X", v); break; case (2): return printf("%o", v); break; case (4): return printf("%s", toBin(&v, 4)); break; default: return printf("%u", v); break;} -} -inline int PIConsole::couts(const ulong v) { - switch (num_format) {case (1): return printf("0x%.16lX", v); break; case (2): return printf("%lo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%lu", v); break;} -} -inline int PIConsole::couts(const ullong v) { - switch (num_format) {case (1): return printf("0x%.16llX", v); break; case (2): return printf("%llo", v); break; case (4): return printf("%s", toBin(&v, sizeof(v))); break; default: return printf("%llu", v); break;} -} -inline int PIConsole::couts(const float v) { - switch (num_format) {case (3): return printf("%e", v); break; default: return printf("%.5g", v); break;} -} -inline int PIConsole::couts(const double v) { - switch (num_format) {case (3): return printf("%le", v); break; default: return printf("%.5lg", v); break;} -} -inline int PIConsole::couts(const PISystemTime & v) { - switch (systime_format) {case (1): return printf("%.6lg", v.toSeconds()); break; - default: return couts(v.seconds) + printf(" s, ") + couts(v.nanoseconds) + printf(" ns"); break;} -} - - -void PIConsole::toUpperLeft() { -#ifdef WINDOWS - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ulcoord); -#else - printf("\e[H"); -#endif -} - -void PIConsole::moveRight(int n) { -#ifdef WINDOWS - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->getWinCoord(n)); -#else - if (n > 0) printf("\e[%dC", n); -#endif -} - -void PIConsole::moveLeft(int n) { -#ifdef WINDOWS - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->getWinCoord(-n)); -#else - if (n > 0) printf("\e[%dD", n); -#endif -} - -void PIConsole::moveTo(int x, int y) { -#ifdef WINDOWS - PRIVATE->ccoord.X = x; - PRIVATE->ccoord.Y = PRIVATE->ulcoord.Y + y; - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord); -#else - printf("\e[%d;%dH", y, x); -#endif -} - -void PIConsole::clearScreen() { -#ifdef WINDOWS - couts(fstr(Normal)); - toUpperLeft(); - FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written); - FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width * (height + 1), PRIVATE->ulcoord, &PRIVATE->written); -#else - couts(fstr(Normal)); printf("\e[H\e[J"); -#endif -} - -void PIConsole::clearScreenLower() { -#ifdef WINDOWS - couts(fstr(Normal)); - PRIVATE->getWinCurCoord(); - FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); - FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width * height - width * PRIVATE->ccoord.Y + PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); -#else - couts(fstr(Normal)); printf("\e[J"); -#endif -} - -void PIConsole::clearLine() { -#ifdef WINDOWS - PRIVATE->getWinCurCoord(); - FillConsoleOutputAttribute(PRIVATE->hOut, PRIVATE->dattr, width - PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); - FillConsoleOutputCharacter(PRIVATE->hOut, ' ', width - PRIVATE->ccoord.X, PRIVATE->ccoord, &PRIVATE->written); -#else - printf("\e[K"); -#endif -} - -void PIConsole::newLine() { -#ifdef WINDOWS - PRIVATE->getWinCurCoord(); - PRIVATE->ccoord.X = 0; PRIVATE->ccoord.Y++; - SetConsoleCursorPosition(PRIVATE->hOut, PRIVATE->ccoord); -#else - printf("\eE"); -#endif -} - -void PIConsole::hideCursor() { -#ifdef WINDOWS - PRIVATE->curinfo.bVisible = false; - SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); -#else - printf("\e[?25l"); -#endif -} - -void PIConsole::showCursor() { -#ifdef WINDOWS - PRIVATE->curinfo.bVisible = true; SetConsoleCursorInfo(PRIVATE->hOut, &PRIVATE->curinfo); -#else - printf("\e[?25h"); -#endif -} - - -void PIConsole::begin() { -#ifdef WINDOWS - SetConsoleMode(PRIVATE->hOut, ENABLE_WRAP_AT_EOL_OUTPUT); -#endif - max_y = 0; - PICout::__mutex__().lock(); - clearScreen(); - hideCursor(); - fillLabels(); - PICout::__mutex__().unlock(); -} - - -void PIConsole::run() { - if (pause_) return; - uint cx, clen = 0; - int j; -#ifdef WINDOWS - GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); - width = PRIVATE->sbi.srWindow.Right - PRIVATE->sbi.srWindow.Left; - height = PRIVATE->sbi.srWindow.Bottom - PRIVATE->sbi.srWindow.Top; -#else -# ifdef FREERTOS - width = 80; - height = 24; -# else - winsize ws; - ioctl(0, TIOCGWINSZ, &ws); - width = ws.ws_col; - height = ws.ws_row; -# endif -#endif - //fflush(0); return; - PICout::__mutex__().lock(); - if (pwidth != width || pheight != height) { - clearScreen(); - fillLabels(); - } - pwidth = width; - pheight = height; - col_cnt = columns().size(); - col_wid = (col_cnt > 0) ? width / col_cnt : width; - for (uint i = 0; i < col_cnt; ++i) { - PIVector & cvars(tabs[cur_tab].columns[i].variables); - cx = col_wid * i; - toUpperLeft(); - if (max_y < cvars.size()) max_y = cvars.size(); - j = 0; - piForeachC (Variable & tv_, cvars) { - if (j > height - 3) continue; - j++; - moveRight(cx); - if (tv_.type == 15) { - newLine(); - continue; - } - moveRight(tv_.offset); - const void * ptr = 0; - if (tv_.remote) { - if (tv_.type == 0) { - rstr.clear(); - rba = tv_.rdata; - rba >> rstr; - rstr.trim(); - ptr = &rstr; - } else - ptr = tv_.rdata.data(); - } else - ptr = tv_.ptr; - switch (tv_.type) { - case 0: clen = printValue(ptr != 0 ? *(const PIString*)ptr : PIString(), tv_.format); break; - case 1: clen = printValue(ptr != 0 ? *(const bool*)ptr : false, tv_.format); break; - case 2: clen = printValue(ptr != 0 ? *(const int*)ptr : 0, tv_.format); break; - case 3: clen = printValue(ptr != 0 ? *(const long*)ptr : 0l, tv_.format); break; - case 4: clen = printValue(ptr != 0 ? *(const char*)ptr : char(0), tv_.format); break; - case 5: clen = printValue(ptr != 0 ? *(const float*)ptr : 0.f, tv_.format); break; - case 6: clen = printValue(ptr != 0 ? *(const double*)ptr : 0., tv_.format); break; - case 7: clen = printValue(ptr != 0 ? *(const short*)ptr : short(0), tv_.format); break; - case 8: clen = printValue(ptr != 0 ? *(const uint*)ptr : 0u, tv_.format); break; - case 9: clen = printValue(ptr != 0 ? *(const ulong*)ptr : 0ul, tv_.format); break; - case 10: clen = printValue(ptr != 0 ? *(const ushort*)ptr : ushort(0), tv_.format); break; - case 11: clen = printValue(ptr != 0 ? *(const uchar*)ptr : uchar(0), tv_.format); break; - case 12: clen = printValue(ptr != 0 ? *(const llong*)ptr : 0l, tv_.format); break; - case 13: clen = printValue(ptr != 0 ? *(const ullong*)ptr: 0ull, tv_.format); break; - case 20: clen = printValue(ptr != 0 ? *(const PISystemTime*)ptr: PISystemTime(), tv_.format); break; - case 14: clen = printValue(bitsValue(ptr, tv_.bitFrom, tv_.bitCount), tv_.format); break; - } - if (clen + tv_.offset < (uint)col_wid) { - PIString ts = PIString( - #if defined(QNX) || defined(FREE_BSD) - col_wid - clen - tv_.offset - 1, ' '); -#else - col_wid - clen - tv_.offset, ' '); -#endif - printf("%s", ts.data()); - } - newLine(); - } - } -#ifdef WINDOWS - moveTo(0, max_y + 1); -#else - moveTo(0, max_y + 2); -#endif - fflush(0); - PICout::__mutex__().unlock(); -} - - -void PIConsole::fillLabels() { - if (!isRunning()) return; - uint cx, cy, mx = 0, dx; -#ifdef WINDOWS - GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); - width = PRIVATE->sbi.srWindow.Right - PRIVATE->sbi.srWindow.Left; - height = PRIVATE->sbi.srWindow.Bottom - PRIVATE->sbi.srWindow.Top; -#else -# ifdef FREERTOS - width = 80; - height = 24; -# else - winsize ws; - ioctl(0, TIOCGWINSZ, &ws); - width = ws.ws_col; - height = ws.ws_row; -# endif -#endif - max_y = 0; - col_cnt = columns().size(); - col_wid = (col_cnt > 0) ? width / col_cnt : width; - for (uint i = 0; i < col_cnt; ++i) { - Column & ccol(tabs[cur_tab].columns[i]); - PIVector & cvars(ccol.variables); - if (ccol.alignment != Nothing) { - mx = 0; - piForeachC (Variable & j, cvars) - if (!j.isEmpty()) - if (mx < j.name.size()) - mx = j.name.size(); - mx += 2; - } - cx = col_wid * i; - cy = 1; - toUpperLeft(); - for (uint j = 0; j < cvars.size(); ++j) { - if (int(j) > height - 3) continue; - if (max_y < j) max_y = j; - moveRight(cx); - Variable & tv_(cvars[j]); - cvars[j].nx = cx; - cvars[j].ny = cy; - if (tv_.name.isEmpty()) { - cvars[j].offset = 0; - clearLine(); - newLine(); - cy++; - continue; - } - clearLine(); - //piCout << tv_.name << tv_.type << tv_.ptr; - if (tv_.type == 15) { - cvars[j].offset = cvars[j].name.length(); - cvars[j].nx += cvars[j].offset; - printLine(tv_.name, cx, tv_.format); - newLine(); - cy++; - continue; - } - if (!tv_.isEmpty()) { - switch (ccol.alignment) { - case Nothing: - cvars[j].offset = (tv_.name + ": ").length(); - cvars[j].nx += cvars[j].offset; - printValue(tv_.name + ": ", tv_.format); - break; - case Left: - cvars[j].offset = mx; - cvars[j].nx += cvars[j].offset; - printValue(tv_.name + ": ", tv_.format); - break; - case Right: - cvars[j].offset = mx; - cvars[j].nx += cvars[j].offset; - dx = mx - (tv_.name + ": ").length(); - moveRight(dx); - printValue(tv_.name + ": ", tv_.format); - moveLeft(dx); - break; - } - } - newLine(); - cy++; - } - } -#ifdef WINDOWS - moveTo(0, max_y + 1); -#else - moveTo(0, max_y + 2); -#endif - if (!tabs[cur_tab].status.isEmpty()) { - printValue(tabs[cur_tab].status); - newLine(); - } - status(); -} - - -void PIConsole::status() { - Tab * ctab; - for (uint i = 0; i < tabsCount(); ++i) { - ctab = &tabs[i]; - if (ctab->key == 0) continue; - printValue(ctab->key, PIConsole::White | PIConsole::Bold); - if (i == cur_tab) - printValue(ctab->name + " ", PIConsole::BackYellow | PIConsole::Black); - else - printValue(ctab->name + " ", PIConsole::Cyan | PIConsole::Inverse); - printValue(" "); - } - newLine(); -} - - -int PIConsole::bitsValue(const void * src, int offset, int count) const { - int ret = 0, stbyte = offset / 8, cbit = offset - stbyte * 8; - char cbyte = reinterpret_cast(src)[stbyte]; - for (int i = 0; i < count; i++) { - ret |= ((cbyte >> cbit & 1) << i); - cbit++; - if (cbit == 8) { - cbit = 0; - stbyte++; - cbyte = reinterpret_cast(src)[stbyte]; - } - } - return ret; -} - - -const char * PIConsole::toBin(const void * d, int s) { - binstr.clear(); - uchar cc, b; - for (int i = 0; i < s; ++i) { - cc = ((const uchar *)d)[i]; - b = 1; - for (int j = 0; j < 8; ++j) { - binstr << (cc & b ? "1" : "0"); - b <<= 1; - } - if (i < s - 1) binstr << " "; - } - binstr.reverse(); - return binstr.data(); -} - - -#define ADD_VAR_BODY vid++; tv.id = vid; tv.name = name; tv.bitFrom = tv.bitCount = 0; tv.format = format; tv.remote = false; checkColumn(col); - -void PIConsole::addString(const PIString & name, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 15; tv.size = 0; tv.ptr = 0; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const PIString * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 0; tv.size = 0; tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const bool * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 1; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const int * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 2; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const long * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 3; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const char * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 4; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const float * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 5; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const double * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 6; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const short * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 7; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const uint * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 8; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const ulong * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 9; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const ushort * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 10; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const uchar * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 11; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const llong * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 12; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const ullong * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 13; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -void PIConsole::addVariable(const PIString & name, const PISystemTime * ptr, int col, FormatFlags format) { - ADD_VAR_BODY tv.type = 20; tv.size = sizeof(*ptr); tv.ptr = ptr; column(col).push_back(tv);} -/** \brief Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - * \details This function add to column "column" next lines: - * * " diagnostics" - * * "Received count": \a PIDiagnostics::receiveCount - * * "Invalid count": \a PIDiagnostics::wrongCount - * * "Sended count": \a PIDiagnostics::sendCount - * * "Immediate Frequency, Hz": \a PIDiagnostics::immediateFrequency - * * "Integral Frequency, Hz": \a PIDiagnostics::integralFrequency - * * "Receive speed": \a PIDiagnostics::receiveSpeed - * * "Send speed": \a PIDiagnostics::sendSpeed - * * "Quality": \a PIDiagnostics::quality - * */ -void PIConsole::addVariable(const PIString & name, const PIDiagnostics * ptr, int col, FormatFlags format) { - addString(name + " diagnostics", col, format | PIConsole::Bold); -// addVariable("Received count", ptr->receiveCount_ptr(), col, format); -// addVariable("Invalid count", ptr->wrongCount_ptr(), col, format); -// addVariable("Sended count", ptr->sendCount_ptr(), col, format); -// addVariable("Immediate Frequency, Hz", ptr->immediateFrequency_ptr(), col, format); -// addVariable("Integral Frequency, Hz", ptr->integralFrequency_ptr(), col, format); -// addVariable("Receive speed", ptr->receiveSpeed_ptr(), col, format); -// addVariable("Send speed", ptr->sendSpeed_ptr(), col, format); -// addVariable("Quality", ptr->quality_ptr(), col, format); -} -void PIConsole::addVariable(const PIString & name, const PISystemMonitor * ptr, int col, FormatFlags format) { - addString("monitor " + name, col, format | PIConsole::Bold); - //addVariable("PID", &(ptr->statistic().ID), col, format); - //addVariable("state", &(ptr->statistic().state), col, format); - //addVariable("threads", &(ptr->statistic().threads), col, format); - //addVariable("priority", &(ptr->statistic().priority), col, format); - //addVariable("memory physical", &(ptr->statistic().physical_memsize_readable), col, format); - //addVariable("memory shared", &(ptr->statistic().share_memsize_readable), col, format); - //addVariable("cpu load kernel", &(ptr->statistic().cpu_load_system), col, format); - //addVariable("cpu load user", &(ptr->statistic().cpu_load_user), col, format); -} -void PIConsole::addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitCount, int col, FormatFlags format) { - vid++; tv.id = vid; tv.size = sizeof(ullong); tv.name = name; tv.bitFrom = fromBit; tv.bitCount = bitCount; tv.type = 14; tv.ptr = ptr; tv.format = format; - checkColumn(col); column(col).push_back(tv);} -void PIConsole::addEmptyLine(int col, uint count) { - tv.id = 0; tv.size = 0; tv.name = ""; tv.type = 0; tv.ptr = 0; tv.format = Normal; - for (uint i = 0; i < count; ++i) { - checkColumn(col); - column(col).push_back(tv); - } -} - - -PIString PIConsole::getString(int x, int y) { - bool run = isRunning(); - if (run) PIThread::stop(true); - listener->setActive(false); - msleep(50); -#ifdef WINDOWS - moveTo(x - 1, y - 1); -#else - moveTo(x, y); -#endif - showCursor(); - PIByteArray ba(4096); -#ifdef CC_VC - int ret = scanf_s(" %s", ba.data()); -#else - int ret = scanf(" %s", ba.data()); -#endif - listener->setActive(true); - if (run) start(); - if (ret >= 1) return PIString(ba); - else return PIString(); -} - - -PIString PIConsole::getString(const PIString & name) { - piForeachC (Column & i, tabs[cur_tab].columns) - piForeachC (Variable & j, i.variables) - if (j.name == name) - return getString(j.nx + 1, j.ny); - return PIString(); -} - - -#define PRINT_VAR_BODY couts(fstr(format)); int ret = couts(value); couts(fstr(PIConsole::Dec)); return ret; - -inline void PIConsole::printLine(const PIString & value, int dx, FormatFlags format) { - int i = width - value.length() - dx; -#if defined(QNX) || defined(FREE_BSD) - --i; -#endif - PIString ts = fstr(format); - couts(ts); - if (i >= 0) ts = value + PIString(i, ' '); - else ts = value.left(value.size() + i); - couts(ts); - couts(fstr(Dec)); -} -inline int PIConsole::printValue(const PIString & value, FormatFlags format) { - couts(fstr(format)); - int ret = couts(value); - fstr(PIConsole::Dec); - return ret; -} -inline int PIConsole::printValue(const char * value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const bool value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const int value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const long value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const llong value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const float value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const double value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const char value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const short value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const uchar value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const ushort value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const uint value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const ulong value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const ullong value, FormatFlags format) {PRINT_VAR_BODY} -inline int PIConsole::printValue(const PISystemTime & value, FormatFlags format) {PRINT_VAR_BODY} - - - -void PIConsole::startServer(const PIString & name) { - stopPeer(); - server_mode = true; - peer = new PIPeer("_rcs_:" + name); - CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived); - CONNECT1(void, const PIString & , peer, peerDisconnectedEvent, this, peerDisconnectedEvent); - peer_timer->start(50.); - serverSendInfo(); -} - - -void PIConsole::stopPeer() { - remote_clients.clear(); - peer_timer->stop(); - if (peer != 0) delete peer; - peer = 0; - state = Disconnected; -} - - -PIStringList PIConsole::clients() const { - PIStringList sl; - if (peer == 0) return sl; - piForeachC (PIPeer::PeerInfo & i, peer->allPeers()) { - if (i.name.left(6) != "_rcc_:") continue; - sl << i.name.right(i.name.length() - 6); - } - return sl; -} - - -void PIConsole::listenServers() { - stopPeer(); - server_mode = false; - server_name.clear(); - randomize(); - peer = new PIPeer("_rcc_:" + PIDateTime::current().toString("hhmmssddMMyy_") + PIString::fromNumber(randomi())); - CONNECT2(void, const PIString & , const PIByteArray &, peer, dataReceivedEvent, this, peerReceived); - peer_timer->start(100.); -} - - -PIStringList PIConsole::availableServers() const { - PIStringList sl; - if (peer == 0) return sl; - piForeachC (PIPeer::PeerInfo & i, peer->allPeers()) { - if (i.name.left(6) != "_rcs_:") continue; - sl << i.name.right(i.name.length() - 6); - } - return sl; -} - - -void PIConsole::connectToServer(const PIString & name) { - if (peer == 0) listenServers(); - server_name = name; -} - - -void PIConsole::disconnect() { - stopPeer(); -} - - -void PIConsole::serverSendInfo() { - if (peer == 0) return; - PIByteArray ba; - ba << int(0xAA); - peer->sendToAll(ba); -} - - -void PIConsole::serverSendData() { - if (peer == 0) return; - PIByteArray ba; - PIVector content; - piForeach (Tab & t, tabs) - piForeach (Column & c, t.columns) - piForeach (Variable & v, c.variables) - if (!v.isEmpty() && v.id > 0) { - VariableContent vc; - vc.id = v.id; - v.writeData(vc.rdata); - content << vc; - } - piForeach (RemoteClient & rc, remote_clients) { - ba.clear(); - switch (rc.state) { - case FetchingData: - ba << int(0xCC) << tabs; - //piCout << "server send const data" << rc.name << ba.size_s(); - break; - case Committing: - ba << int(0xDD); - break; - case Connected: - ba << int(0xEE) << content; - //piCout << "send data" << ba.size(); - break; - default: break; - } - if (!ba.isEmpty()) - peer->send(rc.name, ba); - } -} - - -PIConsole::RemoteClient & PIConsole::remoteClient(const PIString & fname) { - piForeach (RemoteClient & i, remote_clients) - if (i.name == fname) - return i; - remote_clients << RemoteClient(fname); - return remote_clients.back(); -} - - -void PIConsole::peerReceived(const PIString & from, const PIByteArray & data) { - int type; - PIByteArray ba(data); - ba >> type; - //piCout << "rec packet from" << from << "type" << PICoutManipulators::Hex << type; - if (server_mode) { - if (from.left(5) != "_rcc_") return; - //PIString rcn = from.right(from.length() - 6); - RemoteClient & rc(remoteClient(from)); - switch (type) { - case 0xBB: // fetch const data request - //piCout << "fetch data request from" << from << rc.state; - if (rc.state != Connected) - rc.state = FetchingData; - break; - case 0xCC: // const data commit - //piCout << "commit from" << from; - if (rc.state != Connected) - rc.state = Connected; - break; - default: break; - } - } else { - PIVector content; - PIMap vids; - if (from.left(5) != "_rcs_") return; - //PIString rcn = from.right(from.length() - 6); - switch (type) { - case 0xAA: // new server - //piCout << "new server" << rcn; - break; - case 0xCC: // const data - //piCout << "received const data"; - state = Committing; - ba >> tabs; - cur_tab = tabs.isEmpty() ? -1 : 0; - piForeach (Tab & t, tabs) - piForeach (Column & c, t.columns) - piForeach (Variable & v, c.variables) - v.remote = true; - break; - case 0xDD: // const data commit - //piCout << "received commit"; - state = Connected; - break; - case 0xEE: // dynamic data - //piCout << "received data" << ba.size_s(); - piForeach (Tab & t, tabs) - piForeach (Column & c, t.columns) - piForeach (Variable & v, c.variables) - if (!v.isEmpty() && v.id > 0) - vids[v.id] = &v; - ba >> content; - piForeach (VariableContent & vc, content) { - if (vc.id <= 0) continue; - Variable * v = vids.at(vc.id); - if (v == 0) continue; - //piCout << "read" << v->name << vc.rdata.size_s(); - v->rdata = vc.rdata; - } - break; - default: break; - } - } -} - - -void PIConsole::peerTimer(void * data, int delim) { - if (peer == 0) return; - //piCout << "timer" << delim; - if (server_mode) { - if (delim == 20) - serverSendInfo(); - else - serverSendData(); - } else { - if (delim != 1 || server_name.isEmpty()) return; - const PIPeer::PeerInfo * p = peer->getPeerByName("_rcs_:" + server_name); - if (p == 0) return; - PIByteArray ba; - switch (state) { - case Disconnected: - peer_tm.reset(); - ba << int(0xBB); - //piCout << "send to" << server_name << "fetch request disc"; - peer->send(p, ba); - state = FetchingData; - break; - case FetchingData: - if (peer_tm.elapsed_s() < 3.) - return; - peer_tm.reset(); - ba << int(0xBB); - //piCout << "send to" << server_name << "fetch request fd"; - peer->send(p, ba); - break; - case Committing: - peer_tm.reset(); - ba << int(0xCC); - //piCout << "send to" << server_name << "committing"; - state = Connected; - peer->send(p, ba); - break; - default: break; - }; - } -} - - -void PIConsole::peerDisconnectedEvent(const PIString & name) { - for (int i = 0; i < remote_clients.size_s(); ++i) - if (remote_clients[i].name == name) { - remote_clients.remove(i); - --i; - } -} diff --git a/lib/main/concurrent/piconditionlock.h b/lib/main/concurrent/piconditionlock.h deleted file mode 100644 index eba7a8a3..00000000 --- a/lib/main/concurrent/piconditionlock.h +++ /dev/null @@ -1,51 +0,0 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 PICONDITIONLOCK_H -#define PICONDITIONLOCK_H - -#include "pibase.h" - - -/** - * @brief Continued - */ -class PIP_EXPORT PIConditionLock { -public: - NO_COPY_CLASS(PIConditionLock) - explicit PIConditionLock(); - ~PIConditionLock(); - - //! \brief lock - void lock(); - - //! \brief unlock - void unlock(); - - //! \brief tryLock - bool tryLock(); - - void * handle(); - -private: - PRIVATE_DECLARATION -}; - - -#endif // PICONDITIONLOCK_H diff --git a/lib/main/console/piconsole.h b/lib/main/console/piconsole.h deleted file mode 100644 index 5e843d1d..00000000 --- a/lib/main/console/piconsole.h +++ /dev/null @@ -1,461 +0,0 @@ -/*! \file piconsole.h - * \brief Console output class -*/ -/* - PIP - Platform Independent Primitives - Console output/input - 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 PICONSOLE_H -#define PICONSOLE_H - -#include "pikbdlistener.h" - -class PIProtocol; -class PIDiagnostics; -class PISystemMonitor; -class PIPeer; -class PITimer; - -class PIP_EXPORT PIConsole: public PIThread -{ - PIOBJECT_SUBCLASS(PIConsole, PIThread) -public: - - //! Constructs %PIConsole with key handler "slot" and if "startNow" start it - explicit PIConsole(bool startNow = true, PIKbdListener::KBFunc slot = 0); - - ~PIConsole(); - - - //! Variables output format - enum Format { - Normal /** Default console format */ = 0x01, - Bold /** Bold text */ = 0x02, - Faint = 0x04, - Italic = 0x08, - Underline /** Underlined text */ = 0x10, - Blink /** Blinked text */ = 0x20, - Inverse /** Swap text and background colors */ = 0x40, - Black /** Black text */ = 0x100, - Red /** Red text */ = 0x200, - Green /** Green text */ = 0x400, - Yellow /** Yellow text */ = 0x800, - Blue /** Blue text */ = 0x1000, - Magenta /** Magenta text */ = 0x2000, - Cyan /** Cyan text */ = 0x4000, - White /** White text */ = 0x8000, - BackBlack /** Black background */ = 0x10000, - BackRed /** Red background */ = 0x20000, - BackGreen /** Green background */ = 0x40000, - BackYellow /** Yellow background */ = 0x80000, - BackBlue /** Blue background */ = 0x100000, - BackMagenta /** Magenta background */ = 0x200000, - BackCyan /** Cyan background */ = 0x400000, - BackWhite /** White background */ = 0x800000, - Dec /** Decimal base for integers */ = 0x1000000, - Hex /** Hexadecimal base for integers */ = 0x2000000, - Oct /** Octal base for integers */ = 0x4000000, - Bin /** Binary base for integers */ = 0x8000000, - Scientific /** Scientific representation of floats */ = 0x10000000, - SystemTimeSplit /** PISystemTime split representation (* s, * ns) */ = 0x20000000, - SystemTimeSeconds /** PISystemTime seconds representation (*.* s) */ = 0x40000000 - }; - - //! Column labels alignment - enum Alignment { - Nothing /** No alignment */ , - Left /** Labels align left and variables align left */ , - Right /** Labels align right and variables align left */ - }; - - typedef PIFlags FormatFlags; - - //! Add to current tab to column "column" string "name" with format "format" - void addString(const PIString & name, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const PIString * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const char * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const bool * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const short * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const int * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const long * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const llong * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const uchar * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const ushort * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const uint * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const ulong * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const ullong * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const float * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const double * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" variable with label "name", pointer "ptr" and format "format" - void addVariable(const PIString & name, const PISystemTime * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - void addVariable(const PIString & name, const PIDiagnostics * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - void addVariable(const PIString & name, const PISystemMonitor * ptr, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" bits field with label "name", pointer "ptr" and format "format" - void addBitVariable(const PIString & name, const void * ptr, int fromBit, int bitsCount, int column = 1, FormatFlags format = PIConsole::Normal); - - //! Add to current tab to column "column" "count" empty lines - void addEmptyLine(int column = 1, uint count = 1); - - PIString getString(int x, int y); - short getShort(int x, int y) {return getString(x, y).toShort();} - int getInt(int x, int y) {return getString(x, y).toInt();} - float getFloat(int x, int y) {return getString(x, y).toFloat();} - double getDouble(int x, int y) {return getString(x, y).toDouble();} - PIString getString(const PIString & name); - short getShort(const PIString & name) {return getString(name).toShort();} - int getInt(const PIString & name) {return getString(name).toInt();} - float getFloat(const PIString & name) {return getString(name).toFloat();} - double getDouble(const PIString & name) {return getString(name).toDouble();} - - - //! Returns tabs count - uint tabsCount() const {return tabs.size();} - - //! Returns current tab name - PIString currentTab() const {return tabs[cur_tab].name;} - - //! Returns current tab index - int currentTabIndex() const {return cur_tab;} - - //! Add new tab with name "name", bind key "bind_key" and returns this tab index - int addTab(const PIString & name, char bind_key = 0); - - //! Remove tab with index "index" - void removeTab(uint index); - - //! Remove tab with name "name" - void removeTab(const PIString & name); - - //! Clear content of tab with index "index" - void clearTab(uint index); - - //! Clear content of tab with name "name" - void clearTab(const PIString & name); - - //! Set current tab to tab with index "index", returns if tab exists - bool setTab(uint index); - - //! Set current tab to tab with name "name", returns if tab exists - bool setTab(const PIString & name); - - //! Set tab with index "index" bind key to "bind_key", returns if tab exists - bool setTabBindKey(uint index, char bind_key); - - //! Set tab with name "name" bind key to "bind_key", returns if tab exists - bool setTabBindKey(const PIString & name, char bind_key); - - //! Remove all tabs and if "clearScreen" clear the screen - void clearTabs(bool clearScreen = true) {if (clearScreen && isRunning()) {toUpperLeft(); clearScreenLower();} tabs.clear();} - - - //! Set custom status text of current tab to "str" - void addCustomStatus(const PIString & str) {tabs[cur_tab].status = str;} - - //! Clear custom status text of current tab - void clearCustomStatus() {tabs[cur_tab].status.clear();} - - //! Returns default alignment - Alignment defaultAlignment() const {return def_align;} - - //! Set default alignment to "align" - void setDefaultAlignment(Alignment align) {def_align = align;} - - //! Set column "col" alignment to "align" - void setColumnAlignment(int col, Alignment align) {if (col < 0 || col >= columns().size_s()) return; column(col).alignment = align;} - - //! Set all columns of all tabs alignment to "align" - void setColumnAlignmentToAll(Alignment align) {piForeach (Tab & i, tabs) piForeach (Column & j, i.columns) j.alignment = align; fillLabels();} - - - //! Directly call function from \a PIKbdListener - void enableExitCapture(char key = 'Q') {listener->enableExitCapture(key);} - - //! Directly call function from \a PIKbdListener - void disableExitCapture() {listener->disableExitCapture();} - - //! Directly call function from \a PIKbdListener - bool exitCaptured() const {return listener->exitCaptured();} - - //! Directly call function from \a PIKbdListener - char exitKey() const {return listener->exitKey();} - - - int windowWidth() const {return width;} - int windowHeight() const {return height;} - - PIString fstr(FormatFlags f); - void update(); - void pause(bool yes) {pause_ = yes;} - - // Server functions - void startServer(const PIString & name); - void stopPeer(); - bool isServerStarted() const {return peer != 0;} - PIStringList clients() const; - - // Client functions - void listenServers(); - PIStringList availableServers() const; - PIString selectedServer() const {return server_name;} - void connectToServer(const PIString & name); - void disconnect(); - bool isConnected() const {return state == Connected;} - - void toUpperLeft(); - void moveRight(int n = 1); - void moveLeft(int n = 1); - void moveTo(int x = 0, int y = 0); - void clearScreen(); - void clearScreenLower(); - void clearLine(); - void newLine(); - void hideCursor(); - void showCursor(); - - EVENT_HANDLER0(void, clearVariables) {clearVariables(true);} - EVENT_HANDLER1(void, clearVariables, bool, clearScreen); - - EVENT_HANDLER0(void, waitForFinish) {WAIT_FOR_EXIT} - EVENT_HANDLER0(void, start) {start(false);} - EVENT_HANDLER1(void, start, bool, wait) {PIThread::start(40); if (wait) waitForFinish();} - EVENT_HANDLER0(void, stop) {stop(false);} - EVENT_HANDLER1(void, stop, bool, clear); - - EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data) - - //! \handlers - //! \{ - - //! \fn void waitForFinish() - //! \brief block until finished (exit key will be pressed) - - //! \fn void clearVariables(bool clearScreen = true) - //! \brief Remove all columns at current tab and if "clearScreen" clear the screen - - //! \fn void start(bool wait = false) - //! \brief Start console output and if "wait" block until finished (exit key will be pressed) - - //! \fn void stop(bool clear = false) - //! \brief Stop console output and if "clear" clear the screen - - //! \} - //! \events - //! \{ - - //! \fn void keyPressed(PIKbdListener::KeyEvent key, void * data) - //! \brief Raise on key "key" pressed, "data" is pointer to %PIConsole object - - //! \} - - private: - void begin(); - void run(); - void fillLabels(); - void status(); - void checkColumn(uint col) {while (columns().size() < col) columns().push_back(Column(def_align));} - int bitsValue(const void * src, int offset, int count) const; - const char * toBin(const void * d, int s); - inline void printLine(const PIString & str, int dx = 0, FormatFlags format = PIConsole::Normal); - inline int printValue(const PIString & str, FormatFlags format = PIConsole::Normal); - inline int printValue(const char * str, FormatFlags format = PIConsole::Normal); - inline int printValue(const bool value, FormatFlags format = PIConsole::Normal); - inline int printValue(const int value, FormatFlags format = PIConsole::Normal); - inline int printValue(const long value, FormatFlags format = PIConsole::Normal); - inline int printValue(const llong value, FormatFlags format = PIConsole::Normal); - inline int printValue(const float value, FormatFlags format = PIConsole::Normal); - inline int printValue(const double value, FormatFlags format = PIConsole::Normal); - inline int printValue(const char value, FormatFlags format = PIConsole::Normal); - inline int printValue(const short value, FormatFlags format = PIConsole::Normal); - inline int printValue(const uchar value, FormatFlags format = PIConsole::Normal); - inline int printValue(const ushort value, FormatFlags format = PIConsole::Normal); - inline int printValue(const uint value, FormatFlags format = PIConsole::Normal); - inline int printValue(const ulong value, FormatFlags format = PIConsole::Normal); - inline int printValue(const ullong value, FormatFlags format = PIConsole::Normal); - inline int printValue(const PISystemTime & value, FormatFlags format = PIConsole::Normal); - static void key_event(PIKbdListener::KeyEvent key, void * t); - - struct Variable { - Variable() {nx = ny = type = offset = bitFrom = bitCount = size = 0; format = Normal; remote = false; ptr = 0; id = 1;} - Variable(const Variable & src) {remote = src.remote; name = src.name; format = src.format; type = src.type; offset = src.offset; size = src.size; - bitFrom = src.bitFrom; bitCount = src.bitCount; ptr = src.ptr; nx = src.nx; ny = src.ny; rdata = src.rdata; id = src.id;} - bool isEmpty() const {return (remote ? false : ptr == 0);} - const void * data() {return (remote ? rdata.data() : ptr);} - void writeData(PIByteArray & ba) { - if (remote) ba << rdata; - else { - if (type == 0) ba << (*(PIString * )ptr); - else ba << PIByteArray::RawData(ptr, size); - } - } - PIString name; - FormatFlags format; - int nx; - int ny; - int type; - int offset; - int bitFrom; - int bitCount; - int size; - int id; - bool remote; - const void * ptr; - PIByteArray rdata; - void operator =(const Variable & src) {remote = src.remote; name = src.name; format = src.format; type = src.type; offset = src.offset; size = src.size; - bitFrom = src.bitFrom; bitCount = src.bitCount; ptr = src.ptr; nx = src.nx; ny = src.ny; rdata = src.rdata; id = src.id;} - }; - - struct VariableContent { - int id; - PIByteArray rdata; - }; - - struct Column { - Column(Alignment align = PIConsole::Right) {variables.reserve(32); alignment = align;} - PIVector variables; - Alignment alignment; - uint size() const {return variables.size();} - Variable & operator [](int index) {return variables[index];} - const Variable & operator [](int index) const {return variables[index];} - void push_back(const Variable & v) {variables.push_back(v);} - void operator =(const Column & src) {variables = src.variables; alignment = src.alignment;} - }; - - struct Tab { - Tab(PIString n = "", char k = 0) {columns.reserve(8); name = n; key = k;} - PIVector columns; - PIString name; - PIString status; - char key; - }; - - enum ConnectedState {Disconnected, FetchingData, Committing, Connected}; - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::VariableContent & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::VariableContent & v); - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Variable & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::Variable & v); - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Column & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::Column & v); - - friend PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Tab & v); - friend PIByteArray & operator >>(PIByteArray & ba, PIConsole::Tab & v); - - PIVector & columns() {return tabs[cur_tab].columns;} - Column & column(int index) {return tabs[cur_tab].columns[index - 1];} - int couts(const PIString & v); - int couts(const char * v); - int couts(const bool v); - int couts(const char v); - int couts(const short v); - int couts(const int v); - int couts(const long v); - int couts(const llong v); - int couts(const uchar v); - int couts(const ushort v); - int couts(const uint v); - int couts(const ulong v); - int couts(const ullong v); - int couts(const float v); - int couts(const double v); - int couts(const PISystemTime & v); - - struct RemoteClient; - - void serverSendInfo(); - void serverSendData(); - RemoteClient & remoteClient(const PIString & fname); - EVENT_HANDLER2(void, peerReceived, const PIString &, from, const PIByteArray &, data); - EVENT_HANDLER2(void, peerTimer, void * , data, int, delim); - EVENT_HANDLER1(void, peerDisconnectedEvent, const PIString &, name); - - PRIVATE_DECLARATION - PIVector tabs; - PIString binstr, rstr; - PIByteArray rba; - Variable tv; - PIKbdListener * listener; - Alignment def_align; - PIKbdListener::KBFunc ret_func; - int width, height, pwidth, pheight, col_wid, num_format, systime_format; - uint max_y; - int vid; - uint cur_tab, col_cnt; - - PIPeer * peer; - PITimer * peer_timer; - PITimeMeasurer peer_tm; - PIString server_name; - bool server_mode, pause_; - ConnectedState state; - - struct RemoteClient { - RemoteClient(const PIString & n = "") {name = n; state = Disconnected;} - PIString name; - ConnectedState state; - }; - - PIVector remote_clients; - -}; - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::VariableContent & v) {ba << v.id << v.rdata; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::VariableContent & v) {ba >> v.id; ba >> v.rdata; return ba;} - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Variable & v) {ba << v.name << v.id << (int)v.format << v.type << v.size << v.bitFrom << v.bitCount; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::Variable & v) {ba >> v.name >> v.id >> (int & )v.format >> v.type >> v.size >> v.bitFrom >> v.bitCount; return ba;} - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Column & v) {ba << (int)v.alignment << v.variables; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::Column & v) {int a; ba >> a >> v.variables; v.alignment = (PIConsole::Alignment)a; return ba;} - -inline PIByteArray & operator <<(PIByteArray & ba, const PIConsole::Tab & v) {ba << v.name << v.status << (uchar)v.key << v.columns; return ba;} -inline PIByteArray & operator >>(PIByteArray & ba, PIConsole::Tab & v) {ba >> v.name >> v.status >> (uchar&)v.key >> v.columns; return ba;} - -#endif // PICONSOLE_H diff --git a/lib/main/console/piconsolemodule.h b/lib/main/console/piconsolemodule.h index d6f24eab..a266884c 100644 --- a/lib/main/console/piconsolemodule.h +++ b/lib/main/console/piconsolemodule.h @@ -21,7 +21,6 @@ #define PICONSOLEMODULE_H #include "pikbdlistener.h" -#include "piconsole.h" #include "piscreen.h" #include "piscreentiles.h" diff --git a/lib/main/containers/pideque.h b/lib/main/containers/pideque.h index d8c8de06..c5e3c1b8 100644 --- a/lib/main/containers/pideque.h +++ b/lib/main/containers/pideque.h @@ -49,6 +49,9 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(pid_size, f); } + inline PIDeque(PIDeque && other): pid_data(0), pid_size(0), pid_rsize(0), pid_start(0) { + swap(other); + } inline virtual ~PIDeque() { //piCout << "~PIDeque"; PIINTROSPECTION_CONTAINER_DELETE(T) @@ -66,6 +69,12 @@ public: return *this; } + inline PIDeque & operator =(PIDeque && other) { + if (this == &other) return *this; + swap(other); + return *this; + } + typedef T value_type; class iterator { @@ -256,6 +265,23 @@ public: elementNew(pid_data + pid_start + index, v); return *this; } + inline PIDeque & insert(size_t index, T && v) { + bool dir = pid_rsize <= 2 ? true : (index >= pid_rsize / 2 ? true : false); + if (dir) { + alloc(pid_size + 1, true); + if (index < pid_size - 1) { + size_t os = pid_size - index - 1; + memmove((void*)(&(pid_data[index + pid_start + 1])), (const void*)(&(pid_data[index + pid_start])), os * sizeof(T)); + } + } else { + alloc(pid_size + 1, false, -1); + if (index > 0) + memmove((void*)(&(pid_data[pid_start])), (const void*)(&(pid_data[pid_start + 1])), index * sizeof(T)); + } + PIINTROSPECTION_CONTAINER_USED(T, 1) + elementNew(pid_data + pid_start + index, v); + return *this; + } inline PIDeque & insert(size_t index, const PIDeque & other) { if (other.isEmpty()) return *this; assert(&other != this); @@ -336,7 +362,14 @@ public: elementNew(pid_data + pid_start + pid_size - 1, v); return *this; } + inline PIDeque & push_back(T && v) { + alloc(pid_size + 1, true); + PIINTROSPECTION_CONTAINER_USED(T, 1); + elementNew(pid_data + pid_start + pid_size - 1, v); + return *this; + } inline PIDeque & append(const T & v) {return push_back(v);} + inline PIDeque & append(T && v) {return push_back(v);} inline PIDeque & append(const PIDeque & t) { assert(&t != this); size_t ps = pid_size; @@ -345,6 +378,7 @@ public: return *this; } inline PIDeque & operator <<(const T & v) {return push_back(v);} + inline PIDeque & operator <<(T && v) {return push_back(v);} inline PIDeque & operator <<(const PIDeque & t) {return append(t);} inline PIDeque & push_front(const T & v) {insert(0, v); return *this;} @@ -412,6 +446,7 @@ private: } } inline void elementNew(T * to, const T & from) {new(to)T(from);} + inline void elementNew(T * to, T && from) {piSwap(*to, from);} inline void elementDelete(T & from) {from.~T();} inline void dealloc() { if ((uchar*)pid_data != 0) free((uchar*)pid_data); @@ -485,6 +520,7 @@ private: template<> inline void PIDeque::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIDeque::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIDeque::elementNew(T * to, const T & from) {(*to) = from;} \ + template<> inline void PIDeque::elementNew(T * to, T && from) {(*to) = from;} \ template<> inline void PIDeque::elementDelete(T &) {;} \ template<> inline PIDeque & PIDeque::_resizeRaw(size_t new_size) { \ if (new_size > pid_size) { \ diff --git a/lib/main/containers/pimap.h b/lib/main/containers/pimap.h index f397a09f..6939eb53 100644 --- a/lib/main/containers/pimap.h +++ b/lib/main/containers/pimap.h @@ -74,6 +74,7 @@ class PIMap { public: PIMap() {;} PIMap(const PIMap & other) {*this = other;} + PIMap(PIMap && other) {swap(other);} virtual ~PIMap() {;} PIMap & operator =(const PIMap & other) { @@ -84,6 +85,12 @@ public: return *this; } + PIMap & operator =(PIMap && other) { + if (this == &other) return *this; + swap(other); + return *this; + } + typedef T mapped_type; typedef Key key_type; typedef PIPair value_type; diff --git a/lib/main/containers/pivector.h b/lib/main/containers/pivector.h index d943af3d..1ea45b15 100644 --- a/lib/main/containers/pivector.h +++ b/lib/main/containers/pivector.h @@ -48,6 +48,9 @@ public: PIINTROSPECTION_CONTAINER_NEW(T, sizeof(T)) resize(piv_size, f); } + inline PIVector(PIVector && other): piv_data(0), piv_size(0), piv_rsize(0) { + swap(other); + } inline virtual ~PIVector() { PIINTROSPECTION_CONTAINER_DELETE(T) PIINTROSPECTION_CONTAINER_FREE(T, (piv_rsize)) @@ -65,6 +68,12 @@ public: return *this; } + inline PIVector & operator =(PIVector && other) { + if (this == &other) return *this; + swap(other); + return *this; + } + typedef T value_type; class iterator { @@ -253,6 +262,16 @@ public: elementNew(piv_data + index, v); return *this; } + inline PIVector & insert(size_t index, T && v) { + alloc(piv_size + 1); + if (index < piv_size - 1) { + size_t os = piv_size - index - 1; + memmove((void*)(&(piv_data[index + 1])), (const void*)(&(piv_data[index])), os * sizeof(T)); + } + PIINTROSPECTION_CONTAINER_USED(T, 1) + elementNew(piv_data + index, v); + return *this; + } inline PIVector & insert(size_t index, const PIVector & other) { if (other.isEmpty()) return *this; assert(&other != this); @@ -320,7 +339,14 @@ public: elementNew(piv_data + piv_size - 1, v); return *this; } + inline PIVector & push_back(T && v) { + alloc(piv_size + 1); + PIINTROSPECTION_CONTAINER_USED(T, 1); + elementNew(piv_data + piv_size - 1, v); + return *this; + } inline PIVector & append(const T & v) {return push_back(v);} + inline PIVector & append(T && v) {return push_back(v);} inline PIVector & append(const PIVector & other) { assert(&other != this); size_t ps = piv_size; @@ -329,6 +355,7 @@ public: return *this; } inline PIVector & operator <<(const T & v) {return push_back(v);} + inline PIVector & operator <<(T && v) {return push_back(v);} inline PIVector & operator <<(const PIVector & other) {return append(other);} inline PIVector & push_front(const T & v) {insert(0, v); return *this;} @@ -405,6 +432,7 @@ private: } } inline void elementNew(T * to, const T & from) {new(to)T(from);} + inline void elementNew(T * to, T && from) {piSwap(*to, from);} inline void elementDelete(T & from) {from.~T();} inline void dealloc() { if ((uchar*)piv_data != 0) free((uchar*)piv_data); @@ -434,6 +462,7 @@ private: template<> inline void PIVector::newT(T * dst, const T * src, size_t s) {PIINTROSPECTION_CONTAINER_USED(T, s); memcpy((void*)(dst), (const void*)(src), s * sizeof(T));} \ template<> inline void PIVector::deleteT(T *, size_t sz) {PIINTROSPECTION_CONTAINER_UNUSED(T, sz);} \ template<> inline void PIVector::elementNew(T * to, const T & from) {(*to) = from;} \ + template<> inline void PIVector::elementNew(T * to, T && from) {(*to) = from;} \ template<> inline void PIVector::elementDelete(T &) {;} \ template<> inline PIVector & PIVector::_resizeRaw(size_t new_size) { \ if (new_size > piv_size) { \ diff --git a/lib/main/core/picout.cpp b/lib/main/core/picout.cpp index c20cf82f..ff37a625 100644 --- a/lib/main/core/picout.cpp +++ b/lib/main/core/picout.cpp @@ -18,9 +18,9 @@ */ #include "piincludes_p.h" #include "picout.h" -#include "piconsole.h" #include "pibytearray.h" #include "pistack.h" +#include "piobject.h" #include "pistring_std.h" #ifdef WINDOWS # include diff --git a/lib/main/core/piincludes.cpp b/lib/main/core/piincludes.cpp index 5600257c..6b480a21 100644 --- a/lib/main/core/piincludes.cpp +++ b/lib/main/core/piincludes.cpp @@ -19,7 +19,6 @@ #include "piincludes.h" #include "piincludes_p.h" -#include "piconsole.h" #include "pitime.h" #ifndef QNX # include diff --git a/lib/main/core/piincludes.h b/lib/main/core/piincludes.h index 1027228f..7d74775e 100644 --- a/lib/main/core/piincludes.h +++ b/lib/main/core/piincludes.h @@ -27,10 +27,9 @@ # include #endif #include -#include -typedef std::mutex PIMutex; -//typedef std::lock_guard PIMutexLocker; +class PIMutex; +class PIMutexLocker; class PIObject; class PIString; class PIByteArray; diff --git a/lib/main/core/pistring.h b/lib/main/core/pistring.h index e7affb17..00c87197 100644 --- a/lib/main/core/pistring.h +++ b/lib/main/core/pistring.h @@ -51,6 +51,8 @@ public: PIString(const PIString & o): PIDeque() {*this += o;} + PIString(PIString && o): PIDeque() {swap(o);} + //! Contructs string with single symbol "c" PIString(const PIChar & c): PIDeque() {*this += c;} @@ -89,6 +91,8 @@ public: PIString & operator =(const PIString & o) {if (this == &o) return *this; clear(); *this += o; return *this;} + PIString & operator =(PIString && o) {if (this == &o) return *this; swap(o); return *this;} + /*! \brief Return c-string representation of string * \details Converts content of string to c-string and return * pointer to first char. This buffer is valid until new convertion diff --git a/lib/main/core/pistringlist.h b/lib/main/core/pistringlist.h index 0a9669f0..6e81f034 100644 --- a/lib/main/core/pistringlist.h +++ b/lib/main/core/pistringlist.h @@ -83,6 +83,7 @@ public: PIStringList & operator =(const PIStringList & o) {PIDeque::operator=(o); return *this;} PIStringList & operator <<(const PIString & str) {append(str); return *this;} + PIStringList & operator <<(PIString && str) {append(str); return *this;} PIStringList & operator <<(const PIStringList & sl) {append(sl); return *this;} }; diff --git a/lib/main/system/picodec.cpp b/lib/main/system/picodec.cpp deleted file mode 100644 index 235d2ad6..00000000 --- a/lib/main/system/picodec.cpp +++ /dev/null @@ -1,45 +0,0 @@ -/* - PIP - Platform Independent Primitives - Text codings coder, based on "iconv" - 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 PIP_FREERTOS - -#include "picodec.h" - - -PIStringList PICodec::availableCodecs() { - exec("/usr/bin/iconv", "-l"); - waitForFinish(); - PIString str(readOutput()); - str.cutLeft(str.find("\n ")); - str.replaceAll("\n", ""); - return str.split("//"); -} - - -PIByteArray PICodec::exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str) { - tf.openTemporary(PIIODevice::ReadWrite); - tf.clear(); - tf << str; - tf.close(); - exec("/usr/bin/iconv", PIStringList() << ("-f=" + from) << ("-t=" + to) << tf.path()); - waitForFinish(); - return readOutput(); -} - -#endif // PIP_FREERTOS diff --git a/lib/main/system/picodec.h b/lib/main/system/picodec.h deleted file mode 100644 index 67a88941..00000000 --- a/lib/main/system/picodec.h +++ /dev/null @@ -1,54 +0,0 @@ -/* - PIP - Platform Independent Primitives - Text codings coder, based on "iconv" - 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 PICODEC_H -#define PICODEC_H - -#ifndef PIP_FREERTOS - -#include "piprocess.h" - -class PIP_EXPORT PICodec: protected PIProcess -{ - PIOBJECT(PICodec) -public: - PICodec(): PIProcess() {setGrabOutput(true);} - PICodec(const PIString & from, const PIString & to): PIProcess() {setCodings(from, to);} - ~PICodec() {tf.remove();} - - void setFromCoding(const PIString & from) {c_from = from;} - void setToCoding(const PIString & to) {c_to = to;} - void setCodings(const PIString & from, const PIString & to) {c_from = from; c_to = to;} - - PIStringList availableCodecs(); - PIString encode(PIString & str) {return PIString(exec_iconv(c_from, c_to, str.toByteArray()));} - PIString encode(const PIByteArray & str) {return PIString(exec_iconv(c_from, c_to, str));} - PIString decode(PIString & str) {return PIString(exec_iconv(c_to, c_from, str.toByteArray()));} - PIString decode(const PIByteArray & str) {return PIString(exec_iconv(c_to, c_from, str));} - -private: - PIByteArray exec_iconv(const PIString & from, const PIString & to, const PIByteArray & str); - - PIString c_from, c_to; - PIFile tf; - -}; - -#endif // PIP_FREERTOS -#endif // PICODEC_H diff --git a/lib/main/system/pisystemmodule.h b/lib/main/system/pisystemmodule.h index f550868f..a75662c4 100644 --- a/lib/main/system/pisystemmodule.h +++ b/lib/main/system/pisystemmodule.h @@ -20,7 +20,6 @@ #ifndef PISYSTEMMODULE_H #define PISYSTEMMODULE_H -#include "picodec.h" #include "pisignals.h" #include "pilibrary.h" #include "pisysteminfo.h" diff --git a/lib/main/concurrent/piblockingdequeue.h b/lib/main/thread/piblockingdequeue.h similarity index 93% rename from lib/main/concurrent/piblockingdequeue.h rename to lib/main/thread/piblockingdequeue.h index 5f64da06..fe8f5a1f 100644 --- a/lib/main/concurrent/piblockingdequeue.h +++ b/lib/main/thread/piblockingdequeue.h @@ -17,8 +17,8 @@ along with this program. If not, see . */ -#ifndef PIP_TESTS_PIBLOCKINGDEQUEUE_H -#define PIP_TESTS_PIBLOCKINGDEQUEUE_H +#ifndef PIBLOCKINGDEQUEUE_H +#define PIBLOCKINGDEQUEUE_H #include "pideque.h" #include "piconditionvar.h" @@ -140,14 +140,14 @@ public: * return value is retrieved value * @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available */ - T poll(int timeoutMs, const T & defaultVal = T(), bool* isOk = nullptr) { + T poll(int timeoutMs, const T & defaultVal = T(), bool * isOk = nullptr) { T t; mutex.lock(); bool isNotEmpty = cond_var_add->waitFor(mutex, timeoutMs, [&]() { return !PIDeque::isEmpty(); }); t = isNotEmpty ? T(PIDeque::take_front()) : defaultVal; mutex.unlock(); if (isNotEmpty) cond_var_rem->notifyOne(); - if (isOk != nullptr) *isOk = isNotEmpty; + if (isOk) *isOk = isNotEmpty; return t; } @@ -160,14 +160,14 @@ public: * return value is retrieved value * @return the head of this queue, or defaultVal if the specified waiting time elapses before an element is available */ - T poll(const T & defaultVal = T(), bool* isOk = nullptr) { + T poll(const T & defaultVal = T(), bool * isOk = nullptr) { T t; mutex.lock(); bool isNotEmpty = !PIDeque::isEmpty(); t = isNotEmpty ? T(PIDeque::take_front()) : defaultVal; mutex.unlock(); if (isNotEmpty) cond_var_rem->notifyOne(); - if (isOk != nullptr) *isOk = isNotEmpty; + if (isOk) *isOk = isNotEmpty; return t; } @@ -213,7 +213,7 @@ public: */ size_t drainTo(PIDeque& other, size_t maxCount = SIZE_MAX) { mutex.lock(); - size_t count = maxCount > PIDeque::size() ? PIDeque::size() : maxCount; + size_t count = ((maxCount > PIDeque::size()) ? PIDeque::size() : maxCount); for (size_t i = 0; i < count; ++i) other.push_back(PIDeque::take_front()); mutex.unlock(); return count; @@ -235,11 +235,11 @@ public: } private: - PIConditionLock mutex; - PIConditionVariable* cond_var_add; - PIConditionVariable* cond_var_rem; + PIMutex mutex; + PIConditionVariable * cond_var_add, * cond_var_rem; size_t max_size; + }; -#endif //PIP_TESTS_PIBLOCKINGDEQUEUE_H +#endif // PIBLOCKINGDEQUEUE_H diff --git a/lib/concurrent/piconditionvar.cpp b/lib/main/thread/piconditionvar.cpp similarity index 87% rename from lib/concurrent/piconditionvar.cpp rename to lib/main/thread/piconditionvar.cpp index 5f3fac3a..395f53f6 100644 --- a/lib/concurrent/piconditionvar.cpp +++ b/lib/main/thread/piconditionvar.cpp @@ -1,141 +1,141 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 . -*/ - -#include "piconditionvar.h" -#include "pithread.h" -#include "pitime.h" - -#ifdef WINDOWS -# undef _WIN32_WINNT -# define _WIN32_WINNT 0x0600 -# include -# include -# include -#endif - - -PRIVATE_DEFINITION_START(PIConditionVariable) -#ifdef WINDOWS - CONDITION_VARIABLE nativeHandle; -#else - pthread_cond_t nativeHandle; - PIConditionLock* currentLock; -#endif - bool isDestroying; -PRIVATE_DEFINITION_END(PIConditionVariable) - - -PIConditionVariable::PIConditionVariable() { -#ifdef WINDOWS - InitializeConditionVariable(&PRIVATE->nativeHandle); -#else - PRIVATE->isDestroying = false; - PRIVATE->currentLock = nullptr; - memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); - pthread_cond_init(&PRIVATE->nativeHandle, NULL); -#endif -} - - -PIConditionVariable::~PIConditionVariable() { -#ifdef WINDOWS -#else - pthread_cond_destroy(&PRIVATE->nativeHandle); -#endif -} - - -void PIConditionVariable::wait(PIConditionLock& lk) { -#ifdef WINDOWS - SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); -#else - pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); -#endif -} - - -void PIConditionVariable::wait(PIConditionLock& lk, const std::function& condition) { - bool isCondition; - while (true) { - isCondition = condition(); - if (isCondition) break; -#ifdef WINDOWS - SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); -#else - pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); -#endif - if (PRIVATE->isDestroying) return; - } -} - - -bool PIConditionVariable::waitFor(PIConditionLock &lk, int timeoutMs) { - bool isNotTimeout; -#ifdef WINDOWS - isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; -#else - timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs * 1000 * 1000}; - isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; -#endif - if (PRIVATE->isDestroying) return false; - return isNotTimeout; -} - - -bool PIConditionVariable::waitFor(PIConditionLock& lk, int timeoutMs, const std::function &condition) { - bool isCondition; - PITimeMeasurer measurer; - while (true) { - isCondition = condition(); - if (isCondition) break; -#ifdef WINDOWS - WINBOOL isTimeout = SleepConditionVariableCS( - &PRIVATE->nativeHandle, - (PCRITICAL_SECTION)lk.handle(), - timeoutMs - (int)measurer.elapsed_m()); - if (isTimeout == 0) return false; -#else - int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); - timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr * 1000 * 1000}; - bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; - if (isTimeout) return false; -#endif - if (PRIVATE->isDestroying) return false; - } - return true; -} - - -void PIConditionVariable::notifyOne() { -#ifdef WINDOWS - WakeConditionVariable(&PRIVATE->nativeHandle); -#else - pthread_cond_signal(&PRIVATE->nativeHandle); -#endif -} - - -void PIConditionVariable::notifyAll() { -#ifdef WINDOWS - WakeAllConditionVariable(&PRIVATE->nativeHandle); -#else - pthread_cond_broadcast(&PRIVATE->nativeHandle); -#endif -} - +/* + PIP - Platform Independent Primitives + + Stephan Fomenko + + 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 . +*/ + +#include "piconditionvar.h" +#include "pithread.h" +#include "pitime.h" + +#ifdef WINDOWS +# undef _WIN32_WINNT +# define _WIN32_WINNT 0x0600 +# include +# include +# include +#endif + + +PRIVATE_DEFINITION_START(PIConditionVariable) +#ifdef WINDOWS + CONDITION_VARIABLE nativeHandle; +#else + pthread_cond_t nativeHandle; + PIMutex * currentLock; +#endif + bool isDestroying; +PRIVATE_DEFINITION_END(PIConditionVariable) + + +PIConditionVariable::PIConditionVariable() { +#ifdef WINDOWS + InitializeConditionVariable(&PRIVATE->nativeHandle); +#else + PRIVATE->isDestroying = false; + PRIVATE->currentLock = nullptr; + memset(&(PRIVATE->nativeHandle), 0, sizeof(PRIVATE->nativeHandle)); + pthread_cond_init(&PRIVATE->nativeHandle, NULL); +#endif +} + + +PIConditionVariable::~PIConditionVariable() { +#ifdef WINDOWS +#else + pthread_cond_destroy(&PRIVATE->nativeHandle); +#endif +} + + +void PIConditionVariable::wait(PIMutex& lk) { +#ifdef WINDOWS + SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); +#else + pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); +#endif +} + + +void PIConditionVariable::wait(PIMutex& lk, const std::function& condition) { + bool isCondition; + while (true) { + isCondition = condition(); + if (isCondition) break; +#ifdef WINDOWS + SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), INFINITE); +#else + pthread_cond_wait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle()); +#endif + if (PRIVATE->isDestroying) return; + } +} + + +bool PIConditionVariable::waitFor(PIMutex &lk, int timeoutMs) { + bool isNotTimeout; +#ifdef WINDOWS + isNotTimeout = SleepConditionVariableCS(&PRIVATE->nativeHandle, (PCRITICAL_SECTION)lk.handle(), timeoutMs) != 0; +#else + timespec abstime = {.tv_sec = timeoutMs / 1000, .tv_nsec = timeoutMs * 1000 * 1000}; + isNotTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; +#endif + if (PRIVATE->isDestroying) return false; + return isNotTimeout; +} + + +bool PIConditionVariable::waitFor(PIMutex& lk, int timeoutMs, const std::function &condition) { + bool isCondition; + PITimeMeasurer measurer; + while (true) { + isCondition = condition(); + if (isCondition) break; +#ifdef WINDOWS + WINBOOL isTimeout = SleepConditionVariableCS( + &PRIVATE->nativeHandle, + (PCRITICAL_SECTION)lk.handle(), + timeoutMs - (int)measurer.elapsed_m()); + if (isTimeout == 0) return false; +#else + int timeoutCurr = timeoutMs - (int)measurer.elapsed_m(); + timespec abstime = {.tv_sec = timeoutCurr / 1000, .tv_nsec = timeoutCurr * 1000 * 1000}; + bool isTimeout = pthread_cond_timedwait(&PRIVATE->nativeHandle, (pthread_mutex_t*)lk.handle(), &abstime) == 0; + if (isTimeout) return false; +#endif + if (PRIVATE->isDestroying) return false; + } + return true; +} + + +void PIConditionVariable::notifyOne() { +#ifdef WINDOWS + WakeConditionVariable(&PRIVATE->nativeHandle); +#else + pthread_cond_signal(&PRIVATE->nativeHandle); +#endif +} + + +void PIConditionVariable::notifyAll() { +#ifdef WINDOWS + WakeAllConditionVariable(&PRIVATE->nativeHandle); +#else + pthread_cond_broadcast(&PRIVATE->nativeHandle); +#endif +} + diff --git a/lib/main/concurrent/piconditionvar.h b/lib/main/thread/piconditionvar.h similarity index 83% rename from lib/main/concurrent/piconditionvar.h rename to lib/main/thread/piconditionvar.h index 4d011187..923e2ba7 100644 --- a/lib/main/concurrent/piconditionvar.h +++ b/lib/main/thread/piconditionvar.h @@ -20,14 +20,13 @@ #ifndef PICONDITIONVAR_H #define PICONDITIONVAR_H -#include "piconditionlock.h" #include "pithread.h" /** * @brief A condition variable is an object able to block the calling thread until notified to resume. * - * It uses a PIConditionLock to lock the thread when one of its wait functions is called. The thread remains + * It uses a PIMutex to lock the thread when one of its wait functions is called. The thread remains * blocked until woken up by another thread that calls a notification function on the same PIConditionVariable object. */ class PIP_EXPORT PIConditionVariable { @@ -49,20 +48,20 @@ public: void notifyAll(); /** - * @brief see wait(PIConditionLock&, const std::function&) + * @brief see wait(PIMutex &, const std::function&) */ - virtual void wait(PIConditionLock& lk); + virtual void wait(PIMutex & lk); /** * @brief Wait until notified * - * The execution of the current thread (which shall have locked with lk method PIConditionLock::lock()) is blocked + * The execution of the current thread (which shall have locked with lk method PIMutex::lock()) is blocked * until notified. * - * At the moment of blocking the thread, the function automatically calls lk.unlock() (PIConditionLock::unlock()), + * At the moment of blocking the thread, the function automatically calls lk.unlock() (PIMutex::unlock()), * allowing other locked threads to continue. * - * Once notified (explicitly, by some other thread), the function unblocks and calls lk.lock() (PIConditionLock::lock()), + * Once notified (explicitly, by some other thread), the function unblocks and calls lk.lock() (PIMutex::lock()), * leaving lk in the same state as when the function was called. Then the function returns (notice that this last mutex * locking may block again the thread before returning). * @@ -77,23 +76,23 @@ public: * @param condition A callable object or function that takes no arguments and returns a value that can be evaluated * as a bool. This is called repeatedly until it evaluates to true. */ - virtual void wait(PIConditionLock& lk, const std::function& condition); + virtual void wait(PIMutex& lk, const std::function& condition); /** - * @brief see waitFor(PIConditionLock&, int, const std::function&) + * @brief see waitFor(PIMutex &, int, const std::function&) */ - virtual bool waitFor(PIConditionLock& lk, int timeoutMs); + virtual bool waitFor(PIMutex & lk, int timeoutMs); /** * @brief Wait for timeout or until notified * - * The execution of the current thread (which shall have locked with lk method PIConditionLock::lock()) is blocked + * The execution of the current thread (which shall have locked with lk method PIMutex::lock()) is blocked * during timeoutMs, or until notified (if the latter happens first). * - * At the moment of blocking the thread, the function automatically calls lk.lock() (PIConditionLock::lock()), allowing + * At the moment of blocking the thread, the function automatically calls lk.lock() (PIMutex::lock()), allowing * other locked threads to continue. * - * Once notified or once timeoutMs has passed, the function unblocks and calls lk.unlock() (PIConditionLock::unlock()), + * Once notified or once timeoutMs has passed, the function unblocks and calls lk.unlock() (PIMutex::unlock()), * leaving lk in the same state as when the function was called. Then the function returns (notice that this last * mutex locking may block again the thread before returning). * @@ -109,7 +108,7 @@ public: * as a bool. This is called repeatedly until it evaluates to true. * @return false if timeout reached or true if wakeup condition is true */ - virtual bool waitFor(PIConditionLock& lk, int timeoutMs, const std::function& condition); + virtual bool waitFor(PIMutex& lk, int timeoutMs, const std::function& condition); private: PRIVATE_DECLARATION diff --git a/lib/main/thread/pimutex.cpp b/lib/main/thread/pimutex.cpp new file mode 100644 index 00000000..2c0a97b2 --- /dev/null +++ b/lib/main/thread/pimutex.cpp @@ -0,0 +1,122 @@ +/* + PIP - Platform Independent Primitives + Mutex + Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@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 . +*/ + +/** \class PIMutex + * \brief Mutex + * \details + * \section PIMutex_sec0 Synopsis + * %PIMutex provides synchronization blocks between several threads. + * Using mutex guarantees execution of some code only one of threads. + * Mutex contains logic state and functions to change it: \a lock(), + * \a unlock() and \a tryLock(). + * + * \section PIMutex_sec1 Usage + * Block of code that should to be executed only one thread simultaniously + * should to be started with \a lock() and ended with \a unlock(). + * \snippet pimutex.cpp main + * "mutex" in this example is one for all threads. + * + * */ + +#include "pimutex.h" +#include "piincludes_p.h" +#ifdef WINDOWS +# include +#else +# include +#endif + + + +PRIVATE_DEFINITION_START(PIMutex) +#ifdef WINDOWS + CRITICAL_SECTION +#else + pthread_mutex_t +#endif + mutex; +PRIVATE_DEFINITION_END(PIMutex) + + +PIMutex::PIMutex() { + init(); +} + + +PIMutex::~PIMutex() { + destroy(); +} + + +void PIMutex::lock() { +#ifdef WINDOWS + EnterCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutex_lock(&(PRIVATE->mutex)); +#endif +} + + +void PIMutex::unlock() { +#ifdef WINDOWS + LeaveCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutex_unlock(&(PRIVATE->mutex)); +#endif +} + + +bool PIMutex::tryLock() { + bool ret = +#ifdef WINDOWS + (TryEnterCriticalSection(&(PRIVATE->mutex)) != 0); +#else + (pthread_mutex_trylock(&(PRIVATE->mutex)) == 0); +#endif + return ret; +} + + +void * PIMutex::handle() { + return (void*)&(PRIVATE->mutex); +} + + +void PIMutex::init() { +#ifdef WINDOWS + InitializeCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutexattr_t attr; + memset(&attr, 0, sizeof(attr)); + pthread_mutexattr_init(&attr); + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_NORMAL); + memset(&(PRIVATE->mutex), 0, sizeof(PRIVATE->mutex)); + pthread_mutex_init(&(PRIVATE->mutex), &attr); + pthread_mutexattr_destroy(&attr); +#endif +} + + +void PIMutex::destroy() { +#ifdef WINDOWS + DeleteCriticalSection(&(PRIVATE->mutex)); +#else + pthread_mutex_destroy(&(PRIVATE->mutex)); +#endif +} diff --git a/lib/main/thread/pimutex.h b/lib/main/thread/pimutex.h index 02892916..b71b1600 100644 --- a/lib/main/thread/pimutex.h +++ b/lib/main/thread/pimutex.h @@ -4,7 +4,7 @@ /* PIP - Platform Independent Primitives PIMutexLocker - Ivan Pelipenko peri4ko@yandex.ru, Andrey Bychkov work.a.b@yandex.ru + Ivan Pelipenko peri4ko@yandex.ru, Stephan Fomenko, Andrey Bychkov work.a.b@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 @@ -24,6 +24,45 @@ #define PIMUTEX_H #include "piinit.h" +#include + + +class PIP_EXPORT PIMutex +{ +public: + NO_COPY_CLASS(PIMutex) + + //! Constructs unlocked mutex + explicit PIMutex(); + + //! Destroy mutex + ~PIMutex(); + + + //! \brief Lock mutex + //! \details If mutex is unlocked it set to locked state and returns immediate. + //! If mutex is already locked function blocks until mutex will be unlocked + void lock(); + + //! \brief Unlock mutex + //! \details In any case this function returns immediate + void unlock() ; + + //! \brief Try to lock mutex + //! \details If mutex is unlocked it set to locked state and returns "true" immediate. + //! If mutex is already locked function returns immediate an returns "false" + bool tryLock(); + + void * handle(); + +private: + void init(); + void destroy(); + + PRIVATE_DECLARATION + +}; + //! \brief PIMutexLocker //! \details Same as std::lock_guard. @@ -40,7 +79,7 @@ public: ~PIMutexLocker() {if (cond) mutex.unlock();} private: PIMutex & mutex; - std::atomic_bool cond; + bool cond; }; #endif // PIMUTEX_H diff --git a/lib/main/thread/pithreadmodule.h b/lib/main/thread/pithreadmodule.h index e0d97bcb..5973dfe4 100644 --- a/lib/main/thread/pithreadmodule.h +++ b/lib/main/thread/pithreadmodule.h @@ -25,5 +25,7 @@ #include "pitimer.h" #include "pipipelinethread.h" #include "pigrabberbase.h" +#include "pithreadpoolexecutor.h" +#include "piconditionvar.h" #endif // PITHREADMODULE_H diff --git a/lib/concurrent/executor.cpp b/lib/main/thread/pithreadpoolexecutor.cpp similarity index 71% rename from lib/concurrent/executor.cpp rename to lib/main/thread/pithreadpoolexecutor.cpp index a1c80042..d0feeb83 100644 --- a/lib/concurrent/executor.cpp +++ b/lib/main/thread/pithreadpoolexecutor.cpp @@ -1,74 +1,89 @@ -/* - PIP - Platform Independent Primitives - - Stephan Fomenko - - 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 . -*/ - -#include "executor.h" - - -PIThreadPoolExecutor::PIThreadPoolExecutor(size_t corePoolSize, PIBlockingDequeue> *taskQueue_) : isShutdown_(false), taskQueue(taskQueue_) { - for (size_t i = 0; i < corePoolSize; ++i) { - PIThread * thread = new PIThread([&, i](){ - auto runnable = taskQueue->poll(100, std::function()); - if (runnable) { - runnable(); - } - if (isShutdown_ && taskQueue->size() == 0) threadPool[i]->stop(); - }); - threadPool.push_back(thread); - thread->start(); - } -} - - -bool PIThreadPoolExecutor::awaitTermination(int timeoutMs) { - PITimeMeasurer measurer; - for (size_t i = 0; i < threadPool.size(); ++i) { - int dif = timeoutMs - (int)measurer.elapsed_m(); - if (dif < 0) return false; - if (!threadPool[i]->waitForFinish(dif)) return false; - } - return true; -} - - -void PIThreadPoolExecutor::shutdownNow() { - isShutdown_ = true; - for (size_t i = 0; i < threadPool.size(); ++i) threadPool[i]->stop(); -} - - -PIThreadPoolExecutor::~PIThreadPoolExecutor() { - shutdownNow(); - while (threadPool.size() > 0) delete threadPool.take_back(); - delete taskQueue; -} - - -void PIThreadPoolExecutor::execute(const std::function &runnable) { - if (!isShutdown_) taskQueue->offer(runnable); -} - - -bool PIThreadPoolExecutor::isShutdown() const { - return isShutdown_; -} - - -void PIThreadPoolExecutor::shutdown() { - isShutdown_ = true; -} +/* + PIP - Platform Independent Primitives + + Stephan Fomenko + + 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 . +*/ + +#include "pithreadpoolexecutor.h" +#include "pisysteminfo.h" + +/*! \class PIThreadPoolExecutor + * @brief Thread pools address two different problems: they usually provide improved performance when executing large + * numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and + * managing the resources, including threads, consumed when executing a collection of tasks. + */ + + +PIThreadPoolExecutor::PIThreadPoolExecutor(size_t corePoolSize, PIBlockingDequeue > * taskQueue_) : isShutdown_(false) { + queue_own = false; + if (corePoolSize <= 0) + corePoolSize = PISystemInfo::instance()->processorsCount; + if (!taskQueue_) { + taskQueue = new PIBlockingDequeue >(); + queue_own = true; + } + for (size_t i = 0; i < corePoolSize; ++i) { + PIThread * thread = new PIThread([&, i](){ + auto runnable = taskQueue->poll(100, std::function()); + if (runnable) { + runnable(); + } + if (isShutdown_ && taskQueue->size() == 0) threadPool[i]->stop(); + }); + threadPool.push_back(thread); + thread->start(); + } +} + + +bool PIThreadPoolExecutor::awaitTermination(int timeoutMs) { + PITimeMeasurer measurer; + for (size_t i = 0; i < threadPool.size(); ++i) { + int dif = timeoutMs - (int)measurer.elapsed_m(); + if (dif < 0) return false; + if (!threadPool[i]->waitForFinish(dif)) return false; + } + return true; +} + + +void PIThreadPoolExecutor::shutdownNow() { + isShutdown_ = true; + for (size_t i = 0; i < threadPool.size(); ++i) threadPool[i]->stop(); +} + + +PIThreadPoolExecutor::~PIThreadPoolExecutor() { + shutdownNow(); + while (threadPool.size() > 0) delete threadPool.take_back(); + if (queue_own) + delete taskQueue; +} + + +void PIThreadPoolExecutor::execute(const std::function & runnable) { + if (!isShutdown_) taskQueue->offer(runnable); +} + + +bool PIThreadPoolExecutor::isShutdown() const { + return isShutdown_; +} + + +void PIThreadPoolExecutor::shutdown() { + isShutdown_ = true; +} diff --git a/lib/main/concurrent/executor.h b/lib/main/thread/pithreadpoolexecutor.h similarity index 70% rename from lib/main/concurrent/executor.h rename to lib/main/thread/pithreadpoolexecutor.h index 63a6135c..d8655843 100644 --- a/lib/main/concurrent/executor.h +++ b/lib/main/thread/pithreadpoolexecutor.h @@ -17,20 +17,16 @@ along with this program. If not, see . */ -#ifndef PIP_TESTS_EXECUTOR_H -#define PIP_TESTS_EXECUTOR_H +#ifndef PITHREADPOOLEXECUTOR_H +#define PITHREADPOOLEXECUTOR_H #include "piblockingdequeue.h" #include -/** - * @brief Thread pools address two different problems: they usually provide improved performance when executing large - * numbers of asynchronous tasks, due to reduced per-task invocation overhead, and they provide a means of bounding and - * managing the resources, including threads, consumed when executing a collection of tasks. - */ + class PIThreadPoolExecutor { public: - explicit PIThreadPoolExecutor(size_t corePoolSize = 1, PIBlockingDequeue >* taskQueue_ = new PIBlockingDequeue >()); + explicit PIThreadPoolExecutor(size_t corePoolSize = -1, PIBlockingDequeue > * taskQueue_ = 0); virtual ~PIThreadPoolExecutor(); @@ -41,7 +37,7 @@ public: * * @param runnable not empty function for thread pool execution */ - void execute(const std::function& runnable); + void execute(const std::function & runnable); void shutdownNow(); @@ -55,10 +51,13 @@ public: bool isShutdown() const; bool awaitTermination(int timeoutMs); + private: std::atomic_bool isShutdown_; - PIBlockingDequeue >* taskQueue; + PIBlockingDequeue > * taskQueue; PIVector threadPool; + bool queue_own; + }; -#endif //PIP_TESTS_EXECUTOR_H +#endif // PITHREADPOOLEXECUTOR_H diff --git a/main.cpp b/main.cpp index d78cedcf..5bc395f7 100644 --- a/main.cpp +++ b/main.cpp @@ -1,5 +1,5 @@ #include "pip.h" -#ifdef PIP_LUA +/*#ifdef PIP_LUA #include "piluaprogram.h" static const char * script @@ -30,3 +30,29 @@ int main() { return 0; } #endif +*/ + +#include "picodeparser.h" +int main() { + piDebug = false; + double min = -1, max = -1, mean = 0; + for (int i = 0; i < 50; ++i) { + PITimeMeasurer tm; + /*PICodeParser cp; + cp.parseFile("SH_plugin_base.h");*/ + PIStringList sl; + for (int i = 0; i < 5000; ++i) { + //PIString s("1234567890-="); + //sl << s; + sl << PIString("1234567890-="); + } + double ms = tm.elapsed_m(); + if (min < 0) min = ms; + if (max < 0) max = ms; + min = piMin(min, ms); + max = piMax(max, ms); + mean += ms; + } + piDebug = true; + piCout << min << (mean / 50) << max; +}