diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-12-11 16:45:37 +0100 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2019-12-11 17:45:31 +0100 |
commit | b1b6dd71d0d4609e81e14cbc94ef3dafa06712ba (patch) | |
tree | 56af4d445f39f5fa92b9c914dc5818ad52fb2bf8 | |
parent | Support pasring - in a version string (diff) | |
download | rtems-b1b6dd71d0d4609e81e14cbc94ef3dafa06712ba.tar.bz2 |
pipe: Use condition variables
Use self-contained condition variables instead of Classic API barriers.
This simplifies the implementation and configuration.
Update #3840.
-rw-r--r-- | cpukit/include/rtems/confdefs.h | 22 | ||||
-rw-r--r-- | cpukit/include/rtems/pipe.h | 4 | ||||
-rw-r--r-- | cpukit/libfs/src/pipe/fifo.c | 66 | ||||
-rw-r--r-- | testsuites/sptests/spfifo02/init.c | 75 | ||||
-rw-r--r-- | 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 922e4d7a9d..2e48af3f7a 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 083e1343e9..eb016ed0a6 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 f7f186c6d2..b64c0d95b6 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 4fca304d92..89a9a77a1e 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 32cac6d442..b8d66acbd9 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 |