Changeset c3764ce in rtems


Ignore:
Timestamp:
10/05/16 08:37:56 (6 years ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
5, master
Children:
e34fe38
Parents:
a5c56af
git-author:
Sebastian Huber <sebastian.huber@…> (10/05/16 08:37:56)
git-committer:
Sebastian Huber <sebastian.huber@…> (12/16/16 08:04:58)
Message:

termios: Use mutex for task driven mode

Termios has a task driven mode (TERMIOS_TASK_DRIVEN). This mode aims to
avoid long sections with disabled interrupts. This is only partly
implemented since the device level state is still protected by disabled
interrupts. Use a mutex to protect the device level state in task driven
mode to fix this issue.

Update #2838.

Location:
cpukit/libcsupport
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • cpukit/libcsupport/include/rtems/termiostypes.h

    ra5c56af rc3764ce  
    7171 */
    7272typedef struct rtems_termios_device_context {
    73   rtems_interrupt_lock interrupt_lock;
     73  union {
     74    /* Used for TERMIOS_POLLED and TERMIOS_IRQ_DRIVEN */
     75    rtems_interrupt_lock interrupt;
     76
     77    /* Used for TERMIOS_TASK_DRIVEN */
     78    rtems_id mutex;
     79  } lock;
     80
     81  void ( *lock_acquire )(
     82    struct rtems_termios_device_context *,
     83    rtems_interrupt_lock_context *
     84  );
     85
     86  void ( *lock_release )(
     87    struct rtems_termios_device_context *,
     88    rtems_interrupt_lock_context *
     89  );
    7490} rtems_termios_device_context;
    7591
     
    87103)
    88104{
    89   rtems_interrupt_lock_initialize( &context->interrupt_lock, name );
     105  rtems_interrupt_lock_initialize( &context->lock.interrupt, name );
    90106}
    91107
     
    97113 */
    98114#define RTEMS_TERMIOS_DEVICE_CONTEXT_INITIALIZER( name ) \
    99   { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) }
     115  { { RTEMS_INTERRUPT_LOCK_INITIALIZER( name ) } }
    100116
    101117/**
     
    409425)
    410426{
    411   rtems_interrupt_lock_acquire( &context->interrupt_lock, lock_context );
     427  ( *context->lock_acquire )( context, lock_context );
    412428}
    413429
     
    424440)
    425441{
    426   rtems_interrupt_lock_release( &context->interrupt_lock, lock_context );
     442  ( *context->lock_release )( context, lock_context );
    427443}
    428444
  • cpukit/libcsupport/src/termios.c

    ra5c56af rc3764ce  
    273273}
    274274
     275static bool
     276needDeviceMutex (rtems_termios_tty *tty)
     277{
     278  return tty->handler.mode == TERMIOS_TASK_DRIVEN;
     279}
     280
    275281static void
    276282rtems_termios_destroy_tty (rtems_termios_tty *tty, void *arg, bool last_close)
     
    319325    rtems_semaphore_delete (tty->rawInBuf.Semaphore);
    320326
    321   if (tty->device_context == &tty->legacy_device_context)
    322     rtems_interrupt_lock_destroy (&tty->legacy_device_context.interrupt_lock);
     327  if (needDeviceMutex (tty)) {
     328    rtems_semaphore_delete (tty->device_context->lock.mutex);
     329  } else if (tty->device_context == &tty->legacy_device_context) {
     330    rtems_interrupt_lock_destroy (&tty->legacy_device_context.lock.interrupt);
     331  }
    323332
    324333  free (tty->rawInBuf.theBuf);
     
    326335  free (tty->cbuf);
    327336  free (tty);
     337}
     338
     339static void
     340deviceAcquireMutex(
     341  rtems_termios_device_context *ctx,
     342  rtems_interrupt_lock_context *lock_context
     343)
     344{
     345  rtems_status_code sc;
     346
     347  sc = rtems_semaphore_obtain (ctx->lock.mutex, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
     348  _Assert (sc == RTEMS_SUCCESSFUL);
     349  (void) sc;
     350}
     351
     352static void
     353deviceReleaseMutex(
     354  rtems_termios_device_context *ctx,
     355  rtems_interrupt_lock_context *lock_context
     356)
     357{
     358  rtems_status_code sc;
     359
     360  sc = rtems_semaphore_release (ctx->lock.mutex);
     361  _Assert (sc == RTEMS_SUCCESSFUL);
     362  (void) sc;
     363}
     364
     365static void
     366deviceAcquireInterrupt(
     367  rtems_termios_device_context *ctx,
     368  rtems_interrupt_lock_context *lock_context
     369)
     370{
     371  rtems_interrupt_lock_acquire (&ctx->lock.interrupt, lock_context);
     372}
     373
     374static void
     375deviceReleaseInterrupt(
     376  rtems_termios_device_context *ctx,
     377  rtems_interrupt_lock_context *lock_context
     378)
     379{
     380  rtems_interrupt_lock_release (&ctx->lock.interrupt, lock_context);
    328381}
    329382
     
    342395  if (tty == NULL) {
    343396    static char c = 'a';
     397    rtems_termios_device_context *ctx;
    344398
    345399    /*
     
    458512      tty->device_context = &tty->legacy_device_context;
    459513      rtems_termios_device_context_initialize (tty->device_context, "Termios");
     514    }
     515
     516    ctx = tty->device_context;
     517
     518    if (needDeviceMutex (tty)) {
     519      sc = rtems_semaphore_create (
     520        rtems_build_name ('T', 'l', 'k', c),
     521        1,
     522        RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
     523        0,
     524        &ctx->lock.mutex);
     525      if (sc != RTEMS_SUCCESSFUL) {
     526        rtems_fatal_error_occurred (sc);
     527      }
     528
     529      ctx->lock_acquire = deviceAcquireMutex;
     530      ctx->lock_release = deviceReleaseMutex;
     531    } else {
     532      ctx->lock_acquire = deviceAcquireInterrupt;
     533      ctx->lock_release = deviceReleaseInterrupt;
    460534    }
    461535
Note: See TracChangeset for help on using the changeset viewer.