summaryrefslogtreecommitdiffstats
path: root/testsuites/smptests/smplock01
diff options
context:
space:
mode:
authorSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-18 14:34:26 +0200
committerSebastian Huber <sebastian.huber@embedded-brains.de>2016-05-19 11:50:38 +0200
commit41ce30a9676341af2fe3688ea6160cc386d5d90f (patch)
treee6afdeaa941e51a275485c9389eaff560c7b1f5f /testsuites/smptests/smplock01
parentSMP: Add and use lock statistics helper (diff)
downloadrtems-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')
-rw-r--r--testsuites/smptests/smplock01/init.c173
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);