This mechanism can be used to safely move the interrupt server from one scheduler instance to another for example. --- c/src/lib/libbsp/shared/src/irq-server.c | 61 ++++++++++++++++++++++++++++++-- cpukit/include/rtems/irq-extension.h | 39 ++++++++++++++++++++ cpukit/rtems/include/rtems/rtems/event.h | 6 ++++ 3 files changed, 104 insertions(+), 2 deletions(-)
diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c index a37c9caafc..542276c601 100644 --- a/c/src/lib/libbsp/shared/src/irq-server.c +++ b/c/src/lib/libbsp/shared/src/irq-server.c @@ -635,7 +635,7 @@ void rtems_interrupt_server_entry_submit( bsp_interrupt_server_trigger(entry); } -static void bsp_interrupt_server_entry_destroy_helper(void *arg) +static void bsp_interrupt_server_entry_synchronize_helper(void *arg) { bsp_interrupt_server_helper_data *hd = arg; @@ -665,7 +665,7 @@ void rtems_interrupt_server_entry_destroy( 0, NULL, NULL, - bsp_interrupt_server_entry_destroy_helper + bsp_interrupt_server_entry_synchronize_helper ); } @@ -693,3 +693,60 @@ rtems_status_code rtems_interrupt_server_request_initialize( ); return RTEMS_SUCCESSFUL; } + +static void bsp_interrupt_server_entry_suspend_helper(void *arg) +{ + bsp_interrupt_server_helper_data *hd = arg; + rtems_event_set events; + + rtems_event_transient_send(hd->task); + rtems_event_system_receive( + RTEMS_EVENT_SYSTEM_SERVER_RESUME, + RTEMS_WAIT, + RTEMS_NO_TIMEOUT, + &events + ); +} + +rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index) +{ + rtems_status_code sc; + bsp_interrupt_server_context *s; + + s = bsp_interrupt_server_get_context(server_index, &sc); + if (s == NULL) { + return sc; + } + + bsp_interrupt_server_call_helper( + s, + BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR, + 0, + NULL, + NULL, + bsp_interrupt_server_entry_suspend_helper + ); + return RTEMS_SUCCESSFUL; +} + +rtems_status_code rtems_interrupt_server_resume(uint32_t server_index) +{ + rtems_status_code sc; + bsp_interrupt_server_context *s; + + s = bsp_interrupt_server_get_context(server_index, &sc); + if (s == NULL) { + return sc; + } + + rtems_event_system_send(s->server, RTEMS_EVENT_SYSTEM_SERVER_RESUME); + bsp_interrupt_server_call_helper( + s, + BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR, + 0, + NULL, + NULL, + bsp_interrupt_server_entry_synchronize_helper + ); + return RTEMS_SUCCESSFUL; +} diff --git a/cpukit/include/rtems/irq-extension.h b/cpukit/include/rtems/irq-extension.h index 0c72b6e086..4b49a1a078 100644 --- a/cpukit/include/rtems/irq-extension.h +++ b/cpukit/include/rtems/irq-extension.h @@ -362,6 +362,45 @@ rtems_status_code rtems_interrupt_server_handler_iterate( ); /** + * @brief Suspends the specified interrupt server. + * + * A suspend request is sent to the specified interrupt server. This function + * waits for an acknowledgment from the specified interrupt server. + * + * This function must be called from thread context. It may block. Calling + * this function within the context of an interrupt server is undefined + * behaviour. + * + * @param[in] server_index The interrupt server index. Use + * @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server. + * + * @see rtems_interrupt_server_resume(). + * + * @retval RTEMS_SUCCESSFUL Successful operation + * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized. + * @retval RTEMS_INVALID_ID If the interrupt server index is invalid. + */ +rtems_status_code rtems_interrupt_server_suspend( uint32_t server_index ); + +/** + * @brief Resumes the specified interrupt server. + * + * This function must be called from thread context. It may block. Calling + * this function within the context of an interrupt server is undefined + * behaviour. + * + * @param[in] server_index The interrupt server index. Use + * @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server. + * + * @see rtems_interrupt_server_suspend(). + * + * @retval RTEMS_SUCCESSFUL Successful operation + * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized. + * @retval RTEMS_INVALID_ID If the interrupt server index is invalid. + */ +rtems_status_code rtems_interrupt_server_resume( uint32_t server_index ); + +/** * @brief Initializes the specified interrupt server entry. * * @param[in] server_index The interrupt server index. Use diff --git a/cpukit/rtems/include/rtems/rtems/event.h b/cpukit/rtems/include/rtems/rtems/event.h index 4263a4b881..1cd64c0cfa 100644 --- a/cpukit/rtems/include/rtems/rtems/event.h +++ b/cpukit/rtems/include/rtems/rtems/event.h @@ -319,6 +319,12 @@ rtems_status_code rtems_event_receive ( #define RTEMS_EVENT_SYSTEM_NETWORK_CLOSE RTEMS_EVENT_26 /** + * @brief Reserved system event to resume server threads, e.g timer or + * interrupt server. + */ +#define RTEMS_EVENT_SYSTEM_SERVER_RESUME RTEMS_EVENT_29 + +/** * @brief Reserved system event for the server threads, e.g timer or interrupt * server. */ -- 2.12.3 _______________________________________________ devel mailing list devel@rtems.org http://lists.rtems.org/mailman/listinfo/devel