Changeset b1b6dd71 in rtems


Ignore:
Timestamp:
Dec 11, 2019, 3:45:37 PM (2 months ago)
Author:
Sebastian Huber <sebastian.huber@…>
Branches:
master
Children:
08bd7d3
Parents:
86c70e71
git-author:
Sebastian Huber <sebastian.huber@…> (12/11/19 15:45:37)
git-committer:
Sebastian Huber <sebastian.huber@…> (12/11/19 16:45:31)
Message:

pipe: Use condition variables

Use self-contained condition variables instead of Classic API barriers.
This simplifies the implementation and configuration.

Update #3840.

Files:
5 edited

Legend:

Unmodified
Added
Removed
  • cpukit/include/rtems/confdefs.h

    r86c70e71 rb1b6dd71  
    212212#if !defined(CONFIGURE_MAXIMUM_PIPES)
    213213  #define CONFIGURE_MAXIMUM_PIPES 0
    214 #endif
    215 
    216 /*
    217  * This specifies the number of barriers required for the configured
    218  * number of FIFOs and named pipes.
    219  */
    220 #if CONFIGURE_MAXIMUM_FIFOS > 0 || CONFIGURE_MAXIMUM_PIPES > 0
    221   #define _CONFIGURE_BARRIERS_FOR_FIFOS \
    222     (2 * (CONFIGURE_MAXIMUM_FIFOS + CONFIGURE_MAXIMUM_PIPES))
    223 #else
    224   #define _CONFIGURE_BARRIERS_FOR_FIFOS   0
    225214#endif
    226215
     
    20422031#endif
    20432032
    2044 /*
    2045  * This macro is calculated to specify the number of Classic API
    2046  * Barriers required by the application and configured capabilities.
    2047  */
    2048 #define _CONFIGURE_BARRIERS \
    2049   (CONFIGURE_MAXIMUM_BARRIERS + _CONFIGURE_BARRIERS_FOR_FIFOS)
    2050 
    20512033#ifndef CONFIGURE_MAXIMUM_USER_EXTENSIONS
    20522034  /**
     
    27382720  );
    27392721
    2740   #if _CONFIGURE_BARRIERS > 0
    2741     BARRIER_INFORMATION_DEFINE( _CONFIGURE_BARRIERS );
     2722  #if CONFIGURE_MAXIMUM_BARRIERS > 0
     2723    BARRIER_INFORMATION_DEFINE( CONFIGURE_MAXIMUM_BARRIERS );
    27422724  #endif
    27432725
  • cpukit/include/rtems/pipe.h

    r86c70e71 rb1b6dd71  
    4848  unsigned int writerCounter;     /* for differentiation of successive opens */
    4949  rtems_mutex Mutex;
    50   rtems_id readBarrier;   /* wait queues */
    51   rtems_id writeBarrier;
     50  rtems_condition_variable readBarrier;   /* wait queues */
     51  rtems_condition_variable writeBarrier;
    5252#if 0
    5353  boolean Anonymous;      /* anonymous pipe or FIFO */
  • cpukit/libfs/src/pipe/fifo.c

    r86c70e71 rb1b6dd71  
    2828#include <rtems/libio_.h>
    2929#include <rtems/pipe.h>
    30 #include <rtems/rtems/barrierimpl.h>
    31 #include <rtems/score/statesimpl.h>
    3230
    3331#define LIBIO_ACCMODE(_iop) (rtems_libio_iop_flags(_iop) & LIBIO_FLAGS_READ_WRITE)
     
    4745
    4846#define PIPE_READWAIT(_pipe)  \
    49   ( rtems_barrier_wait(_pipe->readBarrier, RTEMS_NO_TIMEOUT)  \
    50    == RTEMS_SUCCESSFUL)
     47  rtems_condition_variable_wait(&(_pipe)->readBarrier, &(_pipe)->Mutex)
    5148
    5249#define PIPE_WRITEWAIT(_pipe)  \
    53   ( rtems_barrier_wait(_pipe->writeBarrier, RTEMS_NO_TIMEOUT)  \
    54    == RTEMS_SUCCESSFUL)
     50  rtems_condition_variable_wait(&(_pipe)->writeBarrier, &(_pipe)->Mutex)
    5551
    5652#define PIPE_WAKEUPREADERS(_pipe) \
    57   do {uint32_t n; rtems_barrier_release(_pipe->readBarrier, &n); } while(0)
     53  rtems_condition_variable_broadcast(&(_pipe)->readBarrier)
    5854
    5955#define PIPE_WAKEUPWRITERS(_pipe) \
    60   do {uint32_t n; rtems_barrier_release(_pipe->writeBarrier, &n); } while(0)
     56  rtems_condition_variable_broadcast(&(_pipe)->writeBarrier)
    6157
    6258/*
     
    7975  pipe->Size = PIPE_BUF;
    8076  pipe->Buffer = malloc(pipe->Size);
    81   if (! pipe->Buffer)
    82     goto err_buf;
    83 
    84   err = -ENOMEM;
    85 
    86   if (rtems_barrier_create(
    87         rtems_build_name ('P', 'I', 'r', c),
    88         RTEMS_BARRIER_MANUAL_RELEASE, 0,
    89         &pipe->readBarrier) != RTEMS_SUCCESSFUL)
    90     goto err_rbar;
    91   if (rtems_barrier_create(
    92         rtems_build_name ('P', 'I', 'w', c),
    93         RTEMS_BARRIER_MANUAL_RELEASE, 0,
    94         &pipe->writeBarrier) != RTEMS_SUCCESSFUL)
    95     goto err_wbar;
     77  if (pipe->Buffer == NULL) {
     78    free(pipe);
     79    return -ENOMEM;
     80  }
     81
     82  rtems_condition_variable_init(&pipe->readBarrier, "Pipe Read");
     83  rtems_condition_variable_init(&pipe->writeBarrier, "Pipe Write");
    9684  rtems_mutex_init(&pipe->Mutex, "Pipe");
    9785
     
    10088    c = 'a';
    10189  return 0;
    102 
    103 err_wbar:
    104   rtems_barrier_delete(pipe->readBarrier);
    105 err_rbar:
    106   free(pipe->Buffer);
    107 err_buf:
    108   free(pipe);
    109   return err;
    11090}
    11191
     
    11595)
    11696{
    117   rtems_barrier_delete(pipe->readBarrier);
    118   rtems_barrier_delete(pipe->writeBarrier);
     97  rtems_condition_variable_destroy(&pipe->readBarrier);
     98  rtems_condition_variable_destroy(&pipe->writeBarrier);
    11999  rtems_mutex_destroy(&pipe->Mutex);
    120100  free(pipe->Buffer);
     
    242222        /* Wait until a writer opens the pipe */
    243223        do {
    244           PIPE_UNLOCK(pipe);
    245           if (! PIPE_READWAIT(pipe))
    246             goto out_error;
    247           PIPE_LOCK(pipe);
     224          PIPE_READWAIT(pipe);
    248225        } while (prevCounter == pipe->writerCounter);
    249226      }
     
    266243        err = -EINTR;
    267244        do {
    268           PIPE_UNLOCK(pipe);
    269           if (! PIPE_WRITEWAIT(pipe))
    270             goto out_error;
    271           PIPE_LOCK(pipe);
     245          PIPE_WRITEWAIT(pipe);
    272246        } while (prevCounter == pipe->readerCounter);
    273247      }
     
    315289    /* Wait until pipe is no more empty or no writer exists */
    316290    pipe->waitingReaders ++;
    317     PIPE_UNLOCK(pipe);
    318     if (! PIPE_READWAIT(pipe))
    319       ret = -EINTR;
    320     PIPE_LOCK(pipe);
     291    PIPE_READWAIT(pipe);
    321292    pipe->waitingReaders --;
    322293    if (ret != 0)
     
    385356      /* Wait until there is chunk bytes space or no reader exists */
    386357      pipe->waitingWriters ++;
    387       PIPE_UNLOCK(pipe);
    388       if (! PIPE_WRITEWAIT(pipe))
    389         ret = -EINTR;
    390       PIPE_LOCK(pipe);
     358      PIPE_WRITEWAIT(pipe);
    391359      pipe->waitingWriters --;
    392360      if (ret != 0)
  • testsuites/sptests/spfifo02/init.c

    r86c70e71 rb1b6dd71  
    2020#include <unistd.h>
    2121#include <errno.h>
    22 #include <rtems/libcsupport.h>
     22#include <rtems/malloc.h>
    2323
    2424const char rtems_test_name[] = "SPFIFO 2";
    2525
    26 /* forward declarations to avoid warnings */
    27 rtems_task Init(rtems_task_argument argument);
    28 void create_all_barriers(void);
    29 void delete_barrier(void);
    30 void create_fifo(void);
    31 void open_fifo(int expected, int flags);
    32 
    33 #define MAXIMUM 10
    3426#define NUM_OPEN_REQ 26
    3527
    36 rtems_id Barriers[MAXIMUM];
    37 int BarrierCount;
    38 
    39 rtems_id Semaphores[MAXIMUM];
    40 int SemaphoreCount;
    41 
    42 void create_all_barriers(void)
    43 {
    44   rtems_status_code status;
    45   int               i;
    46 
    47   BarrierCount = 0;
    48 
    49   memset( Barriers, 0, sizeof(Barriers) );
    50   for ( i=0 ; i<MAXIMUM ; i++ ) {
    51     status = rtems_barrier_create(
    52       rtems_build_name( 'B', 'A', 'R', 0x30+i ),
    53       RTEMS_BARRIER_MANUAL_RELEASE,
    54       0,
    55       &Barriers[i]
    56     );
    57     if ( status == RTEMS_TOO_MANY ) {
    58       printf( "%d Barriers created\n", BarrierCount+1 );
    59       return;
    60     }
    61 
    62     directive_failed( status, "barrier create" );
    63     BarrierCount++;
    64   }
    65 }
    66 
    67 void delete_barrier(void)
    68 {
    69   rtems_status_code status;
    70  
    71   BarrierCount--;
    72   printf( "Deleting barrier id=0x%08x\n",
    73     (unsigned int)Barriers[BarrierCount] );
    74   status = rtems_barrier_delete( Barriers[BarrierCount] );
    75   directive_failed( status, "barrier delete" );
    76 }
    77 
    78 void create_fifo(void)
     28static void create_fifo(void)
    7929{
    8030  int status;
     
    8434}
    8535
    86 void open_fifo(int expected, int flags)
     36static void open_fifo(int expected, int flags)
    8737{
    8838  int fd;
     
    9949}
    10050
    101 rtems_task Init(
     51static rtems_task Init(
    10252  rtems_task_argument argument
    10353)
    10454{
    105   void *alloc_ptr = (void *)0;
     55  void *p;
    10656  int num_opens = 0;
    10757  int index = 0;
     
    10959  TEST_BEGIN();
    11060
    111   puts( "Creating all barriers" );
    112   create_all_barriers();
    113 
    11461  puts( "Creating FIFO" );
    11562  create_fifo();
    11663
    117   alloc_ptr = malloc( malloc_free_space() - 4 );
     64  p = rtems_heap_greedy_allocate(NULL, 0);
    11865  puts("Opening FIFO.. expect ENOMEM since no memory is available");
    11966  open_fifo(ENOMEM, O_RDWR);
     67  rtems_heap_greedy_free(p);
    12068
    121   free(alloc_ptr);
    122   puts( "Opening FIFO.. expect ENOMEM (barrier-1 for pipe could not be created)" );
    123   open_fifo(ENOMEM, O_RDWR);
    124 
    125   delete_barrier();
    126   puts( "Opening FIFO.. expect ENOMEM (barrier-2 for pipe could not be created" );
    127   open_fifo(ENOMEM, O_RDWR);
    128 
    129   delete_barrier();
    13069  puts( "Opening FIFO in RDWR mode. Expect OK" );
    13170  open_fifo(0, O_RDWR);
Note: See TracChangeset for help on using the changeset viewer.