feat: enable polling support for k_pipe interface

This commit adds polling support to the newly rewritten k_pipe interface.
Changes include:

* Removed ifdef CONFIG_POLL from kernel/poll.c to let both implementations
  coexist.
* Added the needed datastructures to the new k_pipe struct.
* k_pipe_write(..) now notifies the poll subsystem that data is available.

Signed-off-by: Måns Ansgariusson <Mansgariusson@gmail.com>
This commit is contained in:
Måns Ansgariusson 2024-12-22 23:48:59 +01:00 committed by Benjamin Cabé
commit a9ab8cb779
3 changed files with 13 additions and 14 deletions

View file

@ -5215,6 +5215,8 @@ struct k_pipe {
_wait_q_t data;
_wait_q_t space;
uint8_t flags;
Z_DECL_POLL_EVENT
};
/**
@ -5227,6 +5229,7 @@ struct k_pipe {
.space = Z_WAIT_Q_INIT(&obj.space), \
.flags = PIPE_FLAG_OPEN, \
.waiting = 0, \
Z_POLL_EVENT_OBJ_INIT(obj) \
}
/**
* INTERNAL_HIDDEN @endcond
@ -6010,9 +6013,7 @@ struct k_poll_event {
struct k_fifo *fifo, *typed_K_POLL_TYPE_FIFO_DATA_AVAILABLE;
struct k_queue *queue, *typed_K_POLL_TYPE_DATA_AVAILABLE;
struct k_msgq *msgq, *typed_K_POLL_TYPE_MSGQ_DATA_AVAILABLE;
#ifdef CONFIG_PIPES
struct k_pipe *pipe, *typed_K_POLL_TYPE_PIPE_DATA_AVAILABLE;
#endif
};
};

View file

@ -76,6 +76,10 @@ void z_impl_k_pipe_init(struct k_pipe *pipe, uint8_t *buffer, size_t buffer_size
z_waitq_init(&pipe->data);
z_waitq_init(&pipe->space);
k_object_init(pipe);
#ifdef CONFIG_POLL
sys_dlist_init(&pipe->poll_events);
#endif /* CONFIG_POLL */
}
int z_impl_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_timeout_t timeout)
@ -122,6 +126,10 @@ int z_impl_k_pipe_write(struct k_pipe *pipe, const uint8_t *data, size_t len, k_
rc = ring_buf_put(&pipe->buf, &data[written], len - written);
if (likely(rc != 0)) {
notify_waiter(&pipe->data);
#ifdef CONFIG_POLL
z_handle_obj_poll_events(&pipe->poll_events,
K_POLL_STATE_PIPE_DATA_AVAILABLE);
#endif /* CONFIG_POLL */
}
k_spin_unlock(&pipe->lock, key);
written += rc;

View file

@ -87,13 +87,9 @@ static inline bool is_condition_met(struct k_poll_event *event, uint32_t *state)
return true;
}
break;
#ifdef CONFIG_PIPES
case K_POLL_TYPE_PIPE_DATA_AVAILABLE:
if (k_pipe_read_avail(event->pipe)) {
*state = K_POLL_STATE_PIPE_DATA_AVAILABLE;
return true;
}
#endif /* CONFIG_PIPES */
*state = K_POLL_STATE_PIPE_DATA_AVAILABLE;
return true;
case K_POLL_TYPE_IGNORE:
break;
default:
@ -154,12 +150,10 @@ static inline void register_event(struct k_poll_event *event,
__ASSERT(event->msgq != NULL, "invalid message queue\n");
add_event(&event->msgq->poll_events, event, poller);
break;
#ifdef CONFIG_PIPES
case K_POLL_TYPE_PIPE_DATA_AVAILABLE:
__ASSERT(event->pipe != NULL, "invalid pipe\n");
add_event(&event->pipe->poll_events, event, poller);
break;
#endif /* CONFIG_PIPES */
case K_POLL_TYPE_IGNORE:
/* nothing to do */
break;
@ -195,12 +189,10 @@ static inline void clear_event_registration(struct k_poll_event *event)
__ASSERT(event->msgq != NULL, "invalid message queue\n");
remove_event = true;
break;
#ifdef CONFIG_PIPES
case K_POLL_TYPE_PIPE_DATA_AVAILABLE:
__ASSERT(event->pipe != NULL, "invalid pipe\n");
remove_event = true;
break;
#endif /* CONFIG_PIPES */
case K_POLL_TYPE_IGNORE:
/* nothing to do */
break;
@ -413,11 +405,9 @@ static inline int z_vrfy_k_poll(struct k_poll_event *events,
case K_POLL_TYPE_MSGQ_DATA_AVAILABLE:
K_OOPS(K_SYSCALL_OBJ(e->msgq, K_OBJ_MSGQ));
break;
#ifdef CONFIG_PIPES
case K_POLL_TYPE_PIPE_DATA_AVAILABLE:
K_OOPS(K_SYSCALL_OBJ(e->pipe, K_OBJ_PIPE));
break;
#endif /* CONFIG_PIPES */
default:
ret = -EINVAL;
goto out_free;