summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2017-07-11 11:20:06 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2017-07-12 07:46:55 +0200
commitccc87c8b9ed61d2bcf01c5721a0336a611be970e (patch)
tree23683ea298a6bf31de5ac565aa68c779d55f4841
parentAdd interrupt server set affinity (diff)
downloadrtems-ccc87c8b9ed61d2bcf01c5721a0336a611be970e.tar.bz2
Add interrupt server move
Update #3071.
-rw-r--r--c/src/lib/libbsp/shared/src/irq-server.c75
-rw-r--r--cpukit/include/rtems/irq-extension.h26
2 files changed, 101 insertions, 0 deletions
diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c
index 61d31754c2..a7b277c62c 100644
--- a/c/src/lib/libbsp/shared/src/irq-server.c
+++ b/c/src/lib/libbsp/shared/src/irq-server.c
@@ -694,6 +694,81 @@ rtems_status_code rtems_interrupt_server_request_initialize(
return RTEMS_SUCCESSFUL;
}
+static void bsp_interrupt_server_handler_move_helper(void *arg)
+{
+ bsp_interrupt_server_helper_data *hd = arg;
+ bsp_interrupt_server_handler_iterate_helper_data *hihd = hd->arg;
+ rtems_interrupt_server_entry *e;
+ rtems_option trigger_options;
+
+ bsp_interrupt_lock();
+
+ e = bsp_interrupt_server_query_entry(hd->vector, &trigger_options);
+ if (e != NULL) {
+ rtems_interrupt_lock_context lock_context;
+ bsp_interrupt_server_context *src = e->server;
+ bsp_interrupt_server_context *dst = hihd->arg;
+ bool pending;
+
+ rtems_interrupt_lock_acquire(&src->lock, &lock_context);
+
+ pending = !rtems_chain_is_node_off_chain(&e->node);
+ if (pending) {
+ rtems_chain_extract_unprotected(&e->node);
+ rtems_chain_set_off_chain(&e->node);
+ }
+
+ rtems_interrupt_lock_release(&src->lock, &lock_context);
+
+ e->server = dst;
+
+ if (pending) {
+ bsp_interrupt_server_trigger(e);
+ }
+ }
+
+ bsp_interrupt_unlock();
+
+ rtems_event_transient_send(hd->task);
+}
+
+rtems_status_code rtems_interrupt_server_move(
+ uint32_t source_server_index,
+ rtems_vector_number vector,
+ uint32_t destination_server_index
+)
+{
+ rtems_status_code sc;
+ bsp_interrupt_server_context *src;
+ bsp_interrupt_server_context *dst;
+ bsp_interrupt_server_handler_iterate_helper_data hihd;
+
+ src = bsp_interrupt_server_get_context(source_server_index, &sc);
+ if (src == NULL) {
+ return sc;
+ }
+
+ dst = bsp_interrupt_server_get_context(destination_server_index, &sc);
+ if (dst == NULL) {
+ return sc;
+ }
+
+ if (!bsp_interrupt_is_valid_vector(vector)) {
+ return RTEMS_INVALID_ID;
+ }
+
+ hihd.arg = dst;
+ bsp_interrupt_server_call_helper(
+ src,
+ vector,
+ 0,
+ NULL,
+ &hihd,
+ bsp_interrupt_server_handler_move_helper
+ );
+ return RTEMS_SUCCESSFUL;
+}
+
static void bsp_interrupt_server_entry_suspend_helper(void *arg)
{
bsp_interrupt_server_helper_data *hd = arg;
diff --git a/cpukit/include/rtems/irq-extension.h b/cpukit/include/rtems/irq-extension.h
index 9cade113ad..e3fb4c5fea 100644
--- a/cpukit/include/rtems/irq-extension.h
+++ b/cpukit/include/rtems/irq-extension.h
@@ -362,6 +362,32 @@ rtems_status_code rtems_interrupt_server_handler_iterate(
);
/**
+ * @brief Moves the interrupt handlers installed on the specified source
+ * interrupt server to the destination 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] source_server_index The source interrupt server index. Use
+ * @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
+ * @param[in] vector The interrupt vector number.
+ * @param[in] destination_server_index The destination interrupt server index.
+ * Use @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
+ *
+ * @retval RTEMS_SUCCESSFUL Successful operation
+ * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
+ * @retval RTEMS_INVALID_ID The destination interrupt server index is invalid.
+ * @retval RTEMS_INVALID_ID The vector number is invalid.
+ * @retval RTEMS_INVALID_ID The destination interrupt server index is invalid.
+ */
+rtems_status_code rtems_interrupt_server_move(
+ uint32_t source_server_index,
+ rtems_vector_number vector,
+ uint32_t destination_server_index
+);
+
+/**
* @brief Suspends the specified interrupt server.
*
* A suspend request is sent to the specified interrupt server. This function