rtems: Allow initially locked MrsP semaphores

Rejecting initially locked MrsP semaphores was due to a limitiation of
the early limitiation of the MrsP protocol.  This limitation no longer
exists.
This commit is contained in:
Sebastian Huber
2021-03-12 14:37:10 +01:00
parent 0965b7c8b7
commit 4ebdbee815
3 changed files with 32 additions and 13 deletions

View File

@@ -240,9 +240,6 @@ extern "C" {
* * When the directive operates on a global object, the directive sends a * * When the directive operates on a global object, the directive sends a
* message to remote nodes. This may preempt the calling task. * message to remote nodes. This may preempt the calling task.
* *
* * When a semaphore using the MrsP locking protocol is created, the initial
* count shall be exactly one.
*
* * The number of semaphores available to the application is configured * * The number of semaphores available to the application is configured
* through the #CONFIGURE_MAXIMUM_SEMAPHORES application configuration * through the #CONFIGURE_MAXIMUM_SEMAPHORES application configuration
* option. * option.

View File

@@ -295,12 +295,13 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
bool initially_locked bool initially_locked
) )
{ {
uint32_t scheduler_count = _Scheduler_Count; Thread_queue_Context queue_context;
uint32_t i; ISR_Level level;
size_t scheduler_count;
size_t i;
Status_Control status;
if ( initially_locked ) { scheduler_count = _Scheduler_Count;
return STATUS_INVALID_NUMBER;
}
for ( i = 0 ; i < scheduler_count ; ++i ) { for ( i = 0 ; i < scheduler_count ; ++i ) {
const Scheduler_Control *scheduler_of_index; const Scheduler_Control *scheduler_of_index;
@@ -316,7 +317,22 @@ RTEMS_INLINE_ROUTINE Status_Control _MRSP_Initialize(
} }
_Thread_queue_Object_initialize( &mrsp->Wait_queue ); _Thread_queue_Object_initialize( &mrsp->Wait_queue );
return STATUS_SUCCESSFUL;
if ( !initially_locked ) {
return STATUS_SUCCESSFUL;
}
_Thread_queue_Context_initialize( &queue_context );
_Thread_queue_Context_ISR_disable( &queue_context, level );
_Thread_queue_Context_set_ISR_level( &queue_context, level );
_MRSP_Acquire_critical( mrsp, &queue_context );
status = _MRSP_Claim_ownership( mrsp, executing, &queue_context );
if ( status != STATUS_SUCCESSFUL ) {
_Thread_queue_Destroy( &mrsp->Wait_queue );
}
return status;
} }
/** /**

View File

@@ -734,12 +734,12 @@ static void test_mrsp_flush_error(test_context *ctx)
rtems_test_assert(sc == RTEMS_SUCCESSFUL); rtems_test_assert(sc == RTEMS_SUCCESSFUL);
} }
static void test_mrsp_initially_locked_error(void) static void test_mrsp_initially_locked(void)
{ {
rtems_status_code sc; rtems_status_code sc;
rtems_id id; rtems_id id;
puts("test MrsP initially locked error"); puts("test MrsP initially locked");
sc = rtems_semaphore_create( sc = rtems_semaphore_create(
rtems_build_name('M', 'R', 'S', 'P'), rtems_build_name('M', 'R', 'S', 'P'),
@@ -749,7 +749,13 @@ static void test_mrsp_initially_locked_error(void)
1, 1,
&id &id
); );
rtems_test_assert(sc == RTEMS_INVALID_NUMBER); rtems_test_assert(sc == RTEMS_SUCCESSFUL);
sc = rtems_semaphore_release(id);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
sc = rtems_semaphore_delete(id);
rtems_test_assert(sc == RTEMS_SUCCESSFUL);
} }
static void test_mrsp_nested_obtain_error(test_context *ctx) static void test_mrsp_nested_obtain_error(test_context *ctx)
@@ -1750,7 +1756,7 @@ static void Init(rtems_task_argument arg)
} }
test_mrsp_flush_error(ctx); test_mrsp_flush_error(ctx);
test_mrsp_initially_locked_error(); test_mrsp_initially_locked();
test_mrsp_nested_obtain_error(ctx); test_mrsp_nested_obtain_error(ctx);
test_mrsp_deadlock_error(ctx); test_mrsp_deadlock_error(ctx);
test_mrsp_multiple_obtain(ctx); test_mrsp_multiple_obtain(ctx);