tests: workq: Add a regression test for issue #45267
When an object availability event triggers a k_work_poll item, the object lock should not be held anymore during the execution of the work callback. Signed-off-by: Lucas Dietrich <ld.adecy@gmail.com>
This commit is contained in:
parent
9a848b3ad4
commit
616efeb2f2
2 changed files with 102 additions and 3 deletions
|
@ -1,6 +1,8 @@
|
|||
CONFIG_ZTEST=y
|
||||
CONFIG_POLL=y
|
||||
|
||||
CONFIG_ASSERT=y
|
||||
|
||||
# Not a single test case here is SMP-safe. Save the cycles needed for
|
||||
# all the ztest_1cpu spinning.
|
||||
CONFIG_MP_NUM_CPUS=1
|
||||
|
|
|
@ -63,6 +63,28 @@ static int results[NUM_TEST_ITEMS];
|
|||
static int num_results;
|
||||
static int expected_poll_result;
|
||||
|
||||
#define MSG_PROVIDER_THREAD_STACK_SIZE 0x400U
|
||||
#define MSG_CONSUMER_WORKQ_STACK_SIZE 0x400U
|
||||
|
||||
#define MSG_PROVIDER_THREAD_PRIO K_PRIO_PREEMPT(8)
|
||||
#define MSG_CONSUMER_WORKQ_PRIO K_PRIO_COOP(7)
|
||||
#define MSG_SIZE 16U
|
||||
|
||||
static K_THREAD_STACK_DEFINE(provider_thread_stack, MSG_PROVIDER_THREAD_STACK_SIZE);
|
||||
static K_THREAD_STACK_DEFINE(consumer_workq_stack, MSG_CONSUMER_WORKQ_STACK_SIZE);
|
||||
|
||||
struct triggered_from_msgq_test_item {
|
||||
k_tid_t tid;
|
||||
struct k_thread msg_provider_thread;
|
||||
struct k_work_q msg_consumer_workq;
|
||||
struct k_work_poll work;
|
||||
char msgq_buf[1][MSG_SIZE];
|
||||
struct k_msgq msgq;
|
||||
struct k_poll_event event;
|
||||
};
|
||||
|
||||
static struct triggered_from_msgq_test_item triggered_from_msgq_test;
|
||||
|
||||
static void work_handler(struct k_work *work)
|
||||
{
|
||||
struct delayed_test_item *ti =
|
||||
|
@ -701,12 +723,86 @@ static void test_triggered_wait_expired(void)
|
|||
reset_results();
|
||||
}
|
||||
|
||||
|
||||
static void msg_provider_thread(void *p1, void *p2, void *p3)
|
||||
{
|
||||
ARG_UNUSED(p1);
|
||||
ARG_UNUSED(p2);
|
||||
ARG_UNUSED(p3);
|
||||
|
||||
char msg[MSG_SIZE];
|
||||
|
||||
k_msgq_put(&triggered_from_msgq_test.msgq, &msg, K_NO_WAIT);
|
||||
}
|
||||
|
||||
static void triggered_from_msgq_work_handler(struct k_work *work)
|
||||
{
|
||||
char msg[MSG_SIZE];
|
||||
|
||||
k_msgq_get(&triggered_from_msgq_test.msgq, &msg, K_NO_WAIT);
|
||||
}
|
||||
|
||||
static void test_triggered_from_msgq_init(void)
|
||||
{
|
||||
struct triggered_from_msgq_test_item *const ctx = &triggered_from_msgq_test;
|
||||
|
||||
ctx->tid = k_thread_create(&ctx->msg_provider_thread,
|
||||
provider_thread_stack,
|
||||
MSG_PROVIDER_THREAD_STACK_SIZE,
|
||||
msg_provider_thread,
|
||||
NULL, NULL, NULL,
|
||||
MSG_PROVIDER_THREAD_PRIO, 0, K_FOREVER);
|
||||
k_work_queue_init(&ctx->msg_consumer_workq);
|
||||
k_msgq_init(&ctx->msgq,
|
||||
(char *)ctx->msgq_buf,
|
||||
MSG_SIZE, 1U);
|
||||
k_work_poll_init(&ctx->work, triggered_from_msgq_work_handler);
|
||||
k_poll_event_init(&ctx->event, K_POLL_TYPE_MSGQ_DATA_AVAILABLE,
|
||||
K_POLL_MODE_NOTIFY_ONLY, &ctx->msgq);
|
||||
|
||||
k_work_queue_start(&ctx->msg_consumer_workq, consumer_workq_stack,
|
||||
MSG_CONSUMER_WORKQ_STACK_SIZE, MSG_CONSUMER_WORKQ_PRIO,
|
||||
NULL);
|
||||
k_work_poll_submit_to_queue(&ctx->msg_consumer_workq, &ctx->work,
|
||||
&ctx->event, 1U, K_FOREVER);
|
||||
}
|
||||
|
||||
static void test_triggered_from_msgq_start(void)
|
||||
{
|
||||
k_thread_start(triggered_from_msgq_test.tid);
|
||||
}
|
||||
/**
|
||||
* @brief Test triggered work item, triggered by a msgq message.
|
||||
*
|
||||
* Regression test for issue #45267:
|
||||
*
|
||||
* When an object availability event triggers a k_work_poll item,
|
||||
* the object lock should not be held anymore during the execution
|
||||
* of the work callback.
|
||||
*
|
||||
* Tested with msgq with K_POLL_TYPE_MSGQ_DATA_AVAILABLE.
|
||||
*
|
||||
* @ingroup kernel_workqueue_tests
|
||||
*
|
||||
* @see k_work_poll_init(), k_work_poll_submit()
|
||||
*
|
||||
*/
|
||||
static void test_triggered_from_msgq(void)
|
||||
{
|
||||
TC_PRINT("Starting triggered from msgq test\n");
|
||||
|
||||
TC_PRINT(" - Initializing kernel objects\n");
|
||||
test_triggered_from_msgq_init();
|
||||
|
||||
TC_PRINT(" - Starting the thread\n");
|
||||
test_triggered_from_msgq_start();
|
||||
|
||||
reset_results();
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test delayed work queue define macro.
|
||||
*
|
||||
* The macro should initialize the k_delayed_work exactly the same as
|
||||
* @ref k_delayed_work_init does.
|
||||
*
|
||||
* @ingroup kernel_workqueue_tests
|
||||
*
|
||||
* @see K_DELAYED_WORK_DEFINE()
|
||||
|
@ -773,6 +869,7 @@ void test_main(void)
|
|||
ztest_1cpu_unit_test(test_triggered_no_wait_expired),
|
||||
ztest_1cpu_unit_test(test_triggered_wait),
|
||||
ztest_1cpu_unit_test(test_triggered_wait_expired),
|
||||
ztest_1cpu_unit_test(test_triggered_from_msgq),
|
||||
ztest_1cpu_unit_test(test_delayed_work_define),
|
||||
ztest_1cpu_unit_test(test_triggered_cancel)
|
||||
);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue