[rtems commit] pipe: Use condition variables

Sebastian Huber sebh at rtems.org
Wed Dec 11 16:46:23 UTC 2019


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

Author:    Sebastian Huber <sebastian.huber at embedded-brains.de>
Date:      Wed Dec 11 16:45:37 2019 +0100

pipe: Use condition variables

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

Update #3840.

---

 cpukit/include/rtems/confdefs.h          | 22 +---------
 cpukit/include/rtems/pipe.h              |  4 +-
 cpukit/libfs/src/pipe/fifo.c             | 66 ++++++++--------------------
 testsuites/sptests/spfifo02/init.c       | 75 +++-----------------------------
 testsuites/sptests/spfifo02/spfifo02.doc |  1 -
 5 files changed, 28 insertions(+), 140 deletions(-)

diff --git a/cpukit/include/rtems/confdefs.h b/cpukit/include/rtems/confdefs.h
index 922e4d7..2e48af3 100644
--- a/cpukit/include/rtems/confdefs.h
+++ b/cpukit/include/rtems/confdefs.h
@@ -213,17 +213,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
   #define CONFIGURE_MAXIMUM_PIPES 0
 #endif
 
-/*
- * This specifies the number of barriers required for the configured
- * number of FIFOs and named pipes.
- */
-#if CONFIGURE_MAXIMUM_FIFOS > 0 || CONFIGURE_MAXIMUM_PIPES > 0
-  #define _CONFIGURE_BARRIERS_FOR_FIFOS \
-    (2 * (CONFIGURE_MAXIMUM_FIFOS + CONFIGURE_MAXIMUM_PIPES))
-#else
-  #define _CONFIGURE_BARRIERS_FOR_FIFOS   0
-#endif
-
 /**
  *  @defgroup ConfigFilesystems Filesystems and Mount Table Configuration
  *
@@ -2041,13 +2030,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
   #define CONFIGURE_MAXIMUM_BARRIERS               0
 #endif
 
-/*
- * This macro is calculated to specify the number of Classic API
- * Barriers required by the application and configured capabilities.
- */
-#define _CONFIGURE_BARRIERS \
-  (CONFIGURE_MAXIMUM_BARRIERS + _CONFIGURE_BARRIERS_FOR_FIFOS)
-
 #ifndef CONFIGURE_MAXIMUM_USER_EXTENSIONS
   /**
    * This configuration parameter specifies the maximum number of
@@ -2737,8 +2719,8 @@ struct _reent *__getreent(void)
     _CONFIGURE_IDLE_TASKS_COUNT + _CONFIGURE_MPCI_RECEIVE_SERVER_COUNT
   );
 
-  #if _CONFIGURE_BARRIERS > 0
-    BARRIER_INFORMATION_DEFINE( _CONFIGURE_BARRIERS );
+  #if CONFIGURE_MAXIMUM_BARRIERS > 0
+    BARRIER_INFORMATION_DEFINE( CONFIGURE_MAXIMUM_BARRIERS );
   #endif
 
   #if CONFIGURE_MAXIMUM_MESSAGE_QUEUES > 0
diff --git a/cpukit/include/rtems/pipe.h b/cpukit/include/rtems/pipe.h
index 083e134..eb016ed 100644
--- a/cpukit/include/rtems/pipe.h
+++ b/cpukit/include/rtems/pipe.h
@@ -47,8 +47,8 @@ typedef struct pipe_control {
   unsigned int readerCounter;     /* incremental counters */
   unsigned int writerCounter;     /* for differentiation of successive opens */
   rtems_mutex Mutex;
-  rtems_id readBarrier;   /* wait queues */
-  rtems_id writeBarrier;
+  rtems_condition_variable readBarrier;   /* wait queues */
+  rtems_condition_variable writeBarrier;
 #if 0
   boolean Anonymous;      /* anonymous pipe or FIFO */
 #endif
diff --git a/cpukit/libfs/src/pipe/fifo.c b/cpukit/libfs/src/pipe/fifo.c
index f7f186c..b64c0d9 100644
--- a/cpukit/libfs/src/pipe/fifo.c
+++ b/cpukit/libfs/src/pipe/fifo.c
@@ -27,8 +27,6 @@
 #include <rtems.h>
 #include <rtems/libio_.h>
 #include <rtems/pipe.h>
-#include <rtems/rtems/barrierimpl.h>
-#include <rtems/score/statesimpl.h>
 
 #define LIBIO_ACCMODE(_iop) (rtems_libio_iop_flags(_iop) & LIBIO_FLAGS_READ_WRITE)
 #define LIBIO_NODELAY(_iop) rtems_libio_iop_is_no_delay(_iop)
@@ -46,18 +44,16 @@ static rtems_mutex pipe_mutex = RTEMS_MUTEX_INITIALIZER("Pipes");
 #define PIPE_UNLOCK(_pipe) rtems_mutex_unlock(&(_pipe)->Mutex)
 
 #define PIPE_READWAIT(_pipe)  \
-  ( rtems_barrier_wait(_pipe->readBarrier, RTEMS_NO_TIMEOUT)  \
-   == RTEMS_SUCCESSFUL)
+  rtems_condition_variable_wait(&(_pipe)->readBarrier, &(_pipe)->Mutex)
 
 #define PIPE_WRITEWAIT(_pipe)  \
-  ( rtems_barrier_wait(_pipe->writeBarrier, RTEMS_NO_TIMEOUT)  \
-   == RTEMS_SUCCESSFUL)
+  rtems_condition_variable_wait(&(_pipe)->writeBarrier, &(_pipe)->Mutex)
 
 #define PIPE_WAKEUPREADERS(_pipe) \
-  do {uint32_t n; rtems_barrier_release(_pipe->readBarrier, &n); } while(0)
+  rtems_condition_variable_broadcast(&(_pipe)->readBarrier)
 
 #define PIPE_WAKEUPWRITERS(_pipe) \
-  do {uint32_t n; rtems_barrier_release(_pipe->writeBarrier, &n); } while(0)
+  rtems_condition_variable_broadcast(&(_pipe)->writeBarrier)
 
 /*
  * Alloc pipe control structure, buffer, and resources.
@@ -78,35 +74,19 @@ static int pipe_alloc(
 
   pipe->Size = PIPE_BUF;
   pipe->Buffer = malloc(pipe->Size);
-  if (! pipe->Buffer)
-    goto err_buf;
-
-  err = -ENOMEM;
-
-  if (rtems_barrier_create(
-        rtems_build_name ('P', 'I', 'r', c),
-        RTEMS_BARRIER_MANUAL_RELEASE, 0,
-        &pipe->readBarrier) != RTEMS_SUCCESSFUL)
-    goto err_rbar;
-  if (rtems_barrier_create(
-        rtems_build_name ('P', 'I', 'w', c),
-        RTEMS_BARRIER_MANUAL_RELEASE, 0,
-        &pipe->writeBarrier) != RTEMS_SUCCESSFUL)
-    goto err_wbar;
+  if (pipe->Buffer == NULL) {
+    free(pipe);
+    return -ENOMEM;
+  }
+
+  rtems_condition_variable_init(&pipe->readBarrier, "Pipe Read");
+  rtems_condition_variable_init(&pipe->writeBarrier, "Pipe Write");
   rtems_mutex_init(&pipe->Mutex, "Pipe");
 
   *pipep = pipe;
   if (c ++ == 'z')
     c = 'a';
   return 0;
-
-err_wbar:
-  rtems_barrier_delete(pipe->readBarrier);
-err_rbar:
-  free(pipe->Buffer);
-err_buf:
-  free(pipe);
-  return err;
 }
 
 /* Called with pipe_semaphore held. */
@@ -114,8 +94,8 @@ static inline void pipe_free(
   pipe_control_t *pipe
 )
 {
-  rtems_barrier_delete(pipe->readBarrier);
-  rtems_barrier_delete(pipe->writeBarrier);
+  rtems_condition_variable_destroy(&pipe->readBarrier);
+  rtems_condition_variable_destroy(&pipe->writeBarrier);
   rtems_mutex_destroy(&pipe->Mutex);
   free(pipe->Buffer);
   free(pipe);
@@ -241,10 +221,7 @@ int fifo_open(
         err = -EINTR;
         /* Wait until a writer opens the pipe */
         do {
-          PIPE_UNLOCK(pipe);
-          if (! PIPE_READWAIT(pipe))
-            goto out_error;
-          PIPE_LOCK(pipe);
+          PIPE_READWAIT(pipe);
         } while (prevCounter == pipe->writerCounter);
       }
       break;
@@ -265,10 +242,7 @@ int fifo_open(
         prevCounter = pipe->readerCounter;
         err = -EINTR;
         do {
-          PIPE_UNLOCK(pipe);
-          if (! PIPE_WRITEWAIT(pipe))
-            goto out_error;
-          PIPE_LOCK(pipe);
+          PIPE_WRITEWAIT(pipe);
         } while (prevCounter == pipe->readerCounter);
       }
       break;
@@ -314,10 +288,7 @@ ssize_t pipe_read(
 
     /* Wait until pipe is no more empty or no writer exists */
     pipe->waitingReaders ++;
-    PIPE_UNLOCK(pipe);
-    if (! PIPE_READWAIT(pipe))
-      ret = -EINTR;
-    PIPE_LOCK(pipe);
+    PIPE_READWAIT(pipe);
     pipe->waitingReaders --;
     if (ret != 0)
       goto out_locked;
@@ -384,10 +355,7 @@ ssize_t pipe_write(
 
       /* Wait until there is chunk bytes space or no reader exists */
       pipe->waitingWriters ++;
-      PIPE_UNLOCK(pipe);
-      if (! PIPE_WRITEWAIT(pipe))
-        ret = -EINTR;
-      PIPE_LOCK(pipe);
+      PIPE_WRITEWAIT(pipe);
       pipe->waitingWriters --;
       if (ret != 0)
         goto out_locked;
diff --git a/testsuites/sptests/spfifo02/init.c b/testsuites/sptests/spfifo02/init.c
index 4fca304..89a9a77 100644
--- a/testsuites/sptests/spfifo02/init.c
+++ b/testsuites/sptests/spfifo02/init.c
@@ -19,63 +19,13 @@
 #include <fcntl.h>
 #include <unistd.h>
 #include <errno.h>
-#include <rtems/libcsupport.h>
+#include <rtems/malloc.h>
 
 const char rtems_test_name[] = "SPFIFO 2";
 
-/* forward declarations to avoid warnings */
-rtems_task Init(rtems_task_argument argument);
-void create_all_barriers(void);
-void delete_barrier(void);
-void create_fifo(void);
-void open_fifo(int expected, int flags);
-
-#define MAXIMUM 10
 #define NUM_OPEN_REQ 26
 
-rtems_id Barriers[MAXIMUM];
-int BarrierCount;
-
-rtems_id Semaphores[MAXIMUM];
-int SemaphoreCount;
-
-void create_all_barriers(void)
-{
-  rtems_status_code status;
-  int               i;
-
-  BarrierCount = 0;
-
-  memset( Barriers, 0, sizeof(Barriers) );
-  for ( i=0 ; i<MAXIMUM ; i++ ) {
-    status = rtems_barrier_create(
-      rtems_build_name( 'B', 'A', 'R', 0x30+i ),
-      RTEMS_BARRIER_MANUAL_RELEASE,
-      0,
-      &Barriers[i]
-    );
-    if ( status == RTEMS_TOO_MANY ) {
-      printf( "%d Barriers created\n", BarrierCount+1 );
-      return;
-    } 
-
-    directive_failed( status, "barrier create" );
-    BarrierCount++;
-  }
-}
-
-void delete_barrier(void)
-{
-  rtems_status_code status;
-  
-  BarrierCount--;
-  printf( "Deleting barrier id=0x%08x\n",
-    (unsigned int)Barriers[BarrierCount] );
-  status = rtems_barrier_delete( Barriers[BarrierCount] );
-  directive_failed( status, "barrier delete" );
-}
-
-void create_fifo(void)
+static void create_fifo(void)
 {
   int status;
 
@@ -83,7 +33,7 @@ void create_fifo(void)
   rtems_test_assert(status == 0);
 }
 
-void open_fifo(int expected, int flags)
+static void open_fifo(int expected, int flags)
 {
   int fd;
 
@@ -98,35 +48,24 @@ void open_fifo(int expected, int flags)
   }
 }
 
-rtems_task Init(
+static rtems_task Init(
   rtems_task_argument argument
 )
 {
-  void *alloc_ptr = (void *)0;
+  void *p;
   int num_opens = 0;
   int index = 0;
 
   TEST_BEGIN();
 
-  puts( "Creating all barriers" );
-  create_all_barriers();
-
   puts( "Creating FIFO" );
   create_fifo();
 
-  alloc_ptr = malloc( malloc_free_space() - 4 );
+  p = rtems_heap_greedy_allocate(NULL, 0);
   puts("Opening FIFO.. expect ENOMEM since no memory is available");
   open_fifo(ENOMEM, O_RDWR);
+  rtems_heap_greedy_free(p);
 
-  free(alloc_ptr);
-  puts( "Opening FIFO.. expect ENOMEM (barrier-1 for pipe could not be created)" );
-  open_fifo(ENOMEM, O_RDWR);
-
-  delete_barrier();
-  puts( "Opening FIFO.. expect ENOMEM (barrier-2 for pipe could not be created" );
-  open_fifo(ENOMEM, O_RDWR);
-
-  delete_barrier();
   puts( "Opening FIFO in RDWR mode. Expect OK" );
   open_fifo(0, O_RDWR);
   ++num_opens;
diff --git a/testsuites/sptests/spfifo02/spfifo02.doc b/testsuites/sptests/spfifo02/spfifo02.doc
index 32cac6d..b8d66ac 100644
--- a/testsuites/sptests/spfifo02/spfifo02.doc
+++ b/testsuites/sptests/spfifo02/spfifo02.doc
@@ -18,4 +18,3 @@ directives:
 concepts:
 
 + memory allocation error cases 
-+ resource allocation error cases 



More information about the vc mailing list