[rtems commit] Create one interrupt server per processor

Sebastian Huber sebh at rtems.org
Wed Jul 12 06:02:01 UTC 2017


Module:    rtems
Branch:    master
Commit:    e7ee719f795fdbd8b5185769bdc893d8840b6855
Changeset: http://git.rtems.org/rtems/commit/?id=e7ee719f795fdbd8b5185769bdc893d8840b6855

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Tue Jul 11 08:25:09 2017 +0200

Create one interrupt server per processor

This allows load balancing of interrupt processing in SMP
configurations.

Update #3071.

---

 c/src/lib/libbsp/shared/src/irq-server.c | 263 +++++++++++++++++++++----------
 cpukit/include/rtems/irq-extension.h     | 129 ++++++++-------
 2 files changed, 254 insertions(+), 138 deletions(-)

diff --git a/c/src/lib/libbsp/shared/src/irq-server.c b/c/src/lib/libbsp/shared/src/irq-server.c
index 1f9b75f..a37c9ca 100644
--- a/c/src/lib/libbsp/shared/src/irq-server.c
+++ b/c/src/lib/libbsp/shared/src/irq-server.c
@@ -30,47 +30,70 @@
 
 #define BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR (BSP_INTERRUPT_VECTOR_MAX + 1)
 
-RTEMS_INTERRUPT_LOCK_DEFINE(
-  static,
-  bsp_interrupt_server_lock,
-  "Interrupt Server"
+typedef struct {
+  RTEMS_INTERRUPT_LOCK_MEMBER(lock);
+  rtems_chain_control entries;
+  rtems_id server;
+  unsigned errors;
+} bsp_interrupt_server_context;
+
+#if defined(RTEMS_SMP)
+static bsp_interrupt_server_context *bsp_interrupt_server_instances;
+#else
+static bsp_interrupt_server_context bsp_interrupt_server_instance;
+#endif
+
+static bsp_interrupt_server_context *bsp_interrupt_server_get_context(
+  uint32_t server_index,
+  rtems_status_code *sc
 )
-
-static rtems_id bsp_interrupt_server_id = RTEMS_ID_NONE;
-
-static RTEMS_CHAIN_DEFINE_EMPTY(bsp_interrupt_server_chain);
-
-static rtems_status_code bsp_interrupt_server_is_initialized(void)
 {
-  if (bsp_interrupt_server_id != RTEMS_ID_NONE) {
-    return RTEMS_SUCCESSFUL;
-  } else {
-    return RTEMS_INCORRECT_STATE;
+#if defined(RTEMS_SMP)
+  if (bsp_interrupt_server_instances == NULL) {
+    *sc = RTEMS_INCORRECT_STATE;
+    return NULL;
   }
-}
+#else
+  if (bsp_interrupt_server_instance.server == RTEMS_ID_NONE) {
+    *sc = RTEMS_INCORRECT_STATE;
+    return NULL;
+  }
+#endif
 
-static unsigned bsp_interrupt_server_errors;
+  if (server_index >= rtems_get_processor_count()) {
+    *sc = RTEMS_INVALID_ID;
+    return NULL;
+  }
+
+  *sc = RTEMS_SUCCESSFUL;
+#if defined(RTEMS_SMP)
+  return &bsp_interrupt_server_instances[server_index];
+#else
+  return &bsp_interrupt_server_instance;
+#endif
+}
 
 static void bsp_interrupt_server_trigger(void *arg)
 {
   rtems_interrupt_lock_context lock_context;
   rtems_interrupt_server_entry *e = arg;
+  bsp_interrupt_server_context *s = e->server;
 
   if (bsp_interrupt_is_valid_vector(e->vector)) {
     bsp_interrupt_vector_disable(e->vector);
   }
 
-  rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);
+  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
 
   if (rtems_chain_is_node_off_chain(&e->node)) {
-    rtems_chain_append_unprotected(&bsp_interrupt_server_chain, &e->node);
+    rtems_chain_append_unprotected(&s->entries, &e->node);
   } else {
-    ++bsp_interrupt_server_errors;
+    ++s->errors;
   }
 
-  rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context);
+  rtems_interrupt_lock_release(&s->lock, &lock_context);
 
-  rtems_event_system_send(bsp_interrupt_server_id, RTEMS_EVENT_SYSTEM_SERVER);
+  rtems_event_system_send(s->server, RTEMS_EVENT_SYSTEM_SERVER);
 }
 
 typedef struct {
@@ -114,6 +137,7 @@ static rtems_interrupt_server_entry *bsp_interrupt_server_query_entry(
 }
 
 typedef struct {
+  bsp_interrupt_server_context *server;
   rtems_vector_number vector;
   rtems_option options;
   rtems_interrupt_handler handler;
@@ -146,6 +170,7 @@ static void bsp_interrupt_server_install_helper(void *arg)
   if (e == NULL) {
     e = calloc(1, sizeof(*e));
     if (e != NULL) {
+      e->server = hd->server;
       e->vector = hd->vector;
       e->actions = a;
 
@@ -162,6 +187,10 @@ static void bsp_interrupt_server_install_helper(void *arg)
     } else {
       sc = RTEMS_NO_MEMORY;
     }
+#if defined(RTEMS_SMP)
+  } else if (e->server != hd->server) {
+    sc = RTEMS_RESOURCE_IN_USE;
+#endif
   } else if (
     RTEMS_INTERRUPT_IS_UNIQUE(hd->options)
       || RTEMS_INTERRUPT_IS_UNIQUE(trigger_options)
@@ -252,6 +281,7 @@ static void bsp_interrupt_server_remove_helper(void *arg)
 }
 
 static rtems_status_code bsp_interrupt_server_call_helper(
+  bsp_interrupt_server_context *s,
   rtems_vector_number vector,
   rtems_option options,
   rtems_interrupt_handler handler,
@@ -260,6 +290,7 @@ static rtems_status_code bsp_interrupt_server_call_helper(
 )
 {
   bsp_interrupt_server_helper_data hd = {
+    .server = s,
     .vector = vector,
     .options = options,
     .handler = handler,
@@ -271,6 +302,7 @@ static rtems_status_code bsp_interrupt_server_call_helper(
     .arg = &hd
   };
   rtems_interrupt_server_entry e = {
+    .server = s,
     .vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
     .actions = &a
   };
@@ -281,30 +313,32 @@ static rtems_status_code bsp_interrupt_server_call_helper(
   return hd.sc;
 }
 
-static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(void)
+static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(
+  bsp_interrupt_server_context *s
+)
 {
   rtems_interrupt_lock_context lock_context;
   rtems_interrupt_server_entry *e;
-  rtems_chain_control *chain;
 
-  rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);
-  chain = &bsp_interrupt_server_chain;
+  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
 
-  if (!rtems_chain_is_empty(chain)) {
+  if (!rtems_chain_is_empty(&s->entries)) {
     e = (rtems_interrupt_server_entry *)
-      rtems_chain_get_first_unprotected(chain);
+      rtems_chain_get_first_unprotected(&s->entries);
     rtems_chain_set_off_chain(&e->node);
   } else {
     e = NULL;
   }
 
-  rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context);
+  rtems_interrupt_lock_release(&s->lock, &lock_context);
 
   return e;
 }
 
 static void bsp_interrupt_server_task(rtems_task_argument arg)
 {
+  bsp_interrupt_server_context *s = (bsp_interrupt_server_context *) arg;
+
   while (true) {
     rtems_event_set events;
     rtems_interrupt_server_entry *e;
@@ -316,7 +350,7 @@ static void bsp_interrupt_server_task(rtems_task_argument arg)
       &events
     );
 
-    while ((e = bsp_interrupt_server_get_entry()) != NULL) {
+    while ((e = bsp_interrupt_server_get_entry(s)) != NULL) {
       rtems_interrupt_server_action *action = e->actions;
       rtems_vector_number vector = e->vector;
 
@@ -334,7 +368,7 @@ static void bsp_interrupt_server_task(rtems_task_argument arg)
 }
 
 rtems_status_code rtems_interrupt_server_handler_install(
-  rtems_id server,
+  uint32_t server_index,
   rtems_vector_number vector,
   const char *info,
   rtems_option options,
@@ -343,17 +377,15 @@ rtems_status_code rtems_interrupt_server_handler_install(
 )
 {
   rtems_status_code sc;
+  bsp_interrupt_server_context *s;
 
-  sc = bsp_interrupt_server_is_initialized();
-  if (sc != RTEMS_SUCCESSFUL) {
+  s = bsp_interrupt_server_get_context(server_index, &sc);
+  if (s == NULL) {
     return sc;
   }
 
-  if (server != RTEMS_ID_NONE) {
-    return RTEMS_NOT_IMPLEMENTED;
-  }
-
   return bsp_interrupt_server_call_helper(
+    s,
     vector,
     options,
     handler,
@@ -363,24 +395,22 @@ rtems_status_code rtems_interrupt_server_handler_install(
 }
 
 rtems_status_code rtems_interrupt_server_handler_remove(
-  rtems_id server,
+  uint32_t server_index,
   rtems_vector_number vector,
   rtems_interrupt_handler handler,
   void *arg
 )
 {
   rtems_status_code sc;
+  bsp_interrupt_server_context *s;
 
-  sc = bsp_interrupt_server_is_initialized();
-  if (sc != RTEMS_SUCCESSFUL) {
+  s = bsp_interrupt_server_get_context(server_index, &sc);
+  if (s == NULL) {
     return sc;
   }
 
-  if (server != RTEMS_ID_NONE) {
-    return RTEMS_NOT_IMPLEMENTED;
-  }
-
   return bsp_interrupt_server_call_helper(
+    s,
     vector,
     0,
     handler,
@@ -426,7 +456,7 @@ static void bsp_interrupt_server_handler_iterate_helper(void *arg)
 }
 
 rtems_status_code rtems_interrupt_server_handler_iterate(
-  rtems_id server,
+  uint32_t server_index,
   rtems_vector_number vector,
   rtems_interrupt_per_handler_routine routine,
   void *arg
@@ -434,16 +464,13 @@ rtems_status_code rtems_interrupt_server_handler_iterate(
 {
   rtems_status_code sc;
   bsp_interrupt_server_handler_iterate_helper_data hihd;
+  bsp_interrupt_server_context *s;
 
-  sc = bsp_interrupt_server_is_initialized();
-  if (sc != RTEMS_SUCCESSFUL) {
+  s = bsp_interrupt_server_get_context(server_index, &sc);
+  if (s == NULL) {
     return sc;
   }
 
-  if (server != RTEMS_ID_NONE) {
-    return RTEMS_NOT_IMPLEMENTED;
-  }
-
   if (!bsp_interrupt_is_valid_vector(vector)) {
     return RTEMS_INVALID_ID;
   }
@@ -451,6 +478,7 @@ rtems_status_code rtems_interrupt_server_handler_iterate(
   hihd.routine = routine;
   hihd.arg = arg;
   return bsp_interrupt_server_call_helper(
+    s,
     vector,
     0,
     NULL,
@@ -464,42 +492,98 @@ rtems_status_code rtems_interrupt_server_initialize(
   size_t stack_size,
   rtems_mode modes,
   rtems_attribute attributes,
-  rtems_id *server
+  uint32_t *server_count
 )
 {
-  rtems_status_code sc = RTEMS_SUCCESSFUL;
+  uint32_t cpu_index;
+  uint32_t cpu_count;
+  uint32_t dummy;
+  bsp_interrupt_server_context *instances;
 
-  if (server != NULL) {
-    return RTEMS_NOT_IMPLEMENTED;
+  if (server_count == NULL) {
+    server_count = &dummy;
   }
 
-  sc = rtems_task_create(
-    rtems_build_name('I', 'R', 'Q', 'S'),
-    priority,
-    stack_size,
-    modes,
-    attributes,
-    &bsp_interrupt_server_id
-  );
-  if (sc != RTEMS_SUCCESSFUL) {
-    return RTEMS_TOO_MANY;
+  cpu_count = rtems_get_processor_count();
+
+#if defined(RTEMS_SMP)
+  instances = calloc(cpu_count, sizeof(*instances));
+  if (instances == NULL) {
+    return RTEMS_NO_MEMORY;
   }
+#else
+  instances = &bsp_interrupt_server_instance;
+#endif
+
+  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
+    bsp_interrupt_server_context *s = &instances[cpu_index];
+    rtems_status_code sc;
+#if defined(RTEMS_SMP)
+    rtems_id scheduler;
+    cpu_set_t cpu;
+#endif
+
+    rtems_interrupt_lock_initialize(&s->lock, "Interrupt Server");
+    rtems_chain_initialize_empty(&s->entries);
+
+    sc = rtems_task_create(
+      rtems_build_name('I', 'R', 'Q', 'S'),
+      priority,
+      stack_size,
+      modes,
+      attributes,
+      &s->server
+    );
+    if (sc != RTEMS_SUCCESSFUL) {
+      *server_count = cpu_index;
 
-  sc = rtems_task_start(
-    bsp_interrupt_server_id,
-    bsp_interrupt_server_task,
-    0
-  );
-  _Assert(sc == RTEMS_SUCCESSFUL);
+#if defined(RTEMS_SMP)
+      if (cpu_index > 0) {
+        return RTEMS_SUCCESSFUL;
+      }
+
+      free(instances);
+#endif
+
+      return RTEMS_TOO_MANY;
+    }
+
+#if defined(RTEMS_SMP)
+    sc = rtems_scheduler_ident_by_processor(cpu_index, &scheduler);
+    _Assert(sc == RTEMS_SUCCESSFUL);
+
+    sc = rtems_task_set_scheduler(s->server, scheduler, priority);
+    _Assert(sc == RTEMS_SUCCESSFUL);
+
+    CPU_ZERO(&cpu);
+    CPU_SET(cpu_index, &cpu);
+    sc = rtems_task_set_affinity(s->server, sizeof(cpu), &cpu);
+    _Assert(sc == RTEMS_SUCCESSFUL);
+#endif
+
+    sc = rtems_task_start(
+      s->server,
+      bsp_interrupt_server_task,
+      (rtems_task_argument) s
+    );
+    _Assert(sc == RTEMS_SUCCESSFUL);
+  }
+
+#if defined(RTEMS_SMP)
+  bsp_interrupt_server_instances = instances;
+#endif
+  *server_count = cpu_index;
 
   return RTEMS_SUCCESSFUL;
 }
 
 static void bsp_interrupt_server_entry_initialize(
-  rtems_interrupt_server_entry *entry
+  rtems_interrupt_server_entry *entry,
+  bsp_interrupt_server_context *s
 )
 {
   rtems_chain_set_off_chain(&entry->node);
+  entry->server = s;
   entry->vector = BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR;
   entry->actions = NULL;
 }
@@ -517,11 +601,21 @@ static void bsp_interrupt_server_action_prepend(
   entry->actions = action;
 }
 
-void rtems_interrupt_server_entry_initialize(
+rtems_status_code rtems_interrupt_server_entry_initialize(
+  uint32_t                      server_index,
   rtems_interrupt_server_entry *entry
 )
 {
-  bsp_interrupt_server_entry_initialize(entry);
+  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_entry_initialize(entry, s);
+  return RTEMS_SUCCESSFUL;
 }
 
 void rtems_interrupt_server_action_prepend(
@@ -535,7 +629,6 @@ void rtems_interrupt_server_action_prepend(
 }
 
 void rtems_interrupt_server_entry_submit(
-  rtems_id                      server,
   rtems_interrupt_server_entry *entry
 )
 {
@@ -550,22 +643,24 @@ static void bsp_interrupt_server_entry_destroy_helper(void *arg)
 }
 
 void rtems_interrupt_server_entry_destroy(
-  rtems_id                      server,
   rtems_interrupt_server_entry *entry
 )
 {
+  bsp_interrupt_server_context *s;
   rtems_interrupt_lock_context lock_context;
 
-  rtems_interrupt_lock_acquire(&bsp_interrupt_server_lock, &lock_context);
+  s = entry->server;
+  rtems_interrupt_lock_acquire(&s->lock, &lock_context);
 
   if (!rtems_chain_is_node_off_chain(&entry->node)) {
     rtems_chain_extract_unprotected(&entry->node);
     rtems_chain_set_off_chain(&entry->node);
   }
 
-  rtems_interrupt_lock_release(&bsp_interrupt_server_lock, &lock_context);
+  rtems_interrupt_lock_release(&s->lock, &lock_context);
 
   bsp_interrupt_server_call_helper(
+    s,
     BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR,
     0,
     NULL,
@@ -574,17 +669,27 @@ void rtems_interrupt_server_entry_destroy(
   );
 }
 
-void rtems_interrupt_server_request_initialize(
+rtems_status_code rtems_interrupt_server_request_initialize(
+  uint32_t                        server_index,
   rtems_interrupt_server_request *request,
   rtems_interrupt_handler         handler,
   void                           *arg
 )
 {
-  bsp_interrupt_server_entry_initialize(&request->entry);
+  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_entry_initialize(&request->entry, s);
   bsp_interrupt_server_action_prepend(
     &request->entry,
     &request->action,
     handler,
     arg
   );
+  return RTEMS_SUCCESSFUL;
 }
diff --git a/cpukit/include/rtems/irq-extension.h b/cpukit/include/rtems/irq-extension.h
index fec0767..0c72b6e 100644
--- a/cpukit/include/rtems/irq-extension.h
+++ b/cpukit/include/rtems/irq-extension.h
@@ -116,7 +116,7 @@ typedef void (*rtems_interrupt_handler)(void *);
  *
  * This function may block.
  *
- * @retval RTEMS_SUCCESSFUL Shall be returned in case of success.
+ * @retval RTEMS_SUCCESSFUL Successful operation.
  * @retval RTEMS_CALLED_FROM_ISR If this function is called from interrupt
  * context this shall be returned.
  * @retval RTEMS_INVALID_ADDRESS If the handler address is NULL this shall be
@@ -149,7 +149,7 @@ rtems_status_code rtems_interrupt_handler_install(
  *
  * This function may block.
  *
- * @retval RTEMS_SUCCESSFUL Shall be returned in case of success.
+ * @retval RTEMS_SUCCESSFUL Successful operation.
  * @retval RTEMS_CALLED_FROM_ISR If this function is called from interrupt
  * context this shall be returned.
  * @retval RTEMS_INVALID_ADDRESS If the handler address is NULL this shall be
@@ -189,7 +189,7 @@ typedef void (*rtems_interrupt_per_handler_routine)(
  * This function may block.  Never install or remove an interrupt handler
  * within the iteration routine.  This may result in a deadlock.
  *
- * @retval RTEMS_SUCCESSFUL Shall be returned in case of success.
+ * @retval RTEMS_SUCCESSFUL Successful operation.
  * @retval RTEMS_CALLED_FROM_ISR If this function is called from interrupt
  * context this shall be returned.
  * @retval RTEMS_INVALID_ID If the vector number is out of range this shall be
@@ -218,6 +218,11 @@ typedef struct rtems_interrupt_server_action {
 } rtems_interrupt_server_action;
 
 /**
+ * @brief The interrupt server index of the default interrupt server.
+ */
+#define RTEMS_INTERRUPT_SERVER_DEFAULT 0
+
+/**
  * @brief An interrupt server entry.
  *
  * This structure must be treated as an opaque data type.  Members must not be
@@ -230,6 +235,7 @@ typedef struct rtems_interrupt_server_action {
  */
 typedef struct {
   rtems_chain_node               node;
+  void                          *server;
   rtems_vector_number            vector;
   rtems_interrupt_server_action *actions;
 } rtems_interrupt_server_entry;
@@ -250,28 +256,29 @@ typedef struct {
 } rtems_interrupt_server_request;
 
 /**
- * @brief Initializes an interrupt server task.
+ * @brief Initializes the interrupt server tasks.
  *
- * The task will have the priority @a priority, the stack size @a stack_size,
- * the modes @a modes and the attributes @a attributes.  The identifier of the
- * server task will be returned in @a server.  Interrupt handlers can be
- * installed on the server with rtems_interrupt_server_handler_install() and
- * removed with rtems_interrupt_server_handler_remove() using this identifier.
- * In case of an interrupt the request will be forwarded to the server.  The
- * handlers are executed within the server context.  If one handler blocks on
- * something this may delay the processing of other handlers.
+ * This function tries to create an interrupt server task for each processor in
+ * the system.  The tasks will have the priority @a priority, the stack size @a
+ * stack_size, the modes @a modes and the attributes @a attributes.  The count
+ * of server tasks will be returned in @a server_count.  Interrupt handlers can
+ * be installed on an interrupt server with
+ * rtems_interrupt_server_handler_install() and removed with
+ * rtems_interrupt_server_handler_remove() using a server index.  In case of an
+ * interrupt, the request will be forwarded to the interrupt server.  The
+ * handlers are executed within the interrupt server context.  If one handler
+ * blocks on something this may delay the processing of other handlers.
  *
- * The server identifier pointer @a server may be @a NULL to initialize the
- * default server.
+ * The server count pointer @a server_count may be @a NULL.
  *
  * This function may block.
  *
  * @see rtems_task_create().
  *
- * @retval RTEMS_SUCCESSFUL Shall be returned in case of success.
- * @retval RTEMS_INCORRECT_STATE If the default server is already initialized
- * this shall be returned.
- * @retval RTEMS_TOO_MANY No free task available to create the server task.
+ * @retval RTEMS_SUCCESSFUL Successful operation.
+ * @retval RTEMS_INCORRECT_STATE The interrupt servers are not initialized.
+ * @retval RTEMS_NO_MEMORY Not enough memory.
+ * @retval RTEMS_TOO_MANY No free task available to create at least one server task.
  * @retval RTEMS_UNSATISFIED Task stack size too large.
  * @retval RTEMS_INVALID_PRIORITY Invalid task priority.
  */
@@ -280,7 +287,7 @@ rtems_status_code rtems_interrupt_server_initialize(
   size_t stack_size,
   rtems_mode modes,
   rtems_attribute attributes,
-  rtems_id *server
+  uint32_t *server_count
 );
 
 /**
@@ -288,20 +295,20 @@ rtems_status_code rtems_interrupt_server_initialize(
  * vector with number @a vector on the server @a server.
  *
  * The handler routine will be executed on the corresponding interrupt server
- * task.  A server identifier @a server of @c RTEMS_ID_NONE may be used to
- * install the handler on the default server.
+ * task.  A server index @a server_index of @c RTEMS_INTERRUPT_SERVER_DEFAULT
+ * may be used to install the handler on the default server.
  *
  * This function may block.
  *
  * @see rtems_interrupt_handler_install().
  *
- * @retval RTEMS_SUCCESSFUL Shall be returned in case of success.
- * @retval RTEMS_INCORRECT_STATE If the interrupt handler server is not
- * initialized this shall be returned.
+ * @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.
  * @retval * For other errors see rtems_interrupt_handler_install().
  */
 rtems_status_code rtems_interrupt_server_handler_install(
-  rtems_id server,
+  uint32_t server_index,
   rtems_vector_number vector,
   const char *info,
   rtems_option options,
@@ -313,20 +320,20 @@ rtems_status_code rtems_interrupt_server_handler_install(
  * @brief Removes the interrupt handler routine @a handler with argument @a arg
  * for the interrupt vector with number @a vector from the server @a server.
  *
- * A server identifier @a server of @c RTEMS_ID_NONE may be used to remove the
- * handler from the default server.
+ * A server index @a server_index of @c RTEMS_INTERRUPT_SERVER_DEFAULT may be
+ * used to remove the handler from the default server.
  *
  * This function may block.
  *
  * @see rtems_interrupt_handler_remove().
  *
- * @retval RTEMS_SUCCESSFUL Shall be returned in case of success.
- * @retval RTEMS_INCORRECT_STATE If the interrupt handler server is not
- * initialized this shall be returned.
+ * @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.
  * @retval * For other errors see rtems_interrupt_handler_remove().
  */
 rtems_status_code rtems_interrupt_server_handler_remove(
-  rtems_id server,
+  uint32_t server_index,
   rtems_vector_number vector,
   rtems_interrupt_handler handler,
   void *arg
@@ -337,18 +344,18 @@ rtems_status_code rtems_interrupt_server_handler_remove(
  * number @a vector which are installed on the interrupt server specified by
  * @a server.
  *
- * A server identifier @a server of @c RTEMS_ID_NONE may be used to specify the
- * default server.
+ * A server index @a server_index of @c RTEMS_INTERRUPT_SERVER_DEFAULT may be
+ * used to specify the default server.
  *
  * @see rtems_interrupt_handler_iterate()
  *
- * @retval RTEMS_SUCCESSFUL Shall be returned in case of success.
- * @retval RTEMS_INCORRECT_STATE If the interrupt handler server is not
- * initialized this shall be returned.
+ * @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.
  * @retval * For other errors see rtems_interrupt_handler_iterate().
  */
 rtems_status_code rtems_interrupt_server_handler_iterate(
-  rtems_id server,
+  uint32_t server_index,
   rtems_vector_number vector,
   rtems_interrupt_per_handler_routine routine,
   void *arg
@@ -357,11 +364,18 @@ rtems_status_code rtems_interrupt_server_handler_iterate(
 /**
  * @brief Initializes the specified interrupt server entry.
  *
+ * @param[in] server_index The interrupt server index.  Use
+ *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
  * @param[in] entry The interrupt server entry to initialize.
  *
  * @see rtems_interrupt_server_action_prepend().
+ *
+ * @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.
  */
-void rtems_interrupt_server_entry_initialize(
+rtems_status_code rtems_interrupt_server_entry_initialize(
+  uint32_t                      server_index,
   rtems_interrupt_server_entry *entry
 );
 
@@ -397,8 +411,6 @@ void rtems_interrupt_server_action_prepend(
  * This function may be called from thread or interrupt context.  It does not
  * block.  No error checking is performed.
  *
- * @param[in] server The server identifier.  Use @c RTEMS_ID_NONE to specify
- *   the default server.
  * @param[in] entry The interrupt server entry must be initialized before the
  *   first call to this function via rtems_interrupt_server_entry_initialize()
  *   and rtems_interrupt_server_action_prepend().  The entry and its actions
@@ -406,36 +418,40 @@ void rtems_interrupt_server_action_prepend(
  *   rtems_interrupt_server_entry_destroy() to destroy an entry in use.
  */
 void rtems_interrupt_server_entry_submit(
-  rtems_id                      server,
   rtems_interrupt_server_entry *entry
 );
 
 /**
  * @brief Destroys the specified interrupt server entry.
  *
- * This function must be called from thread context.  It may block.  No error
- * checking is performed.
+ * This function must be called from thread context.  It may block.  Calling
+ * this function within the context of an interrupt server is undefined
+ * behaviour.  No error checking is performed.
  *
- * @param[in] server The server identifier.  Use @c RTEMS_ID_NONE to specify
- *   the default server.
+ * @param[in] server_index The interrupt server index.  Use
+ *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
  * @param[in] entry The interrupt server entry to destroy.  It must have been
  *   initialized via rtems_interrupt_server_entry_initialize().
  */
 void rtems_interrupt_server_entry_destroy(
-  rtems_id                      server,
   rtems_interrupt_server_entry *entry
 );
 
 /**
  * @brief Initializes the specified interrupt server request.
  *
- * No error checking is performed.
- *
+ * @param[in] server_index The interrupt server index.  Use
+ *   @c RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
  * @param[in] request The interrupt server request to initialize.
  * @param[in] handler The interrupt handler for the request action.
  * @param[in] arg The interrupt handler argument for the request action.
+ *
+ * @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.
  */
-void rtems_interrupt_server_request_initialize(
+rtems_status_code rtems_interrupt_server_request_initialize(
+  uint32_t                        server_index,
   rtems_interrupt_server_request *request,
   rtems_interrupt_handler         handler,
   void                           *arg
@@ -452,8 +468,6 @@ void rtems_interrupt_server_request_initialize(
  * This function may be called from thread or interrupt context.  It does not
  * block.  No error checking is performed.
  *
- * @param[in] server The server identifier.  Use @c RTEMS_ID_NONE to specify
- *   the default server.
  * @param[in] request The interrupt server request must be initialized before the
  *   first call to this function via
  *   rtems_interrupt_server_request_initialize().  The request must not be
@@ -461,30 +475,27 @@ void rtems_interrupt_server_request_initialize(
  *   rtems_interrupt_server_request_destroy() to destroy a request in use.
  */
 RTEMS_INLINE_ROUTINE void rtems_interrupt_server_request_submit(
-  rtems_id                        server,
   rtems_interrupt_server_request *request
 )
 {
-  rtems_interrupt_server_entry_submit( server, &request->entry );
+  rtems_interrupt_server_entry_submit( &request->entry );
 }
 
 /**
  * @brief Destroys the specified interrupt server request.
  *
- * This function must be called from thread context.  It may block.  No error
- * checking is performed.
+ * This function must be called from thread context.  It may block.  Calling
+ * this function within the context of an interrupt server is undefined
+ * behaviour.  No error checking is performed.
  *
- * @param[in] server The server identifier.  Use @c RTEMS_ID_NONE to specify
- *   the default server.
  * @param[in] request The interrupt server request to destroy.  It must have
  *   been initialized via rtems_interrupt_server_request_initialize().
  */
 RTEMS_INLINE_ROUTINE void rtems_interrupt_server_request_destroy(
-  rtems_id                        server,
   rtems_interrupt_server_request *request
 )
 {
-  rtems_interrupt_server_entry_destroy( server, &request->entry );
+  rtems_interrupt_server_entry_destroy( &request->entry );
 }
 
 /** @} */




More information about the vc mailing list