pipe: Use self-contained mutex

Update #2843.
This commit is contained in:
Sebastian Huber
2018-02-02 15:01:23 +01:00
parent 0940648f6f
commit 8ddd92d56a
4 changed files with 22 additions and 152 deletions
+1 -14
View File
@@ -227,17 +227,6 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
#define _CONFIGURE_BARRIERS_FOR_FIFOS 0
#endif
/*
* This specifies the number of semaphores required for the configured
* number of FIFOs and named pipes.
*/
#if CONFIGURE_MAXIMUM_FIFOS > 0 || CONFIGURE_MAXIMUM_PIPES > 0
#define _CONFIGURE_SEMAPHORES_FOR_FIFOS \
(1 + (CONFIGURE_MAXIMUM_FIFOS + CONFIGURE_MAXIMUM_PIPES))
#else
#define _CONFIGURE_SEMAPHORES_FOR_FIFOS 0
#endif
/**
* @defgroup ConfigFilesystems Filesystems and Mount Table Configuration
*
@@ -445,9 +434,7 @@ extern rtems_initialization_tasks_table Initialization_tasks[];
* This computes the number of semaphores required for the various
* file systems including the FIFO plugin to the IMFS.
*/
#define _CONFIGURE_SEMAPHORES_FOR_FILE_SYSTEMS \
(_CONFIGURE_SEMAPHORES_FOR_FIFOS + \
_CONFIGURE_SEMAPHORES_FOR_NFS)
#define _CONFIGURE_SEMAPHORES_FOR_FILE_SYSTEMS _CONFIGURE_SEMAPHORES_FOR_NFS
#ifdef CONFIGURE_INIT
+2 -1
View File
@@ -19,6 +19,7 @@
#define _RTEMS_PIPE_H
#include <rtems/libio.h>
#include <rtems/thread.h>
/**
* @defgroup FIFO_PIPE FIFO/Pipe File System Support
@@ -45,7 +46,7 @@ typedef struct pipe_control {
unsigned int waitingWriters;
unsigned int readerCounter; /* incremental counters */
unsigned int writerCounter; /* for differentiation of successive opens */
rtems_id Semaphore;
rtems_mutex Mutex;
rtems_id readBarrier; /* wait queues */
rtems_id writeBarrier;
#if 0
+19 -87
View File
@@ -33,7 +33,7 @@
#define LIBIO_ACCMODE(_iop) (rtems_libio_iop_flags(_iop) & LIBIO_FLAGS_READ_WRITE)
#define LIBIO_NODELAY(_iop) rtems_libio_iop_is_no_delay(_iop)
static rtems_id pipe_semaphore = RTEMS_ID_NONE;
static rtems_mutex pipe_mutex = RTEMS_MUTEX_INITIALIZER("Pipes");
#define PIPE_EMPTY(_pipe) (_pipe->Length == 0)
@@ -41,11 +41,9 @@ static rtems_id pipe_semaphore = RTEMS_ID_NONE;
#define PIPE_SPACE(_pipe) (_pipe->Size - _pipe->Length)
#define PIPE_WSTART(_pipe) ((_pipe->Start + _pipe->Length) % _pipe->Size)
#define PIPE_LOCK(_pipe) \
( rtems_semaphore_obtain(_pipe->Semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT) \
== RTEMS_SUCCESSFUL )
#define PIPE_LOCK(_pipe) rtems_mutex_lock(&(_pipe)->Mutex)
#define PIPE_UNLOCK(_pipe) rtems_semaphore_release(_pipe->Semaphore)
#define PIPE_UNLOCK(_pipe) rtems_mutex_unlock(&(_pipe)->Mutex)
#define PIPE_READWAIT(_pipe) \
( rtems_barrier_wait(_pipe->readBarrier, RTEMS_NO_TIMEOUT) \
@@ -95,18 +93,13 @@ static int pipe_alloc(
RTEMS_BARRIER_MANUAL_RELEASE, 0,
&pipe->writeBarrier) != RTEMS_SUCCESSFUL)
goto err_wbar;
if (rtems_semaphore_create(
rtems_build_name ('P', 'I', 's', c), 1,
RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY,
0, &pipe->Semaphore) != RTEMS_SUCCESSFUL)
goto err_sem;
rtems_mutex_init(&pipe->Mutex, "Pipe");
*pipep = pipe;
if (c ++ == 'z')
c = 'a';
return 0;
err_sem:
rtems_barrier_delete(pipe->writeBarrier);
err_wbar:
rtems_barrier_delete(pipe->readBarrier);
@@ -124,55 +117,19 @@ static inline void pipe_free(
{
rtems_barrier_delete(pipe->readBarrier);
rtems_barrier_delete(pipe->writeBarrier);
rtems_semaphore_delete(pipe->Semaphore);
rtems_mutex_destroy(&pipe->Mutex);
free(pipe->Buffer);
free(pipe);
}
static int pipe_lock(void)
static void pipe_lock(void)
{
rtems_status_code sc = RTEMS_SUCCESSFUL;
if (pipe_semaphore == RTEMS_ID_NONE) {
rtems_libio_lock();
if (pipe_semaphore == RTEMS_ID_NONE) {
sc = rtems_semaphore_create(
rtems_build_name('P', 'I', 'P', 'E'),
1,
RTEMS_BINARY_SEMAPHORE | RTEMS_INHERIT_PRIORITY | RTEMS_PRIORITY,
RTEMS_NO_PRIORITY,
&pipe_semaphore
);
}
rtems_libio_unlock();
}
if (sc == RTEMS_SUCCESSFUL) {
sc = rtems_semaphore_obtain(pipe_semaphore, RTEMS_WAIT, RTEMS_NO_TIMEOUT);
}
if (sc == RTEMS_SUCCESSFUL) {
return 0;
} else {
return -ENOMEM;
}
rtems_mutex_lock(&pipe_mutex);
}
static void pipe_unlock(void)
{
#ifdef RTEMS_DEBUG
rtems_status_code sc = RTEMS_SUCCESSFUL;
sc =
#endif
rtems_semaphore_release(pipe_semaphore);
#ifdef RTEMS_DEBUG
if (sc != RTEMS_SUCCESSFUL) {
rtems_fatal_error_occurred(0xdeadbeef);
}
#endif
rtems_mutex_unlock(&pipe_mutex);
}
/*
@@ -188,9 +145,7 @@ static int pipe_new(
int err = 0;
_Assert( pipep );
err = pipe_lock();
if (err)
return err;
pipe_lock();
pipe = *pipep;
if (pipe == NULL) {
@@ -199,8 +154,7 @@ static int pipe_new(
goto out;
}
if (!PIPE_LOCK(pipe))
err = -EINTR;
PIPE_LOCK(pipe);
if (*pipep == NULL) {
if (err)
@@ -222,15 +176,8 @@ void pipe_release(
pipe_control_t *pipe = *pipep;
uint32_t mode;
#if defined(RTEMS_DEBUG)
/* WARN pipe not freed and pipep not set to NULL! */
if (pipe_lock())
rtems_fatal_error_occurred(0xdeadbeef);
/* WARN pipe not released! */
if (!PIPE_LOCK(pipe))
rtems_fatal_error_occurred(0xdeadbeef);
#endif
pipe_lock();
PIPE_LOCK(pipe);
mode = LIBIO_ACCMODE(iop);
if (mode & LIBIO_FLAGS_READ)
@@ -303,8 +250,7 @@ int fifo_open(
PIPE_UNLOCK(pipe);
if (! PIPE_READWAIT(pipe))
goto out_error;
if (! PIPE_LOCK(pipe))
goto out_error;
PIPE_LOCK(pipe);
} while (prevCounter == pipe->writerCounter);
}
break;
@@ -328,8 +274,7 @@ int fifo_open(
PIPE_UNLOCK(pipe);
if (! PIPE_WRITEWAIT(pipe))
goto out_error;
if (! PIPE_LOCK(pipe))
goto out_error;
PIPE_LOCK(pipe);
} while (prevCounter == pipe->readerCounter);
}
break;
@@ -361,8 +306,7 @@ ssize_t pipe_read(
{
int chunk, chunk1, read = 0, ret = 0;
if (! PIPE_LOCK(pipe))
return -EINTR;
PIPE_LOCK(pipe);
while (PIPE_EMPTY(pipe)) {
/* Not an error */
@@ -379,11 +323,7 @@ ssize_t pipe_read(
PIPE_UNLOCK(pipe);
if (! PIPE_READWAIT(pipe))
ret = -EINTR;
if (! PIPE_LOCK(pipe)) {
/* WARN waitingReaders not restored! */
ret = -EINTR;
goto out_nolock;
}
PIPE_LOCK(pipe);
pipe->waitingReaders --;
if (ret != 0)
goto out_locked;
@@ -413,7 +353,6 @@ ssize_t pipe_read(
out_locked:
PIPE_UNLOCK(pipe);
out_nolock:
if (read > 0)
return read;
return ret;
@@ -432,8 +371,7 @@ ssize_t pipe_write(
if (count == 0)
return 0;
if (! PIPE_LOCK(pipe))
return -EINTR;
PIPE_LOCK(pipe);
if (pipe->Readers == 0) {
ret = -EPIPE;
@@ -455,11 +393,7 @@ ssize_t pipe_write(
PIPE_UNLOCK(pipe);
if (! PIPE_WRITEWAIT(pipe))
ret = -EINTR;
if (! PIPE_LOCK(pipe)) {
/* WARN waitingWriters not restored! */
ret = -EINTR;
goto out_nolock;
}
PIPE_LOCK(pipe);
pipe->waitingWriters --;
if (ret != 0)
goto out_locked;
@@ -490,7 +424,6 @@ ssize_t pipe_write(
out_locked:
PIPE_UNLOCK(pipe);
out_nolock:
#ifdef RTEMS_POSIX_API
/* Signal SIGPIPE */
if (ret == -EPIPE)
@@ -513,8 +446,7 @@ int pipe_ioctl(
if (buffer == NULL)
return -EFAULT;
if (! PIPE_LOCK(pipe))
return -EINTR;
PIPE_LOCK(pipe);
/* Return length of pipe */
*(unsigned int *)buffer = pipe->Length;
-50
View File
@@ -26,9 +26,7 @@ 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 create_all_semaphores(void);
void delete_barrier(void);
void delete_semaphore(void);
void create_fifo(void);
void open_fifo(int expected, int flags);
@@ -66,31 +64,6 @@ void create_all_barriers(void)
}
}
void create_all_semaphores(void)
{
rtems_status_code status;
int i;
SemaphoreCount = 0;
for ( i=0 ; i<MAXIMUM ; i++ ) {
status = rtems_semaphore_create(
rtems_build_name( 'S', 'E', 'M', 0x30+i ),
0,
RTEMS_DEFAULT_ATTRIBUTES,
0,
&Semaphores[i]
);
if ( status == RTEMS_TOO_MANY ) {
printf( "%d Semaphores created\n", SemaphoreCount+1 );
return;
}
directive_failed( status, "semaphore create" );
SemaphoreCount++;
}
}
void delete_barrier(void)
{
rtems_status_code status;
@@ -102,17 +75,6 @@ void delete_barrier(void)
directive_failed( status, "barrier delete" );
}
void delete_semaphore(void)
{
rtems_status_code status;
SemaphoreCount--;
printf( "Deleting semaphore id=0x%08x\n",
(unsigned int) Semaphores[SemaphoreCount] );
status = rtems_semaphore_delete( Semaphores[SemaphoreCount] );
directive_failed( status, "semaphore delete" );
}
void create_fifo(void)
{
int status;
@@ -149,17 +111,9 @@ rtems_task Init(
puts( "Creating all barriers" );
create_all_barriers();
puts( "Creating all semaphores" );
create_all_semaphores();
puts( "Creating FIFO" );
create_fifo();
puts( "Opening FIFO.. expect ENOMEM (semaphore for pipe could not be created)" );
open_fifo(ENOMEM, O_RDWR);
delete_semaphore();
alloc_ptr = malloc( malloc_free_space() - 4 );
puts("Opening FIFO.. expect ENOMEM since no memory is available");
open_fifo(ENOMEM, O_RDWR);
@@ -173,10 +127,6 @@ rtems_task Init(
open_fifo(ENOMEM, O_RDWR);
delete_barrier();
puts( "Opening FIFO.. expect ENOMEM (semaphore-1 for pipe could not be created" );
open_fifo(ENOMEM, O_RDWR);
delete_semaphore();
puts( "Opening FIFO in RDWR mode. Expect OK" );
open_fifo(0, O_RDWR);
++num_opens;