[PATCH 4/7] Add interrupt server suspend/resume

Sebastian Huber sebastian.huber at embedded-brains.de
Tue Jul 11 13:41:12 UTC 2017


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



More information about the devel mailing list