From 7d6e94b12ab94f13d3e769702d50f91be7d5884b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Wed, 4 Mar 2015 08:02:19 +0100 Subject: score: Implement fine-grained locking for events Use the ISR lock of the thread object to protect the event state and use the Giant lock only for the blocking operations. Update #2273. --- testsuites/sptests/spintrcritical10/init.c | 64 +++++++++++++++++------------- testsuites/sptests/spintrcritical21/init.c | 14 ++++++- testsuites/sptests/spsize/size.c | 2 - 3 files changed, 49 insertions(+), 31 deletions(-) (limited to 'testsuites/sptests') diff --git a/testsuites/sptests/spintrcritical10/init.c b/testsuites/sptests/spintrcritical10/init.c index 1d6720cd47..4d25ce6b7c 100644 --- a/testsuites/sptests/spintrcritical10/init.c +++ b/testsuites/sptests/spintrcritical10/init.c @@ -16,6 +16,7 @@ #include #include +#include #include const char rtems_test_name[] = "SPINTRCRITICAL 10"; @@ -34,16 +35,28 @@ typedef struct { bool hit; } test_context; +static bool blocks_for_event(Thread_Wait_flags flags) +{ + return flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK) + || flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_BLOCKED); +} + +static bool interrupts_blocking_op(Thread_Wait_flags flags) +{ + return + flags == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK); +} + static void any_satisfy_before_timeout(rtems_id timer, void *arg) { rtems_status_code sc; test_context *ctx = arg; const Thread_Control *thread = ctx->thread; + Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); - if (thread->Wait.count != 0) { - ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + if (blocks_for_event(flags)) { + ctx->hit = interrupts_blocking_op(flags); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -52,7 +65,6 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, GREEN); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN ); @@ -61,15 +73,13 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, RED); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, &_Event_Sync_state); + _Event_Timeout(thread->Object.id, NULL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == GREEN ); @@ -77,9 +87,12 @@ static void any_satisfy_before_timeout(rtems_id timer, void *arg) if (ctx->hit) { rtems_test_assert( - _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED + _Thread_Wait_flags_get(thread) + == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_SATISFIED) ); } + + rtems_test_assert(thread->Wait.count == EVENTS); } sc = rtems_timer_reset(timer); @@ -115,7 +128,6 @@ static void test_any_satisfy_before_timeout(test_context *ctx) ); ctx->hit = false; - ctx->thread->Wait.count = 0; sc = rtems_timer_fire_after(ctx->timer, 1, any_satisfy_before_timeout, ctx); rtems_test_assert(sc == RTEMS_SUCCESSFUL); @@ -137,11 +149,11 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) rtems_status_code sc; test_context *ctx = arg; const Thread_Control *thread = ctx->thread; + Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); - if (thread->Wait.count != 0) { - ctx->hit = _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + if (blocks_for_event(flags)) { + ctx->hit = interrupts_blocking_op(flags); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -150,7 +162,6 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, GREEN); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -159,15 +170,13 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, RED); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == EVENTS ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, &_Event_Sync_state); + _Event_Timeout(thread->Object.id, NULL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == EVENTS ); @@ -175,9 +184,12 @@ static void all_satisfy_before_timeout(rtems_id timer, void *arg) if (ctx->hit) { rtems_test_assert( - _Event_Sync_state == THREAD_BLOCKING_OPERATION_SATISFIED + _Thread_Wait_flags_get(thread) + == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_SATISFIED) ); } + + rtems_test_assert(thread->Wait.count == EVENTS); } sc = rtems_timer_reset(timer); @@ -208,7 +220,6 @@ static void test_all_satisfy_before_timeout(test_context *ctx) ); ctx->hit = false; - ctx->thread->Wait.count = 0; sc = rtems_timer_fire_after(ctx->timer, 1, all_satisfy_before_timeout, ctx); rtems_test_assert(sc == RTEMS_SUCCESSFUL); @@ -230,20 +241,18 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) rtems_status_code sc; test_context *ctx = arg; const Thread_Control *thread = ctx->thread; + Thread_Wait_flags flags = _Thread_Wait_flags_get(thread); - if (thread->Wait.count != 0) { - ctx->hit = - _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED; + if (blocks_for_event(flags)) { + ctx->hit = interrupts_blocking_op(flags); - rtems_test_assert(thread->Wait.count == EVENTS); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); rtems_test_assert(thread->Wait.return_code == RTEMS_SUCCESSFUL); - _Event_Timeout(thread->Object.id, &_Event_Sync_state); + _Event_Timeout(thread->Object.id, NULL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -252,7 +261,6 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) sc = rtems_event_send(thread->Object.id, EVENTS); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - rtems_test_assert(thread->Wait.count == 0); rtems_test_assert( *(rtems_event_set *) thread->Wait.return_argument == DEADBEEF ); @@ -260,9 +268,12 @@ static void timeout_before_satisfied(rtems_id timer, void *arg) if (ctx->hit) { rtems_test_assert( - _Event_Sync_state == THREAD_BLOCKING_OPERATION_TIMEOUT + _Thread_Wait_flags_get(thread) + == (THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTERRUPT_TIMEOUT) ); } + + rtems_test_assert(thread->Wait.count == EVENTS); } sc = rtems_timer_reset(timer); @@ -298,7 +309,6 @@ static void test_timeout_before_all_satisfy(test_context *ctx) ); ctx->hit = false; - ctx->thread->Wait.count = 0; sc = rtems_timer_fire_after(ctx->timer, 1, timeout_before_satisfied, ctx); rtems_test_assert(sc == RTEMS_SUCCESSFUL); diff --git a/testsuites/sptests/spintrcritical21/init.c b/testsuites/sptests/spintrcritical21/init.c index 8b1ddcfc37..faa48f717c 100644 --- a/testsuites/sptests/spintrcritical21/init.c +++ b/testsuites/sptests/spintrcritical21/init.c @@ -18,6 +18,7 @@ #include +#include #include const char rtems_test_name[] = "SPINTRCRITICAL 21"; @@ -34,8 +35,16 @@ static volatile bool case_hit; static rtems_id main_task; +static Thread_Control *main_thread; + static rtems_id other_task; +static bool is_case_hit( void ) +{ + return _Thread_Wait_flags_get( main_thread) + == ( THREAD_WAIT_CLASS_EVENT | THREAD_WAIT_STATE_INTEND_TO_BLOCK ); +} + static rtems_timer_service_routine test_event_from_isr( rtems_id timer, void *arg @@ -43,7 +52,7 @@ static rtems_timer_service_routine test_event_from_isr( { rtems_status_code status; - if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { + if ( is_case_hit() ) { /* * This event send hits the critical section but sends to * another task so doesn't impact this critical section. @@ -84,7 +93,7 @@ static rtems_timer_service_routine test_event_with_timeout_from_isr( { rtems_status_code status; - if ( _Event_Sync_state == THREAD_BLOCKING_OPERATION_NOTHING_HAPPENED ) { + if ( is_case_hit() ) { /* * We want to catch the task while it is blocking. Otherwise * just send and make it happy. @@ -117,6 +126,7 @@ rtems_task Init( TEST_BEGIN(); main_task = rtems_task_self(); + main_thread = _Thread_Get_executing(); status = rtems_task_create( 0xa5a5a5a5, diff --git a/testsuites/sptests/spsize/size.c b/testsuites/sptests/spsize/size.c index c68199d81d..f427bd25ac 100644 --- a/testsuites/sptests/spsize/size.c +++ b/testsuites/sptests/spsize/size.c @@ -268,8 +268,6 @@ uninitialized = /*dpmemimpl.h*/ (sizeof _Dual_ported_memory_Information) + -/*eventimpl.h*/ (sizeof _Event_Sync_state) + - #if defined(RTEMS_MULTIPROCESSING) /*eventmp.h*/ 0 + #endif -- cgit v1.2.3