From 188c1ab5caae8a195f3e5700e174cc414272e1ed Mon Sep 17 00:00:00 2001 From: Youvedeep Singh Date: Mon, 19 Mar 2018 20:02:40 +0530 Subject: [PATCH] kernel: msg_q: Add routine to fetch basic attrs from message queue. For posix layer implementation of message queue, we need to fetch basic attributes of message queue. Currently this routine is not present in Zephyr. So adding this routing into message queue. Signed-off-by: Youvedeep Singh --- include/kernel.h | 19 ++++++++ kernel/msg_q.c | 19 ++++++++ tests/kernel/msgq/msgq_api/src/main.c | 2 + .../msgq/msgq_api/src/test_msgq_attrs.c | 47 +++++++++++++++++++ 4 files changed, 87 insertions(+) create mode 100644 tests/kernel/msgq/msgq_api/src/test_msgq_attrs.c diff --git a/include/kernel.h b/include/kernel.h index a2720a6a873..ba4111a6617 100644 --- a/include/kernel.h +++ b/include/kernel.h @@ -2865,6 +2865,12 @@ struct k_msgq { #define K_MSGQ_INITIALIZER DEPRECATED_MACRO _K_MSGQ_INITIALIZER +struct k_msgq_attrs { + size_t msg_size; + u32_t max_msgs; + u32_t used_msgs; +}; + /** * INTERNAL_HIDDEN @endcond */ @@ -2985,6 +2991,19 @@ __syscall void k_msgq_purge(struct k_msgq *q); */ __syscall u32_t k_msgq_num_free_get(struct k_msgq *q); +/** + * @brief Get basic attributes of a message queue. + * + * This routine fetches basic attributes of message queue into attr argument. + * + * @param q Address of the message queue. + * @param attrs pointer to message queue attribute structure. + * + * @return N/A + */ +__syscall void k_msgq_get_attrs(struct k_msgq *q, struct k_msgq_attrs *attrs); + + static inline u32_t _impl_k_msgq_num_free_get(struct k_msgq *q) { return q->max_msgs - q->used_msgs; diff --git a/kernel/msg_q.c b/kernel/msg_q.c index 9e8f7e2c607..90867d0a29f 100644 --- a/kernel/msg_q.c +++ b/kernel/msg_q.c @@ -136,6 +136,25 @@ _SYSCALL_HANDLER(k_msgq_put, msgq_p, data, timeout) } #endif +void _impl_k_msgq_get_attrs(struct k_msgq *q, struct k_msgq_attrs *attrs) +{ + attrs->msg_size = q->msg_size; + attrs->max_msgs = q->max_msgs; + attrs->used_msgs = q->used_msgs; +} + +#ifdef CONFIG_USERSPACE +_SYSCALL_HANDLER(k_msgq_get_attrs, msgq_p, attrs) +{ + struct k_msgq *q = (struct k_msgq *)msgq_p; + + _SYSCALL_OBJ(q, K_OBJ_MSGQ); + _SYSCALL_MEMORY_WRITE(attrs, sizeof(struct k_msgq_attrs)); + _impl_k_msgq_get_attrs(q, (struct k_msgq_attrs *) attrs); + return 0; +} +#endif + int _impl_k_msgq_get(struct k_msgq *q, void *data, s32_t timeout) { __ASSERT(!_is_in_isr() || timeout == K_NO_WAIT, ""); diff --git a/tests/kernel/msgq/msgq_api/src/main.c b/tests/kernel/msgq/msgq_api/src/main.c index 87453c6d2ee..8842d23a9b9 100644 --- a/tests/kernel/msgq/msgq_api/src/main.c +++ b/tests/kernel/msgq/msgq_api/src/main.c @@ -18,6 +18,7 @@ extern void test_msgq_isr(void); extern void test_msgq_put_fail(void); extern void test_msgq_get_fail(void); extern void test_msgq_purge_when_put(void); +extern void test_msgq_attrs_get(void); extern struct k_msgq kmsgq; extern struct k_msgq msgq; @@ -37,6 +38,7 @@ void test_main(void) ztest_unit_test(test_msgq_isr), ztest_user_unit_test(test_msgq_put_fail), ztest_user_unit_test(test_msgq_get_fail), + ztest_user_unit_test(test_msgq_attrs_get), ztest_user_unit_test(test_msgq_purge_when_put)); ztest_run_test_suite(test_msgq_api); } diff --git a/tests/kernel/msgq/msgq_api/src/test_msgq_attrs.c b/tests/kernel/msgq/msgq_api/src/test_msgq_attrs.c new file mode 100644 index 00000000000..6a5dba34b73 --- /dev/null +++ b/tests/kernel/msgq/msgq_api/src/test_msgq_attrs.c @@ -0,0 +1,47 @@ +/* + * Copyright (c) 2018 Intel Corporation + * + * SPDX-License-Identifier: Apache-2.0 + */ + +/** + * @addtogroup t_msgq_api + * @{ + * @defgroup t_msgq_attrs test_msgq_attrs + * @brief TestPurpose: verify zephyr msgq get attributes API. + * @} + */ + +#include "test_msgq.h" +extern struct k_msgq msgq; +static char __aligned(4) tbuffer[MSG_SIZE * MSGQ_LEN]; +static u32_t send_buf[MSGQ_LEN] = { MSG0, MSG1 }; +static u32_t rec_buf[MSGQ_LEN] = { MSG0, MSG1 }; + +void test_msgq_attrs_get(void) +{ + int ret; + struct k_msgq_attrs attrs; + + k_msgq_init(&msgq, tbuffer, MSG_SIZE, MSGQ_LEN); + + k_msgq_get_attrs(&msgq, &attrs); + zassert_equal(attrs.used_msgs, 0, NULL); + + /*fill the queue to full*/ + for (int i = 0; i < MSGQ_LEN; i++) { + ret = k_msgq_put(&msgq, (void *)&send_buf[i], K_NO_WAIT); + zassert_equal(ret, 0, NULL); + } + + k_msgq_get_attrs(&msgq, &attrs); + zassert_equal(attrs.used_msgs, MSGQ_LEN, NULL); + + for (int i = 0; i < MSGQ_LEN; i++) { + ret = k_msgq_get(&msgq, (void *)&rec_buf[i], K_NO_WAIT); + zassert_equal(ret, 0, NULL); + } + + k_msgq_get_attrs(&msgq, &attrs); + zassert_equal(attrs.used_msgs, 0, NULL); +}