kernel: pipe: read_avail / write_avail syscalls
These helper functions may clarify how much data is available to read from or write to the circular buffer of a k_pipe. Fixes #25036 Signed-off-by: Christopher Friedt <chrisfriedt@gmail.com>
This commit is contained in:
parent
aa60a51a66
commit
3315f8fecf
2 changed files with 94 additions and 0 deletions
|
@ -4430,6 +4430,26 @@ __syscall int k_pipe_get(struct k_pipe *pipe, void *data,
|
|||
extern void k_pipe_block_put(struct k_pipe *pipe, struct k_mem_block *block,
|
||||
size_t size, struct k_sem *sem);
|
||||
|
||||
/**
|
||||
* @brief Query the number of bytes that may be read from @a pipe.
|
||||
*
|
||||
* @param pipe Address of the pipe.
|
||||
*
|
||||
* @retval a number n such that 0 <= n <= @ref k_pipe.size; the
|
||||
* result is zero for unbuffered pipes.
|
||||
*/
|
||||
__syscall size_t k_pipe_read_avail(struct k_pipe *pipe);
|
||||
|
||||
/**
|
||||
* @brief Query the number of bytes that may be written to @a pipe
|
||||
*
|
||||
* @param pipe Address of the pipe.
|
||||
*
|
||||
* @retval a number n such that 0 <= n <= @ref k_pipe.size; the
|
||||
* result is zero for unbuffered pipes.
|
||||
*/
|
||||
__syscall size_t k_pipe_write_avail(struct k_pipe *pipe);
|
||||
|
||||
/** @} */
|
||||
|
||||
/**
|
||||
|
|
|
@ -805,3 +805,77 @@ void k_pipe_block_put(struct k_pipe *pipe, struct k_mem_block *block,
|
|||
bytes_to_write, K_FOREVER);
|
||||
}
|
||||
#endif
|
||||
|
||||
size_t z_impl_k_pipe_read_avail(struct k_pipe *pipe)
|
||||
{
|
||||
size_t res;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
/* Buffer and size are fixed. No need to spin. */
|
||||
if (pipe->buffer == NULL || pipe->size == 0) {
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&pipe->lock);
|
||||
|
||||
if (pipe->read_index == pipe->write_index) {
|
||||
res = pipe->bytes_used;
|
||||
} else if (pipe->read_index < pipe->write_index) {
|
||||
res = pipe->write_index - pipe->read_index;
|
||||
} else {
|
||||
res = pipe->size - (pipe->read_index - pipe->write_index);
|
||||
}
|
||||
|
||||
k_spin_unlock(&pipe->lock, key);
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
size_t z_vrfy_k_pipe_read_avail(struct k_pipe *pipe)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
||||
|
||||
return z_impl_k_pipe_read_avail(pipe);
|
||||
}
|
||||
#include <syscalls/k_pipe_read_avail_mrsh.c>
|
||||
#endif
|
||||
|
||||
size_t z_impl_k_pipe_write_avail(struct k_pipe *pipe)
|
||||
{
|
||||
size_t res;
|
||||
k_spinlock_key_t key;
|
||||
|
||||
/* Buffer and size are fixed. No need to spin. */
|
||||
if (pipe->buffer == NULL || pipe->size == 0) {
|
||||
res = 0;
|
||||
goto out;
|
||||
}
|
||||
|
||||
key = k_spin_lock(&pipe->lock);
|
||||
|
||||
if (pipe->write_index == pipe->read_index) {
|
||||
res = pipe->size - pipe->bytes_used;
|
||||
} else if (pipe->write_index < pipe->read_index) {
|
||||
res = pipe->read_index - pipe->write_index;
|
||||
} else {
|
||||
res = pipe->size - (pipe->write_index - pipe->read_index);
|
||||
}
|
||||
|
||||
k_spin_unlock(&pipe->lock, key);
|
||||
|
||||
out:
|
||||
return res;
|
||||
}
|
||||
|
||||
#ifdef CONFIG_USERSPACE
|
||||
size_t z_vrfy_k_pipe_write_avail(struct k_pipe *pipe)
|
||||
{
|
||||
Z_OOPS(Z_SYSCALL_OBJ(pipe, K_OBJ_PIPE));
|
||||
|
||||
return z_impl_k_pipe_write_avail(pipe);
|
||||
}
|
||||
#include <syscalls/k_pipe_write_avail_mrsh.c>
|
||||
#endif
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue