diff options
author | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-18 14:34:26 +0200 |
---|---|---|
committer | Sebastian Huber <sebastian.huber@embedded-brains.de> | 2016-05-19 11:50:38 +0200 |
commit | 41ce30a9676341af2fe3688ea6160cc386d5d90f (patch) | |
tree | e6afdeaa941e51a275485c9389eaff560c7b1f5f /testsuites/smptests/smplock01/init.c | |
parent | SMP: Add and use lock statistics helper (diff) | |
download | rtems-41ce30a9676341af2fe3688ea6160cc386d5d90f.tar.bz2 |
SMP: Add Mellor-Crummey and Scott (MCS) lock
Added only for evaluation purposes. We have to compare the performance
against the ticket lock on the interesting platforms via
smptests/smplock01.
The following GCC shortcoming affects the MCS lock:
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=66867
Diffstat (limited to 'testsuites/smptests/smplock01/init.c')
-rw-r--r-- | testsuites/smptests/smplock01/init.c | 173 |
1 files changed, 159 insertions, 14 deletions
diff --git a/testsuites/smptests/smplock01/init.c b/testsuites/smptests/smplock01/init.c index 8cc10fac6e..5eeb1ca347 100644 --- a/testsuites/smptests/smplock01/init.c +++ b/testsuites/smptests/smplock01/init.c @@ -1,5 +1,5 @@ /* - * Copyright (c) 2013-2014 embedded brains GmbH. All rights reserved. + * Copyright (c) 2013, 2016 embedded brains GmbH. All rights reserved. * * embedded brains GmbH * Dornierstr. 4 @@ -17,6 +17,7 @@ #endif #include <rtems/score/smplock.h> +#include <rtems/score/smplockmcs.h> #include <rtems/score/smpbarrier.h> #include <rtems/score/atomic.h> #include <rtems.h> @@ -29,7 +30,7 @@ const char rtems_test_name[] = "SMPLOCK 1"; #define CPU_COUNT 32 -#define TEST_COUNT 5 +#define TEST_COUNT 10 typedef enum { INITIAL, @@ -45,20 +46,33 @@ typedef struct { unsigned long counter[TEST_COUNT]; unsigned long test_counter[TEST_COUNT][CPU_COUNT]; SMP_lock_Control lock; +#if defined(RTEMS_PROFILING) + SMP_lock_Stats mcs_stats; +#endif + SMP_MCS_lock_Control mcs_lock; } global_context; static global_context context = { .state = ATOMIC_INITIALIZER_UINT(INITIAL), .barrier = SMP_BARRIER_CONTROL_INITIALIZER, - .lock = SMP_LOCK_INITIALIZER("global") + .lock = SMP_LOCK_INITIALIZER("global ticket"), +#if defined(RTEMS_PROFILING) + .mcs_stats = SMP_LOCK_STATS_INITIALIZER("global MCS"), +#endif + .mcs_lock = SMP_MCS_LOCK_INITIALIZER }; -static const char *test_names[TEST_COUNT] = { - "aquire global lock with local counter", - "aquire global lock with global counter", - "aquire local lock with local counter", - "aquire local lock with global counter", - "aquire global lock with busy section" +static const char * const test_names[TEST_COUNT] = { + "global ticket lock with local counter", + "global MCS lock with local counter", + "global ticket lock with global counter", + "global MCS lock with global counter", + "local ticket lock with local counter", + "local MCS lock with local counter", + "local ticket lock with global counter", + "local MCS lock with global counter", + "global ticket lock with busy section", + "global MCS lock with busy section" }; static void stop_test_timer(rtems_id timer_id, void *arg) @@ -119,6 +133,26 @@ static void test_1_body( ) { unsigned long counter = 0; + SMP_MCS_lock_Context lock_context; + + while (assert_state(ctx, START_TEST)) { + _SMP_MCS_lock_Acquire(&ctx->mcs_lock, &lock_context, &ctx->mcs_stats); + _SMP_MCS_lock_Release(&ctx->mcs_lock, &lock_context); + ++counter; + } + + ctx->test_counter[test][cpu_self] = counter; +} + +static void test_2_body( + int test, + global_context *ctx, + SMP_barrier_State *bs, + unsigned int cpu_count, + unsigned int cpu_self +) +{ + unsigned long counter = 0; SMP_lock_Context lock_context; while (assert_state(ctx, START_TEST)) { @@ -131,7 +165,28 @@ static void test_1_body( ctx->test_counter[test][cpu_self] = counter; } -static void test_2_body( +static void test_3_body( + int test, + global_context *ctx, + SMP_barrier_State *bs, + unsigned int cpu_count, + unsigned int cpu_self +) +{ + unsigned long counter = 0; + SMP_MCS_lock_Context lock_context; + + while (assert_state(ctx, START_TEST)) { + _SMP_MCS_lock_Acquire(&ctx->mcs_lock, &lock_context, &ctx->mcs_stats); + ++ctx->counter[test]; + _SMP_MCS_lock_Release(&ctx->mcs_lock, &lock_context); + ++counter; + } + + ctx->test_counter[test][cpu_self] = counter; +} + +static void test_4_body( int test, global_context *ctx, SMP_barrier_State *bs, @@ -156,7 +211,37 @@ static void test_2_body( ctx->test_counter[test][cpu_self] = counter; } -static void test_3_body( +static void test_5_body( + int test, + global_context *ctx, + SMP_barrier_State *bs, + unsigned int cpu_count, + unsigned int cpu_self +) +{ + unsigned long counter = 0; +#if defined(RTEMS_PROFILING) + SMP_lock_Stats stats; +#endif + SMP_MCS_lock_Control lock; + SMP_MCS_lock_Context lock_context; + + _SMP_lock_Stats_initialize(&stats, "local"); + _SMP_MCS_lock_Initialize(&lock); + + while (assert_state(ctx, START_TEST)) { + _SMP_MCS_lock_Acquire(&lock, &lock_context, &stats); + _SMP_MCS_lock_Release(&lock, &lock_context); + ++counter; + } + + _SMP_MCS_lock_Destroy(&lock); + _SMP_lock_Stats_destroy(&stats); + + ctx->test_counter[test][cpu_self] = counter; +} + +static void test_6_body( int test, global_context *ctx, SMP_barrier_State *bs, @@ -185,6 +270,40 @@ static void test_3_body( ctx->test_counter[test][cpu_self] = counter; } +static void test_7_body( + int test, + global_context *ctx, + SMP_barrier_State *bs, + unsigned int cpu_count, + unsigned int cpu_self +) +{ + unsigned long counter = 0; +#if defined(RTEMS_PROFILING) + SMP_lock_Stats stats; +#endif + SMP_MCS_lock_Control lock; + SMP_MCS_lock_Context lock_context; + + _SMP_lock_Stats_initialize(&stats, "local"); + _SMP_MCS_lock_Initialize(&lock); + + while (assert_state(ctx, START_TEST)) { + _SMP_MCS_lock_Acquire(&lock, &lock_context, &stats); + + /* The counter value is not interesting, only the access to it */ + ++ctx->counter[test]; + + _SMP_MCS_lock_Release(&lock, &lock_context); + ++counter; + } + + _SMP_MCS_lock_Destroy(&lock); + _SMP_lock_Stats_destroy(&stats); + + ctx->test_counter[test][cpu_self] = counter; +} + static void busy_section(void) { int i; @@ -194,7 +313,7 @@ static void busy_section(void) } } -static void test_4_body( +static void test_8_body( int test, global_context *ctx, SMP_barrier_State *bs, @@ -215,12 +334,38 @@ static void test_4_body( ctx->test_counter[test][cpu_self] = counter; } +static void test_9_body( + int test, + global_context *ctx, + SMP_barrier_State *bs, + unsigned int cpu_count, + unsigned int cpu_self +) +{ + unsigned long counter = 0; + SMP_MCS_lock_Context lock_context; + + while (assert_state(ctx, START_TEST)) { + _SMP_MCS_lock_Acquire(&ctx->mcs_lock, &lock_context, &ctx->mcs_stats); + busy_section(); + _SMP_MCS_lock_Release(&ctx->mcs_lock, &lock_context); + ++counter; + } + + ctx->test_counter[test][cpu_self] = counter; +} + static const test_body test_bodies[TEST_COUNT] = { test_0_body, test_1_body, test_2_body, test_3_body, - test_4_body + test_4_body, + test_5_body, + test_6_body, + test_7_body, + test_8_body, + test_9_body }; static void run_tests( @@ -299,7 +444,7 @@ static void test(void) } } - ctx->timeout = 10 * rtems_clock_get_ticks_per_second(); + ctx->timeout = 5 * rtems_clock_get_ticks_per_second(); sc = rtems_timer_create(rtems_build_name('T', 'I', 'M', 'R'), &ctx->timer_id); rtems_test_assert(sc == RTEMS_SUCCESSFUL); |