Changeset 718124e in rtems


Ignore:
Timestamp:
03/03/14 09:18:01 (10 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
4.11, 5, master
Children:
b323e1fb
Parents:
e0609ac
git-author:
Sebastian Huber <sebastian.huber@…> (03/03/14 09:18:01)
git-committer:
Sebastian Huber <sebastian.huber@…> (03/06/14 08:43:59)
Message:

rtems: Add RTEMS_INTERRUPT_REPLACE

A new option RTEMS_INTERRUPT_REPLACE is introduced that permits updating
the first interrupt handler for the registered interrupt vector and
matching argument. If no match is found, the install function fails
with RTEMS_UNSATISFIED.

The Interrupt Manager Extension offers interrupt handlers with an
argument pointer. It is impossible to update two words (handler and
argument) atomically on most architectures. In order to avoid an SMP
lock in bsp_interrupt_handler_dispatch() which would degrade the
interrupt response time an alternative must be provided that makes it
possible to tear-down interrupt sources without an SMP lock.

Add RTEMS_INTERRUPT_REPLACE option to Interrupt Manager Extension. This
enables a clean tear-down of interrupt sources on SMP configurations.
Instead of an interrupt handler removal a replacement handler can be
installed to silence an interrupt source. This can be used in contexts
that allow no sophisticated synchronization (e.g. in atexit() or fatal
handlers).

Files:
2 edited

Legend:

Unmodified
Added
Removed
  • c/src/lib/libbsp/shared/src/irq-generic.c

    re0609ac r718124e  
    212212  rtems_vector_number index = 0;
    213213  bsp_interrupt_handler_entry *head = NULL;
    214   bsp_interrupt_handler_entry *tail = NULL;
    215   bsp_interrupt_handler_entry *current = NULL;
    216   bsp_interrupt_handler_entry *match = NULL;
    217214  bool enable_vector = false;
     215  bool replace = RTEMS_INTERRUPT_IS_REPLACE(options);
    218216
    219217  /* Check parameters and system state */
     
    238236
    239237  if (bsp_interrupt_is_empty_handler_entry(head)) {
     238    if (replace) {
     239      /* No handler to replace exists */
     240      bsp_interrupt_unlock();
     241      return RTEMS_UNSATISFIED;
     242    }
     243
    240244    /*
    241245     * No real handler installed yet.  So allocate a new index in
     
    261265    enable_vector = true;
    262266  } else {
     267    bsp_interrupt_handler_entry *current = head;
     268    bsp_interrupt_handler_entry *tail = NULL;
     269    bsp_interrupt_handler_entry *match = NULL;
     270
    263271    /* Ensure that a unique handler remains unique */
    264272    if (
    265       RTEMS_INTERRUPT_IS_UNIQUE(options)
    266         || bsp_interrupt_is_handler_unique(index)
     273      !replace
     274        && (RTEMS_INTERRUPT_IS_UNIQUE(options)
     275          || bsp_interrupt_is_handler_unique(index))
    267276    ) {
    268277      /*
     
    278287     * installed.
    279288     */
    280     current = head;
    281289    do {
    282       if (current->handler == handler && current->arg == arg) {
     290      if (
     291        match == NULL
     292          && (current->handler == handler || replace)
     293          && current->arg == arg
     294      ) {
    283295        match = current;
    284296      }
     
    287299    } while (current != NULL);
    288300
    289     /* Ensure the handler is not already installed */
    290     if (match != NULL) {
    291       /* The handler is already installed */
    292       bsp_interrupt_unlock();
    293       return RTEMS_TOO_MANY;
    294     }
    295 
    296     /* Allocate a new entry */
    297     current = bsp_interrupt_allocate_handler_entry();
    298     if (current == NULL) {
    299       /* Not enough memory */
    300       bsp_interrupt_unlock();
    301       return RTEMS_NO_MEMORY;
    302     }
    303 
    304     /* Set entry */
     301    if (replace) {
     302      /* Ensure that a handler to replace exists */
     303      if (match == NULL) {
     304        bsp_interrupt_unlock();
     305        return RTEMS_UNSATISFIED;
     306      }
     307
     308      /* Use existing entry */
     309      current = match;
     310    } else {
     311      /* Ensure the handler is not already installed */
     312      if (match != NULL) {
     313        /* The handler is already installed */
     314        bsp_interrupt_unlock();
     315        return RTEMS_TOO_MANY;
     316      }
     317
     318      /* Allocate a new entry */
     319      current = bsp_interrupt_allocate_handler_entry();
     320      if (current == NULL) {
     321        /* Not enough memory */
     322        bsp_interrupt_unlock();
     323        return RTEMS_NO_MEMORY;
     324      }
     325    }
     326
     327    /* Update existing entry or set new entry */
    305328    current->handler = handler;
    306     current->arg = arg;
    307329    current->info = info;
    308     current->next = NULL;
    309 
    310     /* Link to list tail */
    311     bsp_interrupt_disable(level);
    312     bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
    313     tail->next = current;
    314     bsp_interrupt_enable(level);
     330
     331    if (!replace) {
     332      /* Set new entry */
     333      current->arg = arg;
     334      current->next = NULL;
     335
     336      /* Link to list tail */
     337      bsp_interrupt_disable(level);
     338      bsp_interrupt_fence(ATOMIC_ORDER_RELEASE);
     339      tail->next = current;
     340      bsp_interrupt_enable(level);
     341    }
    315342  }
    316343
  • cpukit/include/rtems/irq-extension.h

    re0609ac r718124e  
    1010 * Based on concepts of Pavel Pisa, Till Straumann and Eric Valette.
    1111 *
    12  * Copyright (c) 2008
    13  * Embedded Brains GmbH
    14  * Obere Lagerstr. 30
    15  * D-82178 Puchheim
    16  * Germany
    17  * rtems@embedded-brains.de
     12 * Copyright (c) 2008-2014 embedded brains GmbH.
     13 *
     14 *  embedded brains GmbH
     15 *  Dornierstr. 4
     16 *  82178 Puchheim
     17 *  Germany
     18 *  <rtems@embedded-brains.de>
    1819 *
    1920 * The license and distribution terms for this file may be
     
    5556
    5657/**
     58 * @brief Forces that this interrupt handler replaces the first handler with
     59 * the same argument.
     60 */
     61#define RTEMS_INTERRUPT_REPLACE ((rtems_option) 0x00000002)
     62
     63/**
    5764 * @brief Returns true if the interrupt handler unique option is set.
    5865 */
     
    6774
    6875/**
     76 * @brief Returns true if the interrupt handler replace option is set.
     77 */
     78#define RTEMS_INTERRUPT_IS_REPLACE( options) \
     79  ((options) & RTEMS_INTERRUPT_REPLACE)
     80
     81/**
    6982 * @brief Interrupt handler routine type.
    7083 */
     
    7992 * - @ref RTEMS_INTERRUPT_UNIQUE
    8093 * - @ref RTEMS_INTERRUPT_SHARED
     94 * - @ref RTEMS_INTERRUPT_REPLACE
    8195 *
    8296 * with the @a options parameter for the interrupt handler.
     
    88102 * If the option @ref RTEMS_INTERRUPT_UNIQUE is set then it shall be ensured
    89103 * that this handler will be the only one for this vector.
     104 *
     105 * If the option @ref RTEMS_INTERRUPT_REPLACE is set then it shall be ensured
     106 * that this handler will replace the first handler with the same argument for
     107 * this vector if it exists, otherwise an error status shall be returned.  A
     108 * second handler with the same argument for this vector shall remain
     109 * unchanged.  The new handler will inherit the unique or shared option from
     110 * the replaced handler.
    90111 *
    91112 * You can provide an informative description @a info.  This may be used for
     
    109130 * @retval RTEMS_TOO_MANY If a handler with this argument is already installed
    110131 * for the vector this shall be returned.
     132 * @retval RTEMS_UNSATISFIED If no handler exists to replace with the specified
     133 * argument and vector this shall be returned.
    111134 * @retval RTEMS_IO_ERROR Reserved for board support package specific error
    112135 * conditions.
Note: See TracChangeset for help on using the changeset viewer.