From 79a998d8629e8603e5df1191483409973f9a119d Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Thu, 16 Nov 2017 14:08:20 +0100 Subject: rtems: rtems_semaphore_flush() with prio inherit The _Semaphore_Get_operations() must return the proper operations for priority inheritance semaphores. Add a test case for rtems_semaphore_flush() with priority inheritance. Close #3235. --- cpukit/rtems/include/rtems/rtems/semimpl.h | 8 +++-- testsuites/sptests/spmutex01/init.c | 58 ++++++++++++++++++++++++------ 2 files changed, 53 insertions(+), 13 deletions(-) diff --git a/cpukit/rtems/include/rtems/rtems/semimpl.h b/cpukit/rtems/include/rtems/rtems/semimpl.h index 48b0a84c68..6d0f156e5c 100644 --- a/cpukit/rtems/include/rtems/rtems/semimpl.h +++ b/cpukit/rtems/include/rtems/rtems/semimpl.h @@ -58,11 +58,15 @@ RTEMS_INLINE_ROUTINE const Thread_queue_Operations *_Semaphore_Get_operations( const Semaphore_Control *the_semaphore ) { + if ( the_semaphore->variant == SEMAPHORE_VARIANT_MUTEX_INHERIT_PRIORITY ) { + return &_Thread_queue_Operations_priority_inherit; + } + if ( the_semaphore->discipline == SEMAPHORE_DISCIPLINE_PRIORITY ) { return &_Thread_queue_Operations_priority; - } else { - return &_Thread_queue_Operations_FIFO; } + + return &_Thread_queue_Operations_FIFO; } /** diff --git a/testsuites/sptests/spmutex01/init.c b/testsuites/sptests/spmutex01/init.c index 8590dde00f..fa5e716bd8 100644 --- a/testsuites/sptests/spmutex01/init.c +++ b/testsuites/sptests/spmutex01/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2015, 2016 embedded brains GmbH. All rights reserved. + * Copyright (c) 2015, 2017 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -39,16 +39,17 @@ typedef enum { REQ_WAKE_UP_MASTER = RTEMS_EVENT_0, REQ_WAKE_UP_HELPER = RTEMS_EVENT_1, REQ_MTX_0_OBTAIN = RTEMS_EVENT_2, - REQ_MTX_0_RELEASE = RTEMS_EVENT_3, - REQ_MTX_1_OBTAIN = RTEMS_EVENT_4, - REQ_MTX_1_OBTAIN_TIMEOUT = RTEMS_EVENT_5, - REQ_MTX_1_RELEASE = RTEMS_EVENT_6, - REQ_MTX_2_OBTAIN = RTEMS_EVENT_7, - REQ_MTX_2_RELEASE = RTEMS_EVENT_8, - REQ_MTX_C11_OBTAIN = RTEMS_EVENT_9, - REQ_MTX_C11_RELEASE = RTEMS_EVENT_10, - REQ_MTX_POSIX_OBTAIN = RTEMS_EVENT_11, - REQ_MTX_POSIX_RELEASE = RTEMS_EVENT_12 + REQ_MTX_0_OBTAIN_UNSATISFIED = RTEMS_EVENT_3, + REQ_MTX_0_RELEASE = RTEMS_EVENT_4, + REQ_MTX_1_OBTAIN = RTEMS_EVENT_5, + REQ_MTX_1_OBTAIN_TIMEOUT = RTEMS_EVENT_6, + REQ_MTX_1_RELEASE = RTEMS_EVENT_7, + REQ_MTX_2_OBTAIN = RTEMS_EVENT_8, + REQ_MTX_2_RELEASE = RTEMS_EVENT_9, + REQ_MTX_C11_OBTAIN = RTEMS_EVENT_10, + REQ_MTX_C11_RELEASE = RTEMS_EVENT_11, + REQ_MTX_POSIX_OBTAIN = RTEMS_EVENT_12, + REQ_MTX_POSIX_RELEASE = RTEMS_EVENT_13 } request_id; typedef enum { @@ -158,6 +159,14 @@ static void obtain_timeout(test_context *ctx, mutex_id id) rtems_test_assert(sc == RTEMS_TIMEOUT); } +static void obtain_unsatisfied(test_context *ctx, mutex_id id) +{ + rtems_status_code sc; + + sc = rtems_semaphore_obtain(ctx->mtx[id], RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_test_assert(sc == RTEMS_UNSATISFIED); +} + static void obtain(test_context *ctx, mutex_id id) { rtems_status_code sc; @@ -182,6 +191,14 @@ static void release(test_context *ctx, mutex_id id) rtems_test_assert(sc == RTEMS_SUCCESSFUL); } +static void flush(test_context *ctx, mutex_id id) +{ + rtems_status_code sc; + + sc = rtems_semaphore_flush(ctx->mtx[id]); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); +} + static void obtain_c11(test_context *ctx) { int status; @@ -306,6 +323,11 @@ static void worker(rtems_task_argument arg) ++ctx->generation[id]; } + if ((events & REQ_MTX_0_OBTAIN_UNSATISFIED) != 0) { + obtain_unsatisfied(ctx, MTX_0); + ++ctx->generation[id]; + } + if ((events & REQ_MTX_0_RELEASE) != 0) { release(ctx, MTX_0); ++ctx->generation[id]; @@ -525,6 +547,19 @@ static void test_inherit_nested_horizontal(test_context *ctx) check_generations(ctx, A_1, NONE); } +static void test_inherit_flush(test_context *ctx) +{ + assert_prio(ctx, M, 3); + obtain(ctx, MTX_0); + request(ctx, A_1, REQ_MTX_0_OBTAIN_UNSATISFIED); + check_generations(ctx, NONE, NONE); + assert_prio(ctx, M, 1); + flush(ctx, MTX_0); + check_generations(ctx, A_1, NONE); + assert_prio(ctx, M, 3); + release(ctx, MTX_0); +} + static void test_deadlock_two_classic(test_context *ctx) { obtain(ctx, MTX_0); @@ -674,6 +709,7 @@ static void Init(rtems_task_argument arg) test_inherit_nested_vertical(ctx); test_inherit_nested_vertical_timeout(ctx); test_inherit_nested_horizontal(ctx); + test_inherit_flush(ctx); test_deadlock_two_classic(ctx); test_deadlock_three_classic(ctx); test_deadlock_c11_and_classic(ctx); -- cgit v1.2.3