diff --git a/components/libc/posix/io/aio/aio.c b/components/libc/posix/io/aio/aio.c index 978522e4c2..b1d443b334 100644 --- a/components/libc/posix/io/aio/aio.c +++ b/components/libc/posix/io/aio/aio.c @@ -4,8 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2017/12/30 Bernard The first version. + * Date Author Notes + * 2017/12/30 Bernard The first version. + * 2024/03/26 TroyMitchelle Added some function comments */ #include @@ -63,7 +64,7 @@ int aio_cancel(int fd, struct aiocb *cb) * asynchronous I/O operation is the errno value that would be set by the corresponding * read(), write(), */ -int aio_error (const struct aiocb *cb) +int aio_error(const struct aiocb *cb) { if (cb) { @@ -134,6 +135,18 @@ static void aio_fync_work(struct rt_work* work, void* work_data) return ; } +/** + * @brief Initiates an asynchronous fsync operation. + * + * This function initiates an asynchronous fsync operation on the file associated + * with the specified aiocb structure. The operation is queued to the workqueue + * for execution. + * + * @param op The operation to be performed. This parameter is ignored. + * @param cb Pointer to the aiocb structure representing the asynchronous fsync operation. + * + * @return Returns 0 on success. + */ int aio_fsync(int op, struct aiocb *cb) { rt_base_t level; @@ -149,6 +162,16 @@ int aio_fsync(int op, struct aiocb *cb) return 0; } +/** + * @brief Worker function for asynchronous read operation. + * + * This function performs the actual reading of data from the file associated with + * the specified aiocb structure. It sets the result of the operation in the + * aio_result field of the aiocb structure. + * + * @param work Pointer to the work item. + * @param work_data Pointer to the aiocb structure representing the asynchronous read operation. + */ static void aio_read_work(struct rt_work* work, void* work_data) { int len; @@ -290,6 +313,16 @@ int aio_suspend(const struct aiocb *const list[], int nent, return -ENOSYS; } +/** + * @brief Worker function for asynchronous write operation. + * + * This function performs the actual writing of data to the file associated with + * the specified aiocb structure. It sets the result of the operation in the + * aio_result field of the aiocb structure. + * + * @param work Pointer to the work item. + * @param work_data Pointer to the aiocb structure representing the asynchronous write operation. + */ static void aio_write_work(struct rt_work* work, void* work_data) { rt_base_t level; @@ -453,6 +486,14 @@ int lio_listio(int mode, struct aiocb * const list[], int nent, return -ENOSYS; } +/** + * @brief Initializes the asynchronous I/O system. + * + * This function initializes the asynchronous I/O system by creating a workqueue + * for asynchronous I/O operations. + * + * @return Returns 0 on success. + */ int aio_system_init(void) { aio_queue = rt_workqueue_create("aio", 2048, RT_THREAD_PRIORITY_MAX/2); diff --git a/components/libc/posix/io/aio/aio.h b/components/libc/posix/io/aio/aio.h index 35a5c194db..7e104850d7 100644 --- a/components/libc/posix/io/aio/aio.h +++ b/components/libc/posix/io/aio/aio.h @@ -4,8 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2017/12/30 Bernard The first version. + * Date Author Notes + * 2017/12/30 Bernard The first version. + * 2024/03/26 TroyMitchelle Align comments within the aiocb structure */ #ifndef __AIO_H__ @@ -17,14 +18,14 @@ struct aiocb { - int aio_fildes; /* File descriptor. */ - off_t aio_offset; /* File offset. */ + int aio_fildes; /* File descriptor. */ + off_t aio_offset; /* File offset. */ - volatile void *aio_buf; /* Location of buffer. */ - size_t aio_nbytes; /* Length of transfer. */ - int aio_reqprio; /* Request priority offset. */ - struct sigevent aio_sigevent; /* Signal number and value. */ - int aio_lio_opcode; /* Operation to be performed. */ + volatile void *aio_buf; /* Location of buffer. */ + size_t aio_nbytes; /* Length of transfer. */ + int aio_reqprio; /* Request priority offset. */ + struct sigevent aio_sigevent; /* Signal number and value. */ + int aio_lio_opcode; /* Operation to be performed. */ int aio_result; struct rt_work aio_work; diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 6f579e5d7d..7ecb2d5bf1 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -4,8 +4,9 @@ * SPDX-License-Identifier: Apache-2.0 * * Change Logs: - * Date Author Notes - * 2023-07-29 zmq810150896 first version + * Date Author Notes + * 2023-07-29 zmq810150896 first version + * 2024/03/26 TroyMitchelle Add comments for all functions and members within structure members */ #include @@ -29,29 +30,29 @@ struct rt_eventpoll; /* Monitor queue */ struct rt_fd_list { - rt_uint32_t revents; /* Monitored events */ - struct epoll_event epev; - rt_pollreq_t req; - struct rt_eventpoll *ep; - struct rt_wqueue_node wqn; - int exclusive;/* If triggered horizontally, a check is made to see if the data has been read, and if there is any data left to read, the readability event is returned in the next epoll_wait */ - rt_bool_t is_rdl_node; - int fd; - struct rt_fd_list *next; - rt_slist_t rdl_node; + rt_uint32_t revents; /**< Monitored events */ + struct epoll_event epev; /**< Epoll event structure */ + rt_pollreq_t req; /**< Poll request structure */ + struct rt_eventpoll *ep; /**< Pointer to the associated event poll */ + struct rt_wqueue_node wqn; /**< Wait queue node */ + int exclusive; /**< Indicates if the event is exclusive */ + rt_bool_t is_rdl_node; /**< Indicates if the node is in the ready list */ + int fd; /**< File descriptor */ + struct rt_fd_list *next; /**< Pointer to the next file descriptor list */ + rt_slist_t rdl_node; /**< Ready list node */ }; struct rt_eventpoll { - rt_uint32_t tirggered; /* the waited thread whether triggered */ - rt_wqueue_t epoll_read; - rt_thread_t polling_thread; - struct rt_mutex lock; - struct rt_fd_list *fdlist; /* Monitor list */ - int eventpoll_num; /* Number of ready lists */ - rt_pollreq_t req; - struct rt_spinlock spinlock; - rt_slist_t rdl_head; + rt_uint32_t tirggered; /**< Indicates if the wait thread is triggered */ + rt_wqueue_t epoll_read; /**< Epoll read queue */ + rt_thread_t polling_thread; /**< Polling thread */ + struct rt_mutex lock; /**< Mutex lock */ + struct rt_fd_list *fdlist; /**< Monitor list */ + int eventpoll_num; /**< Number of ready lists */ + rt_pollreq_t req; /**< Poll request structure */ + struct rt_spinlock spinlock;/**< Spin lock */ + rt_slist_t rdl_head; /**< Ready list head */ }; static int epoll_close(struct dfs_file *file); @@ -65,6 +66,15 @@ static const struct dfs_file_ops epoll_fops = .poll = epoll_poll, }; +/** + * @brief Closes the file descriptor list associated with epoll. + * + * This function closes the file descriptor list associated with epoll and frees the allocated memory. + * + * @param fdlist Pointer to the file descriptor list. + * + * @return Returns 0 on success. + */ static int epoll_close_fdlist(struct rt_fd_list *fdlist) { struct rt_fd_list *fre_node, *list; @@ -88,6 +98,15 @@ static int epoll_close_fdlist(struct rt_fd_list *fdlist) return 0; } +/** + * @brief Closes the epoll file descriptor. + * + * This function closes the epoll file descriptor and cleans up associated resources. + * + * @param file Pointer to the file structure. + * + * @return Returns 0 on success. + */ static int epoll_close(struct dfs_file *file) { struct rt_eventpoll *ep; @@ -118,6 +137,16 @@ static int epoll_close(struct dfs_file *file) return 0; } +/** + * @brief Polls the epoll file descriptor for events. + * + * This function polls the epoll file descriptor for events and updates the poll request accordingly. + * + * @param file Pointer to the file structure. + * @param req Pointer to the poll request structure. + * + * @return Returns the events occurred on success. + */ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) { struct rt_eventpoll *ep; @@ -144,6 +173,16 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) return events; } +/** + * @brief Callback function for the wait queue. + * + * This function is called when the file descriptor is ready for polling. + * + * @param wait Pointer to the wait queue node. + * @param key Key associated with the wait queue node. + * + * @return Returns 0 on success. + */ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) { struct rt_fd_list *fdlist; @@ -165,7 +204,7 @@ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) fdlist->exclusive = 0; fdlist->is_rdl_node = RT_TRUE; ep->tirggered = 1; - ep->eventpoll_num ++; + ep->eventpoll_num++; rt_wqueue_wakeup(&ep->epoll_read, (void *)POLLIN); } rt_spin_unlock_irqrestore(&ep->spinlock, level); @@ -174,6 +213,15 @@ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) return __wqueue_default_wake(wait, key); } + +/** + * @brief Adds a callback function to the wait queue associated with epoll. + * + * This function adds a callback function to the wait queue associated with epoll. + * + * @param wq Pointer to the wait queue. + * @param req Pointer to the poll request structure. + */ static void epoll_wqueue_add_callback(rt_wqueue_t *wq, rt_pollreq_t *req) { struct rt_fd_list *fdlist; @@ -191,6 +239,14 @@ static void epoll_wqueue_add_callback(rt_wqueue_t *wq, rt_pollreq_t *req) rt_wqueue_add(wq, &fdlist->wqn); } +/** + * @brief Installs a file descriptor list into the epoll control structure. + * + * This function installs a file descriptor list into the epoll control structure. + * + * @param fdlist Pointer to the file descriptor list. + * @param ep Pointer to the epoll control structure. + */ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep) { rt_uint32_t mask = 0; @@ -209,17 +265,24 @@ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep rt_slist_append(&ep->rdl_head, &fdlist->rdl_node); fdlist->exclusive = 0; fdlist->is_rdl_node = RT_TRUE; - ep->tirggered = 1; - ep->eventpoll_num ++; + ep->triggered = 1; + ep->eventpoll_num++; rt_spin_unlock_irqrestore(&ep->spinlock, level); rt_mutex_release(&ep->lock); } } } +/** + * @brief Initializes the epoll control structure. + * + * This function initializes the epoll control structure. + * + * @param ep Pointer to the epoll control structure. + */ static void epoll_member_init(struct rt_eventpoll *ep) { - ep->tirggered = 0; + ep->triggered = 0; ep->eventpoll_num = 0; ep->polling_thread = rt_thread_self(); ep->fdlist = RT_NULL; @@ -230,6 +293,15 @@ static void epoll_member_init(struct rt_eventpoll *ep) rt_spin_lock_init(&ep->spinlock); } +/** + * @brief Initializes the epoll file descriptor. + * + * This function initializes the epoll file descriptor. + * + * @param fd File descriptor. + * + * @return Returns 0 on success. + */ static int epoll_epf_init(int fd) { struct dfs_file *df; @@ -286,6 +358,15 @@ static int epoll_epf_init(int fd) return ret; } +/** + * @brief Creates an epoll file descriptor. + * + * This function creates an epoll file descriptor. + * + * @param size Size of the epoll instance. + * + * @return Returns the file descriptor on success, or -1 on failure. + */ static int epoll_do_create(int size) { rt_err_t ret = -1; @@ -318,6 +399,17 @@ static int epoll_do_create(int size) return ret; } +/** + * @brief Adds a file descriptor to the epoll instance. + * + * This function adds a file descriptor to the epoll instance. + * + * @param df Pointer to the file structure. + * @param fd File descriptor to add. + * @param event Pointer to the epoll event structure. + * + * @return Returns 0 on success, or an error code on failure. + */ static int epoll_ctl_add(struct dfs_file *df, int fd, struct epoll_event *event) { struct rt_fd_list *fdlist; @@ -370,6 +462,16 @@ static int epoll_ctl_add(struct dfs_file *df, int fd, struct epoll_event *event) return ret; } +/** + * @brief Removes a file descriptor from the epoll instance. + * + * This function removes a file descriptor from the epoll instance. + * + * @param df Pointer to the file structure. + * @param fd File descriptor to remove. + * + * @return Returns 0 on success, or an error code on failure. + */ static int epoll_ctl_del(struct dfs_file *df, int fd) { struct rt_fd_list *fdlist, *fre_fd, *rdlist; @@ -423,6 +525,17 @@ static int epoll_ctl_del(struct dfs_file *df, int fd) return ret; } +/** + * @brief Modifies the events associated with a file descriptor in the epoll instance. + * + * This function modifies the events associated with a file descriptor in the epoll instance. + * + * @param df Pointer to the file structure. + * @param fd File descriptor to modify. + * @param event Pointer to the epoll event structure. + * + * @return Returns 0 on success, or an error code on failure. + */ static int epoll_ctl_mod(struct dfs_file *df, int fd, struct epoll_event *event) { struct rt_fd_list *fdlist; @@ -458,6 +571,19 @@ static int epoll_ctl_mod(struct dfs_file *df, int fd, struct epoll_event *event) return ret; } +/** + * @brief Controls an epoll instance. + * + * This function controls an epoll instance, performing operations such as adding, + * modifying, or removing file descriptors associated with the epoll instance. + * + * @param epfd File descriptor of the epoll instance. + * @param op Operation to perform (EPOLL_CTL_ADD, EPOLL_CTL_DEL, or EPOLL_CTL_MOD). + * @param fd File descriptor to add, modify, or remove. + * @param event Pointer to the epoll event structure. + * + * @return Returns 0 on success, or -1 on failure with errno set appropriately. + */ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) { struct dfs_file *epdf; @@ -483,7 +609,7 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) rt_set_errno(EINVAL); return -1; } - event->events |= EPOLLERR | EPOLLHUP; + event->events |= EPOLLERR | EPOLLHUP; } if (!fd_get(fd)) @@ -528,6 +654,17 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) return ret; } + +/** + * @brief Waits for events on an epoll instance with a specified timeout. + * + * This function waits for events on the specified epoll instance within the given timeout. + * + * @param ep Pointer to the epoll instance. + * @param msec Timeout in milliseconds. + * + * @return Returns 0 if no events occurred within the timeout, or 1 if events were triggered. + */ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) { rt_int32_t timeout; @@ -567,6 +704,16 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) return ret; } +/** + * @brief Gets events associated with a file descriptor in the epoll instance. + * + * This function gets events associated with a file descriptor in the epoll instance. + * + * @param fl Pointer to the file descriptor list structure. + * @param req Pointer to the poll request structure. + * + * @return Returns the bitmask of events associated with the file descriptor. + */ static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req) { struct dfs_file *df; @@ -594,6 +741,18 @@ static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req) return mask; } +/** + * @brief Performs epoll operation to get triggered events. + * + * This function performs epoll operation to get triggered events. + * + * @param ep Pointer to the epoll instance. + * @param events Pointer to the array to store triggered events. + * @param maxevents Maximum number of events to store in the array. + * @param timeout Timeout value in milliseconds. + * + * @return Returns the number of triggered events. + */ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int maxevents, int timeout) { struct rt_fd_list *rdlist; @@ -723,6 +882,19 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max return event_num; } +/** + * @brief Waits for events on an epoll instance with specified parameters. + * + * This function waits for events on the specified epoll instance within the given timeout, optionally blocking signals based on the provided signal set. + * + * @param epfd File descriptor referring to the epoll instance. + * @param events Pointer to the array to store triggered events. + * @param maxevents Maximum number of events to store in the array. + * @param timeout Timeout value in milliseconds. + * @param ss Pointer to the signal set indicating signals to block during the wait operation. Pass NULL if no signals need to be blocked. + * + * @return Returns the number of triggered events on success, or -1 on failure. + */ static int epoll_do_wait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) { struct rt_eventpoll *ep; @@ -736,7 +908,7 @@ static int epoll_do_wait(int epfd, struct epoll_event *events, int maxevents, in lwp_thread_signal_mask(rt_thread_self(), LWP_SIG_MASK_CMD_BLOCK, &new_sig, &old_sig); } - if ((maxevents > 0) && (epfd >=0)) + if ((maxevents > 0) && (epfd >= 0)) { df = fd_get(epfd); if (df && df->vnode) @@ -763,27 +935,87 @@ static int epoll_do_wait(int epfd, struct epoll_event *events, int maxevents, in return ret; } +/** + * @brief Creates an epoll instance. + * + * This function creates an epoll instance with the specified size. + * + * @param size Size of the epoll instance. + * + * @return Returns the file descriptor referring to the created epoll instance on success, or -1 on failure. + */ int epoll_create(int size) { return epoll_do_create(size); } +/** + * @brief Modifies an epoll instance. + * + * This function modifies the epoll instance referred to by 'epfd' according to the specified operation 'op', associated with the file descriptor 'fd', and the event structure 'event'. + * + * @param epfd File descriptor referring to the epoll instance. + * @param op Operation to perform (EPOLL_CTL_ADD, EPOLL_CTL_DEL, or EPOLL_CTL_MOD). + * @param fd File descriptor to associate with the epoll instance or remove from it. + * @param event Pointer to the event structure containing the events to modify. + * + * @return Returns 0 on success, or -1 on failure. + */ int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) { return epoll_do_ctl(epfd, op, fd, event); } +/** + * @brief Waits for events on an epoll instance. + * + * This function waits for events on the epoll instance referred to by 'epfd' within the given timeout. + * + * @param epfd File descriptor referring to the epoll instance. + * @param events Pointer to the array to store triggered events. + * @param maxevents Maximum number of events to store in the array. + * @param timeout Timeout value in milliseconds. + * + * @return Returns the number of triggered events on success, or -1 on failure. + */ int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) { return epoll_do_wait(epfd, events, maxevents, timeout, RT_NULL); } +/** + * @brief Waits for events on an epoll instance, blocking signals. + * + * This function waits for events on the epoll instance referred to by 'epfd' within the given timeout, blocking signals based on the provided signal set 'ss'. + * + * @param epfd File descriptor referring to the epoll instance. + * @param events Pointer to the array to store triggered events. + * @param maxevents Maximum number of events to store in the array. + * @param timeout Timeout value in milliseconds. + * @param ss Pointer to the signal set indicating signals to block during the wait operation. + * + * @return Returns the number of triggered events on success, or -1 on failure. + */ int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) { return epoll_do_wait(epfd, events, maxevents, timeout, ss); } +/** + * @brief Waits for events on an epoll instance, blocking signals. + * + * This function waits for events on the epoll instance referred to by 'epfd' within the given timeout, blocking signals based on the provided signal set 'ss'. + * + * @param epfd File descriptor referring to the epoll instance. + * @param events Pointer to the array to store triggered events. + * @param maxevents Maximum number of events to store in the array. + * @param timeout Timeout value in milliseconds. + * @param ss Pointer to the signal set indicating signals to block during the wait operation. + * + * @return Returns the number of triggered events on success, or -1 on failure. + */ int epoll_pwait2(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) { return epoll_do_wait(epfd, events, maxevents, timeout, ss); } +