summaryrefslogtreecommitdiff
path: root/cts/mutex
diff options
context:
space:
mode:
authorDaisuke Nojiri <dnojiri@chromium.org>2016-07-14 14:12:21 -0700
committerchrome-bot <chrome-bot@chromium.org>2016-07-15 21:39:27 -0700
commit8eb3ad19b4a4439d94e6013ca73d84698a5a6641 (patch)
tree827ed43d70d04afbfa1223f6d2c8c72c4fa51140 /cts/mutex
parentff950203e0e5a2f774ebe8453624b311b5213e35 (diff)
downloadchrome-ec-8eb3ad19b4a4439d94e6013ca73d84698a5a6641.tar.gz
cts: Add mutext test
It's imported from test/mutex.c and adjusted to CTS. BUG=chromium:624520 BRANCH=none TEST=Test passed on stm32l476-geval and nucleo-f072rb. make -j buildall Change-Id: I8cab0541ecbb1daa26b4d728fbd3e45e903ee512 Signed-off-by: Daisuke Nojiri <dnojiri@chromium.org> Reviewed-on: https://chromium-review.googlesource.com/360600 Reviewed-by: Chris Chen <twothreecc@google.com>
Diffstat (limited to 'cts/mutex')
-rw-r--r--cts/mutex/cts.tasklist23
-rw-r--r--cts/mutex/dut.c117
-rw-r--r--cts/mutex/th.c117
3 files changed, 257 insertions, 0 deletions
diff --git a/cts/mutex/cts.tasklist b/cts/mutex/cts.tasklist
new file mode 100644
index 0000000000..1c68b8d30a
--- /dev/null
+++ b/cts/mutex/cts.tasklist
@@ -0,0 +1,23 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+/**
+ * List of enabled tasks in the priority order
+ *
+ * The first one has the lowest priority.
+ *
+ * For each task, use the macro TASK_ALWAYS(n, r, d, s) where :
+ * 'n' in the name of the task
+ * 'r' in the main routine of the task
+ * 'd' in an opaque parameter passed to the routine at startup
+ * 's' is the stack size in bytes; must be a multiple of 8
+ */
+#define CONFIG_CTS_TASK_LIST \
+ TASK_ALWAYS(MTX3C, mutex_random_task, NULL, 384) \
+ TASK_ALWAYS(MTX3B, mutex_random_task, NULL, 384) \
+ TASK_ALWAYS(MTX3A, mutex_random_task, NULL, 384) \
+ TASK_ALWAYS(MTX2, mutex_second_task, NULL, 384) \
+ TASK_ALWAYS(MTX1, mutex_main_task, NULL, 384) \
+ TASK_ALWAYS(CTS, cts_task, NULL, TASK_STACK_SIZE)
diff --git a/cts/mutex/dut.c b/cts/mutex/dut.c
new file mode 100644
index 0000000000..c70e7df844
--- /dev/null
+++ b/cts/mutex/dut.c
@@ -0,0 +1,117 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ * Copyright 2011 Google Inc.
+ *
+ * Tasks for mutexes basic tests.
+ */
+
+#include "console.h"
+#include "common.h"
+#include "task.h"
+#include "test_util.h"
+#include "timer.h"
+#include "util.h"
+
+static struct mutex mtx;
+
+/* period between 50us and 3.2ms */
+#define PERIOD_US(num) (((num % 64) + 1) * 50)
+/* one of the 3 MTX3x tasks */
+#define RANDOM_TASK(num) (TASK_ID_MTX3C + (num % 3))
+
+int mutex_random_task(void *unused)
+{
+ char letter = 'A'+(TASK_ID_MTX3A - task_get_current());
+ /* wait to be activated */
+
+ while (1) {
+ task_wait_event(0);
+ ccprintf("%c+\n", letter);
+ mutex_lock(&mtx);
+ ccprintf("%c=\n", letter);
+ task_wait_event(0);
+ ccprintf("%c-\n", letter);
+ mutex_unlock(&mtx);
+ }
+
+ task_wait_event(0);
+
+ return EC_SUCCESS;
+}
+
+int mutex_second_task(void *unused)
+{
+ task_id_t id = task_get_current();
+
+ ccprintf("\n[Mutex second task %d]\n", id);
+
+ task_wait_event(0);
+ ccprintf("MTX2: locking...");
+ mutex_lock(&mtx);
+ ccprintf("done\n");
+ task_wake(TASK_ID_MTX1);
+ ccprintf("MTX2: unlocking...\n");
+ mutex_unlock(&mtx);
+
+ task_wait_event(0);
+
+ return EC_SUCCESS;
+}
+
+int mutex_main_task(void *unused)
+{
+ task_id_t id = task_get_current();
+ uint32_t rdelay = (uint32_t)0x0bad1dea;
+ uint32_t rtask = (uint32_t)0x1a4e1dea;
+ int i;
+
+ ccprintf("\n[Mutex main task %d]\n", id);
+
+ task_wait_event(0);
+
+ /* --- Lock/Unlock without contention --- */
+ ccprintf("No contention :");
+ mutex_lock(&mtx);
+ mutex_unlock(&mtx);
+ mutex_lock(&mtx);
+ mutex_unlock(&mtx);
+ mutex_lock(&mtx);
+ mutex_unlock(&mtx);
+ ccprintf("done.\n");
+
+ /* --- Serialization to test simple contention --- */
+ ccprintf("Simple contention :\n");
+ /* lock the mutex from the other task */
+ task_set_event(TASK_ID_MTX2, TASK_EVENT_WAKE, 1);
+ /* block on the mutex */
+ ccprintf("MTX1: blocking...\n");
+ mutex_lock(&mtx);
+ ccprintf("MTX1: get lock\n");
+ mutex_unlock(&mtx);
+
+ /* --- mass lock-unlocking from several tasks --- */
+ ccprintf("Massive locking/unlocking :\n");
+ for (i = 0; i < 500; i++) {
+ /* Wake up a random task */
+ task_wake(RANDOM_TASK(rtask));
+ /* next pseudo random delay */
+ rtask = prng(rtask);
+ /* Wait for a "random" period */
+ task_wait_event(PERIOD_US(rdelay));
+ /* next pseudo random delay */
+ rdelay = prng(rdelay);
+ }
+
+ test_pass();
+ task_wait_event(0);
+
+ return EC_SUCCESS;
+}
+
+void cts_task(void)
+{
+ wait_for_task_started();
+ task_wake(TASK_ID_MTX1);
+ task_wait_event(-1);
+}
diff --git a/cts/mutex/th.c b/cts/mutex/th.c
new file mode 100644
index 0000000000..c70e7df844
--- /dev/null
+++ b/cts/mutex/th.c
@@ -0,0 +1,117 @@
+/* Copyright 2016 The Chromium OS Authors. All rights reserved.
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ * Copyright 2011 Google Inc.
+ *
+ * Tasks for mutexes basic tests.
+ */
+
+#include "console.h"
+#include "common.h"
+#include "task.h"
+#include "test_util.h"
+#include "timer.h"
+#include "util.h"
+
+static struct mutex mtx;
+
+/* period between 50us and 3.2ms */
+#define PERIOD_US(num) (((num % 64) + 1) * 50)
+/* one of the 3 MTX3x tasks */
+#define RANDOM_TASK(num) (TASK_ID_MTX3C + (num % 3))
+
+int mutex_random_task(void *unused)
+{
+ char letter = 'A'+(TASK_ID_MTX3A - task_get_current());
+ /* wait to be activated */
+
+ while (1) {
+ task_wait_event(0);
+ ccprintf("%c+\n", letter);
+ mutex_lock(&mtx);
+ ccprintf("%c=\n", letter);
+ task_wait_event(0);
+ ccprintf("%c-\n", letter);
+ mutex_unlock(&mtx);
+ }
+
+ task_wait_event(0);
+
+ return EC_SUCCESS;
+}
+
+int mutex_second_task(void *unused)
+{
+ task_id_t id = task_get_current();
+
+ ccprintf("\n[Mutex second task %d]\n", id);
+
+ task_wait_event(0);
+ ccprintf("MTX2: locking...");
+ mutex_lock(&mtx);
+ ccprintf("done\n");
+ task_wake(TASK_ID_MTX1);
+ ccprintf("MTX2: unlocking...\n");
+ mutex_unlock(&mtx);
+
+ task_wait_event(0);
+
+ return EC_SUCCESS;
+}
+
+int mutex_main_task(void *unused)
+{
+ task_id_t id = task_get_current();
+ uint32_t rdelay = (uint32_t)0x0bad1dea;
+ uint32_t rtask = (uint32_t)0x1a4e1dea;
+ int i;
+
+ ccprintf("\n[Mutex main task %d]\n", id);
+
+ task_wait_event(0);
+
+ /* --- Lock/Unlock without contention --- */
+ ccprintf("No contention :");
+ mutex_lock(&mtx);
+ mutex_unlock(&mtx);
+ mutex_lock(&mtx);
+ mutex_unlock(&mtx);
+ mutex_lock(&mtx);
+ mutex_unlock(&mtx);
+ ccprintf("done.\n");
+
+ /* --- Serialization to test simple contention --- */
+ ccprintf("Simple contention :\n");
+ /* lock the mutex from the other task */
+ task_set_event(TASK_ID_MTX2, TASK_EVENT_WAKE, 1);
+ /* block on the mutex */
+ ccprintf("MTX1: blocking...\n");
+ mutex_lock(&mtx);
+ ccprintf("MTX1: get lock\n");
+ mutex_unlock(&mtx);
+
+ /* --- mass lock-unlocking from several tasks --- */
+ ccprintf("Massive locking/unlocking :\n");
+ for (i = 0; i < 500; i++) {
+ /* Wake up a random task */
+ task_wake(RANDOM_TASK(rtask));
+ /* next pseudo random delay */
+ rtask = prng(rtask);
+ /* Wait for a "random" period */
+ task_wait_event(PERIOD_US(rdelay));
+ /* next pseudo random delay */
+ rdelay = prng(rdelay);
+ }
+
+ test_pass();
+ task_wait_event(0);
+
+ return EC_SUCCESS;
+}
+
+void cts_task(void)
+{
+ wait_for_task_started();
+ task_wake(TASK_ID_MTX1);
+ task_wait_event(-1);
+}