kernel: pipe: fix !K_NO_WAIT and >= min_xfer bytes transferred
If timeout != K_NO_WAIT, then return immediately when not all bytes_to_read or bytes_to_write have been transfered, but >= min_xfer have been transferred. Fixes #24485 Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
This commit is contained in:
parent
4008960afc
commit
d650f4b494
3 changed files with 80 additions and 5 deletions
|
@ -529,7 +529,20 @@ int z_pipe_put_internal(struct k_pipe *pipe, struct k_pipe_async *async_desc,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Not all data was copied. */
|
||||
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)
|
||||
&& num_bytes_written >= min_xfer
|
||||
&& min_xfer > 0) {
|
||||
*bytes_written = num_bytes_written;
|
||||
#if (CONFIG_NUM_PIPE_ASYNC_MSGS > 0)
|
||||
if (async_desc != NULL) {
|
||||
pipe_async_finish(async_desc);
|
||||
}
|
||||
#endif
|
||||
k_sched_unlock();
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Not all data was copied */
|
||||
|
||||
#if (CONFIG_NUM_PIPE_ASYNC_MSGS > 0)
|
||||
if (async_desc != NULL) {
|
||||
|
@ -695,7 +708,17 @@ int z_impl_k_pipe_get(struct k_pipe *pipe, void *data, size_t bytes_to_read,
|
|||
return 0;
|
||||
}
|
||||
|
||||
/* Not all data was read. */
|
||||
if (!K_TIMEOUT_EQ(timeout, K_NO_WAIT)
|
||||
&& num_bytes_read >= min_xfer
|
||||
&& min_xfer > 0) {
|
||||
k_sched_unlock();
|
||||
|
||||
*bytes_read = num_bytes_read;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Not all data was read */
|
||||
|
||||
struct k_pipe_desc pipe_desc;
|
||||
|
||||
|
|
|
@ -14,6 +14,8 @@ extern void test_pipe_get_on_empty_pipe(void);
|
|||
extern void test_pipe_forever_timeout(void);
|
||||
extern void test_pipe_get_timeout(void);
|
||||
extern void test_pipe_get_invalid_size(void);
|
||||
extern void test_pipe_get_min_xfer(void);
|
||||
extern void test_pipe_put_min_xfer(void);
|
||||
|
||||
extern struct k_pipe test_pipe;
|
||||
extern struct k_sem put_sem, get_sem, sync_sem, multiple_send_sem;
|
||||
|
@ -36,7 +38,9 @@ void test_main(void)
|
|||
ztest_user_unit_test(test_pipe_get_on_empty_pipe),
|
||||
ztest_user_unit_test(test_pipe_forever_timeout),
|
||||
ztest_user_unit_test(test_pipe_get_timeout),
|
||||
ztest_user_unit_test(test_pipe_get_invalid_size)
|
||||
ztest_user_unit_test(test_pipe_get_invalid_size),
|
||||
ztest_user_unit_test(test_pipe_get_min_xfer),
|
||||
ztest_user_unit_test(test_pipe_put_min_xfer)
|
||||
);
|
||||
|
||||
ztest_run_test_suite(test_pipe);
|
||||
|
|
|
@ -97,8 +97,6 @@ static const struct pipe_sequence wait_elements[] = {
|
|||
{ PIPE_SIZE + 1, ALL_BYTES, PIPE_SIZE + 1, RETURN_SUCCESS },
|
||||
|
||||
{ PIPE_SIZE - 1, ATLEAST_1, PIPE_SIZE - 1, RETURN_SUCCESS },
|
||||
{ PIPE_SIZE, ATLEAST_1, PIPE_SIZE, RETURN_SUCCESS },
|
||||
{ PIPE_SIZE + 1, ATLEAST_1, PIPE_SIZE + 1, RETURN_SUCCESS }
|
||||
};
|
||||
|
||||
static const struct pipe_sequence timeout_elements[] = {
|
||||
|
@ -826,3 +824,53 @@ void test_pipe_get_invalid_size(void)
|
|||
zassert_equal(ret, -EINVAL,
|
||||
"fault didn't occur for min_xfer <= bytes_to_read");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test pipe get returns immediately if >= min_xfer is available
|
||||
* @ingroup kernel_pipe_tests
|
||||
* @see k_pipe_get()
|
||||
*/
|
||||
void test_pipe_get_min_xfer(void)
|
||||
{
|
||||
int res;
|
||||
size_t bytes_written = 0;
|
||||
size_t bytes_read = 0;
|
||||
char buf[8] = {};
|
||||
|
||||
res = k_pipe_put(&test_pipe, "Hi!", 3, &bytes_written,
|
||||
3 /* min_xfer */, K_FOREVER);
|
||||
zassert_equal(res, 0, "did not write entire message");
|
||||
zassert_equal(bytes_written, 3, "did not write entire message");
|
||||
|
||||
res = k_pipe_get(&test_pipe, buf, sizeof(buf), &bytes_read,
|
||||
1 /* min_xfer */, K_FOREVER);
|
||||
zassert_equal(res, 0, "did not read at least one byte");
|
||||
zassert_equal(bytes_read, 3, "did not read all bytes available");
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Test pipe put returns immediately if >= min_xfer is available
|
||||
* @ingroup kernel_pipe_tests
|
||||
* @see k_pipe_put()
|
||||
*/
|
||||
void test_pipe_put_min_xfer(void)
|
||||
{
|
||||
int res;
|
||||
size_t bytes_written = 0;
|
||||
|
||||
/* write 6 bytes into the pipe, so that 2 bytes are still free */
|
||||
for (size_t i = 0; i < 2; ++i) {
|
||||
bytes_written = 0;
|
||||
res = k_pipe_put(&test_pipe, "Hi!", 3, &bytes_written,
|
||||
3 /* min_xfer */, K_FOREVER);
|
||||
zassert_equal(res, 0, "did not write entire message");
|
||||
zassert_equal(bytes_written, 3, "did not write entire message");
|
||||
}
|
||||
|
||||
/* attempt to write 3 bytes, but allow success if >= 1 byte */
|
||||
bytes_written = 0;
|
||||
res = k_pipe_put(&test_pipe, "Hi!", 3, &bytes_written,
|
||||
1 /* min_xfer */, K_FOREVER);
|
||||
zassert_equal(res, 0, "did not write min_xfer");
|
||||
zassert_true(bytes_written >= 1, "did not write min_xfer");
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue