From 9486566ca89de2be63a73f990b49b705990c3a9b Mon Sep 17 00:00:00 2001 From: Sebastian Huber Date: Fri, 21 Mar 2014 09:53:15 +0100 Subject: [PATCH] smptests/smpload01: Improve test Add a task producing memory traffic. Add tasks to obtain a priority inheritance semaphore in a synchronized way. --- testsuites/smptests/smpload01/init.c | 322 ++++++++++++++++++-- testsuites/smptests/smpload01/smpload01.scn | 312 +++++++++++++------ 2 files changed, 512 insertions(+), 122 deletions(-) diff --git a/testsuites/smptests/smpload01/init.c b/testsuites/smptests/smpload01/init.c index 2864257a23..b26437c95d 100644 --- a/testsuites/smptests/smpload01/init.c +++ b/testsuites/smptests/smpload01/init.c @@ -18,30 +18,173 @@ #include "tmacros.h" +#include +#include +#include + #include +#include #include +#include +#include const char rtems_test_name[] = "SMPLOAD 1"; #define CPU_COUNT 32 -#define WORKER_COUNT (3 * CPU_COUNT) +#define MAX_INHERIT_OBTAIN_COUNT CPU_COUNT -struct { - rtems_id sema_prio_inherit; - rtems_id sema_prio_ceiling; +#define SEM_WORKER_COUNT (3 * CPU_COUNT) + +#define INIT_PRIO 1 + +#define INHERIT_RELEASE_PRIO_HIGH (INIT_PRIO + 1) + +#define INHERIT_OBTAIN_PRIO_BASE (INHERIT_RELEASE_PRIO_HIGH + 1) + +#define INHERIT_RELEASE_PRIO_LOW (INHERIT_OBTAIN_PRIO_BASE + MAX_INHERIT_OBTAIN_COUNT) + +#define LOAD_PRIO (INHERIT_RELEASE_PRIO_LOW + 1) + +#define SEM_WORKER_CEILING_PRIO (LOAD_PRIO + 1) + +#define SEM_WORKER_PRIO_BASE (SEM_WORKER_CEILING_PRIO + 1) + +typedef struct { + rtems_id main_task_id; + rtems_id inherit_release_task_id; + rtems_id inherit_main_obtain_task_id; + rtems_id sem_worker_sem_prio_inherit; + rtems_id sem_worker_sem_prio_ceiling; + rtems_id inherit_sem; + rtems_counter_ticks inherit_obtain_delay; + SMP_barrier_Control inherit_barrier; + uint64_t inherit_obtain_counter[MAX_INHERIT_OBTAIN_COUNT]; + uint64_t inherit_release_counter; + uint64_t sem_worker_counter[SEM_WORKER_COUNT]; } test_context; +static test_context test_instance = { + .inherit_barrier = SMP_BARRIER_CONTROL_INITIALIZER +}; + static uint32_t simple_random(uint32_t v) { - v *= 1664525; - v += 1013904223; + v *= 1664525; + v += 1013904223; - return v; + return v; } -static void worker_task(rtems_task_argument arg) +static void inherit_obtain_task(rtems_task_argument arg) { + test_context *ctx = &test_instance; + rtems_status_code sc; + SMP_barrier_State barrier_state = SMP_BARRIER_STATE_INITIALIZER; + uint32_t cpu_count = rtems_smp_get_processor_count(); + rtems_counter_ticks delay = (cpu_count - 1 - arg) * ctx->inherit_obtain_delay; + + while (true) { + _SMP_barrier_Wait(&ctx->inherit_barrier, &barrier_state, cpu_count); + + rtems_counter_delay_ticks(delay); + + /* + * FIXME: Using a smaller value for the timeout triggers bug leading to + * system corruption. + */ + sc = rtems_semaphore_obtain(ctx->inherit_sem, RTEMS_WAIT, 100); + rtems_test_assert(sc == RTEMS_TIMEOUT); + + _SMP_barrier_Wait(&ctx->inherit_barrier, &barrier_state, cpu_count); + + ++ctx->inherit_obtain_counter[arg]; + + if (arg == 0) { + rtems_task_priority prio = INHERIT_RELEASE_PRIO_HIGH; + + sc = rtems_task_set_priority(ctx->inherit_release_task_id, prio, &prio); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_resume(ctx->inherit_release_task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + } + } +} + +static void inherit_release_task(rtems_task_argument arg) +{ + test_context *ctx = &test_instance; + rtems_status_code sc; + + sc = rtems_semaphore_obtain( + ctx->inherit_sem, + RTEMS_WAIT, + RTEMS_NO_TIMEOUT + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_event_transient_send(ctx->main_task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + while (true) { + rtems_task_priority prio = INHERIT_RELEASE_PRIO_LOW; + + sc = rtems_task_suspend(RTEMS_SELF); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_semaphore_release(ctx->inherit_sem); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + ++ctx->inherit_release_counter; + + sc = rtems_semaphore_obtain( + ctx->inherit_sem, + RTEMS_WAIT, + RTEMS_NO_TIMEOUT + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_set_priority(RTEMS_SELF, prio, &prio); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_event_transient_send(ctx->inherit_main_obtain_task_id); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + } +} + +static void load_task(rtems_task_argument arg) +{ + size_t data_size; + volatile int *data; + volatile int dummy; + size_t n; + + data_size = rtems_cache_get_data_cache_size(0); + if (data_size > 0) { + data = malloc(data_size); + rtems_test_assert(data != NULL); + } else { + data_size = sizeof(dummy); + data = &dummy; + } + + n = data_size / sizeof(*data); + while (true) { + size_t i; + + for (i = 0; i < n; ++i) { + data[i] = i; + } + } +} + +static void sem_worker_task(rtems_task_argument arg) +{ + test_context *ctx = &test_instance; uint32_t v = arg; while (true) { @@ -51,9 +194,9 @@ static void worker_task(rtems_task_argument arg) v = simple_random(v); if ((v & 0x80000000) != 0) { - id = test_context.sema_prio_inherit; + id = ctx->sem_worker_sem_prio_inherit; } else { - id = test_context.sema_prio_ceiling; + id = ctx->sem_worker_sem_prio_ceiling; } sc = rtems_semaphore_obtain(id, RTEMS_WAIT, RTEMS_NO_TIMEOUT); @@ -64,37 +207,95 @@ static void worker_task(rtems_task_argument arg) sc = rtems_semaphore_release(id); rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + ++ctx->sem_worker_counter[arg]; } } +static int cmp(const void *ap, const void *bp) +{ + const rtems_counter_ticks *a = ap; + const rtems_counter_ticks *b = bp; + + return *a - *b; +} + +static void get_obtain_delay_estimate(test_context *ctx) +{ + rtems_counter_ticks t[32]; + SMP_lock_Control lock; + ISR_Level level; + size_t n = RTEMS_ARRAY_SIZE(t); + size_t i; + + _SMP_lock_Initialize(&lock, "test"); + + _ISR_Disable_without_giant(level); + + for (i = 0; i < n; ++i) { + SMP_lock_Context lock_context; + rtems_counter_ticks a; + rtems_counter_ticks b; + + a = rtems_counter_read(); + _SMP_lock_ISR_disable_and_acquire(&lock, &lock_context); + b = rtems_counter_read(); + _SMP_lock_Release_and_ISR_enable(&lock, &lock_context); + + t[i] = rtems_counter_difference(b, a); + } + + _ISR_Enable_without_giant(level); + + _SMP_lock_Destroy(&lock); + + qsort(&t[0], n, sizeof(t[0]), cmp); + + ctx->inherit_obtain_delay = t[n / 2]; +} + static void test(void) { + test_context *ctx = &test_instance; uint32_t i; rtems_status_code sc; rtems_id id; + ctx->main_task_id = rtems_task_self(); + + get_obtain_delay_estimate(ctx); + sc = rtems_semaphore_create( - rtems_build_name('I', 'N', 'H', 'R'), + rtems_build_name('S', 'E', 'M', 'I'), 1, RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, 0, - &test_context.sema_prio_inherit + &ctx->sem_worker_sem_prio_inherit ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); sc = rtems_semaphore_create( - rtems_build_name('C', 'E', 'I', 'L'), + rtems_build_name('S', 'E', 'M', 'C'), 1, RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_PRIORITY_CEILING, - 2, - &test_context.sema_prio_ceiling + SEM_WORKER_CEILING_PRIO, + &ctx->sem_worker_sem_prio_ceiling ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - for (i = 0; i < WORKER_COUNT; ++i) { + sc = rtems_semaphore_create( + rtems_build_name('I', 'N', 'H', 'E'), + 1, + RTEMS_BINARY_SEMAPHORE | RTEMS_PRIORITY | RTEMS_INHERIT_PRIORITY, + 0, + &ctx->inherit_sem + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + for (i = 0; i < SEM_WORKER_COUNT; ++i) { sc = rtems_task_create( - rtems_build_name('W', 'O', 'R', 'K'), - 3 + i, + rtems_build_name('S', 'E', 'M', 'W'), + SEM_WORKER_PRIO_BASE + i, RTEMS_MINIMUM_STACK_SIZE, RTEMS_DEFAULT_MODES, RTEMS_DEFAULT_ATTRIBUTES, @@ -102,13 +303,84 @@ static void test(void) ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); - sc = rtems_task_start(id, worker_task, i); + sc = rtems_task_start(id, sem_worker_task, i); rtems_test_assert(sc == RTEMS_SUCCESSFUL); } - sc = rtems_task_wake_after(10 * rtems_clock_get_ticks_per_second()); + sc = rtems_task_create( + rtems_build_name('L', 'O', 'A', 'D'), + LOAD_PRIO, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &id + ); rtems_test_assert(sc == RTEMS_SUCCESSFUL); + sc = rtems_task_start(id, load_task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_task_create( + rtems_build_name('I', 'N', 'H', 'R'), + INHERIT_RELEASE_PRIO_LOW, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + ctx->inherit_release_task_id = id; + + sc = rtems_task_start(id, inherit_release_task, 0); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + sc = rtems_event_transient_receive(RTEMS_WAIT, RTEMS_NO_TIMEOUT); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + for (i = 0; i < rtems_smp_get_processor_count(); ++i) { + sc = rtems_task_create( + rtems_build_name('I', 'N', 'H', 'O'), + INHERIT_OBTAIN_PRIO_BASE + i, + RTEMS_MINIMUM_STACK_SIZE, + RTEMS_DEFAULT_MODES, + RTEMS_DEFAULT_ATTRIBUTES, + &id + ); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + if (i == 0) { + ctx->inherit_main_obtain_task_id = id; + } + + sc = rtems_task_start(id, inherit_obtain_task, i); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + } + + sc = rtems_task_wake_after(30 * rtems_clock_get_ticks_per_second()); + rtems_test_assert(sc == RTEMS_SUCCESSFUL); + + for (i = 0; i < SEM_WORKER_COUNT; ++i) { + printf( + "semaphore worker count %2" PRIu32 ": %" PRIu64 "\n", + i, + ctx->sem_worker_counter[i] + ); + } + + printf( + "priority inheritance release count: %" PRIu64 "\n", + ctx->inherit_release_counter + ); + + for (i = 0; i < rtems_smp_get_processor_count(); ++i) { + printf( + "priority inheritance obtain count %2" PRIu32 ": %" PRIu64 "\n", + i, + ctx->inherit_obtain_counter[i] + ); + } + rtems_profiling_report_xml("SMPLOAD 1", rtems_printf_plugin, NULL, 1, " "); } @@ -125,12 +397,18 @@ static void Init(rtems_task_argument arg) #define CONFIGURE_APPLICATION_NEEDS_CLOCK_DRIVER #define CONFIGURE_APPLICATION_NEEDS_CONSOLE_DRIVER +#define CONFIGURE_MICROSECONDS_PER_TICK 1000 + #define CONFIGURE_SMP_APPLICATION #define CONFIGURE_SMP_MAXIMUM_PROCESSORS CPU_COUNT -#define CONFIGURE_MAXIMUM_TASKS (1 + WORKER_COUNT) -#define CONFIGURE_MAXIMUM_SEMAPHORES 2 +#define CONFIGURE_MAXIMUM_TASKS \ + (1 + MAX_INHERIT_OBTAIN_COUNT + 1 + 1 + SEM_WORKER_COUNT) + +#define CONFIGURE_MAXIMUM_SEMAPHORES 3 + +#define CONFIGURE_INIT_TASK_PRIORITY INIT_PRIO #define CONFIGURE_INITIAL_EXTENSIONS RTEMS_TEST_INITIAL_EXTENSION diff --git a/testsuites/smptests/smpload01/smpload01.scn b/testsuites/smptests/smpload01/smpload01.scn index b97c719330..2110e7e130 100644 --- a/testsuites/smptests/smpload01/smpload01.scn +++ b/testsuites/smptests/smpload01/smpload01.scn @@ -1,168 +1,280 @@ -*** TEST SMPLOAD 1 *** +*** BEGIN OF TEST SMPLOAD 1 *** +semaphore worker count 0: 14986 +semaphore worker count 1: 14876 +semaphore worker count 2: 9943 +semaphore worker count 3: 6954 +semaphore worker count 4: 3780 +semaphore worker count 5: 2084 +semaphore worker count 6: 1293 +semaphore worker count 7: 886 +semaphore worker count 8: 706 +semaphore worker count 9: 487 +semaphore worker count 10: 391 +semaphore worker count 11: 305 +semaphore worker count 12: 254 +semaphore worker count 13: 218 +semaphore worker count 14: 181 +semaphore worker count 15: 140 +semaphore worker count 16: 124 +semaphore worker count 17: 107 +semaphore worker count 18: 114 +semaphore worker count 19: 80 +semaphore worker count 20: 104 +semaphore worker count 21: 66 +semaphore worker count 22: 69 +semaphore worker count 23: 64 +semaphore worker count 24: 50 +semaphore worker count 25: 47 +semaphore worker count 26: 44 +semaphore worker count 27: 34 +semaphore worker count 28: 36 +semaphore worker count 29: 33 +semaphore worker count 30: 33 +semaphore worker count 31: 30 +semaphore worker count 32: 33 +semaphore worker count 33: 29 +semaphore worker count 34: 23 +semaphore worker count 35: 25 +semaphore worker count 36: 26 +semaphore worker count 37: 15 +semaphore worker count 38: 11 +semaphore worker count 39: 14 +semaphore worker count 40: 16 +semaphore worker count 41: 11 +semaphore worker count 42: 17 +semaphore worker count 43: 19 +semaphore worker count 44: 10 +semaphore worker count 45: 16 +semaphore worker count 46: 12 +semaphore worker count 47: 16 +semaphore worker count 48: 10 +semaphore worker count 49: 23 +semaphore worker count 50: 6 +semaphore worker count 51: 9 +semaphore worker count 52: 5 +semaphore worker count 53: 16 +semaphore worker count 54: 8 +semaphore worker count 55: 9 +semaphore worker count 56: 7 +semaphore worker count 57: 6 +semaphore worker count 58: 5 +semaphore worker count 59: 3 +semaphore worker count 60: 7 +semaphore worker count 61: 6 +semaphore worker count 62: 3 +semaphore worker count 63: 5 +semaphore worker count 64: 6 +semaphore worker count 65: 8 +semaphore worker count 66: 10 +semaphore worker count 67: 5 +semaphore worker count 68: 6 +semaphore worker count 69: 7 +semaphore worker count 70: 5 +semaphore worker count 71: 4 +semaphore worker count 72: 7 +semaphore worker count 73: 6 +semaphore worker count 74: 4 +semaphore worker count 75: 8 +semaphore worker count 76: 7 +semaphore worker count 77: 6 +semaphore worker count 78: 5 +semaphore worker count 79: 5 +semaphore worker count 80: 5 +semaphore worker count 81: 2 +semaphore worker count 82: 4 +semaphore worker count 83: 6 +semaphore worker count 84: 0 +semaphore worker count 85: 0 +semaphore worker count 86: 0 +semaphore worker count 87: 0 +semaphore worker count 88: 0 +semaphore worker count 89: 0 +semaphore worker count 90: 0 +semaphore worker count 91: 0 +semaphore worker count 92: 0 +semaphore worker count 93: 0 +semaphore worker count 94: 0 +semaphore worker count 95: 0 +priority inheritance release count: 298 +priority inheritance obtain count 0: 298 +priority inheritance obtain count 1: 298 +priority inheritance obtain count 2: 298 +priority inheritance obtain count 3: 298 - 110405 - 5165 - 170810415 - 215600 - 78390 - 1061 - 89412555 + 439505 + 107380 + 2828036354 + 449825 + 209910 + 45379 + 468103979 - 132930 - 4105 - 142276895 - 8030 + 192520 + 107354 + 2951472564 + 12310 0 - 1029 - 3350735 + 24014 + 55580995 - 96015 - 4086 - 138497785 - 8645 + 180210 + 111122 + 3083151549 + 10800 0 - 1025 - 3154355 + 24595 + 56849370 - 207895 - 4143 - 151584650 - 11145 + 192305 + 129066 + 160126153 + 12715 0 - 1122 - 2717540 + 28961 + 66604305 - 7415 - 19980 - 13 - 29500 - 63445 - 13 + 8305 + 21735 + 16 + 37930 + 76770 + 16 0 0 0 + + 430280 + 445580 + 215584 + 2553573107 + 742278475 + 56087 + 107063 + 51715 + 719 + - 2080 - 5300 + 2340 + 5045 3 - 5810 - 14905 + 6355 + 13795 3 0 0 0 - 66395 - 16045 + 69505 + 17495 12 - 169185 - 84470 + 170575 + 92800 7 4 1 0 - 27355 - 81595 - 6526 - 16099290 - 89849335 - 5922 - 604 + 45820 + 80520 + 191623 + 725817290 + 3761923355 + 183684 + 7939 0 0 - 36025 - 146465 - 5552 - 22070045 - 74385305 - 4629 - 923 + 57105 + 143510 + 178463 + 839695710 + 3300422075 + 164040 + 14423 0 0 - 16895 - 83280 - 4728 - 18585920 - 59083815 - 3868 - 860 + 53715 + 86980 + 183928 + 911318930 + 3376328605 + 168809 + 15119 0 0 - 26365 - 94130 - 6506 - 17592735 - 92991200 - 6170 - 336 + 54975 + 115400 + 214576 + 1114797360 + 3997196165 + 196216 + 18360 0 0 - - 245180 - 232130 - 10102 - 416556635 - 529718895 - 1950 - 4735 - 2441 - 976 - - 7555 - 8805 - 12 - 24785 - 28550 - 12 + 5175 + 12355 + 13 + 25275 + 37815 + 13 0 0 0 - 8400 - 18135 - 12736 - 36411665 - 51414560 - 12728 - 8 + 17910 + 24835 + 255282 + 1081011595 + 1868447965 + 254784 + 498 0 0 - 2940 - 4835 + 2740 + 4520 43 - 74160 - 86065 + 67340 + 103785 43 0 0 0 + + 8490 + 12865 + 103 + 289735 + 537645 + 103 + 0 + 0 + 0 + - 9740 - 15735 + 6525 + 15660 1 - 9740 - 15735 + 6525 + 15660 1 0 0