[PATCH] Add TOD Hooks to allow BSP to take action when TOD is set

Joel Sherrill joel at rtems.org
Thu Nov 14 00:32:38 UTC 2019


Sorry about the indenting. I don't know that we have an RTEMS style
recommendation on that.
It's a personal thing. I suspect there is RTEMS code with it. It makes
lock/unlock regions obvious
but it isn't conducive to unlocking inside if paths.

I will remove the indentation unless we think there is value to it and then
we need a separate
thread to define some rules.

I also fixed the one case of unnecessarily locking the TOD.

On Wed, Nov 13, 2019 at 6:16 PM Chris Johns <chrisj at rtems.org> wrote:

> 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 at rtems.org
> http://lists.rtems.org/mailman/listinfo/devel
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.rtems.org/pipermail/devel/attachments/20191113/9d0d02f1/attachment-0001.html>


More information about the devel mailing list