diff --git a/check/sa_check.ewd b/check/sa_check.ewd index b717b728..7fa1f613 100644 --- a/check/sa_check.ewd +++ b/check/sa_check.ewd @@ -88,7 +88,7 @@ OCLastSavedByProductVersion - 9.50.1.69462 + 9.60.2.5384 UseFlashLoader @@ -584,7 +584,7 @@ IJET_ID 2 - 9 + 10 1 1 @@ -860,6 +860,10 @@ CatchV8ARREL3S 0 + + IjetHWResetTimingOverride + 1 + @@ -2220,7 +2224,7 @@ IJET_ID 2 - 9 + 10 1 0 @@ -2496,6 +2500,10 @@ CatchV8ARREL3S 0 + + IjetHWResetTimingOverride + 1 + diff --git a/check/sa_check.ewp b/check/sa_check.ewp index a2018c81..a57d8e8a 100644 --- a/check/sa_check.ewp +++ b/check/sa_check.ewp @@ -11,7 +11,7 @@ General 3 - 36 + 37 1 1 @@ -70,7 +70,7 @@ OGLastSavedByProductVersion - 9.50.1.69462 + 9.60.2.5384 OGChipSelectEditMenu @@ -98,7 +98,7 @@ GBECoreSlave - 33 + 34 39 @@ -115,7 +115,7 @@ CoreVariant - 33 + 34 39 @@ -138,7 +138,7 @@ GFPUCoreSlave2 - 33 + 34 39 @@ -213,16 +213,20 @@ OG_32_64DeviceCoreSlave - 33 + 34 39 + + GOutputSo + 0 + ICCARM 2 - 38 + 39 1 1 @@ -472,6 +476,14 @@ CCBranchTargetIdentification 0 + + CCPosRadRwpi + 0 + + + CCPosSharedSlave + 0 + @@ -676,11 +688,10 @@ CUSTOM - 3 + 4 - 1 inputOutputBased @@ -688,7 +699,7 @@ ILINK 0 - 27 + 28 1 1 @@ -1056,6 +1067,10 @@ IlinkFpuProcessor 1 + + IlinkSharedSlave + 0 + @@ -1095,7 +1110,7 @@ General 3 - 36 + 37 1 0 @@ -1182,7 +1197,7 @@ GBECoreSlave - 33 + 34 38 @@ -1199,7 +1214,7 @@ CoreVariant - 33 + 34 38 @@ -1222,7 +1237,7 @@ GFPUCoreSlave2 - 33 + 34 38 @@ -1297,16 +1312,20 @@ OG_32_64DeviceCoreSlave - 33 + 34 38 + + GOutputSo + 0 + ICCARM 2 - 38 + 39 1 0 @@ -1556,6 +1575,14 @@ CCBranchTargetIdentification 0 + + CCPosRadRwpi + 0 + + + CCPosSharedSlave + 0 + @@ -1760,11 +1787,10 @@ CUSTOM - 3 + 4 - 0 inputOutputBased @@ -1772,7 +1798,7 @@ ILINK 0 - 27 + 28 1 0 @@ -2140,6 +2166,10 @@ IlinkFpuProcessor 1 + + IlinkSharedSlave + 0 + diff --git a/check/sa_check.ewt b/check/sa_check.ewt index e5a7d38c..0e1a3807 100644 --- a/check/sa_check.ewt +++ b/check/sa_check.ewt @@ -9,9 +9,9 @@ 1 C-STAT - 518 + 519 - 518 + 519 0 @@ -25,7 +25,7 @@ Debug\C-STAT - 2.6.0 + 2.7.2 @@ -194,7 +194,6 @@ - @@ -257,6 +256,7 @@ + @@ -279,7 +279,6 @@ - @@ -290,6 +289,7 @@ + @@ -375,7 +375,6 @@ - @@ -485,7 +484,6 @@ - @@ -844,8 +842,7 @@ - - + @@ -865,6 +862,9 @@ + + + @@ -897,6 +897,7 @@ + @@ -921,15 +922,15 @@ - - + + @@ -959,6 +960,7 @@ + @@ -966,6 +968,7 @@ + @@ -1043,6 +1046,7 @@ + @@ -1093,6 +1097,7 @@ + @@ -1468,9 +1473,9 @@ 0 C-STAT - 518 + 519 - 518 + 519 0 @@ -1484,7 +1489,7 @@ Release\C-STAT - 2.6.0 + 2.7.2 @@ -1653,7 +1658,6 @@ - @@ -1716,6 +1720,7 @@ + @@ -1738,7 +1743,6 @@ - @@ -1749,6 +1753,7 @@ + @@ -1834,7 +1839,6 @@ - @@ -1944,7 +1948,6 @@ - @@ -2303,8 +2306,7 @@ - - + @@ -2324,6 +2326,9 @@ + + + @@ -2356,6 +2361,7 @@ + @@ -2380,15 +2386,15 @@ - - + + @@ -2418,6 +2424,7 @@ + @@ -2425,6 +2432,7 @@ + @@ -2502,6 +2510,7 @@ + @@ -2552,6 +2561,7 @@ + diff --git a/check/settings/sa_check.Debug.cspy.bat b/check/settings/sa_check.Debug.cspy.bat index d357f3bd..383579e2 100644 --- a/check/settings/sa_check.Debug.cspy.bat +++ b/check/settings/sa_check.Debug.cspy.bat @@ -25,7 +25,7 @@ if not "%~1" == "" goto debugFile @echo on -"C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" +"C:\iar\ewarm-9.60.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" @echo off goto end @@ -34,7 +34,7 @@ goto end @echo on -"C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" "--debug_file=%~1" --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" +"C:\iar\ewarm-9.60.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" "--debug_file=%~1" --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" @echo off :end \ No newline at end of file diff --git a/check/settings/sa_check.Debug.cspy.ps1 b/check/settings/sa_check.Debug.cspy.ps1 index 0108a26f..f849855b 100644 --- a/check/settings/sa_check.Debug.cspy.ps1 +++ b/check/settings/sa_check.Debug.cspy.ps1 @@ -23,9 +23,9 @@ if ($debugfile -eq "") { -& "C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" +& "C:\iar\ewarm-9.60.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" } else { -& "C:\Program Files\IAR Systems\Embedded Workbench 9.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" --debug_file=$debugfile --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" +& "C:\iar\ewarm-9.60.2\common\bin\cspybat" -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.general.xcl" --debug_file=$debugfile --backend -f "D:\Camilo\Documents\GitHub\QuarkTS-cpp\check\settings\sa_check.Debug.driver.xcl" } diff --git a/check/simple_dry_test.cpp b/check/simple_dry_test.cpp index 5e96a5ae..05248cb7 100644 --- a/check/simple_dry_test.cpp +++ b/check/simple_dry_test.cpp @@ -8,9 +8,9 @@ class customTask : public task { void activities( event_t e ) override { if ( e.firstCall() ) { - logger::out() << e.thisTask() << logger::endl; + logger::out() << e.thisTask(); } - logger::out() << logger::mag << "im a custom task" << logger::end; + logger::out() << logger::mag << "im a custom task"; } }; @@ -72,18 +72,18 @@ void idleTask_callback( event_t e ) unsigned int a; if ( e.firstCall() ) { - logger::out() << "idle task" << a << logger::end; - logger::out() << e.thisTask() << logger::end; + logger::out() << "idle task" << a;; + logger::out() << e.thisTask(); } co::reenter() { for(;;) { co::getPosition( pos1 ); - logger::out() << e.thisTask() << logger::end; - logger::out() << "sec 1"<< logger::end; + logger::out() << e.thisTask(); + logger::out() << "sec 1"; co::delay( 0.5_sec ); - logger::out() <<"sec 2"<< logger::end; + logger::out() <<"sec 2"; co::delay( 0.5_sec ); - logger::out() <<"sec 3"<< logger::end; + logger::out() <<"sec 3"; co::delay( 0.5_sec ); co::waitUntil( true ); co::waitUntil( true , 500 ); @@ -106,7 +106,7 @@ co::semaphore sem(1); void otherTask( event_t e ) { if ( e.firstCall() ) { - logger::out() << e.thisTask() << logger::end; + logger::out() << e.thisTask(); } co::reenter( otherTaskCrHandle ) { co::restart(); @@ -119,7 +119,7 @@ sm::status s1_callback( sm::handler_t h ) { switch ( h.signal() ) { case sm::SIGNAL_ENTRY: - logger::out() << logger::cyn << h.thisMachine() << h.thisState() << "s1_callback"<< logger::end; + logger::out() << logger::cyn << h.thisMachine() << h.thisState() << "s1_callback"; h.thisMachine().timeoutSet( 0, 5_sec ); break; case sm::SIGNAL_TIMEOUT( 0 ): @@ -135,11 +135,11 @@ sm::status s2_callback( sm::handler_t h ) { static timer tmr; - logger::out() << logger::var(tmr) << logger::end; + logger::out() << logger::var(tmr); switch ( h.signal() ) { case sm::SIGNAL_ENTRY: - logger::out() << logger::cyn << h.thisMachine() << h.thisState() << "s2_callback"<< logger::end; + logger::out() << logger::cyn << h.thisMachine() << h.thisState() << "s2_callback"; tmr( 5_sec ); break; default: @@ -153,18 +153,18 @@ sm::status s2_callback( sm::handler_t h ) void task_callback( event_t e ) { - logger::out() << e.self() << logger::end; + logger::out() << e.self(); if ( e.firstCall() ) { - logger::out() << logger::grn << "first call "<< e.thisTask() << logger::end; + logger::out() << logger::grn << "first call "<< e.thisTask(); } if( trigger::byNotificationSimple == e.getTrigger() ) { - logger::out() << "notified(SIMPLE)! " << e.thisTask() << logger::end; + logger::out() << "notified(SIMPLE)! " << e.thisTask(); } if( trigger::byNotificationQueued == e.getTrigger() ) { - logger::out() << "notified(QUEUED)! " << e.thisTask() << logger::end; + logger::out() << "notified(QUEUED)! " << e.thisTask(); } if ( e.lastIteration() ) { @@ -172,12 +172,12 @@ void task_callback( event_t e ) os.notify( notifyMode::QUEUED, t1, nullptr ); os.notify( notifyMode::QUEUED, t2, nullptr ); os.notify( notifyMode::QUEUED, t1, nullptr ); - logger::out() << "last iteration "<< e.thisTask() << logger::end; + logger::out() << "last iteration "<< e.thisTask(); } int someValue = 457; int *ptr = &someValue; - logger::out() << logger::red <<"test trace "<< logger::dec << logger::var(someValue)<< " " << ptr << logger::end; + logger::out() << logger::red <<"test trace "<< logger::dec << logger::var(someValue)<< " " << ptr; } @@ -218,12 +218,15 @@ int main() uint32_t x = 0xFFAA2211; double y = -3.1416; logger::setOutputFcn( &putCharFcn ); - logger::out() << logger::pre(8) << logger::var(y) << logger::end; - logger::out() << logger::var(x) << logger::mem( sizeof(x) ) << &x << logger::end; - logger::out(logger::info) << "info message"<< logger::end; - logger::out(logger::error) << "error message"<< logger::end; - logger::out(logger::debug) << "debug message"<< logger::end; - logger::out(logger::verbose) << "verbose message"<< logger::end; + logger::out() << logger::pre(8) << logger::var(y); + logger::out() << logger::var(x) << logger::mem( sizeof(x) ) << &x; + logger::out(logger::info) << "info message"; + logger::out(logger::error) << "error message"; + logger::out(logger::debug) << "debug message"; + logger::out(logger::verbose) << "verbose message"; + + + //return 0; os.init( sysClock, idleTask_callback ); @@ -231,11 +234,11 @@ int main() LED_FSM.install( LEDsigqueue ); LED_FSM.install( tm_spectimeout ); - logger::out(logger::debug) << logger::end; + logger::out(logger::debug); State_LEDOff.install( LEDOff_transitions ); State_LEDOn.install( LEDOn_transitions, LedOn_Timeouts ); State_LEDBlink.install( LEDBlink_transitions, LEDBlink_timeouts ); - logger::out(logger::debug) << logger::end; + logger::out(logger::debug); os.add( t1, task_callback, core::LOWEST_PRIORITY, 0.5_sec, task::PERIODIC ); os.add( t2, task_callback, core::HIGHEST_PRIORITY, 0.5_sec, 10U ); os.add( t3, task_callback, core::MEDIUM_PRIORITY, 2_sec, task::PERIODIC ); diff --git a/examples/LED_Blink_Flat_State_Machine/LED_Blink_Flat_State_Machine.ino b/examples/LED_Blink_Flat_State_Machine/LED_Blink_Flat_State_Machine.ino index 847397da..ed70dc30 100644 --- a/examples/LED_Blink_Flat_State_Machine/LED_Blink_Flat_State_Machine.ino +++ b/examples/LED_Blink_Flat_State_Machine/LED_Blink_Flat_State_Machine.ino @@ -50,7 +50,7 @@ sm::timeoutStateDefinition LEDBlink_timeouts[] = { sm::status State_LEDOff_Callback( sm::handler_t h ) { switch ( h.signal() ) { case sm::signalID::SIGNAL_ENTRY: - logger::out() << "LED Off state" << logger::end; + logger::out() << "LED Off state"; digitalWrite( LED_BUILTIN, LOW ); break; default: @@ -62,7 +62,7 @@ sm::status State_LEDOff_Callback( sm::handler_t h ) { sm::status State_LEDOn_Callback( sm::handler_t h ) { switch ( h.signal() ) { case sm::signalID::SIGNAL_ENTRY: - logger::out() << "LED On state" << logger::end; + logger::out() << "LED On state"; digitalWrite( LED_BUILTIN, HIGH ); break; default: @@ -74,7 +74,7 @@ sm::status State_LEDOn_Callback( sm::handler_t h ) { sm::status State_LEDBlink_Callback( sm::handler_t h ) { switch ( h.signal() ) { case sm::signalID::SIGNAL_ENTRY: - logger::out() << "LED blink state" << logger::end; + logger::out() << "LED blink state"; break; case SIGNAL_BLINK: digitalWrite( LED_BUILTIN, !digitalRead(LED_BUILTIN) ); @@ -93,7 +93,7 @@ void tracePutcWrapper( void *arg, const char c ) { void idleTaskCallback( event_t e ) { if ( e.firstCall() ) { - logger::out() << QUARKTS_CPP_CAPTION << logger::end; + logger::out() << QUARKTS_CPP_CAPTION; } } diff --git a/examples/Simple_Example/Simple_Example.ino b/examples/Simple_Example/Simple_Example.ino index 618e75a3..83b7cd6c 100644 --- a/examples/Simple_Example/Simple_Example.ino +++ b/examples/Simple_Example/Simple_Example.ino @@ -5,15 +5,15 @@ task demoTask1, blinkTask; void blinkTask_callback( event_t e ) { if ( e.firstCall() ) { - logger::out() << e.thisTask() << " Launched!" << logger::endl; + logger::out() << e.thisTask() << " Launched!"; } co::reenter() { for(;;) { digitalWrite( LED_BUILTIN, HIGH ); - logger::out() << e.thisTask() << logger::endl; + logger::out() << e.thisTask(); co::delay( 500_ms ); digitalWrite( LED_BUILTIN, LOW ); - logger::out() << e.thisTask() << logger::endl; + logger::out() << e.thisTask(); co::delay( 500_ms ); } } @@ -21,19 +21,19 @@ void blinkTask_callback( event_t e ) { void demoTask1_Callback( event_t e ) { if ( e.firstCall() ) { - logger::out() << e.thisTask() << " Launched!" << logger::endl; + logger::out() << e.thisTask() << " Launched!"; } - logger::out() << e.thisTask() << logger::endl; + logger::out() << e.thisTask(); } void idleTask_callback( event_t e ) { if ( e.firstCall() ) { - logger::out() << e.thisTask() << " Launched!" << logger::endl; + logger::out() << e.thisTask() << " Launched!"; } co::reenter() { for(;;) { co::delay( 500_ms ); - logger::out() << e.thisTask() << logger::endl; + logger::out() << e.thisTask(); } } } diff --git a/library.json b/library.json index e42b7497..238178d6 100644 --- a/library.json +++ b/library.json @@ -16,7 +16,7 @@ "maintainer": true } ], - "version": "1.7.7", + "version": "1.7.8", "license": "MIT", "frameworks": "arduino", "platforms": "*" diff --git a/library.properties b/library.properties index 41dd5e0a..1bcea360 100644 --- a/library.properties +++ b/library.properties @@ -1,5 +1,5 @@ name=QuarkTS -version=1.7.7 +version=1.7.8 license=MIT author=J. Camilo Gomez C. maintainer=J. Camilo Gomez C. diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index d6ebd689..8d412f7e 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -1,6 +1,6 @@ cmake_minimum_required( VERSION 3.2 ) project( quarkts-cpp - VERSION 1.7.7 + VERSION 1.7.8 DESCRIPTION "An open-source OS for small embedded applications" LANGUAGES CXX ) diff --git a/src/QuarkTS.h b/src/QuarkTS.h index 7f8e261d..be6c07b5 100644 --- a/src/QuarkTS.h +++ b/src/QuarkTS.h @@ -1,7 +1,7 @@ /*! * @file QuarkTS.h * @author J. Camilo Gomez C. - * @version 1.7.7 + * @version 1.7.8 * @note This file is part of the QuarkTS++ distribution. * @brief Global inclusion header **/ @@ -41,8 +41,8 @@ This file is part of the QuarkTS++ OS distribution. #ifndef QOS_CPP_H #define QOS_CPP_H -#define QUARKTS_CPP_VERSION "1.7.7" -#define QUARKTS_CPP_VERNUM ( 177u ) +#define QUARKTS_CPP_VERSION "1.7.8" +#define QUARKTS_CPP_VERNUM ( 178u ) #define QUARKTS_CPP_CAPTION "QuarkTS++ OS " QUARKTS_CPP_VERSION #include "config/config.h" @@ -66,7 +66,7 @@ This file is part of the QuarkTS++ OS distribution. namespace qOS { namespace build { - constexpr const uint32_t number = 4181; + constexpr const uint32_t number = 4215; constexpr const char* date = __DATE__; constexpr const char* time = __TIME__; constexpr const char* std = "c++11"; @@ -76,7 +76,7 @@ namespace qOS { constexpr const uint8_t number = QUARKTS_CPP_VERNUM; constexpr const uint8_t mayor = 1U; constexpr const uint8_t minor = 7U; - constexpr const uint8_t rev = 7U; + constexpr const uint8_t rev = 8U; } namespace product { constexpr const char* author = "J. Camilo Gomez C."; diff --git a/src/critical.cpp b/src/critical.cpp index ead553f1..ee36ff73 100644 --- a/src/critical.cpp +++ b/src/critical.cpp @@ -1,43 +1,59 @@ #include "include/critical.hpp" using namespace qOS; -using namespace qOS::critical; /*! @cond */ -struct criticalHandler_t { - int_disabler_t disable; /*< Point to the user-supplied function used to disable the hardware interrupts. */ - int_restorer_t restore; /*< Point to the user-supplied function used to restore the hardware interrupts. */ - volatile uint32_t flags; /*< To save the current interrupt flags before the disable action is performed. */ -}; -static criticalHandler_t c = { nullptr, nullptr , 0UL }; // skipcq: CXX-W2009 +int_disabler_t critical::lock::disable = nullptr; /*< Point to the user-supplied function used to disable the hardware interrupts. */ +int_restorer_t critical::lock::restore = nullptr; /*< Point to the user-supplied function used to restore the hardware interrupts. */ +volatile uint32_t critical::lock::flags = 0UL; /*< To save the current interrupt flags before the disable action is performed. */ +volatile int critical::lock::nestingLevel = 0; /*! @endcond */ /*============================================================================*/ -void critical::enter( void ) noexcept +void critical::lock::enter( void ) noexcept { - if ( nullptr != c.disable ) { - const int_disabler_t xDisabler = c.disable; - - c.flags = xDisabler(); + if ( ( 0 == nestingLevel ) && ( nullptr != disable ) ) { + const int_disabler_t xDisabler = disable; + flags = xDisabler(); } + ++nestingLevel; } /*============================================================================*/ -void critical::exit( void ) noexcept +void critical::lock::exit( void ) noexcept { - if ( nullptr != c.restore ) { - const int_restorer_t xRestorer = c.restore; - - xRestorer( c.flags ); + if ( nestingLevel > 0 ) { + --nestingLevel; + if ( ( 0 == nestingLevel ) && ( nullptr != restore ) ) { + const int_restorer_t xRestorer = restore; + xRestorer( flags ); + } } } /*============================================================================*/ +critical::lock::lock() noexcept +{ + enter(); +} +/*============================================================================*/ +critical::lock::~lock() noexcept +{ + exit(); +} +/*============================================================================*/ +critical::lock::operator bool() noexcept +{ + const bool ret = entered; + entered = false; + return ret; +} +/*============================================================================*/ bool critical::setInterruptsED( const int_restorer_t rFcn, const int_disabler_t dFcn ) noexcept { bool retValue = false; - if ( ( rFcn != c.restore ) || ( dFcn != c.disable ) ) { - c.restore = rFcn; - c.disable = dFcn; + if ( ( rFcn != critical::lock::restore ) || ( dFcn != critical::lock::disable ) ) { + critical::lock::restore = rFcn; + critical::lock::disable = dFcn; retValue = true; } diff --git a/src/include/coroutine.hpp b/src/include/coroutine.hpp index 4e56d77c..5564a1de 100644 --- a/src/include/coroutine.hpp +++ b/src/include/coroutine.hpp @@ -145,7 +145,7 @@ namespace qOS { label = l; return *this; } - inline co::state operator()( void ) const + inline operator co::state() const { return label; } @@ -394,7 +394,7 @@ for ( ; co_ctx != qOS::co::SUSPENDED ; co_ctx = qOS::co::SUSPENDED ) \ break; \ } \ else \ - switch ( co_ctx() ) \ + switch ( co_ctx ) \ case 0 : \ /*============================================================================*/ diff --git a/src/include/critical.hpp b/src/include/critical.hpp index 6f6d77ee..8f7168f4 100644 --- a/src/include/critical.hpp +++ b/src/include/critical.hpp @@ -61,20 +61,53 @@ namespace qOS { */ /** - * @brief Enter a critical section. This function invokes the @b Disabler - * function if available. - * @note Please see critical::setInterruptsED() + * @brief Enables a scoped critical section with minimal syntax overhead. + * + * @code{.cpp} + * void example() { + * critical::scope { + * // Code here runs in a critical section + * } + * } + * @endcode */ - void enter( void ) noexcept; + inline void scope( void ) noexcept {} + /** - * @brief Exit a critical section. This function invokes the @b Enabler - * function if available. - * @note Please see critical::setInterruptsED() + * @brief Scoped critical section lock. + * + * @details + * The `lock` class provides a simple RAII-based mechanism for managing critical + * sections. When an object of this class is created, it automatically enters a + * critical section (disabling interrupts). When the object is destroyed, it exits + * the critical section (restoring interrupts). + * + * @code{.cpp} + * void example() { + * critical::lock l + * // Code that runs in a critical section + * } + * @endcode */ - void exit( void ) noexcept; + class lock final : private nonCopyable { + private: + static void enter( void ) noexcept; + static void exit( void ) noexcept; + static int_disabler_t disable; + static int_restorer_t restore; + static volatile uint32_t flags; + static volatile int nestingLevel; + bool entered{ true }; + friend bool setInterruptsED( const int_restorer_t rFcn, const int_disabler_t dFcn ) noexcept; + public: + lock() noexcept; + ~lock() noexcept; + explicit operator bool() noexcept; + }; + /** * @brief Set the hardware-specific code for global interrupt enable/disable. - * Setting this allows you to communicate safely from Interrupts using + * Setting this allows you to communicate safely from Interrupts using * queued-notifications or queues. * @param[in] rFcn The function with hardware specific code that enables or * restores interrupts. @@ -86,8 +119,15 @@ namespace qOS { /** @}*/ } - /** @}*/ } +/*! @cond */ +/*============================================================================*/ +#define scope \ +scope(); \ +for ( critical::lock critical_lock; critical_lock; ) \ +/*============================================================================*/ +/*! @endcond */ + #endif /*QOS_CPP_CRITICAL*/ diff --git a/src/include/kernel.hpp b/src/include/kernel.hpp index 9d9d6f3c..c633806b 100644 --- a/src/include/kernel.hpp +++ b/src/include/kernel.hpp @@ -93,7 +93,6 @@ namespace qOS { list coreLists[ Q_PRIORITY_LEVELS + 2 ]; // skipcq: CXX-W2066 list& waitingList; // skipcq: CXX-W2012, CXX-W2010 list& suspendedList; // skipcq: CXX-W2012, CXX-W2010 - //list inputWatchers; void(*cpuIdle)(void){ nullptr }; static const priority_t MAX_PRIORITY_VALUE; static const uint32_t BIT_INIT; diff --git a/src/include/list.hpp b/src/include/list.hpp index 5f1d6bfb..234df4d9 100644 --- a/src/include/list.hpp +++ b/src/include/list.hpp @@ -74,7 +74,9 @@ namespace qOS { */ inline list* getContainer( void ) const noexcept { + /*cstat -CONST-member-ret -MISRAC++2008-9-3-1*/ return container; + /*cstat +CONST-member-ret +MISRAC++2008-9-3-1*/ } node() noexcept : next(nullptr), prev(nullptr), container(nullptr) {} /*! @cond */ diff --git a/src/include/logger.hpp b/src/include/logger.hpp index 733a7b64..ae731d97 100644 --- a/src/include/logger.hpp +++ b/src/include/logger.hpp @@ -303,6 +303,8 @@ namespace qOS { */ extern const char * const wht; + struct ChainLoggerProxy; + /*! @cond */ class _logger final : private nonCopyable { private: @@ -336,32 +338,63 @@ namespace qOS { writeNumStr(); return *this; } - _logger& operator<<( const char& v ); - _logger& operator<<( const char * s ); - _logger& operator<<( const short& v ); - _logger& operator<<( const int& v ); - _logger& operator<<( const long int& v ); - _logger& operator<<( const unsigned char& v ); - _logger& operator<<( const unsigned short& v ); - _logger& operator<<( const unsigned int& v ); - _logger& operator<<( const unsigned long& v ); - _logger& operator<<( const void * const p ); - _logger& operator<<( const float64_t& v ); - _logger& operator<<( const lout_base& f ); - _logger& operator<<( const mem& m ); - _logger& operator<<( const pre& m ); - _logger& operator<<( const task& t ); - _logger& operator<<( const qOS::timer& t ); - _logger& operator<<( const qOS::stateMachine& sm ); - _logger& operator<<( const qOS::sm::state& s ); - _logger& operator<<( const qOS::trigger& t ); - _logger& operator<<( const qOS::input::channel& in ); - _logger& operator<<( const qOS::string & s ); - friend _logger& out( const logSeverity s, const source_location &loc ) noexcept; + void toLog( const char& v ); + void toLog( const char * s ); + void toLog( const short& v ); + void toLog( const int& v ); + void toLog( const long int& v ); + void toLog( const unsigned char& v ); + void toLog( const unsigned short& v ); + void toLog( const unsigned int& v ); + void toLog( const unsigned long& v ); + void toLog( const void * const p ); + void toLog( const float64_t& v ); + void toLog( const lout_base& f ); + void toLog( const mem& m ); + void toLog( const pre& m ); + void toLog( const task& t ); + void toLog( const qOS::timer& t ); + void toLog( const qOS::stateMachine& sm ); + void toLog( const qOS::sm::state& s ); + void toLog( const qOS::trigger& t ); + void toLog( const qOS::input::channel& in ); + void toLog( const qOS::string & s ); + + friend ChainLoggerProxy out( const logSeverity s, const source_location &loc ) noexcept; friend void setOutputFcn( util::putChar_t fcn ); + friend class ChainLoggerProxy; }; extern _logger& _logger_out; // skipcq: CXX-W2011, CXX-W2009 + + struct ChainLoggerProxy { + _logger& parent; + ChainLoggerProxy( _logger& p) : parent(p) {} + ChainLoggerProxy( const ChainLoggerProxy& ) = delete; + ChainLoggerProxy( ChainLoggerProxy&& other ) noexcept : parent( other.parent ) {} + ~ChainLoggerProxy(); + ChainLoggerProxy& operator<<( const char& v ); + ChainLoggerProxy& operator<<( const char * s ); + ChainLoggerProxy& operator<<( const short& v ); + ChainLoggerProxy& operator<<( const int& v ); + ChainLoggerProxy& operator<<( const long int& v ); + ChainLoggerProxy& operator<<( const unsigned char& v ); + ChainLoggerProxy& operator<<( const unsigned short& v ); + ChainLoggerProxy& operator<<( const unsigned int& v ); + ChainLoggerProxy& operator<<( const unsigned long& v ); + ChainLoggerProxy& operator<<( const void * const p ); + ChainLoggerProxy& operator<<( const float64_t& v ); + ChainLoggerProxy& operator<<( const lout_base& f ); + ChainLoggerProxy& operator<<( const mem& m ); + ChainLoggerProxy& operator<<( const pre& m ); + ChainLoggerProxy& operator<<( const task& t ); + ChainLoggerProxy& operator<<( const qOS::timer& t ); + ChainLoggerProxy& operator<<( const qOS::stateMachine& sm ); + ChainLoggerProxy& operator<<( const qOS::sm::state& s ); + ChainLoggerProxy& operator<<( const qOS::trigger& t ); + ChainLoggerProxy& operator<<( const qOS::input::channel& in ); + ChainLoggerProxy& operator<<( const qOS::string & s ); + }; /*! @endcond */ /** @@ -371,7 +404,7 @@ namespace qOS { void setOutputFcn( util::putChar_t fcn ); /*! @cond */ - _logger& out( const logSeverity s = logSeverity::none, const source_location &loc = source_location::current() ) noexcept; + ChainLoggerProxy out( const logSeverity s = logSeverity::none, const source_location &loc = source_location::current() ) noexcept; /* cppcheck-suppress functionStatic */ inline const char * var( const char * vname ){ return vname; } /*! @endcond */ diff --git a/src/kernel.cpp b/src/kernel.cpp index a3c5f5af..80357196 100644 --- a/src/kernel.cpp +++ b/src/kernel.cpp @@ -282,10 +282,10 @@ bool core::checkIfReady( void ) noexcept (void)waitingList.remove( listPosition::AT_FRONT ); if ( xTask->getFlag( task::BIT_REMOVE_REQUEST ) ) { #if ( Q_PRIO_QUEUE_SIZE > 0 ) - critical::enter(); - /*clean any entry of this task from the priority queue */ - priorityQueue.cleanUp( *xTask ); - critical::exit(); + critical::scope { + /*clean any entry of this task from the priority queue */ + priorityQueue.cleanUp( *xTask ); + } #endif xTask->setFlags( task::BIT_REMOVE_REQUEST, false ); --core::taskEntries; @@ -350,7 +350,6 @@ void core::dispatchTaskFillEventInfo( task *Task ) noexcept taskEvent::FirstCall = !Task->getFlag( task::BIT_INIT ); taskEvent::TaskData = Task->taskData; taskEvent::currentTask = Task; - //currentTask = Task; } /*============================================================================*/ void core::dispatch( list * const xList ) noexcept diff --git a/src/logger.cpp b/src/logger.cpp index 875da283..79e8b480 100644 --- a/src/logger.cpp +++ b/src/logger.cpp @@ -39,20 +39,35 @@ namespace qOS { _logger_out.writeChar = fcn; } } + /*cstat -MISRAC++2008-0-1-7*/ - _logger& out( const logSeverity s, const source_location &loc ) noexcept + ChainLoggerProxy out( const logSeverity s, const source_location &loc ) noexcept { - _logger_out << "[ " << dec << clock::getTick() << "] " << _logger_out.s_str[ s ]; + _logger_out.toLog( "[ " ); + _logger_out.toLog( dec ); + _logger_out.toLog( clock::getTick() ); + _logger_out.toLog( "] " ); + _logger_out.toLog( _logger_out.s_str[ s ] ); + if ( s == logSeverity::debug ) { - _logger_out << "( " << loc.function_name() << ":" << loc.line() << "): "; + _logger_out.toLog( "( " ); + _logger_out.toLog( loc.function_name() ); + _logger_out.toLog( ":" ); + _logger_out.toLog( loc.line() ); + _logger_out.toLog( "): " ); } else if ( s == logSeverity::verbose ) { - _logger_out << - loc.file_name() << " ( " << loc.function_name() << ":" << loc.line() << "): "; + _logger_out.toLog( loc.file_name() ); + _logger_out.toLog( " ( " ); + _logger_out.toLog( loc.function_name() ); + _logger_out.toLog( ":" ); + _logger_out.toLog( loc.line() ); + _logger_out.toLog( "): " ); } - return _logger_out; + return ChainLoggerProxy(_logger_out); } /*cstat +MISRAC++2008-0-1-7*/ + void _logger::writeNumStr( void ) noexcept { if ( '\0' != preFix[ 0 ] ) { @@ -68,54 +83,52 @@ namespace qOS { return instance; } - _logger& _logger::operator<<( const char& v ) + void _logger::toLog( const char& v ) { writeChar( nullptr, v ); - return *this; } - _logger& _logger::operator<<( const char * s ) + void _logger::toLog( const char * s ) { (void)util::outputString( writeChar, s ); - return *this; } - _logger& _logger::operator<<( const short& v ) + void _logger::toLog( const short& v ) { - return _log_integer( v, true ); + _log_integer( v, true ); } - _logger& _logger::operator<<( const int& v ) + void _logger::toLog( const int& v ) { - return _log_integer( v, true ); + _log_integer( v, true ); } - _logger& _logger::operator<<( const long int& v ) + void _logger::toLog( const long int& v ) { - return _log_integer( v, true ); + _log_integer( v, true ); } - _logger& _logger::operator<<( const unsigned char& v ) + void _logger::toLog( const unsigned char& v ) { - return _log_integer( v, false ); + _log_integer( v, false ); } - _logger& _logger::operator<<( const unsigned short& v ) + void _logger::toLog( const unsigned short& v ) { - return _log_integer( v, false ); + _log_integer( v, false ); } - _logger& _logger::operator<<( const unsigned int& v ) + void _logger::toLog( const unsigned int& v ) { - return _logger::_log_integer( v, false ); + _logger::_log_integer( v, false ); } - _logger& _logger::operator<<( const unsigned long& v ) + void _logger::toLog( const unsigned long& v ) { - return _log_integer( v, false ); + _log_integer( v, false ); } - _logger& _logger::operator<<( const void * const p ) + void _logger::toLog( const void * const p ) { /*cstat -CERT-INT36-C*/ (void)util::unsignedToString( reinterpret_cast( p ), buffer, 16U ); // skipcq: CXX-C1000 @@ -129,18 +142,16 @@ namespace qOS { writeChar( nullptr, ']' ); } writeChar( nullptr, ' ' ); - return *this; } - _logger& _logger::operator<<( const float64_t& v ) + void _logger::toLog( const float64_t& v ) { (void)util::floatToString( v, buffer, precision ); // skipcq: CXX-C1000 (void)util::outputString( writeChar, buffer ); // skipcq: CXX-C1000 writeChar( nullptr, ' ' ); - return *this; } - _logger& _logger::operator<<( const lout_base& f ) + void _logger::toLog( const lout_base& f ) { base = f.base; switch( f.base ) { @@ -157,22 +168,19 @@ namespace qOS { (void)memset( preFix, 0, sizeof(preFix) ); // skipcq: CXX-C1000 break; } - return *this; } - _logger& _logger::operator<<( const mem& m ) + void _logger::toLog( const mem& m ) { n = m.n; - return *this; } - _logger& _logger::operator<<( const pre& m ) + void _logger::toLog( const pre& m ) { precision = m.precision; - return *this; } - _logger& _logger::operator<<( const task& t ) + void _logger::toLog( const task& t ) { (void)util::unsignedToString( t.getID(), buffer, 10 ); // skipcq: CXX-C1000 (void)util::outputString( writeChar , "T{ \"" ); @@ -182,10 +190,9 @@ namespace qOS { (void)util::outputString( writeChar , ", " ); (void)util::outputString( writeChar , ( taskState::ENABLED_STATE == t.getState() )? "enabled" : "disabled" ); (void)util::outputString( writeChar , " } " ); - return *this; } - _logger& _logger::operator<<( const qOS::timer& t ) + void _logger::toLog( const qOS::timer& t ) { (void)util::outputString( writeChar , "t{ E:" ); (void)util::unsignedToString( t.elapsed(), buffer, 10 ); // skipcq: CXX-C1000 @@ -194,10 +201,9 @@ namespace qOS { (void)util::unsignedToString( t.remaining(), buffer, 10 ); // skipcq: CXX-C1000 (void)util::outputString( writeChar , buffer ); // skipcq: CXX-C1000 (void)util::outputString( writeChar , " } " ); - return *this; } /*cstat -CERT-INT36-C*/ - _logger& _logger::operator<<( const qOS::stateMachine& sm ) + void _logger::toLog( const qOS::stateMachine& sm ) { (void)util::outputString( writeChar , "SM{ T: 0x" ); (void)util::unsignedToString( reinterpret_cast( &sm.getTop() ), buffer, 16 ); // skipcq: CXX-C1000 @@ -206,19 +212,17 @@ namespace qOS { (void)util::unsignedToString( reinterpret_cast( sm.getCurrent() ), buffer, 16 ); // skipcq: CXX-C1000 (void)util::outputString( writeChar , buffer ); // skipcq: CXX-C1000 (void)util::outputString( writeChar , " } " ); - return *this; } - _logger& _logger::operator<<( const qOS::sm::state& s ) + void _logger::toLog( const qOS::sm::state& s ) { (void)util::outputString( writeChar , "s{ 0x" ); (void)util::unsignedToString( reinterpret_cast( &s ), buffer, 16 ); // skipcq: CXX-C1000 (void)util::outputString( writeChar , buffer ); // skipcq: CXX-C1000 (void)util::outputString( writeChar , " } " ); - return *this; } - _logger& _logger::operator<<( const qOS::trigger& t ) + void _logger::toLog( const qOS::trigger& t ) { static const char *str[ static_cast( qOS::input::event::MAX_EVENTS ) + 1 ] = { // skipcq: CXX-W2066 "None ", "byTimeElapsed ", "byNotificationQueued ", "byNotificationSimple ", @@ -226,10 +230,9 @@ namespace qOS { "byEventFlags ", "bySchedulingRelease ", "byNoReadyTasks " }; (void)util::outputString( writeChar , str[ static_cast( t ) ] ); // skipcq: CXX-C1000 - return *this; } - _logger& _logger::operator<<( const qOS::input::channel& in ) + void _logger::toLog( const qOS::input::channel& in ) { static const char *str[ static_cast( qOS::input::event::MAX_EVENTS ) ] = { // skipcq: CXX-W2066 "NONE ", "EXCEPTION ", "ON_CHANGE ", "FALLING_EDGE ", "RISING_EDGE ", @@ -250,14 +253,122 @@ namespace qOS { if ( qOS::input::event::NONE != e ) { (void)util::outputString( writeChar , str[ static_cast( e ) ] ); // skipcq: CXX-C1000 } + } + + ChainLoggerProxy::~ChainLoggerProxy() + { + (void)util::outputString( parent.writeChar, logger::end ); + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const char& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const char * s ) + { + parent.toLog( s ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const short& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const int& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const long int& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const unsigned char& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const unsigned short& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const unsigned int& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const unsigned long& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const void * const p ) + { + parent.toLog( p ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const float64_t& v ) + { + parent.toLog( v ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const lout_base& f ) + { + parent.toLog( f ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const mem& m ) + { + parent.toLog( m ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const pre& m ) + { + parent.toLog( m ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const task& t ) + { + parent.toLog( t ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const qOS::timer& t ) + { + parent.toLog( t ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const qOS::stateMachine& sm ) + { + parent.toLog( sm ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const qOS::sm::state& s ) + { + parent.toLog( s ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const qOS::trigger& t ) + { + parent.toLog( t ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const qOS::input::channel& in ) + { + parent.toLog( in ); + return *this; + } + ChainLoggerProxy& ChainLoggerProxy::operator<<( const qOS::string & s ) + { + parent.toLog( s ); return *this; } /*cstat +CERT-INT36-C*/ - _logger& _logger::operator<<( const qOS::string & s ) + void _logger::toLog( const qOS::string & s ) { (void)util::outputString( writeChar, s.c_str() ); - return *this; } } diff --git a/src/prioqueue.cpp b/src/prioqueue.cpp index 0e479f10..533cfe0d 100644 --- a/src/prioqueue.cpp +++ b/src/prioqueue.cpp @@ -6,14 +6,14 @@ using namespace qOS; /*============================================================================*/ prioQueue::prioQueue( pq::queueStack_t *area, const size_t pq_size ) noexcept { - critical::enter(); - stack = area; - size = pq_size; - for ( size_t i = 0U ; i < size ; ++i ) { - stack[ i ].pTask = nullptr; + critical::scope { + stack = area; + size = pq_size; + for ( size_t i = 0U ; i < size ; ++i ) { + stack[ i ].pTask = nullptr; + } + index = -1; } - index = -1; - critical::exit(); } /*============================================================================*/ size_t prioQueue::count( void ) const noexcept @@ -32,22 +32,22 @@ task* prioQueue::get( void ) noexcept task *xTask = nullptr; if ( hasElements() ) { - priority_t maxPriority; - index_t indexTaskToExtract = 0U; + critical::scope { + priority_t maxPriority; + index_t indexTaskToExtract = 0U; - critical::enter(); - maxPriority = stack[ 0 ].pTask->getPriority(); - for ( index_t i = 1U ; ( i < size ) && ( nullptr != stack[ i ].pTask ) ; ++i ) { - const priority_t iPriorityValue = stack[ i ].pTask->getPriority(); - if ( iPriorityValue > maxPriority ) { - maxPriority = iPriorityValue; - indexTaskToExtract = i; + maxPriority = stack[ 0 ].pTask->getPriority(); + for ( index_t i = 1U ; ( i < size ) && ( nullptr != stack[ i ].pTask ) ; ++i ) { + const priority_t iPriorityValue = stack[ i ].pTask->getPriority(); + if ( iPriorityValue > maxPriority ) { + maxPriority = iPriorityValue; + indexTaskToExtract = i; + } } + data = stack[ indexTaskToExtract ].qData; + xTask = stack[ indexTaskToExtract ].pTask; + clearIndex( indexTaskToExtract ); } - data = stack[ indexTaskToExtract ].qData; - xTask = stack[ indexTaskToExtract ].pTask; - clearIndex( indexTaskToExtract ); - critical::exit(); } return xTask; @@ -59,14 +59,14 @@ bool prioQueue::isTaskInside( const task &Task ) const noexcept const base_t currentQueueIndex = index + 1; if ( currentQueueIndex > 0 ) { - critical::enter(); - for ( base_t i = 0 ; i < currentQueueIndex ; ++i ) { - if ( &Task == stack[ i ].pTask ) { - retValue = true; - break; + critical::scope { + for ( base_t i = 0 ; i < currentQueueIndex ; ++i ) { + if ( &Task == stack[ i ].pTask ) { + retValue = true; + break; + } } } - critical::exit(); } return retValue; diff --git a/src/queue.cpp b/src/queue.cpp index be053bbb..5d0fe8b5 100644 --- a/src/queue.cpp +++ b/src/queue.cpp @@ -23,14 +23,14 @@ bool queue::setup( void *pData, const size_t size, const size_t count ) noexcept /*============================================================================*/ void queue::reset( void ) noexcept { - critical::enter(); - /*cstat -CERT-INT30-C_a*/ - tail = head + ( itemsCount*itemSize ); - itemsWaiting = 0U; - writer = head; - reader = head + ( ( itemsCount - 1U )*itemSize ); - /*cstat +CERT-INT30-C_a*/ - critical::exit(); + critical::scope { + /*cstat -CERT-INT30-C_a*/ + tail = head + ( itemsCount*itemSize ); + itemsWaiting = 0U; + writer = head; + reader = head + ( ( itemsCount - 1U )*itemSize ); + /*cstat +CERT-INT30-C_a*/ + } } /*============================================================================*/ bool queue::isEmpty( void ) const noexcept @@ -64,16 +64,17 @@ void queue::moveReader( void ) noexcept bool queue::removeFront( void ) noexcept { bool retValue = false; - size_t waiting; - critical::enter(); - waiting = itemsWaiting; - if ( waiting > 0U ) { - moveReader(); - itemsWaiting = itemsWaiting - 1U; /* --itemsWaiting */ - retValue = true; + critical::scope { + size_t waiting; + + waiting = itemsWaiting; + if ( waiting > 0U ) { + moveReader(); + itemsWaiting = itemsWaiting - 1U; /* --itemsWaiting */ + retValue = true; + } } - critical::exit(); return retValue; } @@ -87,18 +88,17 @@ void queue::copyDataFromQueue( void * const dst ) noexcept bool queue::receive( void *dst ) noexcept { bool retValue = false; - size_t waiting; - - critical::enter(); - waiting = itemsWaiting; - if ( waiting > 0U ) { - copyDataFromQueue( dst ); - itemsWaiting = itemsWaiting - 1U; /* --itemsWaiting */ - retValue = true; - } - critical::exit(); + critical::scope { + size_t waiting; + waiting = itemsWaiting; + if ( waiting > 0U ) { + copyDataFromQueue( dst ); + itemsWaiting = itemsWaiting - 1U; /* --itemsWaiting */ + retValue = true; + } + } return retValue; } /*============================================================================*/ @@ -126,12 +126,12 @@ bool queue::send( void *itemToQueue, const queueSendMode pos ) noexcept bool retValue = false; if ( ( queueSendMode::TO_BACK == pos ) || ( queueSendMode::TO_FRONT == pos ) ) { - critical::enter(); - if ( itemsWaiting < itemsCount ) { - copyDataToQueue( itemToQueue, pos ); - retValue = true; + critical::scope { + if ( itemsWaiting < itemsCount ) { + copyDataToQueue( itemToQueue, pos ); + retValue = true; + } } - critical::exit(); } return retValue; @@ -140,18 +140,17 @@ bool queue::send( void *itemToQueue, const queueSendMode pos ) noexcept void* queue::peek( void ) const noexcept { uint8_t *retValue = nullptr; - size_t waiting; + critical::scope { + size_t waiting; - critical::enter(); - waiting = itemsWaiting; - if ( waiting > 0U ) { - retValue = static_cast( reader + itemSize ); - if ( retValue >= tail ) { - retValue = head; + waiting = itemsWaiting; + if ( waiting > 0U ) { + retValue = static_cast( reader + itemSize ); + if ( retValue >= tail ) { + retValue = head; + } } } - critical::exit(); - return static_cast( retValue ); } /*============================================================================*/ diff --git a/src/task.cpp b/src/task.cpp index 86a894b2..ab84431c 100644 --- a/src/task.cpp +++ b/src/task.cpp @@ -201,18 +201,12 @@ trigger task::queueCheckEvents( void ) noexcept trigger retValue = trigger::None; if ( nullptr != aQueue ) { - bool fullFlag; - bool countFlag; - bool receiverFlag; - bool emptyFlag; - size_t qCount; /*current queue count*/ + const bool fullFlag = getFlag( BIT_QUEUE_FULL ); + const bool countFlag = getFlag( BIT_QUEUE_COUNT ); + const bool receiverFlag = getFlag( BIT_QUEUE_RECEIVER ); + const bool emptyFlag = getFlag( BIT_QUEUE_EMPTY ); + const size_t qCount = aQueue->count(); /*current queue count*/ - fullFlag = getFlag( BIT_QUEUE_FULL ); - countFlag = getFlag( BIT_QUEUE_COUNT ); - receiverFlag = getFlag( BIT_QUEUE_RECEIVER ); - emptyFlag = getFlag( BIT_QUEUE_EMPTY ); - - qCount = aQueue->count(); /*to avoid side effects*/ /*check the queue events in the corresponding precedence order*/ /*cstat -MISRAC++2008-5-14-1*/ if ( fullFlag && aQueue->isFull() ) { /*isFull() is known to not have side effects*/