diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-07-11 08:48:15 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2017-07-12 07:46:49 +0200 |
commit | a961e1980c1674679b1090bb24630cf3de8d6b48 (patch) | |
tree | 50c4a2072af466cb14e9a810cbccf25ea4de81ca /c/src/lib/libbsp/shared | |
parent | Create one interrupt server per processor (diff) | |
download | rtems-a961e1980c1674679b1090bb24630cf3de8d6b48.tar.bz2 |
Add interrupt server suspend/resume
This mechanism can be used to safely move the interrupt server from one
scheduler instance to another for example.
Update #3071.
Diffstat (limited to 'c/src/lib/libbsp/shared')
-rw-r--r-- | c/src/lib/libbsp/shared/src/irq-server.c | 61 |
1 files changed, 59 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; +} |