[PATCH 1/1] rtems: Add rtems_interrupt_server_build()

Gedare Bloom gedare at rtems.org
Fri Jul 31 15:28:11 UTC 2020


I think it is OK to add to 5, since it is an extension to an
undocumented API ;)

On Fri, Jul 31, 2020 at 9:27 AM Gedare Bloom <gedare at rtems.org> wrote:
>
> reviewing for feature on 5/
>
> On Fri, Jul 31, 2020 at 5:43 AM Sebastian Huber
> <sebastian.huber at embedded-brains.de> wrote:
> >
> > Add rtems_interrupt_server_destroy().
> >
> > Before this patch, the only way to create interrupt servers was
> > rtems_interrupt_server_initialize(). This function creates the default
> > interrupt server and in SMP configurations additional interrupt servers
> > for the additional processors. The interrupt server is heavily used by
> > libbsd. This includes the epoch based reclamation which performs time
> > consuming resource and memory deallocation work. This does not work well
> > with time critical services, for example an UART over SPI or I2C. One
> > approach to address this problem is to allow the application to create
> > custom interrupt servers with the right priority and task properties.
> > The interrupt server API accounted for this, however, it was not
> > implemented before this patch.
> >
> > Close #4033.
> > ---
> >  bsps/shared/irq/irq-server.c         | 360 ++++++++++++++++++---------
> >  cpukit/include/rtems/irq-extension.h | 124 +++++++--
> >  2 files changed, 355 insertions(+), 129 deletions(-)
> >
> > diff --git a/bsps/shared/irq/irq-server.c b/bsps/shared/irq/irq-server.c
> > index 93e2d144d8..aa8b8aa186 100644
> > --- a/bsps/shared/irq/irq-server.c
> > +++ b/bsps/shared/irq/irq-server.c
> > @@ -7,13 +7,7 @@
> >   */
> >
> >  /*
> > - * Copyright (c) 2009, 2019 embedded brains GmbH.  All rights reserved.
> > - *
> > - *  embedded brains GmbH
> > - *  Dornierstr. 4
> > - *  82178 Puchheim
> > - *  Germany
> > - *  <rtems at embedded-brains.de>
> > + * Copyright (C) 2009, 2020 embedded brains GmbH (http://www.embedded-brains.de)
> >   *
> >   * The license and distribution terms for this file may be
> >   * found in the file LICENSE in this distribution or at
> > @@ -21,6 +15,7 @@
> >   */
> >
> >  #include <stdlib.h>
> > +#include <string.h>
> >
> >  #include <rtems.h>
> >  #include <rtems/chain.h>
> > @@ -30,54 +25,43 @@
> >
> >  #define BSP_INTERRUPT_SERVER_MANAGEMENT_VECTOR (BSP_INTERRUPT_VECTOR_MAX + 1)
> >
> > -typedef struct {
> > -  RTEMS_INTERRUPT_LOCK_MEMBER(lock);
> > -  rtems_chain_control entries;
> > -  rtems_id server;
> > -  unsigned errors;
> > -} bsp_interrupt_server_context;
> > +static rtems_interrupt_server_control bsp_interrupt_server_default;
> >
> > -#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 rtems_chain_control bsp_interrupt_server_chain =
> > +  RTEMS_CHAIN_INITIALIZER_EMPTY(bsp_interrupt_server_chain);
> >
> > -static bsp_interrupt_server_context *bsp_interrupt_server_get_context(
> > +static rtems_interrupt_server_control *bsp_interrupt_server_get_context(
> >    uint32_t server_index,
> >    rtems_status_code *sc
> >  )
> >  {
> > -#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
> > +  rtems_chain_node *node;
> > +
> > +  bsp_interrupt_lock();
> > +  node = rtems_chain_first(&bsp_interrupt_server_chain);
> > +
> > +  while (node != rtems_chain_tail(&bsp_interrupt_server_chain)) {
> > +    rtems_interrupt_server_control *s;
> >
> > -  if (server_index >= rtems_scheduler_get_processor_maximum()) {
> > -    *sc = RTEMS_INVALID_ID;
> > -    return NULL;
> > +    s = RTEMS_CONTAINER_OF(node, rtems_interrupt_server_control, node);
> > +    if (s->index == server_index) {
> > +      bsp_interrupt_unlock();
> set sc = RTEMS_SUCCESSFUL?
>
> > +      return s;
> > +    }
> > +
> > +    node = rtems_chain_next(node);
> >    }
> >
> > -  *sc = RTEMS_SUCCESSFUL;
> > -#if defined(RTEMS_SMP)
> > -  return &bsp_interrupt_server_instances[server_index];
> > -#else
> > -  return &bsp_interrupt_server_instance;
> > -#endif
> > +  bsp_interrupt_unlock();
> > +  *sc = RTEMS_INVALID_ID;
> > +  return NULL;
> >  }
> >
> >  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;
> > +  rtems_interrupt_server_control *s = e->server;
> >
> >    if (bsp_interrupt_is_valid_vector(e->vector)) {
> >      bsp_interrupt_vector_disable(e->vector);
> > @@ -137,7 +121,7 @@ static rtems_interrupt_server_entry *bsp_interrupt_server_query_entry(
> >  }
> >
> >  typedef struct {
> > -  bsp_interrupt_server_context *server;
> > +  rtems_interrupt_server_control *server;
> >    rtems_vector_number vector;
> >    rtems_option options;
> >    rtems_interrupt_handler handler;
> > @@ -281,7 +265,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_interrupt_server_control *s,
> >    rtems_vector_number vector,
> >    rtems_option options,
> >    rtems_interrupt_handler handler,
> > @@ -314,7 +298,7 @@ static rtems_status_code bsp_interrupt_server_call_helper(
> >  }
> >
> >  static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(
> > -  bsp_interrupt_server_context *s
> > +  rtems_interrupt_server_control *s
> >  )
> >  {
> >    rtems_interrupt_lock_context lock_context;
> > @@ -337,7 +321,7 @@ static rtems_interrupt_server_entry *bsp_interrupt_server_get_entry(
> >
> >  static void bsp_interrupt_server_task(rtems_task_argument arg)
> >  {
> > -  bsp_interrupt_server_context *s = (bsp_interrupt_server_context *) arg;
> > +  rtems_interrupt_server_control *s = (rtems_interrupt_server_control *) arg;
> >
> >    while (true) {
> >      rtems_event_set events;
> > @@ -377,7 +361,7 @@ rtems_status_code rtems_interrupt_server_handler_install(
> >  )
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> >    if (s == NULL) {
> > @@ -402,7 +386,7 @@ rtems_status_code rtems_interrupt_server_handler_remove(
> >  )
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> >    if (s == NULL) {
> > @@ -464,7 +448,7 @@ 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;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> >    if (s == NULL) {
> > @@ -487,103 +471,249 @@ rtems_status_code rtems_interrupt_server_handler_iterate(
> >    );
> >  }
> >
> > -rtems_status_code rtems_interrupt_server_initialize(
> > +static void bsp_interrupt_server_destroy_memset(
> > +  rtems_interrupt_server_control *s
> > +)
> > +{
> > +  memset(s, 0, sizeof(*s));
>
> should this also free?
>
> > +}
> > +
> > +#if defined(RTEMS_SMP)
> > +static void bsp_interrupt_server_destroy_free(
> > +  rtems_interrupt_server_control *s
> > +)
> > +{
> > +  free(s);
> > +}
> > +#endif
> > +
> > +static rtems_status_code bsp_interrupt_server_create(
> > +  rtems_interrupt_server_control *s,
> >    rtems_task_priority priority,
> >    size_t stack_size,
> >    rtems_mode modes,
> >    rtems_attribute attributes,
> > -  uint32_t *server_count
> > +  uint32_t cpu_index
> >  )
> >  {
> > -  uint32_t cpu_index;
> > -  uint32_t cpu_count;
> > -  uint32_t dummy;
> > -  bsp_interrupt_server_context *instances;
> > +  rtems_status_code sc;
> > +#if defined(RTEMS_SMP)
> > +  rtems_id scheduler;
> > +  cpu_set_t cpu;
> > +#endif
> >
> > -  if (server_count == NULL) {
> > -    server_count = &dummy;
> > -  }
> > +  rtems_interrupt_lock_initialize(&s->lock, "Interrupt Server");
> > +  rtems_chain_initialize_empty(&s->entries);
> >
> > -  cpu_count = rtems_scheduler_get_processor_maximum();
> > +  sc = rtems_task_create(
> > +    rtems_build_name('I', 'R', 'Q', 'S'),
>
> this name needs to be documented as "reserved" in case the irq server is used
>
> > +    priority,
> > +    stack_size,
> > +    modes,
> > +    attributes,
> > +    &s->server
> > +  );
> > +  if (sc != RTEMS_SUCCESSFUL) {
> > +    return sc;
> > +  }
> >
> >  #if defined(RTEMS_SMP)
> > -  instances = calloc(cpu_count, sizeof(*instances));
> > -  if (instances == NULL) {
> > -    return RTEMS_NO_MEMORY;
> > +  sc = rtems_scheduler_ident_by_processor(cpu_index, &scheduler);
> > +  if (sc != RTEMS_SUCCESSFUL) {
> > +    /* Do not start an interrupt server on a processor without a scheduler */
> > +    return RTEMS_SUCCESSFUL;
> >    }
> > +
> > +  sc = rtems_task_set_scheduler(s->server, scheduler, priority);
> > +  _Assert(sc == RTEMS_SUCCESSFUL);
> > +
> > +  /* Set the task to processor affinity on a best-effort basis */
> > +  CPU_ZERO(&cpu);
> > +  CPU_SET(cpu_index, &cpu);
> > +  (void) rtems_task_set_affinity(s->server, sizeof(cpu), &cpu);
> >  #else
> > -  instances = &bsp_interrupt_server_instance;
> > +  (void) cpu_index;
> >  #endif
> >
> > -  for (cpu_index = 0; cpu_index < cpu_count; ++cpu_index) {
> > -    bsp_interrupt_server_context *s = &instances[cpu_index];
> > -    rtems_status_code sc;
> > +  rtems_chain_append_unprotected(&bsp_interrupt_server_chain, &s->node);
> > +
> > +  sc = rtems_task_start(
> > +    s->server,
> > +    bsp_interrupt_server_task,
> > +    (rtems_task_argument) s
> > +  );
> > +  _Assert(sc == RTEMS_SUCCESSFUL);
> > +
> > +  return sc;
> > +}
> > +
> > +rtems_status_code rtems_interrupt_server_initialize(
> > +  rtems_task_priority priority,
> > +  size_t stack_size,
> > +  rtems_mode modes,
> > +  rtems_attribute attributes,
> > +  uint32_t *server_count
> > +)
> > +{
> > +  rtems_status_code sc;
> > +  rtems_interrupt_server_control *s;
> > +  uint32_t cpu_index;
> >  #if defined(RTEMS_SMP)
> > -    rtems_id scheduler;
> > -    cpu_set_t cpu;
> > +  uint32_t cpu_count;
> >  #endif
> >
> > -    rtems_interrupt_lock_initialize(&s->lock, "Interrupt Server");
> > -    rtems_chain_initialize_empty(&s->entries);
> > +  cpu_index = 0;
> > +  s = &bsp_interrupt_server_default;
> > +
> > +  bsp_interrupt_lock();
> > +
> > +  if (s->server != 0) {
> > +    sc = RTEMS_INCORRECT_STATE;
> > +    goto done;
> > +  }
> > +
> > +  s->destroy = bsp_interrupt_server_destroy_memset;
> > +  sc = bsp_interrupt_server_create(
> > +    s,
> > +    priority,
> > +    stack_size,
> > +    modes,
> > +    attributes,
> > +    cpu_index
> > +  );
> > +  if (sc != RTEMS_SUCCESSFUL) {
> > +    goto done;
> > +  }
> > +
> > +  cpu_index = 1;
> > +
> > +#if defined(RTEMS_SMP)
> > +  cpu_count = rtems_scheduler_get_processor_maximum();
> > +
> > +  while (cpu_index < cpu_count) {
> > +    s = calloc(1, sizeof(*s));
> >
> > -    sc = rtems_task_create(
> > -      rtems_build_name('I', 'R', 'Q', 'S'),
> > +    if (s == NULL) {
> > +      sc = RTEMS_NO_MEMORY;
> > +      goto done;
> > +    }
> > +
> > +    s->destroy = bsp_interrupt_server_destroy_free;
> > +    s->index = cpu_index;
> > +    sc = bsp_interrupt_server_create(
> > +      s,
> >        priority,
> >        stack_size,
> >        modes,
> >        attributes,
> > -      &s->server
> > +      cpu_index
> >      );
> >      if (sc != RTEMS_SUCCESSFUL) {
> > -      *server_count = cpu_index;
> > -
> > -#if defined(RTEMS_SMP)
> > -      if (cpu_index > 0) {
> > -        bsp_interrupt_server_instances = instances;
> > -        return RTEMS_SUCCESSFUL;
> > -      }
> > +      goto done;
> > +    }
> >
> > -      free(instances);
> > +    ++cpu_index;
> > +  }
> >  #endif
> >
> > -      return RTEMS_TOO_MANY;
> > -    }
> > +done:
> > +  bsp_interrupt_unlock();
> >
> > -#if defined(RTEMS_SMP)
> > -    sc = rtems_scheduler_ident_by_processor(cpu_index, &scheduler);
> > -    if (sc != RTEMS_SUCCESSFUL) {
> > -      /* Do not start an interrupt server on a processor without a scheduler */
> > -      continue;
> > -    }
> > +  if (server_count != NULL) {
> > +    *server_count = cpu_index;
> > +  }
> >
> > -    sc = rtems_task_set_scheduler(s->server, scheduler, priority);
> > -    _Assert(sc == RTEMS_SUCCESSFUL);
> > +  return sc;
> > +}
> >
> > -    /* Set the task to processor affinity on a best-effort basis */
> > -    CPU_ZERO(&cpu);
> > -    CPU_SET(cpu_index, &cpu);
> > -    (void) rtems_task_set_affinity(s->server, sizeof(cpu), &cpu);
> > -#endif
> > +rtems_status_code rtems_interrupt_server_build(
> > +  rtems_interrupt_server_control      *s,
> > +  const rtems_interrupt_server_config *config,
> > +  uint32_t                            *server_index
> > +)
> > +{
> > +  rtems_status_code sc;
> >
> > -    sc = rtems_task_start(
> > -      s->server,
> > -      bsp_interrupt_server_task,
> > -      (rtems_task_argument) s
> > -    );
> > -    _Assert(sc == RTEMS_SUCCESSFUL);
> > +  sc = rtems_task_create(
> > +    rtems_build_name('I', 'R', 'Q', 'S'),
> > +    config->priority,
> > +    config->stack_size,
> > +    config->modes,
> > +    config->attributes,
> > +    &s->server
> > +  );
> > +  if (sc != RTEMS_SUCCESSFUL) {
> > +    return sc;
> >    }
> >
> > -#if defined(RTEMS_SMP)
> > -  bsp_interrupt_server_instances = instances;
> > +  rtems_interrupt_lock_initialize(&s->lock, "Interrupt Server");
> > +  rtems_chain_initialize_empty(&s->entries);
> > +  s->destroy = config->destroy;
> > +  s->index = rtems_object_id_get_index(s->server)
> > +    + rtems_scheduler_get_processor_maximum();
> > +  *server_index = s->index;
> > +
> > +  bsp_interrupt_lock();
> > +  rtems_chain_initialize_node(&s->node);
> > +  rtems_chain_append_unprotected(&bsp_interrupt_server_chain, &s->node);
> > +  bsp_interrupt_unlock();
> > +
> > +  sc = rtems_task_start(
> > +    s->server,
> > +    bsp_interrupt_server_task,
> > +    (rtems_task_argument) s
> > +  );
> > +  _Assert(sc == RTEMS_SUCCESSFUL);
> > +
> > +  return RTEMS_SUCCESSFUL;
> > +}
> > +
> > +static void bsp_interrupt_server_destroy_helper(void *arg)
> > +{
> > +  bsp_interrupt_server_helper_data *hd = arg;
> > +  rtems_interrupt_server_control *s = hd->server;
> > +#if defined(RTEMS_DEBUG)
> > +  rtems_status_code sc;
> >  #endif
> > -  *server_count = cpu_index;
> >
> > +  bsp_interrupt_lock();
> > +  rtems_chain_extract_unprotected(&s->node);
> > +  bsp_interrupt_unlock();
> > +
> > +  if (s->destroy != NULL) {
> > +    (*s->destroy)(s);
> > +  }
> > +
> > +  sc = rtems_event_transient_send(hd->task);
> > +  _Assert(sc == RTEMS_SUCCESSFUL);
> > +
> > +  rtems_task_exit();
> > +}
> > +
> > +rtems_status_code rtems_interrupt_server_destroy(uint32_t server_index)
> > +{
> > +  rtems_status_code sc;
> > +  rtems_interrupt_server_control *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_destroy_helper
> > +  );
> >    return RTEMS_SUCCESSFUL;
> >  }
> >
> >  static void bsp_interrupt_server_entry_initialize(
> >    rtems_interrupt_server_entry *entry,
> > -  bsp_interrupt_server_context *s
> > +  rtems_interrupt_server_control *s
> >  )
> >  {
> >    rtems_chain_set_off_chain(&entry->node);
> > @@ -611,7 +741,7 @@ rtems_status_code rtems_interrupt_server_entry_initialize(
> >  )
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> >    if (s == NULL) {
> > @@ -645,7 +775,7 @@ rtems_status_code rtems_interrupt_server_entry_move(
> >  )
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(destination_server_index, &sc);
> >    if (s == NULL) {
> > @@ -667,7 +797,7 @@ void rtems_interrupt_server_entry_destroy(
> >    rtems_interrupt_server_entry *entry
> >  )
> >  {
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >    rtems_interrupt_lock_context lock_context;
> >
> >    s = entry->server;
> > @@ -698,7 +828,7 @@ rtems_status_code rtems_interrupt_server_request_initialize(
> >  )
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> >    if (s == NULL) {
> > @@ -727,8 +857,8 @@ static void bsp_interrupt_server_handler_move_helper(void *arg)
> >    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;
> > +    rtems_interrupt_server_control *src = e->server;
> > +    rtems_interrupt_server_control *dst = hihd->arg;
> >      bool pending;
> >
> >      /* The source server is only used in SMP configurations for the lock */
> > @@ -763,8 +893,8 @@ rtems_status_code rtems_interrupt_server_move(
> >  )
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *src;
> > -  bsp_interrupt_server_context *dst;
> > +  rtems_interrupt_server_control *src;
> > +  rtems_interrupt_server_control *dst;
> >    bsp_interrupt_server_handler_iterate_helper_data hihd;
> >
> >    src = bsp_interrupt_server_get_context(source_server_index, &sc);
> > @@ -810,7 +940,7 @@ static void bsp_interrupt_server_entry_suspend_helper(void *arg)
> >  rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index)
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> >    if (s == NULL) {
> > @@ -831,7 +961,7 @@ rtems_status_code rtems_interrupt_server_suspend(uint32_t server_index)
> >  rtems_status_code rtems_interrupt_server_resume(uint32_t server_index)
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> >    if (s == NULL) {
> > @@ -858,7 +988,7 @@ rtems_status_code rtems_interrupt_server_set_affinity(
> >  )
> >  {
> >    rtems_status_code sc;
> > -  bsp_interrupt_server_context *s;
> > +  rtems_interrupt_server_control *s;
> >    rtems_id scheduler;
> >
> >    s = bsp_interrupt_server_get_context(server_index, &sc);
> > diff --git a/cpukit/include/rtems/irq-extension.h b/cpukit/include/rtems/irq-extension.h
> > index 0d77b320bc..4219d0f384 100644
> > --- a/cpukit/include/rtems/irq-extension.h
> > +++ b/cpukit/include/rtems/irq-extension.h
> > @@ -9,13 +9,7 @@
> >  /*
> >   * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
> >   *
> > - * Copyright (C) 2008, 2019 embedded brains GmbH
> > - *
> > - *  embedded brains GmbH
> > - *  Dornierstr. 4
> > - *  82178 Puchheim
> > - *  Germany
> > - *  <rtems at embedded-brains.de>
> > + * Copyright (C) 2008, 2020 embedded brains GmbH (http://www.embedded-brains.de)
> >   *
> >   * The license and distribution terms for this file may be
> >   * found in the file LICENSE in this distribution or at
> > @@ -259,6 +253,60 @@ typedef struct rtems_interrupt_server_action {
> >   */
> >  #define RTEMS_INTERRUPT_SERVER_DEFAULT 0
> >
> > +/**
> > + * @brief An interrupt server control.
> > + *
> > + * This structure must be treated as an opaque data type.  Members must not be
> > + * accessed directly.
> > + *
> > + * @see rtems_interrupt_server_build()
> > + */
> > +typedef struct rtems_interrupt_server_control {
> > +  RTEMS_INTERRUPT_LOCK_MEMBER( lock )
> > +  rtems_chain_control          entries;
> > +  rtems_id                     server;
> > +  unsigned long                errors;
> > +  uint32_t                     index;
> > +  rtems_chain_node             node;
> > +  void ( *destroy )( struct rtems_interrupt_server_control * );
> > +} rtems_interrupt_server_control;
> > +
> > +/**
> > + * @brief An interrupt server configuration.
> > + *
> > + * @see rtems_interrupt_server_build()
> > + */
> > +typedef struct {
> > +  /**
> > +   * @brief The initial task priority of the interrupt server.
> > +   */
> > +  rtems_task_priority priority;
> > +
> > +  /**
> > +   * @brief The task stack size of the interrupt server.
> > +   */
> > +  size_t stack_size;
> > +
> > +  /**
> > +   * @brief The initial task modes of the interrupt server.
> > +   */
> > +  rtems_mode modes;
> > +
> > +  /**
> > +   * @brief The task attributes of the interrupt server.
> > +   */
> > +  rtems_attribute attributes;
> > +
> > +  /**
> > +   * @brief An optional handler to destroy the interrupt server control handed
> > +   *   over to rtems_interrupt_server_build().
> > +   *
> > +   * This handler is called in the context of the interrupt server to be
> > +   * destroyed.
> > +   */
> > +  void ( *destroy )( rtems_interrupt_server_control * );
> > +} rtems_interrupt_server_config;
> > +
> >  /**
> >   * @brief An interrupt server entry.
> >   *
> > @@ -311,14 +359,14 @@ typedef struct {
> >   *
> >   * This function may block.
> >   *
> > - * @see rtems_task_create().
> > + * @retval RTEMS_SUCCESSFUL The operation was successful.
> >   *
> > - * @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.
> > + * @retval RTEMS_INCORRECT_STATE The interrupt servers were already initialized.
> > + *
> > + * @return The function uses rtems_task_create().  If this operation is not
> > + *   successful, then its status code is returned.
> > + *
> > + * @see rtems_interrupt_server_build() and rtems_interrupt_server_destroy().
> >   */
> >  rtems_status_code rtems_interrupt_server_initialize(
> >    rtems_task_priority priority,
> > @@ -328,6 +376,54 @@ rtems_status_code rtems_interrupt_server_initialize(
> >    uint32_t *server_count
> >  );
> >
> > +/**
> > + * @brief Builds an interrupt server.
> > + *
> > + * This function may block.
> > + *
> > + * @param[out] control is the interrupt server control.  The ownership of this
> > + *   structure is transferred from the caller of this function to the interrupt
> > + *   server management.
> > + *
> > + * @param config is the interrupt server configuration.
> > + *
> > + * @param[out] server_index is the pointer to a server index variable.  The
> > + *   index of the built interrupt server will be stored in the referenced
> > + *   variable if the operation was successful.
> > + *
> > + * @retval RTEMS_SUCCESSFUL The operation was successful.
> > + *
> > + * @return The function uses rtems_task_create().  If this operation is not
> > + *   successful, then its status code is returned.
> > + *
> > + * @see rtems_interrupt_server_initialize() and
> > + *   rtems_interrupt_server_destroy().
> > + */
> > +rtems_status_code rtems_interrupt_server_build(
> name change to create is fine, update the @brief also.
>
> > +  rtems_interrupt_server_control      *control,
> > +  const rtems_interrupt_server_config *config,
> > +  uint32_t                            *server_index
> > +);
> > +
> > +/**
> > + * @brief Destroys an interrupt server.
> > + *
> > + * This function may block.
> > + *
> > + * The interrupt server deletes itself, so after the return of the function the
> > + * interrupt server may be still in the termination process depending on the
> > + * task priorities of the system.
> > + *
> > + * @param server_index is the index of the interrupt server to destroy.  Use
> > + *   ::RTEMS_INTERRUPT_SERVER_DEFAULT to specify the default server.
> > + *
> > + * @retval RTEMS_SUCCESSFUL The operation was successful.
> > + * @retval RTEMS_INVALID_ID The interrupt server index was invalid.
> > + *
> > + * @see rtems_interrupt_server_build()
> > + */
> > +rtems_status_code rtems_interrupt_server_destroy( uint32_t server_index );
> > +
> >  /**
> >   * @brief Installs the interrupt handler routine @a handler for the interrupt
> >   * vector with number @a vector on the server @a server.
>
> The rtems_interrupt_server* should get user-facing documentation
> (eventually). Please open a ticket for adding it.
>
> > --
> > 2.26.2
> >
> > _______________________________________________
> > devel mailing list
> > devel at rtems.org
> > http://lists.rtems.org/mailman/listinfo/devel


More information about the devel mailing list