On 14/11/19 12:46 am, Joel Sherrill wrote: > Two use cases were envisioned for this. > > 1) a BSP or application which desires to update a real-time clock > when the RTEMS TOD is set. > > 2) a paravirtualized BSP can use this to propagate setting the time > in an RTEMS application to the hosting environment. This enables > the entire set of applications in the virtualized environments > to have a single consistent TOD. > --- > cpukit/Makefile.am | 4 + > cpukit/include/rtems/score/todimpl.h | 97 +++++- > cpukit/posix/src/clocksettime.c | 16 +- > cpukit/rtems/src/clockset.c | 9 +- > cpukit/score/src/coretodhookdata.c | 45 +++ > cpukit/score/src/coretodhookregister.c | 60 ++++ > cpukit/score/src/coretodhookrun.c | 69 +++++ > cpukit/score/src/coretodhookunregister.c | 59 ++++ > cpukit/score/src/coretodset.c | 10 +- > testsuites/sptests/Makefile.am | 9 + > testsuites/sptests/configure.ac | 1 + > testsuites/sptests/spclock_todhook01/init.c | 334 > +++++++++++++++++++++ > .../spclock_todhook01/spclock_todhook01.doc | 35 +++ > .../spclock_todhook01/spclock_todhook01.scn | 0 > 14 files changed, 740 insertions(+), 8 deletions(-) > create mode 100644 cpukit/score/src/coretodhookdata.c > create mode 100644 cpukit/score/src/coretodhookregister.c > create mode 100644 cpukit/score/src/coretodhookrun.c > create mode 100644 cpukit/score/src/coretodhookunregister.c > create mode 100644 testsuites/sptests/spclock_todhook01/init.c > create mode 100644 testsuites/sptests/spclock_todhook01/spclock_todhook01.doc > create mode 100644 testsuites/sptests/spclock_todhook01/spclock_todhook01.scn > > diff --git a/cpukit/Makefile.am b/cpukit/Makefile.am > index 7698fe5..8cf5fb8 100644 > --- a/cpukit/Makefile.am > +++ b/cpukit/Makefile.am > @@ -981,6 +981,10 @@ librtemscpu_a_SOURCES += score/src/coretodset.c > librtemscpu_a_SOURCES += score/src/coretodtickspersec.c > librtemscpu_a_SOURCES += score/src/coretodadjust.c > librtemscpu_a_SOURCES += score/src/watchdoginsert.c > +librtemscpu_a_SOURCES += score/src/coretodhookdata.c > +librtemscpu_a_SOURCES += score/src/coretodhookregister.c > +librtemscpu_a_SOURCES += score/src/coretodhookrun.c > +librtemscpu_a_SOURCES += score/src/coretodhookunregister.c > librtemscpu_a_SOURCES += score/src/watchdogremove.c > librtemscpu_a_SOURCES += score/src/watchdogtick.c > librtemscpu_a_SOURCES += score/src/watchdogtickssinceboot.c > diff --git a/cpukit/include/rtems/score/todimpl.h > b/cpukit/include/rtems/score/todimpl.h > index 0d4faac..36e66a0 100644 > --- a/cpukit/include/rtems/score/todimpl.h > +++ b/cpukit/include/rtems/score/todimpl.h > @@ -141,6 +141,9 @@ typedef struct { > bool is_set; > } TOD_Control; > > +/** > + * @brief TOD Management information > + */ > extern TOD_Control _TOD; > > /** > @@ -183,8 +186,11 @@ static inline void _TOD_Acquire( ISR_lock_Context > *lock_context ) > * @param lock_context The ISR lock context used for the corresponding > * _TOD_Acquire(). The caller must be the owner of the TOD lock. This > * function will release the TOD lock. > + * > + * @retval true on success > + * @retval false on failure > */ > -void _TOD_Set( > +bool _TOD_Set( > const struct timespec *tod, > ISR_lock_Context *lock_context > ); > @@ -320,6 +326,95 @@ RTEMS_INLINE_ROUTINE bool _TOD_Is_set( void ) > > /** @} */ > > +/** > + * @defgroup RTEMSScoreTODHooks Time of Day Handler Action Hooks > + * > + * @ingroup RTEMSScoreTOD > + * > + * @brief Time of Day Handler Action Hooks > + * > + * The following support registering a hook which is invoked > + * when the TOD is set. These can be used by a paravirtualized > + * BSP to mirror time changes to the hosting environment or a > + * regular BSP to program a real-time clock when the RTEMS TOD > + * is set. > + * > + * @{ > + */ > + > +/** > + * @brief Possible actions where a registered hook could be invoked > + */ > +typedef enum { > + /** > + * @brief Constant to indicate the TOD is being set. > + */ > + TOD_ACTION_SET_CLOCK > +} TOD_Action; > + > +/** > + * @brief Structure to manage each TOD action hook > + */ > +typedef struct TOD_Hook { > + /** This is the chain node portion of an object. */ > + Chain_Node Node; > + > + /** This is the TOD action hook that is invoked. */ > + bool (*handler)(TOD_Action, const struct timespec *); > +} TOD_Hook; > + > +/** > + * @brief Set of registered methods for TOD Actions > + */ > +extern Chain_Control _TOD_Hooks; > + > +/** > + * @brief Add a TOD Action Hook > + * > + * This method is used to add a hook to the TOD action set. > + * > + * @brief hook is the action hook to register. > + * > + * @retval true if the hook is added. > + * @retval false if the hook cannot be added. > + */ > +bool _TOD_Hook_Register( > + TOD_Hook *hook > +); > + > +/** > + * @brief Remove a TOD Action Hook > + * > + * This method is used to remove a hook from the TOD action set. > + * > + * @brief hook is the action hook to unregister. > + * > + * @retval true if the hook is unregister. > + * @retval false if the hook cannot be unregister. > + */ > +bool _TOD_Hook_Unregister( > + TOD_Hook *hook > +); > + > +/** > + * @brief Run the TOD Action Hooks > + * > + * This method is used to invoke the set of TOD action hooks. > + * > + * @brief action is the action which triggered this run. > + * @brief tod is the current tod > + * > + * @retval true if the hooks can be run. > + * @retval false if the hook cannot be run. > + */ > +bool _TOD_Hook_Run( > + TOD_Action action, > + const struct timespec *tod > +); > + > + > +/** @} */ > + > #ifdef __cplusplus > } > #endif > diff --git a/cpukit/posix/src/clocksettime.c b/cpukit/posix/src/clocksettime.c > index a0fdd91..bfae46f 100644 > --- a/cpukit/posix/src/clocksettime.c > +++ b/cpukit/posix/src/clocksettime.c > @@ -32,6 +32,8 @@ int clock_settime( > const struct timespec *tp > ) > { > + bool retval; > + > if ( !tp ) > rtems_set_errno_and_return_minus_one( EINVAL ); > > @@ -43,19 +45,25 @@ int clock_settime( > > _TOD_Lock(); > _TOD_Acquire( &lock_context ); > - _TOD_Set( tp, &lock_context ); > + retval = _TOD_Set( tp, &lock_context );
Indented ... > _TOD_Unlock(); > + if ( retval == false ) { > + rtems_set_errno_and_return_minus_one( EPERM ); > + } > } > #ifdef _POSIX_CPUTIME > - else if ( clock_id == CLOCK_PROCESS_CPUTIME_ID ) > + else if ( clock_id == CLOCK_PROCESS_CPUTIME_ID ) { > rtems_set_errno_and_return_minus_one( ENOSYS ); > + } > #endif > #ifdef _POSIX_THREAD_CPUTIME > - else if ( clock_id == CLOCK_THREAD_CPUTIME_ID ) > + else if ( clock_id == CLOCK_THREAD_CPUTIME_ID ) { > rtems_set_errno_and_return_minus_one( ENOSYS ); > + } > #endif > - else > + else { > rtems_set_errno_and_return_minus_one( EINVAL ); > + } > > return 0; > } > diff --git a/cpukit/rtems/src/clockset.c b/cpukit/rtems/src/clockset.c > index d772682..a885fe1 100644 > --- a/cpukit/rtems/src/clockset.c > +++ b/cpukit/rtems/src/clockset.c > @@ -26,6 +26,8 @@ rtems_status_code rtems_clock_set( > const rtems_time_of_day *tod > ) > { > + bool retval; > + > if ( !tod ) > return RTEMS_INVALID_ADDRESS; > > @@ -39,10 +41,13 @@ rtems_status_code rtems_clock_set( > > _TOD_Lock(); > _TOD_Acquire( &lock_context ); > - _TOD_Set( &tod_as_timespec, &lock_context ); > + retval = _TOD_Set( &tod_as_timespec, &lock_context ); Not indented ... > _TOD_Unlock(); > > - return RTEMS_SUCCESSFUL; > + if ( retval == true ) { > + return RTEMS_SUCCESSFUL; > + } > + return RTEMS_IO_ERROR; > } > > return RTEMS_INVALID_CLOCK; > diff --git a/cpukit/score/src/coretodhookdata.c > b/cpukit/score/src/coretodhookdata.c > new file mode 100644 > index 0000000..6e7bcff > --- /dev/null > +++ b/cpukit/score/src/coretodhookdata.c > @@ -0,0 +1,45 @@ > +/** > + * @file > + * > + * @brief TOD Hook Set > + * > + * @ingroup RTEMSScoreTODHooks > + */ > + > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * COPYRIGHT (c) 2019. > + * On-Line Applications Research Corporation (OAR). > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#if HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <rtems/score/todimpl.h> > +#include <rtems/score/chainimpl.h> > + > +Chain_Control _TOD_Hooks = CHAIN_INITIALIZER_EMPTY(_TOD_Hooks); > + > diff --git a/cpukit/score/src/coretodhookregister.c > b/cpukit/score/src/coretodhookregister.c > new file mode 100644 > index 0000000..64cfdc9 > --- /dev/null > +++ b/cpukit/score/src/coretodhookregister.c > @@ -0,0 +1,60 @@ > +/** > + * @file > + * > + * @brief Register Hook to be in TOD Hook Set > + * > + * @ingroup RTEMSScoreTODHooks > + */ > + > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * COPYRIGHT (c) 2019. > + * On-Line Applications Research Corporation (OAR). > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#if HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <rtems/score/todimpl.h> > +#include <rtems/score/chainimpl.h> > + > +bool _TOD_Hook_Register( > + TOD_Hook *hook > +) > +{ > + ISR_lock_Context lock_context; > + > + if ( hook == NULL ) { > + return FALSE; > + } > + > + _TOD_Lock(); > + _TOD_Acquire( &lock_context ); > + _Chain_Append_unprotected( &_TOD_Hooks, &hook->Node ); Indented ... (and so on) ... > + _TOD_Unlock(); > + return true; > +} > + > diff --git a/cpukit/score/src/coretodhookrun.c > b/cpukit/score/src/coretodhookrun.c > new file mode 100644 > index 0000000..731dd9c > --- /dev/null > +++ b/cpukit/score/src/coretodhookrun.c > @@ -0,0 +1,69 @@ > +/** > + * @file > + * > + * @brief Run TOD Hook Set > + * > + * @ingroup RTEMSScoreTODHooks > + */ > + > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * COPYRIGHT (c) 2019. > + * On-Line Applications Research Corporation (OAR). > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#if HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <rtems/score/todimpl.h> > +#include <rtems/score/chainimpl.h> > + > +bool _TOD_Hook_Run( > + TOD_Action action, > + const struct timespec *tod > +) > +{ > + ISR_lock_Context lock_context; > + Chain_Node *the_node; > + bool retval = true; > + > + _TOD_Lock(); > + _TOD_Acquire( &lock_context ); > + for ( the_node = _Chain_First( &_TOD_Hooks ); > + !_Chain_Is_tail( &_TOD_Hooks, the_node ) ; > + the_node = the_node->next ) { > + TOD_Hook *the_hook = (TOD_Hook *) the_node; > + > + retval = (the_hook->handler)( action, tod ); > + if ( retval == false ) { > + break; > + } > + } Is the indenting of a lock region something new? I have not noticed it before now. What happens to the indenting when an unlock is in the loop with a return or there is a goto to an error label? Chris > + _TOD_Unlock(); > + > + return retval; > +} > + > diff --git a/cpukit/score/src/coretodhookunregister.c > b/cpukit/score/src/coretodhookunregister.c > new file mode 100644 > index 0000000..a766c46 > --- /dev/null > +++ b/cpukit/score/src/coretodhookunregister.c > @@ -0,0 +1,59 @@ > +/** > + * @file > + * > + * @brief Remove Hook from TOD Hook Set > + * > + * @ingroup RTEMSScoreTODHooks > + */ > + > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * COPYRIGHT (c) 2019. > + * On-Line Applications Research Corporation (OAR). > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > +#if HAVE_CONFIG_H > +#include "config.h" > +#endif > + > +#include <rtems/score/todimpl.h> > +#include <rtems/score/chainimpl.h> > + > +bool _TOD_Hook_Unregister( > + TOD_Hook *hook > +) > +{ > + ISR_lock_Context lock_context; > + > + if ( hook == NULL ) { > + return FALSE; > + } > + > + _TOD_Lock(); > + _TOD_Acquire( &lock_context ); > + _Chain_Extract_unprotected( &hook->Node ); > + _TOD_Unlock(); > + return true; > +} > diff --git a/cpukit/score/src/coretodset.c b/cpukit/score/src/coretodset.c > index b021a58..744d0e4 100644 > --- a/cpukit/score/src/coretodset.c > +++ b/cpukit/score/src/coretodset.c > @@ -22,7 +22,7 @@ > #include <rtems/score/assert.h> > #include <rtems/score/watchdogimpl.h> > > -void _TOD_Set( > +bool _TOD_Set( > const struct timespec *tod, > ISR_lock_Context *lock_context > ) > @@ -31,9 +31,15 @@ void _TOD_Set( > uint64_t tod_as_ticks; > uint32_t cpu_max; > uint32_t cpu_index; > + bool retval; > > _Assert( _TOD_Is_owner() ); > > + retval = _TOD_Hook_Run( TOD_ACTION_SET_CLOCK, tod ); > + if ( retval == false ) { > + return false; > + } > + > timespec2bintime( tod, &tod_as_bintime ); > _Timecounter_Set_clock( &tod_as_bintime, lock_context ); > > @@ -67,4 +73,6 @@ void _TOD_Set( > } > > _TOD.is_set = true; > + > + return true; > } > diff --git a/testsuites/sptests/Makefile.am b/testsuites/sptests/Makefile.am > index 09751b6..f127c2b 100644 > --- a/testsuites/sptests/Makefile.am > +++ b/testsuites/sptests/Makefile.am > @@ -707,6 +707,15 @@ spclock_err02_CPPFLAGS = $(AM_CPPFLAGS) > $(TEST_FLAGS_spclock_err02) \ > $(support_includes) > endif > > +if TEST_spclock_todhook01 > +sp_tests += spclock_todhook01 > +sp_screens += spclock_todhook01/spclock_todhook01.scn > +sp_docs += spclock_todhook01/spclock_todhook01.doc > +spclock_todhook01_SOURCES = spclock_todhook01/init.c > +spclock_todhook01_CPPFLAGS = $(AM_CPPFLAGS) $(TEST_FLAGS_spclock_todhook01) \ > + $(support_includes) > +endif > + > if TEST_spconfig01 > sp_tests += spconfig01 > sp_screens += spconfig01/spconfig01.scn > diff --git a/testsuites/sptests/configure.ac b/testsuites/sptests/configure.ac > index 3222196..2ad0c61 100644 > --- a/testsuites/sptests/configure.ac > +++ b/testsuites/sptests/configure.ac > @@ -117,6 +117,7 @@ RTEMS_TEST_CHECK([spcbssched03]) > RTEMS_TEST_CHECK([spchain]) > RTEMS_TEST_CHECK([spclock_err01]) > RTEMS_TEST_CHECK([spclock_err02]) > +RTEMS_TEST_CHECK([spclock_todhook01]) > RTEMS_TEST_CHECK([spconfig01]) > RTEMS_TEST_CHECK([spconfig02]) > RTEMS_TEST_CHECK([spconsole01]) > diff --git a/testsuites/sptests/spclock_todhook01/init.c > b/testsuites/sptests/spclock_todhook01/init.c > new file mode 100644 > index 0000000..5bbb51a > --- /dev/null > +++ b/testsuites/sptests/spclock_todhook01/init.c > @@ -0,0 +1,334 @@ > +/** > + * @file > + * > + * @brief Test TOD Set Hook > + * > + * @ingroup sptests > + */ > + > +/* > + * SPDX-License-Identifier: BSD-2-Clause > + * > + * COPYRIGHT (c) 2019. > + * On-Line Applications Research Corporation (OAR). > + * > + * Redistribution and use in source and binary forms, with or without > + * modification, are permitted provided that the following conditions > + * are met: > + * 1. Redistributions of source code must retain the above copyright > + * notice, this list of conditions and the following disclaimer. > + * 2. Redistributions in binary form must reproduce the above copyright > + * notice, this list of conditions and the following disclaimer in the > + * documentation and/or other materials provided with the distribution. > + * > + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS > IS" > + * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE > + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE > + * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE > + * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR > + * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF > + * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS > + * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN > + * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) > + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE > + * POSSIBILITY OF SUCH DAMAGE. > + */ > + > + > +#include <rtems.h> > +#include <rtems/score/todimpl.h> > + > +#include <errno.h> > +#include <stdio.h> > +#include <time.h> > +#include "tmacros.h" > + > +/* #define TEST_DEBUG */ > + > +const char rtems_test_name[] = "SPCLOCK TOD HOOK 1"; > + > +typedef struct test_case { > + bool do_settime; > + bool use_posix; > + bool do_hook1; > + bool do_hook2; > + struct tm tm; > +} testcase_t; > + > +testcase_t Cases[] = { > + /* should not trigger hooks when time not set */ > + { false, false, false, false, { 0, 0, 9, 31, 11, 88 } }, > + { false, false, true, true, { 0, 0, 9, 24, 5, 95 } }, > + /* should trigger hook when time is set with Classic API rtems_clock_set */ > + { true, false, false, false, { 0, 0, 9, 24, 5, 95 } }, > + { true, false, false, false, { 0, 0, 9, 31, 11, 88 } }, > + { true, false, true, false, { 0, 0, 9, 31, 11, 88 } }, > + { true, false, true, true, { 0, 0, 9, 24, 5, 105 } }, > + /* should trigger hook when time is set with POSIX API clock_settime */ > + { true, true, false, false, { 0, 0, 9, 24, 5, 95 } }, > + { true, true, false, false, { 0, 9, 6, 14, 2, 114 } }, > + { true, true, true, false, { 0, 0, 9, 31, 11, 88 } }, > + { true, true, true, true, { 0, 0, 9, 24, 5, 105 } }, > +}; > + > +#define NUM_CASES (sizeof(Cases)/sizeof(testcase_t)) > + > +static struct timespec tod_set; > + > +static bool hook1_executed; > +static bool hook2_executed; > + > +static bool tod_hook1( > + TOD_Action action, > + const struct timespec *tod > +) > +{ > + rtems_test_assert( action == TOD_ACTION_SET_CLOCK ); > + > + rtems_test_assert( tod->tv_sec == tod_set.tv_sec ); > + rtems_test_assert( tod->tv_nsec == tod_set.tv_nsec ); > + > + hook1_executed = true; > + > + return true; > +} > + > +static bool tod_hook2( > + TOD_Action action, > + const struct timespec *tod > +) > +{ > + rtems_test_assert( action == TOD_ACTION_SET_CLOCK ); > + > + rtems_test_assert( tod->tv_sec == tod_set.tv_sec ); > + rtems_test_assert( tod->tv_nsec == tod_set.tv_nsec ); > + > + hook2_executed = true; > + > + return true; > +} > + > +/* > + * Execute one positive test case. > + * > + * Assume no hooks registered at begining. Unregister if needed at the end. > + */ > +static void do_positive_case(int i) > +{ > + testcase_t *testcase = &Cases[i]; > + bool bc; > + TOD_Hook hook1; > + TOD_Hook hook2; > + > + #ifdef TEST_DEBUG > + printf( > + "%d: do_settime=%d use_posix=%d do_hook1=%d do_hook2=%d\n", > + i, > + testcase->do_settime, > + testcase->use_posix, > + testcase->do_hook1, > + testcase->do_hook2 > + ); > + #endif > + > + hook1.handler = tod_hook1; > + hook2.handler = tod_hook2; > + > + hook1_executed = false; > + hook2_executed = false; > + > + /* > + * Register the TOD Hooks > + */ > + if ( testcase->do_hook1 == true ) { > + bc =_TOD_Hook_Register( &hook1 ); > + rtems_test_assert( bc == true ); > + } > + > + if ( testcase->do_hook2 == true ) { > + bc =_TOD_Hook_Register( &hook2 ); > + rtems_test_assert( bc == true ); > + } > + > + /* > + * Now set the time and if registered, let the handlers fire > + */ > + if ( testcase->do_settime == true ) { > + rtems_time_of_day time; > + rtems_status_code status; > + struct tm *tm = &testcase->tm; > + > + tod_set.tv_sec = mktime( tm ); > + tod_set.tv_nsec = 0; > + > + if ( testcase->use_posix == false ) { > + build_time( > + &time, > + tm->tm_mon + 1, > + tm->tm_mday, > + tm->tm_year + 1900, > + tm->tm_hour, > + tm->tm_min, > + 0, > + 0 > + ); > + status = rtems_clock_set( &time ); > + directive_failed( status, "rtems_clock_set" ); > + } else { > + int rc; > + > + rc = clock_settime( CLOCK_REALTIME, &tod_set ); > + rtems_test_assert( rc == 0 ); > + } > + } > + > + /* > + * Unregister the TOD hooks > + */ > + if ( testcase->do_hook1 == true ) { > + bc =_TOD_Hook_Unregister( &hook1 ); > + rtems_test_assert( bc == true ); > + } > + > + if ( testcase->do_hook2 == true ) { > + bc =_TOD_Hook_Unregister( &hook2 ); > + rtems_test_assert( bc == true ); > + } > + > + #ifdef TEST_DEBUG > + printf( > + " hook1_executed=%d hook2_executed=%d\n", > + hook1_executed, > + hook2_executed > + ); > + #endif > + > + /* > + * Check expected results > + */ > + if ( testcase->do_hook1 == true ) { > + rtems_test_assert( testcase->do_settime == hook1_executed ); > + } else { > + rtems_test_assert( hook1_executed == false ); > + } > + > + if ( testcase->do_hook2 == true ) { > + rtems_test_assert( testcase->do_settime == hook2_executed ); > + } else { > + rtems_test_assert( hook2_executed == false ); > + } > +} > + > +static bool hook_error_executed; > + > +static bool tod_hook_error( > + TOD_Action action, > + const struct timespec *tod > +) > +{ > + rtems_test_assert( action == TOD_ACTION_SET_CLOCK ); > + > + rtems_test_assert( tod->tv_sec == tod_set.tv_sec ); > + rtems_test_assert( tod->tv_nsec == tod_set.tv_nsec ); > + > + hook_error_executed = true; > + > + return false; > +} > +/* > + * Execute one negative test case. > + * > + * Assume no hooks registered at begining. Unregister if needed at the end. > + */ > +static void do_negative_case(bool use_posix) > +{ > + bool bc; > + TOD_Hook hook_error; > + rtems_time_of_day time; > + rtems_status_code status; > + struct tm *tm = &Cases[0].tm; > + > + > + hook_error.handler = tod_hook_error; > + > + hook_error_executed = false; > + > + /* > + * Register the TOD Hooks > + */ > + bc =_TOD_Hook_Register( &hook_error ); > + rtems_test_assert( bc == true ); > + > + /* > + * Now set the time and if registered, let the handlers fire > + */ > + tod_set.tv_sec = mktime( tm ); > + tod_set.tv_nsec = 0; > + > + if ( use_posix == false ) { > + build_time( > + &time, > + tm->tm_mon + 1, > + tm->tm_mday, > + tm->tm_year + 1900, > + tm->tm_hour, > + tm->tm_min, > + 0, > + 0 > + ); > + status = rtems_clock_set( &time ); > + rtems_test_assert( status == RTEMS_IO_ERROR ); > + } else { > + int rc; > + > + rc = clock_settime( CLOCK_REALTIME, &tod_set ); > + rtems_test_assert( rc == -1 ); > + rtems_test_assert( errno == EPERM ); > + } > + > + /* > + * Unregister the TOD hooks > + */ > + bc =_TOD_Hook_Unregister( &hook_error ); > + rtems_test_assert( bc == true ); > + > + /* > + * Check expected results > + */ > + rtems_test_assert( hook_error_executed == true ); > +} > + > + > +static rtems_task Init(rtems_task_argument ignored) > +{ > + // rtems_status_code status; > + int i; > + > + TEST_BEGIN(); > + > + // test positive cases > + for (i=0 ; i < NUM_CASES ; i++) { > + do_positive_case( i ); > + } > + > + // test error cases > + do_negative_case(false); > + do_negative_case(true); > + > + TEST_END(); > + > + rtems_test_exit(0); > +} > + > +/* configuration information */ > +#define CONFIGURE_APPLICATION_NEEDS_SIMPLE_CONSOLE_DRIVER > +#define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER > + > +#define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION > + > +#define CONFIGURE_RTEMS_INIT_TASKS_TABLE > +#define CONFIGURE_MAXIMUM_TASKS 1 > + > +#define CONFIGURE_INIT > +#include <rtems/confdefs.h> > + > diff --git a/testsuites/sptests/spclock_todhook01/spclock_todhook01.doc > b/testsuites/sptests/spclock_todhook01/spclock_todhook01.doc > new file mode 100644 > index 0000000..0be564e > --- /dev/null > +++ b/testsuites/sptests/spclock_todhook01/spclock_todhook01.doc > @@ -0,0 +1,35 @@ > +# COPYRIGHT (c) 1989-2014. > +# On-Line Applications Research Corporation (OAR). > +# > +# The license and distribution terms for this file may be > +# found in the file LICENSE in this distribution or at > +# http://www.rtems.com/license/LICENSE. > +# > + > + > +This file describes the directives and concepts tested by this test set. > + > +test set name: spclock_todhook01 > + > +directives: > + _TOD_Hook_Register > + _TOD_Hook_Unregister > + rtems_clock_set > + clock_settime > + > + > +concepts: > + > +- Verifies that TOD Hooks can be registered > + > +- Verifies that TOD Hooks can be unregistered > + > +- Verifies that an empty TOD Hooks set is properly processed when the TOD is > set > + > +- Verifies that TOD Hooks are executed when the TOD is set > + > +- Verifies that a TOD Hook returning an error is properly reported by > + rtems_clock_set > + > +- Verifies that a TOD Hook returning an error is properly reported by > + clock_settime > diff --git a/testsuites/sptests/spclock_todhook01/spclock_todhook01.scn > b/testsuites/sptests/spclock_todhook01/spclock_todhook01.scn > new file mode 100644 > index 0000000..e69de29 > _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel