diff options
Diffstat (limited to 'cpukit/rtems')
57 files changed, 438 insertions, 712 deletions
diff --git a/cpukit/rtems/Makefile.am b/cpukit/rtems/Makefile.am index 5e6f2eafa0..f38990d2a7 100644 --- a/cpukit/rtems/Makefile.am +++ b/cpukit/rtems/Makefile.am @@ -155,10 +155,8 @@ librtems_a_SOURCES += src/clockgettod.c librtems_a_SOURCES += src/clockgettodtimeval.c librtems_a_SOURCES += src/clockgetuptime.c librtems_a_SOURCES += src/clockgetuptimetimeval.c -librtems_a_SOURCES += src/clockgetuptimeseconds.c librtems_a_SOURCES += src/clockgetuptimenanoseconds.c librtems_a_SOURCES += src/clockset.c -librtems_a_SOURCES += src/clocksetnsecshandler.c librtems_a_SOURCES += src/clocktick.c librtems_a_SOURCES += src/clocktodtoseconds.c librtems_a_SOURCES += src/clocktodvalidate.c @@ -210,7 +208,6 @@ librtems_a_SOURCES += src/eventreceive.c librtems_a_SOURCES += src/eventseize.c librtems_a_SOURCES += src/eventsend.c librtems_a_SOURCES += src/eventsurrender.c -librtems_a_SOURCES += src/eventtimeout.c librtems_a_SOURCES += src/systemeventsend.c librtems_a_SOURCES += src/systemeventreceive.c diff --git a/cpukit/rtems/include/rtems/rtems/barrierimpl.h b/cpukit/rtems/include/rtems/rtems/barrierimpl.h index 963ebd93da..e718028715 100644 --- a/cpukit/rtems/include/rtems/rtems/barrierimpl.h +++ b/cpukit/rtems/include/rtems/rtems/barrierimpl.h @@ -86,6 +86,7 @@ RTEMS_INLINE_ROUTINE void _Barrier_Free ( Barrier_Control *the_barrier ) { + _CORE_barrier_Destroy( &the_barrier->Barrier ); _Objects_Free( &_Barrier_Information, &the_barrier->Object ); } diff --git a/cpukit/rtems/include/rtems/rtems/clock.h b/cpukit/rtems/include/rtems/rtems/clock.h index 2a1c77251f..989bf2f5c9 100644 --- a/cpukit/rtems/include/rtems/rtems/clock.h +++ b/cpukit/rtems/include/rtems/rtems/clock.h @@ -14,7 +14,6 @@ * * - set the current date and time * - obtain the current date and time - * - set the nanoseconds since last clock tick handler * - announce a clock tick * - obtain the system uptime */ @@ -35,6 +34,7 @@ #include <rtems/rtems/status.h> #include <rtems/rtems/types.h> #include <rtems/config.h> +#include <rtems/score/timecounterimpl.h> #include <sys/time.h> /* struct timeval */ @@ -69,12 +69,6 @@ typedef enum { } rtems_clock_get_options; /** - * Type for the nanoseconds since last tick BSP extension. - */ -typedef TOD_Nanoseconds_since_last_tick_routine - rtems_nanoseconds_extension_routine; - -/** * @brief Obtain Current Time of Day * * @deprecated rtems_clock_get() is deprecated. Use the more explicit @@ -279,24 +273,6 @@ rtems_status_code rtems_clock_set( rtems_status_code rtems_clock_tick( void ); /** - * @brief Set the BSP specific Nanoseconds Extension - * - * Clock Manager - * - * This directive sets the BSP provided nanoseconds since last tick - * extension. - * - * @param[in] routine is a pointer to the extension routine - * - * @return This method returns RTEMS_SUCCESSFUL if there was not an - * error. Otherwise, a status code is returned indicating the - * source of the error. - */ -rtems_status_code rtems_clock_set_nanoseconds_extension( - rtems_nanoseconds_extension_routine routine -); - -/** * @brief Obtain the System Uptime * * This directive returns the system uptime. @@ -328,7 +304,10 @@ void rtems_clock_get_uptime_timeval( struct timeval *uptime ); * * @retval The system uptime in seconds. */ -time_t rtems_clock_get_uptime_seconds( void ); +RTEMS_INLINE_ROUTINE time_t rtems_clock_get_uptime_seconds( void ) +{ + return _Timecounter_Time_uptime - 1; +} /** * @brief Returns the system uptime in nanoseconds. diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h index dce7de1165..012452a9d8 100644 --- a/cpukit/rtems/include/rtems/rtems/event.h +++ b/cpukit/rtems/include/rtems/rtems/event.h @@ -319,6 +319,11 @@ rtems_status_code rtems_event_receive ( #define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26 /** + * @brief Reserved system event for the timer server. + */ +#define RTEMS_EVENT_SYSTEM_TIMER_SERVER RTEMS_EVENT_30 + +/** * @brief Reserved system event for transient usage. */ #define RTEMS_EVENT_SYSTEM_TRANSIENT RTEMS_EVENT_31 diff --git a/cpukit/rtems/include/rtems/rtems/messageimpl.h b/cpukit/rtems/include/rtems/rtems/messageimpl.h index e2bc88d0db..2399d65f29 100644 --- a/cpukit/rtems/include/rtems/rtems/messageimpl.h +++ b/cpukit/rtems/include/rtems/rtems/messageimpl.h @@ -18,6 +18,7 @@ #include <rtems/rtems/message.h> #include <rtems/score/objectimpl.h> +#include <rtems/score/coremsgimpl.h> #ifdef __cplusplus extern "C" { @@ -138,6 +139,21 @@ RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Get ( _Objects_Get( &_Message_queue_Information, id, location ); } +RTEMS_INLINE_ROUTINE Message_queue_Control * +_Message_queue_Get_interrupt_disable( + Objects_Id id, + Objects_Locations *location, + ISR_lock_Context *lock_context +) +{ + return (Message_queue_Control *) _Objects_Get_isr_disable( + &_Message_queue_Information, + id, + location, + lock_context + ); +} + RTEMS_INLINE_ROUTINE Message_queue_Control *_Message_queue_Allocate( void ) { return (Message_queue_Control *) diff --git a/cpukit/rtems/include/rtems/rtems/regionimpl.h b/cpukit/rtems/include/rtems/rtems/regionimpl.h index 9ff7b966ca..ae1a50d208 100644 --- a/cpukit/rtems/include/rtems/rtems/regionimpl.h +++ b/cpukit/rtems/include/rtems/rtems/regionimpl.h @@ -20,6 +20,7 @@ #include <rtems/rtems/region.h> #include <rtems/score/heapimpl.h> #include <rtems/score/objectimpl.h> +#include <rtems/score/threadqimpl.h> #include <rtems/debug.h> #ifdef __cplusplus @@ -84,6 +85,7 @@ RTEMS_INLINE_ROUTINE void _Region_Free ( Region_Control *the_region ) { + _Thread_queue_Destroy( &the_region->Wait_queue ); _Objects_Free( &_Region_Information, &the_region->Object ); } diff --git a/cpukit/rtems/include/rtems/rtems/timerimpl.h b/cpukit/rtems/include/rtems/rtems/timerimpl.h index b695d5e2fe..e5b37aa5f1 100644 --- a/cpukit/rtems/include/rtems/rtems/timerimpl.h +++ b/cpukit/rtems/include/rtems/rtems/timerimpl.h @@ -50,9 +50,9 @@ extern "C" { typedef struct Timer_server_Control Timer_server_Control; /** - * @brief Method used to schedule the insertion of task based timers. + * @brief Method used for task based timers. */ -typedef void (*Timer_server_Schedule_operation)( +typedef void (*Timer_server_Method)( Timer_server_Control *timer_server, Timer_Control *timer ); @@ -65,28 +65,52 @@ typedef struct { Watchdog_Control System_watchdog; /** + * @brief Remaining delta of the system watchdog. + */ + Watchdog_Interval system_watchdog_delta; + + /** + * @brief Unique identifier of the context which deals currently with the + * system watchdog. + */ + Thread_Control *system_watchdog_helper; + + /** + * @brief Each insert and tickle operation increases the generation count so + * that the system watchdog dealer notices updates of the watchdog chain. + */ + uint32_t generation; + + /** * @brief Watchdog header managed by the timer server. */ Watchdog_Header Header; /** - * @brief Last known time snapshot of the timer server. + * @brief Last time snapshot of the timer server. * * The units may be ticks or seconds. */ - Watchdog_Interval volatile last_snapshot; + Watchdog_Interval last_snapshot; + + /** + * @brief Current time snapshot of the timer server. + * + * The units may be ticks or seconds. + */ + Watchdog_Interval current_snapshot; } Timer_server_Watchdogs; struct Timer_server_Control { /** - * @brief Timer server thread. + * @brief The cancel method of the timer server. */ - Thread_Control *thread; + Timer_server_Method cancel; /** * @brief The schedule operation method of the timer server. */ - Timer_server_Schedule_operation schedule_operation; + Timer_server_Method schedule_operation; /** * @brief Interval watchdogs triggered by the timer server. @@ -97,26 +121,6 @@ struct Timer_server_Control { * @brief TOD watchdogs triggered by the timer server. */ Timer_server_Watchdogs TOD_watchdogs; - - /** - * @brief Chain of timers scheduled for insert. - * - * This pointer is not @c NULL whenever the interval and TOD chains are - * processed. After the processing this list will be checked and if - * necessary the processing will be restarted. Processing of these chains - * can be only interrupted through interrupts. - */ - Chain_Control *volatile insert_chain; - - /** - * @brief Indicates that the timer server is active or not. - * - * The server is active after the delay on a system watchdog. The activity - * period of the server ends when no more watchdogs managed by the server - * fire. The system watchdogs must not be manipulated when the server is - * active. - */ - bool volatile active; }; /** @@ -220,6 +224,8 @@ RTEMS_INLINE_ROUTINE bool _Timer_Is_dormant_class ( return ( the_class == TIMER_DORMANT ); } +void _Timer_Cancel( Timer_Control *the_timer ); + /**@}*/ #ifdef __cplusplus diff --git a/cpukit/rtems/src/clockgetuptime.c b/cpukit/rtems/src/clockgetuptime.c index 91ce6c46ee..acbe39a00e 100644 --- a/cpukit/rtems/src/clockgetuptime.c +++ b/cpukit/rtems/src/clockgetuptime.c @@ -42,6 +42,6 @@ rtems_status_code rtems_clock_get_uptime( if ( !uptime ) return RTEMS_INVALID_ADDRESS; - _TOD_Get_uptime_as_timespec( uptime ); + _TOD_Get_zero_based_uptime_as_timespec( uptime ); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/clockgetuptimenanoseconds.c b/cpukit/rtems/src/clockgetuptimenanoseconds.c index 0310e592e9..03ff73bba3 100644 --- a/cpukit/rtems/src/clockgetuptimenanoseconds.c +++ b/cpukit/rtems/src/clockgetuptimenanoseconds.c @@ -23,13 +23,8 @@ uint64_t rtems_clock_get_uptime_nanoseconds( void ) { Timestamp_Control snapshot_as_timestamp; - uint32_t nanoseconds; - ISR_lock_Context lock_context; - _TOD_Acquire( &_TOD, &lock_context ); - snapshot_as_timestamp = _TOD.uptime; - nanoseconds = ( *_TOD.nanoseconds_since_last_tick )(); - _TOD_Release( &_TOD, &lock_context ); + _TOD_Get_zero_based_uptime(&snapshot_as_timestamp); - return _Timestamp_Get_As_nanoseconds( &snapshot_as_timestamp, nanoseconds ); + return _Timestamp_Get_as_nanoseconds(&snapshot_as_timestamp); } diff --git a/cpukit/rtems/src/clockgetuptimeseconds.c b/cpukit/rtems/src/clockgetuptimeseconds.c deleted file mode 100644 index 0312921113..0000000000 --- a/cpukit/rtems/src/clockgetuptimeseconds.c +++ /dev/null @@ -1,43 +0,0 @@ -/** - * @file - * - * @brief Returns the system uptime in seconds. - * @ingroup ClassicClock Clocks - */ - -/* - * Copyright (c) 2012 embedded brains GmbH. All rights reserved. - * - * embedded brains GmbH - * Obere Lagerstr. 30 - * 82178 Puchheim - * Germany - * <rtems@embedded-brains.de> - * - * The license and distribution terms for this file may be - * found in the file LICENSE in this distribution or at - * http://www.rtems.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include <rtems/rtems/clock.h> -#include <rtems/score/todimpl.h> - -time_t rtems_clock_get_uptime_seconds( void ) -{ - TOD_Control *tod = &_TOD; - Timestamp_Control snapshot_as_timestamp; - struct timespec snapshot_as_timespec; - ISR_lock_Context lock_context; - - _TOD_Acquire( tod, &lock_context ); - snapshot_as_timestamp = tod->uptime; - _TOD_Release( tod, &lock_context ); - - _Timestamp_To_timespec( &snapshot_as_timestamp, &snapshot_as_timespec ); - - return snapshot_as_timespec.tv_sec; -} diff --git a/cpukit/rtems/src/clockgetuptimetimeval.c b/cpukit/rtems/src/clockgetuptimetimeval.c index 0cbaa836bc..2e09ae2cd2 100644 --- a/cpukit/rtems/src/clockgetuptimetimeval.c +++ b/cpukit/rtems/src/clockgetuptimetimeval.c @@ -30,6 +30,6 @@ void rtems_clock_get_uptime_timeval( struct timeval *uptime ) { Timestamp_Control snapshot_as_timestamp; - _TOD_Get_uptime( &snapshot_as_timestamp ); + _TOD_Get_zero_based_uptime( &snapshot_as_timestamp ); _Timestamp_To_timeval( &snapshot_as_timestamp, uptime ); } diff --git a/cpukit/rtems/src/clocksetnsecshandler.c b/cpukit/rtems/src/clocksetnsecshandler.c deleted file mode 100644 index ae08246902..0000000000 --- a/cpukit/rtems/src/clocksetnsecshandler.c +++ /dev/null @@ -1,34 +0,0 @@ -/** - * @file - * - * @brief Set the BSP specific Nanoseconds Extension - * @ingroup ClassicClock Clocks - */ - -/* - * COPYRIGHT (c) 1989-2006. - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H -#include "config.h" -#endif - -#include <rtems/rtems/clock.h> -#include <rtems/score/todimpl.h> - -rtems_status_code rtems_clock_set_nanoseconds_extension( - rtems_nanoseconds_extension_routine routine -) -{ - if ( !routine ) - return RTEMS_INVALID_ADDRESS; - - _TOD_Set_nanoseconds_since_last_tick_handler( routine ); - - return RTEMS_SUCCESSFUL; -} diff --git a/cpukit/rtems/src/clocktick.c b/cpukit/rtems/src/clocktick.c index a026b44494..e2cd35f5fc 100644 --- a/cpukit/rtems/src/clocktick.c +++ b/cpukit/rtems/src/clocktick.c @@ -19,30 +19,14 @@ #endif #include <rtems/rtems/clock.h> -#include <rtems/score/schedulerimpl.h> -#include <rtems/score/threadimpl.h> -#include <rtems/score/todimpl.h> -#include <rtems/score/watchdogimpl.h> +#include <rtems/score/timecounter.h> rtems_status_code rtems_clock_tick( void ) { -#if defined( RTEMS_SMP ) - _Thread_Disable_dispatch(); -#endif - - _TOD_Tickle_ticks(); - - _Watchdog_Tickle_ticks(); - - _Scheduler_Tick(); - -#if defined( RTEMS_SMP ) - _Thread_Enable_dispatch(); -#else - if ( _Thread_Is_context_switch_necessary() && - _Thread_Dispatch_is_enabled() ) - _Thread_Dispatch(); -#endif + _Timecounter_Tick_simple( + rtems_configuration_get_microseconds_per_tick(), + 0 + ); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/eventmp.c b/cpukit/rtems/src/eventmp.c index b2a5ce8a72..e2e43fcd0d 100644 --- a/cpukit/rtems/src/eventmp.c +++ b/cpukit/rtems/src/eventmp.c @@ -59,7 +59,8 @@ rtems_status_code _Event_MP_Send_request_packet ( _MPCI_Send_request_packet( _Objects_Get_node( event_id ), &the_packet->Prefix, - STATES_READY + STATES_READY, + RTEMS_TIMEOUT ); break; diff --git a/cpukit/rtems/src/eventseize.c b/cpukit/rtems/src/eventseize.c index 929665641c..a9290b38e8 100644 --- a/cpukit/rtems/src/eventseize.c +++ b/cpukit/rtems/src/eventseize.c @@ -84,12 +84,17 @@ void _Event_Seize( executing->Wait.return_argument = event_out; _Thread_Wait_flags_set( executing, intend_to_block ); - cpu_self = _Thread_Dispatch_disable_critical(); + cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Thread_Lock_release_default( executing, lock_context ); - _Giant_Acquire( cpu_self ); if ( ticks ) { - _Watchdog_Initialize( &executing->Timer, _Event_Timeout, 0, executing ); + _Thread_Wait_set_timeout_code( executing, RTEMS_TIMEOUT ); + _Watchdog_Initialize( + &executing->Timer, + _Thread_Timeout, + 0, + executing + ); _Watchdog_Insert_ticks( &executing->Timer, ticks ); } @@ -101,10 +106,9 @@ void _Event_Seize( wait_class | THREAD_WAIT_STATE_BLOCKED ); if ( !success ) { - _Watchdog_Remove( &executing->Timer ); + _Watchdog_Remove_ticks( &executing->Timer ); _Thread_Unblock( executing ); } - _Giant_Release( cpu_self ); _Thread_Dispatch_enable( cpu_self ); } diff --git a/cpukit/rtems/src/eventsend.c b/cpukit/rtems/src/eventsend.c index c9e81fb95f..23eed740a8 100644 --- a/cpukit/rtems/src/eventsend.c +++ b/cpukit/rtems/src/eventsend.c @@ -44,7 +44,6 @@ rtems_status_code rtems_event_send( THREAD_WAIT_CLASS_EVENT, &lock_context ); - _Objects_Put_for_get_isr_disable( &thread->Object ); sc = RTEMS_SUCCESSFUL; break; #ifdef RTEMS_MULTIPROCESSING diff --git a/cpukit/rtems/src/eventsurrender.c b/cpukit/rtems/src/eventsurrender.c index ba4e429f1e..156586023d 100644 --- a/cpukit/rtems/src/eventsurrender.c +++ b/cpukit/rtems/src/eventsurrender.c @@ -85,7 +85,7 @@ void _Event_Surrender( success = _Thread_Wait_flags_try_change_critical( the_thread, intend_to_block, - wait_class | THREAD_WAIT_STATE_INTERRUPT_SATISFIED + wait_class | THREAD_WAIT_STATE_READY_AGAIN ); if ( success ) { _Event_Satisfy( the_thread, event, pending_events, seized_events ); @@ -94,7 +94,7 @@ void _Event_Surrender( _Event_Satisfy( the_thread, event, pending_events, seized_events ); _Thread_Wait_flags_set( the_thread, - wait_class | THREAD_WAIT_STATE_SATISFIED + wait_class | THREAD_WAIT_STATE_READY_AGAIN ); unblock = true; } else { @@ -107,14 +107,12 @@ void _Event_Surrender( if ( unblock ) { Per_CPU_Control *cpu_self; - cpu_self = _Thread_Dispatch_disable_critical(); + cpu_self = _Thread_Dispatch_disable_critical( lock_context ); _Thread_Lock_release_default( the_thread, lock_context ); - _Giant_Acquire( cpu_self ); - _Watchdog_Remove( &the_thread->Timer ); + _Watchdog_Remove_ticks( &the_thread->Timer ); _Thread_Unblock( the_thread ); - _Giant_Release( cpu_self ); _Thread_Dispatch_enable( cpu_self ); } else { _Thread_Lock_release_default( the_thread, lock_context ); diff --git a/cpukit/rtems/src/eventtimeout.c b/cpukit/rtems/src/eventtimeout.c deleted file mode 100644 index 9c091748c0..0000000000 --- a/cpukit/rtems/src/eventtimeout.c +++ /dev/null @@ -1,70 +0,0 @@ -/** - * @file - * - * @brief Timeout Event - * @ingroup ClassicEvent - */ - -/* - * COPYRIGHT (c) 1989-2008. - * 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.org/license/LICENSE. - */ - -#if HAVE_CONFIG_H - #include "config.h" -#endif - -#include <rtems/rtems/eventimpl.h> -#include <rtems/score/threadimpl.h> - -void _Event_Timeout( - Objects_Id id, - void *arg -) -{ - Thread_Control *the_thread; - ISR_lock_Context lock_context; - Thread_Wait_flags wait_flags; - Thread_Wait_flags wait_class; - Thread_Wait_flags intend_to_block; - Thread_Wait_flags blocked; - bool success; - bool unblock; - - the_thread = arg; - _Thread_Lock_acquire_default( the_thread, &lock_context ); - - wait_flags = _Thread_Wait_flags_get( the_thread ); - wait_class = wait_flags & THREAD_WAIT_CLASS_MASK; - intend_to_block = wait_class | THREAD_WAIT_STATE_INTEND_TO_BLOCK; - blocked = wait_class | THREAD_WAIT_STATE_BLOCKED; - success = _Thread_Wait_flags_try_change_critical( - the_thread, - intend_to_block, - wait_class | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT - ); - - if ( success ) { - the_thread->Wait.return_code = RTEMS_TIMEOUT; - unblock = false; - } else if ( _Thread_Wait_flags_get( the_thread ) == blocked ) { - the_thread->Wait.return_code = RTEMS_TIMEOUT; - _Thread_Wait_flags_set( - the_thread, - wait_class | THREAD_WAIT_STATE_TIMEOUT - ); - unblock = true; - } else { - unblock = false; - } - - _Thread_Lock_release_default( the_thread, &lock_context ); - - if ( unblock ) { - _Thread_Unblock( the_thread ); - } -} diff --git a/cpukit/rtems/src/msgmp.c b/cpukit/rtems/src/msgmp.c index 7043138963..83b5a31f52 100644 --- a/cpukit/rtems/src/msgmp.c +++ b/cpukit/rtems/src/msgmp.c @@ -148,7 +148,8 @@ rtems_status_code _Message_queue_MP_Send_request_packet ( return (rtems_status_code) _MPCI_Send_request_packet( _Objects_Get_node(message_queue_id), &the_packet->Prefix, - STATES_WAITING_FOR_MESSAGE + STATES_WAITING_FOR_MESSAGE, + RTEMS_TIMEOUT ); break; @@ -173,7 +174,8 @@ rtems_status_code _Message_queue_MP_Send_request_packet ( return (rtems_status_code) _MPCI_Send_request_packet( _Objects_Get_node(message_queue_id), &the_packet->Prefix, - STATES_WAITING_FOR_MESSAGE + STATES_WAITING_FOR_MESSAGE, + RTEMS_TIMEOUT ); break; @@ -291,7 +293,7 @@ void _Message_queue_MP_Process_packet ( the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); if (! _Thread_Is_null( the_thread ) ) - _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + _Thread_queue_Extract( the_thread ); _MPCI_Return_packet( the_packet_prefix ); break; diff --git a/cpukit/rtems/src/msgqbroadcast.c b/cpukit/rtems/src/msgqbroadcast.c index 64ea80e3de..aabbf3f6ac 100644 --- a/cpukit/rtems/src/msgqbroadcast.c +++ b/cpukit/rtems/src/msgqbroadcast.c @@ -40,6 +40,7 @@ rtems_status_code rtems_message_queue_broadcast( Message_queue_Control *the_message_queue; Objects_Locations location; CORE_message_queue_Status core_status; + ISR_lock_Context lock_context; if ( !buffer ) return RTEMS_INVALID_ADDRESS; @@ -47,7 +48,11 @@ rtems_status_code rtems_message_queue_broadcast( if ( !count ) return RTEMS_INVALID_ADDRESS; - the_message_queue = _Message_queue_Get( id, &location ); + the_message_queue = _Message_queue_Get_interrupt_disable( + id, + &location, + &lock_context + ); switch ( location ) { case OBJECTS_LOCAL: @@ -61,10 +66,9 @@ rtems_status_code rtems_message_queue_broadcast( #else NULL, #endif - count + count, + &lock_context ); - - _Objects_Put( &the_message_queue->Object ); return _Message_queue_Translate_core_message_queue_return_code( core_status ); diff --git a/cpukit/rtems/src/msgqflush.c b/cpukit/rtems/src/msgqflush.c index 7ae7ef4544..809c243b52 100644 --- a/cpukit/rtems/src/msgqflush.c +++ b/cpukit/rtems/src/msgqflush.c @@ -54,16 +54,23 @@ rtems_status_code rtems_message_queue_flush( { Message_queue_Control *the_message_queue; Objects_Locations location; + ISR_lock_Context lock_context; if ( !count ) return RTEMS_INVALID_ADDRESS; - the_message_queue = _Message_queue_Get( id, &location ); + the_message_queue = _Message_queue_Get_interrupt_disable( + id, + &location, + &lock_context + ); switch ( location ) { case OBJECTS_LOCAL: - *count = _CORE_message_queue_Flush( &the_message_queue->message_queue ); - _Objects_Put( &the_message_queue->Object ); + *count = _CORE_message_queue_Flush( + &the_message_queue->message_queue, + &lock_context + ); return RTEMS_SUCCESSFUL; #if defined(RTEMS_MULTIPROCESSING) diff --git a/cpukit/rtems/src/msgqreceive.c b/cpukit/rtems/src/msgqreceive.c index db09cfe547..2b9a4e742b 100644 --- a/cpukit/rtems/src/msgqreceive.c +++ b/cpukit/rtems/src/msgqreceive.c @@ -42,6 +42,7 @@ rtems_status_code rtems_message_queue_receive( Objects_Locations location; bool wait; Thread_Control *executing; + ISR_lock_Context lock_context; if ( !buffer ) return RTEMS_INVALID_ADDRESS; @@ -49,7 +50,11 @@ rtems_status_code rtems_message_queue_receive( if ( !size ) return RTEMS_INVALID_ADDRESS; - the_message_queue = _Message_queue_Get( id, &location ); + the_message_queue = _Message_queue_Get_interrupt_disable( + id, + &location, + &lock_context + ); switch ( location ) { case OBJECTS_LOCAL: @@ -66,9 +71,9 @@ rtems_status_code rtems_message_queue_receive( buffer, size, wait, - timeout + timeout, + &lock_context ); - _Objects_Put( &the_message_queue->Object ); return _Message_queue_Translate_core_message_queue_return_code( executing->Wait.return_code ); diff --git a/cpukit/rtems/src/msgqsend.c b/cpukit/rtems/src/msgqsend.c index 34b7c29e7c..fb3979ed78 100644 --- a/cpukit/rtems/src/msgqsend.c +++ b/cpukit/rtems/src/msgqsend.c @@ -62,11 +62,16 @@ rtems_status_code rtems_message_queue_send( Message_queue_Control *the_message_queue; Objects_Locations location; CORE_message_queue_Status status; + ISR_lock_Context lock_context; if ( !buffer ) return RTEMS_INVALID_ADDRESS; - the_message_queue = _Message_queue_Get( id, &location ); + the_message_queue = _Message_queue_Get_interrupt_disable( + id, + &location, + &lock_context + ); switch ( location ) { case OBJECTS_LOCAL: @@ -77,11 +82,10 @@ rtems_status_code rtems_message_queue_send( id, MESSAGE_QUEUE_MP_HANDLER, false, /* sender does not block */ - 0 /* no timeout */ + 0, /* no timeout */ + &lock_context ); - _Objects_Put( &the_message_queue->Object ); - /* * Since this API does not allow for blocking sends, we can directly * return the returned status. diff --git a/cpukit/rtems/src/msgqurgent.c b/cpukit/rtems/src/msgqurgent.c index 85a9d4f1b4..e6ae5efcf0 100644 --- a/cpukit/rtems/src/msgqurgent.c +++ b/cpukit/rtems/src/msgqurgent.c @@ -45,11 +45,16 @@ rtems_status_code rtems_message_queue_urgent( Message_queue_Control *the_message_queue; Objects_Locations location; CORE_message_queue_Status status; + ISR_lock_Context lock_context; if ( !buffer ) return RTEMS_INVALID_ADDRESS; - the_message_queue = _Message_queue_Get( id, &location ); + the_message_queue = _Message_queue_Get_interrupt_disable( + id, + &location, + &lock_context + ); switch ( location ) { case OBJECTS_LOCAL: @@ -60,9 +65,9 @@ rtems_status_code rtems_message_queue_urgent( id, MESSAGE_QUEUE_MP_HANDLER, false, /* sender does not block */ - 0 /* no timeout */ + 0, /* no timeout */ + &lock_context ); - _Objects_Put( &the_message_queue->Object ); /* * Since this API does not allow for blocking sends, we can directly diff --git a/cpukit/rtems/src/partmp.c b/cpukit/rtems/src/partmp.c index 943c24ac6d..9593ce58a9 100644 --- a/cpukit/rtems/src/partmp.c +++ b/cpukit/rtems/src/partmp.c @@ -104,7 +104,8 @@ rtems_status_code _Partition_MP_Send_request_packet ( _MPCI_Send_request_packet( _Objects_Get_node( partition_id ), &the_packet->Prefix, - STATES_READY /* Not used */ + STATES_READY, /* Not used */ + RTEMS_TIMEOUT ); break; @@ -209,7 +210,7 @@ void _Partition_MP_Process_packet ( the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); if ( ! _Thread_Is_null( the_thread ) ) - _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + _Thread_queue_Extract( the_thread ); _MPCI_Return_packet( the_packet_prefix ); break; diff --git a/cpukit/rtems/src/ratemoncancel.c b/cpukit/rtems/src/ratemoncancel.c index d4a9102955..67b230fbfc 100644 --- a/cpukit/rtems/src/ratemoncancel.c +++ b/cpukit/rtems/src/ratemoncancel.c @@ -38,7 +38,7 @@ rtems_status_code rtems_rate_monotonic_cancel( _Objects_Put( &the_period->Object ); return RTEMS_NOT_OWNER_OF_RESOURCE; } - (void) _Watchdog_Remove( &the_period->Timer ); + _Watchdog_Remove_ticks( &the_period->Timer ); the_period->state = RATE_MONOTONIC_INACTIVE; _Scheduler_Release_job( the_period->owner, 0 ); _Objects_Put( &the_period->Object ); diff --git a/cpukit/rtems/src/ratemondelete.c b/cpukit/rtems/src/ratemondelete.c index 971ad8ef3d..77cf3fe306 100644 --- a/cpukit/rtems/src/ratemondelete.c +++ b/cpukit/rtems/src/ratemondelete.c @@ -37,7 +37,7 @@ rtems_status_code rtems_rate_monotonic_delete( case OBJECTS_LOCAL: _Scheduler_Release_job( the_period->owner, 0 ); _Objects_Close( &_Rate_monotonic_Information, &the_period->Object ); - (void) _Watchdog_Remove( &the_period->Timer ); + _Watchdog_Remove_ticks( &the_period->Timer ); the_period->state = RATE_MONOTONIC_INACTIVE; _Objects_Put( &the_period->Object ); _Rate_monotonic_Free( the_period ); diff --git a/cpukit/rtems/src/regioncreate.c b/cpukit/rtems/src/regioncreate.c index 0daf644ce3..409510c892 100644 --- a/cpukit/rtems/src/regioncreate.c +++ b/cpukit/rtems/src/regioncreate.c @@ -71,6 +71,11 @@ rtems_status_code rtems_region_create( return_status = RTEMS_TOO_MANY; else { + _Thread_queue_Initialize( + &the_region->Wait_queue, + _Attributes_Is_priority( attribute_set ) ? + THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO + ); the_region->maximum_segment_size = _Heap_Initialize( &the_region->Memory, starting_address, length, page_size @@ -79,23 +84,13 @@ rtems_status_code rtems_region_create( if ( !the_region->maximum_segment_size ) { _Region_Free( the_region ); return_status = RTEMS_INVALID_SIZE; - } - - else { - + } else { the_region->starting_address = starting_address; the_region->length = length; the_region->page_size = page_size; the_region->attribute_set = attribute_set; the_region->number_of_used_blocks = 0; - _Thread_queue_Initialize( - &the_region->Wait_queue, - _Attributes_Is_priority( attribute_set ) ? - THREAD_QUEUE_DISCIPLINE_PRIORITY : THREAD_QUEUE_DISCIPLINE_FIFO, - RTEMS_TIMEOUT - ); - _Objects_Open( &_Region_Information, &the_region->Object, diff --git a/cpukit/rtems/src/regiondelete.c b/cpukit/rtems/src/regiondelete.c index 5a2df7c009..b5209da890 100644 --- a/cpukit/rtems/src/regiondelete.c +++ b/cpukit/rtems/src/regiondelete.c @@ -52,7 +52,6 @@ rtems_status_code rtems_region_delete( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/regionextend.c b/cpukit/rtems/src/regionextend.c index 65b68cdf1a..2ee2b992e4 100644 --- a/cpukit/rtems/src/regionextend.c +++ b/cpukit/rtems/src/regionextend.c @@ -65,7 +65,6 @@ rtems_status_code rtems_region_extend( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/regiongetfreeinfo.c b/cpukit/rtems/src/regiongetfreeinfo.c index be0f0089a9..6ebd1abbd2 100644 --- a/cpukit/rtems/src/regiongetfreeinfo.c +++ b/cpukit/rtems/src/regiongetfreeinfo.c @@ -56,7 +56,6 @@ rtems_status_code rtems_region_get_free_information( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/regiongetinfo.c b/cpukit/rtems/src/regiongetinfo.c index c3466f0566..d5eee727d3 100644 --- a/cpukit/rtems/src/regiongetinfo.c +++ b/cpukit/rtems/src/regiongetinfo.c @@ -50,7 +50,6 @@ rtems_status_code rtems_region_get_information( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/regiongetsegment.c b/cpukit/rtems/src/regiongetsegment.c index 1a52bc1d59..26437b5188 100644 --- a/cpukit/rtems/src/regiongetsegment.c +++ b/cpukit/rtems/src/regiongetsegment.c @@ -79,18 +79,16 @@ rtems_status_code rtems_region_get_segment( _Thread_Disable_dispatch(); _RTEMS_Unlock_allocator(); - executing->Wait.queue = &the_region->Wait_queue; executing->Wait.id = id; executing->Wait.count = size; executing->Wait.return_argument = segment; - _Thread_queue_Enter_critical_section( &the_region->Wait_queue ); - _Thread_queue_Enqueue( &the_region->Wait_queue, executing, STATES_WAITING_FOR_SEGMENT, - timeout + timeout, + RTEMS_TIMEOUT ); _Objects_Put( &the_region->Object ); @@ -102,7 +100,6 @@ rtems_status_code rtems_region_get_segment( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/regiongetsegmentsize.c b/cpukit/rtems/src/regiongetsegmentsize.c index 8f823fcec9..ab07a56e9c 100644 --- a/cpukit/rtems/src/regiongetsegmentsize.c +++ b/cpukit/rtems/src/regiongetsegmentsize.c @@ -53,7 +53,6 @@ rtems_status_code rtems_region_get_segment_size( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/regionmp.c b/cpukit/rtems/src/regionmp.c index 58dfa99dde..135a69dd97 100644 --- a/cpukit/rtems/src/regionmp.c +++ b/cpukit/rtems/src/regionmp.c @@ -102,7 +102,8 @@ rtems_status_code _Region_MP_Send_request_packet ( return (rtems_status_code) _MPCI_Send_request_packet( _Objects_Get_node( region_id ), &the_packet->Prefix, - STATES_READY /* Not used */ + STATES_READY, /* Not used */ + RTEMS_TIMEOUT ); break; @@ -195,7 +196,7 @@ void _Region_MP_Process_packet ( the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); if ( ! _Thread_Is_null( the_thread ) ) - _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + _Thread_queue_Extract( the_thread ); _MPCI_Return_packet( the_packet_prefix ); break; diff --git a/cpukit/rtems/src/regionprocessqueue.c b/cpukit/rtems/src/regionprocessqueue.c index 54081af84d..a06a077e3d 100644 --- a/cpukit/rtems/src/regionprocessqueue.c +++ b/cpukit/rtems/src/regionprocessqueue.c @@ -61,7 +61,7 @@ void _Region_Process_queue( *(void **)the_thread->Wait.return_argument = the_segment; the_region->number_of_used_blocks += 1; - _Thread_queue_Extract( &the_region->Wait_queue, the_thread ); + _Thread_queue_Extract( the_thread ); the_thread->Wait.return_code = RTEMS_SUCCESSFUL; } _Thread_Enable_dispatch(); diff --git a/cpukit/rtems/src/regionresizesegment.c b/cpukit/rtems/src/regionresizesegment.c index ee3499a729..b1d9482c79 100644 --- a/cpukit/rtems/src/regionresizesegment.c +++ b/cpukit/rtems/src/regionresizesegment.c @@ -79,7 +79,6 @@ rtems_status_code rtems_region_resize_segment( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/regionreturnsegment.c b/cpukit/rtems/src/regionreturnsegment.c index 6ae537fd4f..98f2240a23 100644 --- a/cpukit/rtems/src/regionreturnsegment.c +++ b/cpukit/rtems/src/regionreturnsegment.c @@ -82,7 +82,6 @@ rtems_status_code rtems_region_return_segment( #if defined(RTEMS_MULTIPROCESSING) case OBJECTS_REMOTE: /* this error cannot be returned */ - break; #endif case OBJECTS_ERROR: diff --git a/cpukit/rtems/src/semdelete.c b/cpukit/rtems/src/semdelete.c index a805ac61de..e9c3ad21e9 100644 --- a/cpukit/rtems/src/semdelete.c +++ b/cpukit/rtems/src/semdelete.c @@ -76,12 +76,14 @@ rtems_status_code rtems_semaphore_delete( SEMAPHORE_MP_OBJECT_WAS_DELETED, CORE_MUTEX_WAS_DELETED ); + _CORE_mutex_Destroy( &the_semaphore->Core_control.mutex ); } else { _CORE_semaphore_Flush( &the_semaphore->Core_control.semaphore, SEMAPHORE_MP_OBJECT_WAS_DELETED, CORE_SEMAPHORE_WAS_DELETED ); + _CORE_semaphore_Destroy( &the_semaphore->Core_control.semaphore ); } _Objects_Close( &_Semaphore_Information, &the_semaphore->Object ); diff --git a/cpukit/rtems/src/semmp.c b/cpukit/rtems/src/semmp.c index eabd1b7a0b..f4c5cb73df 100644 --- a/cpukit/rtems/src/semmp.c +++ b/cpukit/rtems/src/semmp.c @@ -95,7 +95,8 @@ rtems_status_code _Semaphore_MP_Send_request_packet ( return _MPCI_Send_request_packet( _Objects_Get_node( semaphore_id ), &the_packet->Prefix, - STATES_WAITING_FOR_SEMAPHORE + STATES_WAITING_FOR_SEMAPHORE, + RTEMS_TIMEOUT ); break; @@ -188,7 +189,7 @@ void _Semaphore_MP_Process_packet ( the_thread = _Thread_MP_Find_proxy( the_packet->proxy_id ); if ( ! _Thread_Is_null( the_thread ) ) - _Thread_queue_Extract( the_thread->Wait.queue, the_thread ); + _Thread_queue_Extract( the_thread ); _MPCI_Return_packet( the_packet_prefix ); break; diff --git a/cpukit/rtems/src/semobtain.c b/cpukit/rtems/src/semobtain.c index 0edac96264..bda39fa80e 100644 --- a/cpukit/rtems/src/semobtain.c +++ b/cpukit/rtems/src/semobtain.c @@ -56,19 +56,16 @@ rtems_status_code rtems_semaphore_obtain( attribute_set = the_semaphore->attribute_set; wait = !_Options_Is_no_wait( option_set ); #if defined(RTEMS_SMP) - _Thread_Disable_dispatch(); if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { MRSP_Status mrsp_status; - _ISR_lock_ISR_enable( &lock_context ); mrsp_status = _MRSP_Obtain( &the_semaphore->Core_control.mrsp, executing, wait, - timeout + timeout, + &lock_context ); - _Thread_Enable_dispatch(); - _Objects_Put_for_get_isr_disable( &the_semaphore->Object ); return _Semaphore_Translate_MRSP_status_code( mrsp_status ); } else #endif @@ -81,16 +78,12 @@ rtems_status_code rtems_semaphore_obtain( timeout, &lock_context ); -#if defined(RTEMS_SMP) - _Thread_Enable_dispatch(); -#endif - _Objects_Put_for_get_isr_disable( &the_semaphore->Object ); return _Semaphore_Translate_core_mutex_return_code( executing->Wait.return_code ); } /* must be a counting semaphore */ - _CORE_semaphore_Seize_isr_disable( + _CORE_semaphore_Seize( &the_semaphore->Core_control.semaphore, executing, id, @@ -98,10 +91,6 @@ rtems_status_code rtems_semaphore_obtain( timeout, &lock_context ); -#if defined(RTEMS_SMP) - _Thread_Enable_dispatch(); -#endif - _Objects_Put_for_get_isr_disable( &the_semaphore->Object ); return _Semaphore_Translate_core_semaphore_return_code( executing->Wait.return_code ); diff --git a/cpukit/rtems/src/semrelease.c b/cpukit/rtems/src/semrelease.c index 37a05b2507..5d41b6cfae 100644 --- a/cpukit/rtems/src/semrelease.c +++ b/cpukit/rtems/src/semrelease.c @@ -62,19 +62,26 @@ rtems_status_code rtems_semaphore_release( CORE_mutex_Status mutex_status; CORE_semaphore_Status semaphore_status; rtems_attribute attribute_set; + ISR_lock_Context lock_context; - the_semaphore = _Semaphore_Get( id, &location ); + the_semaphore = _Semaphore_Get_interrupt_disable( + id, + &location, + &lock_context + ); switch ( location ) { case OBJECTS_LOCAL: attribute_set = the_semaphore->attribute_set; #if defined(RTEMS_SMP) if ( _Attributes_Is_multiprocessor_resource_sharing( attribute_set ) ) { - MRSP_Status mrsp_status = _MRSP_Release( + MRSP_Status mrsp_status; + + mrsp_status = _MRSP_Release( &the_semaphore->Core_control.mrsp, - _Thread_Get_executing() + _Thread_Executing, + &lock_context ); - _Objects_Put( &the_semaphore->Object ); return _Semaphore_Translate_MRSP_status_code( mrsp_status ); } else #endif @@ -82,17 +89,17 @@ rtems_status_code rtems_semaphore_release( mutex_status = _CORE_mutex_Surrender( &the_semaphore->Core_control.mutex, id, - MUTEX_MP_SUPPORT + MUTEX_MP_SUPPORT, + &lock_context ); - _Objects_Put( &the_semaphore->Object ); return _Semaphore_Translate_core_mutex_return_code( mutex_status ); } else { semaphore_status = _CORE_semaphore_Surrender( &the_semaphore->Core_control.semaphore, id, - MUTEX_MP_SUPPORT + MUTEX_MP_SUPPORT, + &lock_context ); - _Objects_Put( &the_semaphore->Object ); return _Semaphore_Translate_core_semaphore_return_code( semaphore_status ); } diff --git a/cpukit/rtems/src/signalmp.c b/cpukit/rtems/src/signalmp.c index 9d2177d214..4a2d5738af 100644 --- a/cpukit/rtems/src/signalmp.c +++ b/cpukit/rtems/src/signalmp.c @@ -60,7 +60,8 @@ rtems_status_code _Signal_MP_Send_request_packet ( return _MPCI_Send_request_packet( _Objects_Get_node( task_id ), &the_packet->Prefix, - STATES_READY /* Not used */ + STATES_READY, /* Not used */ + RTEMS_TIMEOUT ); break; diff --git a/cpukit/rtems/src/systemeventsend.c b/cpukit/rtems/src/systemeventsend.c index 1892c13fe7..3c821c9ef9 100644 --- a/cpukit/rtems/src/systemeventsend.c +++ b/cpukit/rtems/src/systemeventsend.c @@ -50,7 +50,6 @@ rtems_status_code rtems_event_system_send( THREAD_WAIT_CLASS_SYSTEM_EVENT, &lock_context ); - _Objects_Put_for_get_isr_disable( &thread->Object ); sc = RTEMS_SUCCESSFUL; break; #ifdef RTEMS_MULTIPROCESSING diff --git a/cpukit/rtems/src/taskmp.c b/cpukit/rtems/src/taskmp.c index 4b97ffe639..339544cdc4 100644 --- a/cpukit/rtems/src/taskmp.c +++ b/cpukit/rtems/src/taskmp.c @@ -108,7 +108,8 @@ rtems_status_code _RTEMS_tasks_MP_Send_request_packet ( return _MPCI_Send_request_packet( _Objects_Get_node( task_id ), &the_packet->Prefix, - STATES_READY /* Not used */ + STATES_READY, /* Not used */ + RTEMS_TIMEOUT ); break; diff --git a/cpukit/rtems/src/tasksetpriority.c b/cpukit/rtems/src/tasksetpriority.c index 4e4835675d..582c67f9f2 100644 --- a/cpukit/rtems/src/tasksetpriority.c +++ b/cpukit/rtems/src/tasksetpriority.c @@ -41,16 +41,18 @@ rtems_status_code rtems_task_set_priority( switch ( location ) { case OBJECTS_LOCAL: - *old_priority = _RTEMS_tasks_Priority_from_Core( - the_thread->current_priority - ); if ( new_priority != RTEMS_CURRENT_PRIORITY ) { - the_thread->real_priority = _RTEMS_tasks_Priority_to_Core( - new_priority - ); - if ( !_Thread_Owns_resources( the_thread ) || - the_thread->current_priority > new_priority ) - _Thread_Change_priority( the_thread, new_priority, false ); + _Thread_Set_priority( + the_thread, + _RTEMS_tasks_Priority_to_Core( new_priority ), + old_priority, + false + ); + *old_priority = _RTEMS_tasks_Priority_from_Core( *old_priority ); + } else { + *old_priority = _RTEMS_tasks_Priority_from_Core( + the_thread->current_priority + ); } _Objects_Put( &the_thread->Object ); return RTEMS_SUCCESSFUL; diff --git a/cpukit/rtems/src/taskwakeafter.c b/cpukit/rtems/src/taskwakeafter.c index 6f0322723a..b7f328f5bc 100644 --- a/cpukit/rtems/src/taskwakeafter.c +++ b/cpukit/rtems/src/taskwakeafter.c @@ -30,23 +30,25 @@ rtems_status_code rtems_task_wake_after( * It is critical to obtain the executing thread after thread dispatching is * disabled on SMP configurations. */ - Thread_Control *executing; + Thread_Control *executing; + Per_CPU_Control *cpu_self; - _Thread_Disable_dispatch(); + cpu_self = _Thread_Dispatch_disable(); executing = _Thread_Executing; if ( ticks == 0 ) { _Thread_Yield( executing ); } else { _Thread_Set_state( executing, STATES_DELAYING ); + _Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED ); _Watchdog_Initialize( &executing->Timer, - _Thread_Delay_ended, + _Thread_Timeout, 0, executing ); _Watchdog_Insert_ticks( &executing->Timer, ticks ); } - _Thread_Enable_dispatch(); + _Thread_Dispatch_enable( cpu_self ); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/taskwakewhen.c b/cpukit/rtems/src/taskwakewhen.c index a1fc15f047..cf0b303cd3 100644 --- a/cpukit/rtems/src/taskwakewhen.c +++ b/cpukit/rtems/src/taskwakewhen.c @@ -30,6 +30,7 @@ rtems_status_code rtems_task_wake_when( { Watchdog_Interval seconds; Thread_Control *executing; + Per_CPU_Control *cpu_self; if ( !_TOD_Is_set() ) return RTEMS_NOT_DEFINED; @@ -47,12 +48,13 @@ rtems_status_code rtems_task_wake_when( if ( seconds <= _TOD_Seconds_since_epoch() ) return RTEMS_INVALID_CLOCK; - _Thread_Disable_dispatch(); + cpu_self = _Thread_Dispatch_disable(); executing = _Thread_Executing; _Thread_Set_state( executing, STATES_WAITING_FOR_TIME ); + _Thread_Wait_flags_set( executing, THREAD_WAIT_STATE_BLOCKED ); _Watchdog_Initialize( &executing->Timer, - _Thread_Delay_ended, + _Thread_Timeout, 0, executing ); @@ -60,6 +62,6 @@ rtems_status_code rtems_task_wake_when( &executing->Timer, seconds - _TOD_Seconds_since_epoch() ); - _Thread_Enable_dispatch(); + _Thread_Dispatch_enable( cpu_self ); return RTEMS_SUCCESSFUL; } diff --git a/cpukit/rtems/src/timercancel.c b/cpukit/rtems/src/timercancel.c index a8ce1478da..1e737a25bb 100644 --- a/cpukit/rtems/src/timercancel.c +++ b/cpukit/rtems/src/timercancel.c @@ -45,8 +45,7 @@ rtems_status_code rtems_timer_cancel( switch ( location ) { case OBJECTS_LOCAL: - if ( !_Timer_Is_dormant_class( the_timer->the_class ) ) - (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Cancel( the_timer ); _Objects_Put( &the_timer->Object ); return RTEMS_SUCCESSFUL; diff --git a/cpukit/rtems/src/timercreate.c b/cpukit/rtems/src/timercreate.c index 0b1c44bdc2..13a01feda9 100644 --- a/cpukit/rtems/src/timercreate.c +++ b/cpukit/rtems/src/timercreate.c @@ -21,10 +21,39 @@ #include <rtems/system.h> #include <rtems/rtems/status.h> #include <rtems/rtems/support.h> +#include <rtems/score/assert.h> #include <rtems/score/thread.h> #include <rtems/rtems/timerimpl.h> #include <rtems/score/watchdogimpl.h> +void _Timer_Cancel( Timer_Control *the_timer ) +{ + Timer_server_Control *timer_server; + ISR_Level level; + + /* The timer class must not change during the cancel operation */ + _ISR_Disable( level ); + + switch ( the_timer->the_class ) { + case TIMER_INTERVAL: + _Watchdog_Remove_ticks( &the_timer->Ticker ); + break; + case TIMER_TIME_OF_DAY: + _Watchdog_Remove_seconds( &the_timer->Ticker ); + break; + case TIMER_INTERVAL_ON_TASK: + case TIMER_TIME_OF_DAY_ON_TASK: + timer_server = _Timer_server; + (*timer_server->cancel)( timer_server, the_timer ); + break; + default: + _Assert( the_timer->the_class == TIMER_DORMANT ); + break; + } + + _ISR_Enable( level ); +} + rtems_status_code rtems_timer_create( rtems_name name, rtems_id *id diff --git a/cpukit/rtems/src/timerdelete.c b/cpukit/rtems/src/timerdelete.c index 19232c8096..0849ec5ba6 100644 --- a/cpukit/rtems/src/timerdelete.c +++ b/cpukit/rtems/src/timerdelete.c @@ -38,7 +38,7 @@ rtems_status_code rtems_timer_delete( case OBJECTS_LOCAL: _Objects_Close( &_Timer_Information, &the_timer->Object ); - (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Cancel( the_timer ); _Objects_Put( &the_timer->Object ); _Timer_Free( the_timer ); _Objects_Allocator_unlock(); diff --git a/cpukit/rtems/src/timerfireafter.c b/cpukit/rtems/src/timerfireafter.c index 07862cde8c..84cf46bc37 100644 --- a/cpukit/rtems/src/timerfireafter.c +++ b/cpukit/rtems/src/timerfireafter.c @@ -46,7 +46,7 @@ rtems_status_code rtems_timer_fire_after( switch ( location ) { case OBJECTS_LOCAL: - (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Cancel( the_timer ); _ISR_Disable( level ); diff --git a/cpukit/rtems/src/timerfirewhen.c b/cpukit/rtems/src/timerfirewhen.c index 6ac7d17433..1acbaf9b8f 100644 --- a/cpukit/rtems/src/timerfirewhen.c +++ b/cpukit/rtems/src/timerfirewhen.c @@ -51,7 +51,7 @@ rtems_status_code rtems_timer_fire_when( switch ( location ) { case OBJECTS_LOCAL: - (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Cancel( the_timer ); the_timer->the_class = TIMER_TIME_OF_DAY; _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); _Watchdog_Insert_seconds( diff --git a/cpukit/rtems/src/timerreset.c b/cpukit/rtems/src/timerreset.c index 49c4925aa3..7ab172ea4f 100644 --- a/cpukit/rtems/src/timerreset.c +++ b/cpukit/rtems/src/timerreset.c @@ -67,7 +67,7 @@ rtems_status_code rtems_timer_reset( return RTEMS_INCORRECT_STATE; } #endif - _Watchdog_Remove( &the_timer->Ticker ); + (*timer_server->cancel)( timer_server, the_timer ); (*timer_server->schedule_operation)( timer_server, the_timer ); } else { /* diff --git a/cpukit/rtems/src/timerserver.c b/cpukit/rtems/src/timerserver.c index 25191e43d7..047fd0978e 100644 --- a/cpukit/rtems/src/timerserver.c +++ b/cpukit/rtems/src/timerserver.c @@ -15,7 +15,7 @@ /* COPYRIGHT (c) 1989-2008. * On-Line Applications Research Corporation (OAR). * - * Copyright (c) 2009 embedded brains GmbH. + * Copyright (c) 2009-2015 embedded brains GmbH. * * The license and distribution terms for this file may be * found in the file LICENSE in this distribution or at @@ -26,188 +26,129 @@ #include "config.h" #endif +#include <rtems.h> #include <rtems/rtems/timerimpl.h> #include <rtems/rtems/tasksimpl.h> -#include <rtems/score/isrlevel.h> -#include <rtems/score/threadimpl.h> +#include <rtems/score/apimutex.h> #include <rtems/score/todimpl.h> static Timer_server_Control _Timer_server_Default; -static void _Timer_server_Stop_interval_system_watchdog( - Timer_server_Control *ts +static void _Timer_server_Cancel_method( + Timer_server_Control *ts, + Timer_Control *timer ) { - _Watchdog_Remove( &ts->Interval_watchdogs.System_watchdog ); + if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) { + _Watchdog_Remove( &ts->Interval_watchdogs.Header, &timer->Ticker ); + } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) { + _Watchdog_Remove( &ts->TOD_watchdogs.Header, &timer->Ticker ); + } } -static void _Timer_server_Reset_interval_system_watchdog( - Timer_server_Control *ts -) +static Watchdog_Interval _Timer_server_Get_ticks( void ) { - ISR_Level level; - - _Timer_server_Stop_interval_system_watchdog( ts ); - - _ISR_Disable( level ); - if ( !_Watchdog_Is_empty( &ts->Interval_watchdogs.Header ) ) { - Watchdog_Interval delta_interval = - _Watchdog_First( &ts->Interval_watchdogs.Header )->delta_interval; - _ISR_Enable( level ); - - /* - * The unit is TICKS here. - */ - _Watchdog_Insert_ticks( - &ts->Interval_watchdogs.System_watchdog, - delta_interval - ); - } else { - _ISR_Enable( level ); - } + return _Watchdog_Ticks_since_boot; } -static void _Timer_server_Stop_tod_system_watchdog( - Timer_server_Control *ts -) +static Watchdog_Interval _Timer_server_Get_seconds( void ) { - _Watchdog_Remove( &ts->TOD_watchdogs.System_watchdog ); + return _TOD_Seconds_since_epoch(); } -static void _Timer_server_Reset_tod_system_watchdog( - Timer_server_Control *ts +static void _Timer_server_Update_system_watchdog( + Timer_server_Watchdogs *watchdogs, + Watchdog_Header *system_header ) { - ISR_Level level; + ISR_lock_Context lock_context; - _Timer_server_Stop_tod_system_watchdog( ts ); + _Watchdog_Acquire( &watchdogs->Header, &lock_context ); - _ISR_Disable( level ); - if ( !_Watchdog_Is_empty( &ts->TOD_watchdogs.Header ) ) { - Watchdog_Interval delta_interval = - _Watchdog_First( &ts->TOD_watchdogs.Header )->delta_interval; - _ISR_Enable( level ); + if ( watchdogs->system_watchdog_helper == NULL ) { + Thread_Control *executing; + uint32_t my_generation; - /* - * The unit is SECONDS here. - */ - _Watchdog_Insert_seconds( - &ts->TOD_watchdogs.System_watchdog, - delta_interval - ); - } else { - _ISR_Enable( level ); - } -} + executing = _Thread_Executing; + watchdogs->system_watchdog_helper = executing; -static void _Timer_server_Insert_timer( - Timer_server_Control *ts, - Timer_Control *timer -) -{ - if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) { - _Watchdog_Insert( &ts->Interval_watchdogs.Header, &timer->Ticker ); - } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) { - _Watchdog_Insert( &ts->TOD_watchdogs.Header, &timer->Ticker ); + do { + my_generation = watchdogs->generation; + + if ( !_Watchdog_Is_empty( &watchdogs->Header ) ) { + Watchdog_Control *first; + Watchdog_Interval delta; + + first = _Watchdog_First( &watchdogs->Header ); + delta = first->delta_interval; + + if ( + watchdogs->System_watchdog.state == WATCHDOG_INACTIVE + || delta != watchdogs->system_watchdog_delta + ) { + watchdogs->system_watchdog_delta = delta; + _Watchdog_Release( &watchdogs->Header, &lock_context ); + + _Watchdog_Remove( system_header, &watchdogs->System_watchdog ); + watchdogs->System_watchdog.initial = delta; + _Watchdog_Insert( system_header, &watchdogs->System_watchdog ); + + _Watchdog_Acquire( &watchdogs->Header, &lock_context ); + } + } + } while ( watchdogs->generation != my_generation ); + + watchdogs->system_watchdog_helper = NULL; } + + _Watchdog_Release( &watchdogs->Header, &lock_context ); } -static void _Timer_server_Insert_timer_and_make_snapshot( - Timer_server_Control *ts, - Timer_Control *timer +static void _Timer_server_Insert_timer( + Timer_server_Watchdogs *watchdogs, + Timer_Control *timer, + Watchdog_Header *system_header, + Watchdog_Interval (*get_ticks)( void ) ) { - Watchdog_Control *first_watchdog; - Watchdog_Interval delta_interval; - Watchdog_Interval last_snapshot; - Watchdog_Interval snapshot; + ISR_lock_Context lock_context; + Watchdog_Interval now; Watchdog_Interval delta; - ISR_Level level; - /* - * We have to update the time snapshots here, because otherwise we may have - * problems with the integer range of the delta values. The time delta DT - * from the last snapshot to now may be arbitrarily long. The last snapshot - * is the reference point for the delta chain. Thus if we do not update the - * reference point we have to add DT to the initial delta of the watchdog - * being inserted. This could result in an integer overflow. - */ + _Watchdog_Acquire( &watchdogs->Header, &lock_context ); - _Thread_Disable_dispatch(); + now = (*get_ticks)(); + delta = now - watchdogs->last_snapshot; + watchdogs->last_snapshot = now; + watchdogs->current_snapshot = now; - if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) { - /* - * We have to advance the last known ticks value of the server and update - * the watchdog chain accordingly. - */ - _ISR_Disable( level ); - snapshot = _Watchdog_Ticks_since_boot; - last_snapshot = ts->Interval_watchdogs.last_snapshot; - if ( !_Watchdog_Is_empty( &ts->Interval_watchdogs.Header ) ) { - first_watchdog = _Watchdog_First( &ts->Interval_watchdogs.Header ); - - /* - * We assume adequate unsigned arithmetic here. - */ - delta = snapshot - last_snapshot; - - delta_interval = first_watchdog->delta_interval; - if (delta_interval > delta) { - delta_interval -= delta; - } else { - delta_interval = 0; - } - first_watchdog->delta_interval = delta_interval; - } - ts->Interval_watchdogs.last_snapshot = snapshot; - _ISR_Enable( level ); + if ( watchdogs->system_watchdog_delta > delta ) { + watchdogs->system_watchdog_delta -= delta; + } else { + watchdogs->system_watchdog_delta = 0; + } - _Watchdog_Insert( &ts->Interval_watchdogs.Header, &timer->Ticker ); + if ( !_Watchdog_Is_empty( &watchdogs->Header ) ) { + Watchdog_Control *first = _Watchdog_First( &watchdogs->Header ); - if ( !ts->active ) { - _Timer_server_Reset_interval_system_watchdog( ts ); - } - } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) { - /* - * We have to advance the last known seconds value of the server and update - * the watchdog chain accordingly. - */ - _ISR_Disable( level ); - snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch(); - last_snapshot = ts->TOD_watchdogs.last_snapshot; - if ( !_Watchdog_Is_empty( &ts->TOD_watchdogs.Header ) ) { - first_watchdog = _Watchdog_First( &ts->TOD_watchdogs.Header ); - delta_interval = first_watchdog->delta_interval; - if ( snapshot > last_snapshot ) { - /* - * We advanced in time. - */ - delta = snapshot - last_snapshot; - if (delta_interval > delta) { - delta_interval -= delta; - } else { - delta_interval = 0; - } - } else { - /* - * Someone put us in the past. - */ - delta = last_snapshot - snapshot; - delta_interval += delta; - } - first_watchdog->delta_interval = delta_interval; + if ( first->delta_interval > delta ) { + first->delta_interval -= delta; + } else { + first->delta_interval = 0; } - ts->TOD_watchdogs.last_snapshot = snapshot; - _ISR_Enable( level ); + } - _Watchdog_Insert( &ts->TOD_watchdogs.Header, &timer->Ticker ); + _Watchdog_Insert_locked( + &watchdogs->Header, + &timer->Ticker, + &lock_context + ); - if ( !ts->active ) { - _Timer_server_Reset_tod_system_watchdog( ts ); - } - } + ++watchdogs->generation; + + _Watchdog_Release( &watchdogs->Header, &lock_context ); - _Thread_Enable_dispatch(); + _Timer_server_Update_system_watchdog( watchdogs, system_header ); } static void _Timer_server_Schedule_operation_method( @@ -215,143 +156,71 @@ static void _Timer_server_Schedule_operation_method( Timer_Control *timer ) { - if ( ts->insert_chain == NULL ) { - _Timer_server_Insert_timer_and_make_snapshot( ts, timer ); - } else { - /* - * We interrupted a critical section of the timer server. The timer - * server is not preemptible, so we must be in interrupt context here. No - * thread dispatch will happen until the timer server finishes its - * critical section. We have to use the protected chain methods because - * we may be interrupted by a higher priority interrupt. - */ - _Chain_Append( ts->insert_chain, &timer->Object.Node ); + if ( timer->the_class == TIMER_INTERVAL_ON_TASK ) { + _Timer_server_Insert_timer( + &ts->Interval_watchdogs, + timer, + &_Watchdog_Ticks_header, + _Timer_server_Get_ticks + ); + } else if ( timer->the_class == TIMER_TIME_OF_DAY_ON_TASK ) { + _Timer_server_Insert_timer( + &ts->TOD_watchdogs, + timer, + &_Watchdog_Seconds_header, + _Timer_server_Get_seconds + ); } } -static void _Timer_server_Process_interval_watchdogs( +static void _Timer_server_Update_current_snapshot( Timer_server_Watchdogs *watchdogs, - Chain_Control *fire_chain + Watchdog_Interval (*get_ticks)( void ) ) { - Watchdog_Interval snapshot = _Watchdog_Ticks_since_boot; - - /* - * We assume adequate unsigned arithmetic here. - */ - Watchdog_Interval delta = snapshot - watchdogs->last_snapshot; - - watchdogs->last_snapshot = snapshot; + ISR_lock_Context lock_context; - _Watchdog_Adjust_to_chain( &watchdogs->Header, delta, fire_chain ); + _Watchdog_Acquire( &watchdogs->Header, &lock_context ); + watchdogs->current_snapshot = (*get_ticks)(); + watchdogs->system_watchdog_delta = 0; + _Watchdog_Release( &watchdogs->Header, &lock_context ); } -static void _Timer_server_Process_tod_watchdogs( +static void _Timer_server_Tickle( Timer_server_Watchdogs *watchdogs, - Chain_Control *fire_chain + Watchdog_Header *system_header, + Watchdog_Interval (*get_ticks)( void ), + bool ticks ) { - Watchdog_Interval snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch(); - Watchdog_Interval last_snapshot = watchdogs->last_snapshot; - Watchdog_Interval delta; - - /* - * Process the seconds chain. Start by checking that the Time - * of Day (TOD) has not been set backwards. If it has then - * we want to adjust the watchdogs->Header to indicate this. - */ - if ( snapshot > last_snapshot ) { - /* - * This path is for normal forward movement and cases where the - * TOD has been set forward. - */ - delta = snapshot - last_snapshot; - _Watchdog_Adjust_to_chain( &watchdogs->Header, delta, fire_chain ); - - } else if ( snapshot < last_snapshot ) { - /* - * The current TOD is before the last TOD which indicates that - * TOD has been set backwards. - */ - delta = last_snapshot - snapshot; - _Watchdog_Adjust_backward( &watchdogs->Header, delta ); - } - - watchdogs->last_snapshot = snapshot; -} - -static void _Timer_server_Process_insertions( Timer_server_Control *ts ) -{ - while ( true ) { - Timer_Control *timer = (Timer_Control *) _Chain_Get( ts->insert_chain ); - - if ( timer == NULL ) { - break; - } + ISR_lock_Context lock_context; + Watchdog_Interval now; + Watchdog_Interval last; - _Timer_server_Insert_timer( ts, timer ); - } -} - -static void _Timer_server_Get_watchdogs_that_fire_now( - Timer_server_Control *ts, - Chain_Control *insert_chain, - Chain_Control *fire_chain -) -{ - /* - * Afterwards all timer inserts are directed to this chain and the interval - * and TOD chains will be no more modified by other parties. - */ - ts->insert_chain = insert_chain; + _Watchdog_Acquire( &watchdogs->Header, &lock_context ); - while ( true ) { - ISR_Level level; + now = watchdogs->current_snapshot; + last = watchdogs->last_snapshot; + watchdogs->last_snapshot = now; - /* - * Remove all the watchdogs that need to fire so we can invoke them. - */ - _Timer_server_Process_interval_watchdogs( - &ts->Interval_watchdogs, - fire_chain + if ( ticks || now >= last ) { + _Watchdog_Adjust_forward_locked( + &watchdogs->Header, + now - last, + &lock_context + ); + } else { + _Watchdog_Adjust_backward_locked( + &watchdogs->Header, + last - now ); - _Timer_server_Process_tod_watchdogs( &ts->TOD_watchdogs, fire_chain ); - - /* - * The insertions have to take place here, because they reference the - * current time. The previous process methods take a snapshot of the - * current time. In case someone inserts a watchdog with an initial value - * of zero it will be processed in the next iteration of the timer server - * body loop. - */ - _Timer_server_Process_insertions( ts ); - - _ISR_Disable( level ); - if ( _Chain_Is_empty( insert_chain ) ) { - ts->insert_chain = NULL; - _ISR_Enable( level ); - - break; - } else { - _ISR_Enable( level ); - } } -} -/* FIXME: This locking approach for SMP is improvable! */ + ++watchdogs->generation; -static void _Timer_server_SMP_lock_aquire( void ) -{ -#if defined( RTEMS_SMP ) - _Thread_Disable_dispatch(); -#endif -} + _Watchdog_Release( &watchdogs->Header, &lock_context ); -static void _Timer_server_SMP_lock_release( void ) -{ -#if defined( RTEMS_SMP ) - _Thread_Enable_dispatch(); -#endif + _Timer_server_Update_system_watchdog( watchdogs, system_header ); } /** @@ -368,81 +237,73 @@ static rtems_task _Timer_server_Body( ) { Timer_server_Control *ts = (Timer_server_Control *) arg; - Chain_Control insert_chain; - Chain_Control fire_chain; - _Chain_Initialize_empty( &insert_chain ); - _Chain_Initialize_empty( &fire_chain ); + while ( true ) { + rtems_event_set events; - _Timer_server_SMP_lock_aquire(); + _Timer_server_Tickle( + &ts->Interval_watchdogs, + &_Watchdog_Ticks_header, + _Timer_server_Get_ticks, + true + ); - while ( true ) { - _Timer_server_Get_watchdogs_that_fire_now( ts, &insert_chain, &fire_chain ); - - if ( !_Chain_Is_empty( &fire_chain ) ) { - /* - * Fire the watchdogs. - */ - while ( true ) { - Watchdog_Control *watchdog; - ISR_Level level; - - /* - * It is essential that interrupts are disable here since an interrupt - * service routine may remove a watchdog from the chain. - */ - _ISR_Disable( level ); - watchdog = (Watchdog_Control *) _Chain_Get_unprotected( &fire_chain ); - if ( watchdog != NULL ) { - watchdog->state = WATCHDOG_INACTIVE; - _ISR_Enable( level ); - } else { - _ISR_Enable( level ); - - break; - } + _Timer_server_Tickle( + &ts->TOD_watchdogs, + &_Watchdog_Seconds_header, + _Timer_server_Get_seconds, + false + ); - _Timer_server_SMP_lock_release(); + (void) rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_TIMER_SERVER, + RTEMS_EVENT_ALL | RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events + ); + } +} - /* - * The timer server may block here and wait for resources or time. - * The system watchdogs are inactive and will remain inactive since - * the active flag of the timer server is true. - */ - (*watchdog->routine)( watchdog->id, watchdog->user_data ); +static void _Timer_server_Wakeup( + Objects_Id id, + void *arg +) +{ + Timer_server_Control *ts = arg; - _Timer_server_SMP_lock_aquire(); - } - } else { - ts->active = false; + _Timer_server_Update_current_snapshot( + &ts->Interval_watchdogs, + _Timer_server_Get_ticks + ); - /* - * Block until there is something to do. - */ -#if !defined( RTEMS_SMP ) - _Thread_Disable_dispatch(); -#endif - _Thread_Set_state( ts->thread, STATES_DELAYING ); - _Timer_server_Reset_interval_system_watchdog( ts ); - _Timer_server_Reset_tod_system_watchdog( ts ); -#if !defined( RTEMS_SMP ) - _Thread_Enable_dispatch(); -#endif + _Timer_server_Update_current_snapshot( + &ts->TOD_watchdogs, + _Timer_server_Get_seconds + ); - _Timer_server_SMP_lock_release(); - _Timer_server_SMP_lock_aquire(); + (void) rtems_event_system_send( id, RTEMS_EVENT_SYSTEM_TIMER_SERVER ); +} - ts->active = true; +static void _Timer_server_Initialize_watchdogs( + Timer_server_Control *ts, + rtems_id id, + Timer_server_Watchdogs *watchdogs, + Watchdog_Interval (*get_ticks)( void ) +) +{ + Watchdog_Interval now; - /* - * Maybe an interrupt did reset the system timers, so we have to stop - * them here. Since we are active now, there will be no more resets - * until we are inactive again. - */ - _Timer_server_Stop_interval_system_watchdog( ts ); - _Timer_server_Stop_tod_system_watchdog( ts ); - } - } + now = (*get_ticks)(); + watchdogs->last_snapshot = now; + watchdogs->current_snapshot = now; + + _Watchdog_Header_initialize( &watchdogs->Header ); + _Watchdog_Initialize( + &watchdogs->System_watchdog, + _Timer_server_Wakeup, + id, + ts + ); } /** @@ -486,10 +347,10 @@ rtems_status_code rtems_timer_initiate_server( /* * Just to make sure this is only called once. */ - _Thread_Disable_dispatch(); + _Once_Lock(); tmpInitialized = initialized; initialized = true; - _Thread_Enable_dispatch(); + _Once_Unlock(); if ( tmpInitialized ) return RTEMS_INCORRECT_STATE; @@ -530,50 +391,27 @@ rtems_status_code rtems_timer_initiate_server( * Timer Server so we do not have to have a critical section. */ - /* - * We work with the TCB pointer, not the ID, so we need to convert - * to a TCB pointer from here out. - */ - ts->thread = (Thread_Control *)_Objects_Get_local_object( - &_RTEMS_tasks_Information, - _Objects_Get_index(id) + _Timer_server_Initialize_watchdogs( + ts, + id, + &ts->Interval_watchdogs, + _Timer_server_Get_ticks ); - /* - * Initialize the timer lists that the server will manage. - */ - _Watchdog_Header_initialize( &ts->Interval_watchdogs.Header ); - _Watchdog_Header_initialize( &ts->TOD_watchdogs.Header ); - - /* - * Initialize the timers that will be used to control when the - * Timer Server wakes up and services the task-based timers. - */ - _Watchdog_Initialize( - &ts->Interval_watchdogs.System_watchdog, - _Thread_Delay_ended, - 0, - ts->thread - ); - _Watchdog_Initialize( - &ts->TOD_watchdogs.System_watchdog, - _Thread_Delay_ended, - 0, - ts->thread + _Timer_server_Initialize_watchdogs( + ts, + id, + &ts->TOD_watchdogs, + _Timer_server_Get_seconds ); /* - * Initialize the pointer to the timer schedule method so applications that + * Initialize the pointer to the timer server methods so applications that * do not use the Timer Server do not have to pull it in. */ + ts->cancel = _Timer_server_Cancel_method; ts->schedule_operation = _Timer_server_Schedule_operation_method; - ts->Interval_watchdogs.last_snapshot = _Watchdog_Ticks_since_boot; - ts->TOD_watchdogs.last_snapshot = (Watchdog_Interval) _TOD_Seconds_since_epoch(); - - ts->insert_chain = NULL; - ts->active = false; - /* * The default timer server is now available. */ diff --git a/cpukit/rtems/src/timerserverfireafter.c b/cpukit/rtems/src/timerserverfireafter.c index 125664510f..0636782ae0 100644 --- a/cpukit/rtems/src/timerserverfireafter.c +++ b/cpukit/rtems/src/timerserverfireafter.c @@ -50,7 +50,7 @@ rtems_status_code rtems_timer_server_fire_after( switch ( location ) { case OBJECTS_LOCAL: - (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Cancel( the_timer ); _ISR_Disable( level ); diff --git a/cpukit/rtems/src/timerserverfirewhen.c b/cpukit/rtems/src/timerserverfirewhen.c index 32695fb0e6..0069af1c3b 100644 --- a/cpukit/rtems/src/timerserverfirewhen.c +++ b/cpukit/rtems/src/timerserverfirewhen.c @@ -72,7 +72,7 @@ rtems_status_code rtems_timer_server_fire_when( switch ( location ) { case OBJECTS_LOCAL: - (void) _Watchdog_Remove( &the_timer->Ticker ); + _Timer_Cancel( the_timer ); the_timer->the_class = TIMER_TIME_OF_DAY_ON_TASK; _Watchdog_Initialize( &the_timer->Ticker, routine, id, user_data ); the_timer->Ticker.initial = seconds - _TOD_Seconds_since_epoch(); |