From 3c9b0774aeee059369ec6c4cf662b7a5f6718f20 Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Sat, 29 Jul 2023 15:40:41 +0800 Subject: [PATCH 1/8] Add the systemd call epoll --- components/libc/posix/Kconfig | 5 + components/libc/posix/io/epoll/SConscript | 14 + components/libc/posix/io/epoll/epoll.c | 737 ++++++++++++++++++++++ components/lwp/lwp_syscall.c | 53 ++ 4 files changed, 809 insertions(+) create mode 100644 components/libc/posix/io/epoll/SConscript create mode 100644 components/libc/posix/io/epoll/epoll.c diff --git a/components/libc/posix/Kconfig b/components/libc/posix/Kconfig index b3f0e7cb84c..9328f218848 100644 --- a/components/libc/posix/Kconfig +++ b/components/libc/posix/Kconfig @@ -31,6 +31,11 @@ if RT_USING_POSIX_FS select RT_USING_POSIX_POLL default n + config RT_USING_POSIX_EPOLL + bool "Enable I/O Multiplexing epoll " + select RT_USING_POSIX_POLL + default n + config RT_USING_POSIX_SOCKET bool "Enable BSD Socket I/O " select RT_USING_POSIX_SELECT diff --git a/components/libc/posix/io/epoll/SConscript b/components/libc/posix/io/epoll/SConscript new file mode 100644 index 00000000000..cef3fff8a05 --- /dev/null +++ b/components/libc/posix/io/epoll/SConscript @@ -0,0 +1,14 @@ +# RT-Thread building script for component + +from building import * + +cwd = GetCurrentDir() +src = [] +CPPPATH = [cwd] + +if GetDepend('RT_USING_POSIX_EPOLL'): + src += ['epoll.c'] + +group = DefineGroup('POSIX', src, depend = [''], CPPPATH = CPPPATH) + +Return('group') diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c new file mode 100644 index 00000000000..8ff7ca46ee7 --- /dev/null +++ b/components/libc/posix/io/epoll/epoll.c @@ -0,0 +1,737 @@ + +/* + * Copyright (c) 2006-2023, RT-Thread Development Team + * + * SPDX-License-Identifier: Apache-2.0 + * + * Change Logs: + * Date Author Notes + * 2023-07-29 zmq810150896 first version + */ + +#include +#include +#include +#include +#include +#include "sys/epoll.h" +#include "poll.h" +#include + +#define EPOLL_MUTEX_NAME "EVENTEPOLL" + +#define EFD_SHARED_EPOLL_TYPE (EPOLL_CTL_ADD | EPOLL_CTL_DEL | EPOLL_CTL_MOD) + +#define EP_PRIVATE_BITS (EPOLLONESHOT | EPOLLET | EPOLLEXCLUSIVE) +#define EPOLLINOUT_BITS (EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM) +#define EPOLLEXCLUSIVE_BITS (EPOLLINOUT_BITS | EPOLLERR | EPOLLHUP | \ + EPOLLET | EPOLLEXCLUSIVE) + +struct rt_eventpoll; + +/* Monitor queue */ +struct rt_fd_list +{ + rt_uint32_t revents; + struct epoll_event epev; + rt_pollreq_t req; + struct rt_eventpoll *eventpoll; + struct rt_wqueue_node wqn; + struct rt_fd_list *next; +}; + +struct rt_rdllist +{ + int exclusive; + struct rt_fd_list *read_event; + struct rt_rdllist *next; +}; + +struct rt_eventpoll +{ + rt_uint32_t tirggered; + rt_thread_t polling_thread; + struct rt_mutex lock; + struct rt_fd_list *fdlist; + int eventfd_num; + struct rt_rdllist *rlist; +}; + +static int epoll_close(struct dfs_file *file); +static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req); +static int do_epoll(struct rt_fd_list *fl, rt_pollreq_t *req); +static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); +static int get_event(struct dfs_file *df, rt_pollreq_t *req); + +static const struct dfs_file_ops epoll_fops = +{ + .close = epoll_close, + .poll = epoll_poll, +}; + +static int free_fdlist(struct rt_fd_list *fd_list) +{ + struct rt_fd_list *list; + + if (fd_list) + { + while (fd_list->next != RT_NULL) + { + list = fd_list->next; + rt_wqueue_remove(&fd_list->wqn); + rt_free(fd_list); + fd_list = list; + } + + rt_free(fd_list); + } + + return 0; +} + +static int free_rdllist(struct rt_rdllist *rlist) +{ + struct rt_rdllist *list; + + if (rlist) + { + while (rlist->next != RT_NULL) + { + list = rlist->next; + rt_free(rlist); + rlist = list; + } + + rt_free(rlist); + } + + return 0; +} + +static int epoll_close(struct dfs_file *file) +{ + struct rt_eventpoll *ep; + + if (file->vnode) + { + ep = file->vnode->data; + rt_mutex_detach(&ep->lock); + + if (ep) + { + if (ep->fdlist) + { + free_fdlist(ep->fdlist); + } + + if (ep->rlist) + { + free_rdllist(ep->rlist); + } + + rt_free(ep); + } + } + + return 0; +} + +static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) +{ + struct rt_eventpoll *ep; + struct rt_fd_list *fdlist; + int mask; + int events = 0; + + ep = file->vnode->data; + fdlist = ep->fdlist; + if (fdlist) + { + while (fdlist->next != RT_NULL) + { + fdlist = fdlist->next; + mask = do_epoll(fdlist, &fdlist->req); + if (mask & fdlist->epev.events) + { + events |= mask | POLLIN | EPOLLRDNORM; + break; + } + } + } + + return events; +} + +static int rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) +{ + struct rt_rdllist *rlist; + struct rt_eventpoll *ep; + int isexist = 0; + int res = -1; + + ep = fdl->eventpoll; + + if (ep->rlist == RT_NULL) + { + ep->rlist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); + if (ep->rlist == RT_NULL) + { + return -1; + } + ep->rlist->next = RT_NULL; + } + + rlist = ep->rlist; + while (rlist->next != RT_NULL) + { + rlist = rlist->next; + if (rlist->read_event->epev.data.fd == fdl->epev.data.fd) + { + isexist = 1; + res = 0; + break; + } + } + + if (!isexist) + { + rlist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); + if (rlist != RT_NULL) + { + rlist->read_event = fdl; + rlist->read_event->epev.events = revents; + rlist->next = ep->rlist->next; + rlist->exclusive = 0; + + ep->rlist->next = rlist; + ep->eventfd_num ++; + res = 0; + if (rlist->read_event->revents & EPOLLONESHOT) + { + rlist->read_event->epev.events = 0; + } + } + } + + ep->tirggered = 1; + + return res; +} + +static int __wqueue_eventpoll_wake(struct rt_wqueue_node *wait, void *key) +{ + struct rt_fd_list *fdlist; + + if (key && !((rt_ubase_t)key & wait->key)) + return -1; + + fdlist = rt_container_of(wait, struct rt_fd_list, wqn); + + if (fdlist->epev.events) + { + rdllist_add(fdlist, (rt_ubase_t)key); + } + + return __wqueue_default_wake(wait, key); +} + +static void __eventpoll_add(rt_wqueue_t *wq, rt_pollreq_t *req) +{ + struct rt_fd_list *fdlist; + struct rt_eventpoll *ep; + + fdlist = rt_container_of(req, struct rt_fd_list, req); + + ep = fdlist->eventpoll; + fdlist->wqn.key = req->_key; + + rt_list_init(&(fdlist->wqn.list)); + + fdlist->wqn.polling_thread = ep->polling_thread; + fdlist->wqn.wakeup = __wqueue_eventpoll_wake; + + rt_wqueue_add(wq, &fdlist->wqn); +} + +static int get_event(struct dfs_file *df, rt_pollreq_t *req) +{ + int mask = 0; + + if (df) + { + if (df->vnode->fops->poll) + { + req->_key = EPOLLINOUT_BITS ; + mask = df->vnode->fops->poll(df, req); + } + } + + return mask; +} + +static void eventpoll_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep) +{ + struct dfs_file *df; + rt_uint32_t mask = 0; + + fdlist->req._proc = __eventpoll_add; + // fdlist->revents = fdlist->epev.events; + fdlist->eventpoll = ep; + fdlist->req._key = fdlist->epev.events; + + df = fd_get(fdlist->epev.data.fd); + + if (df) + { + mask = get_event(df, &fdlist->req); + if (mask & fdlist->epev.events) + { + rdllist_add(fdlist, mask); + } + } +} + +static void eventpoll_remove(struct rt_fd_list *fdlist) +{ + fdlist->req._proc = __eventpoll_add; + // fdlist->revents = EPOLLEXCLUSIVE_BITS; + rt_wqueue_remove(&fdlist->wqn); +} + +static void eventpoll_init(struct rt_eventpoll *ep) +{ + ep->tirggered = 0; + ep->eventfd_num = 0; + ep->polling_thread = rt_thread_self(); + ep->rlist = RT_NULL; +} + +static int epoll_dfs_file_init(int fd) +{ + struct dfs_file *df; + struct rt_eventpoll *eventpoll; + rt_err_t ret = 0; + + df = fd_get(fd); + + if (df) + { + eventpoll = (struct rt_eventpoll *)rt_malloc(sizeof(struct rt_eventpoll)); + if (eventpoll) + { + eventpoll_init(eventpoll); + + rt_mutex_init(&eventpoll->lock, EPOLL_MUTEX_NAME, RT_IPC_FLAG_FIFO); + + df->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode)); + if (df->vnode) + { + eventpoll->fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); + if (eventpoll->fdlist) + { + eventpoll->fdlist->next = RT_NULL; + eventpoll->fdlist->epev.data.fd = fd; + eventpoll->fdlist->eventpoll = eventpoll; + dfs_vnode_init(df->vnode, FT_REGULAR, &epoll_fops); + df->vnode->data = eventpoll; + } + else + { + ret = -ENOMEM; + rt_free(df->vnode); + rt_free(eventpoll); + } + } + else + { + ret = -ENOMEM; + rt_free(eventpoll); + } + } + else + { + ret = -ENOMEM; + } + } + + return ret; +} + +static int do_epoll_create(int size) +{ + rt_err_t ret = 0; + int status; + int fd; + + if (size < 0) + { + ret = -EINVAL; + } + else + { + fd = fd_new(); + if (fd >= 0) + { + ret = fd; + status = epoll_dfs_file_init(fd); + if (status < 0) + { + fd_release(fd); + ret = status; + } + } + else + { + ret = fd; + } + } + + return ret; +} + +static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event) +{ + struct rt_fd_list *fdlist; + struct rt_eventpoll *eventpoll; + rt_err_t ret = 0; + + eventpoll = df->vnode->data; + + fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); + if (fdlist) + { + fdlist->epev.data.fd = event->data.fd; + fdlist->epev.events = event->events; + fdlist->next = eventpoll->fdlist->next; + fdlist->revents = event->events; + eventpoll->fdlist->next = fdlist; + + eventpoll_install(fdlist, eventpoll); + } + else + { + ret = -ENOMEM; + } + + return ret; +} + +static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) +{ + struct rt_fd_list *fdlist, *fre_fd; + struct rt_eventpoll *eventpoll = df->vnode->data; + rt_err_t ret = 0; + + fdlist = eventpoll->fdlist; + while (fdlist->next != RT_NULL) + { + if (fdlist->next->epev.data.fd == event->data.fd) + { + fre_fd = fdlist->next; + fdlist->next = fdlist->next->next; + eventpoll_remove(fre_fd); + rt_free(fre_fd); + break; + } + + fdlist = fdlist->next; + } + + return ret; +} + +static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event) +{ + struct rt_fd_list *fdlist; + struct rt_eventpoll *eventpoll = df->vnode->data; + rt_err_t ret = 0; + + fdlist = eventpoll->fdlist; + while (fdlist->next != RT_NULL) + { + if (fdlist->next->epev.data.fd == event->data.fd) + { + fdlist->next->epev.events = event->events; + fdlist->next->revents = event->events; + rt_wqueue_remove(&fdlist->wqn); + eventpoll_install(fdlist, eventpoll); + break; + } + + fdlist = fdlist->next; + } + + return ret; +} + +static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + struct dfs_file *epdf; + rt_err_t ret = 0; + + if (op & ~EFD_SHARED_EPOLL_TYPE) + return -EINVAL; + + if ((epfd == fd) || (epfd < 0) || (fd < 0) || (event->data.fd != fd)) + return -EINVAL; + + // if (!(event->events & EPOLLET)) + // { + // event->events |= EPOLLEXCLUSIVE; + // } + + epdf = fd_get(epfd); + if (epdf) + { + switch (op) + { + case EPOLL_CTL_ADD: + ret = epoll_ctl_add(epdf, event); + break; + case EPOLL_CTL_DEL: + ret = epoll_ctl_del(epdf, event); + break; + case EPOLL_CTL_MOD: + ret = epoll_ctl_mod(epdf, event); + break; + default: + ret = -EINVAL; + break; + } + } + else + { + ret = -EINVAL; + } + + return ret; +} + +static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) +{ + rt_int32_t timeout; + struct rt_thread *thread; + rt_base_t level; + int ret = 0; + + thread = ep->polling_thread; + + timeout = rt_tick_from_millisecond(msec); + + level = rt_hw_interrupt_disable(); + + if (timeout != 0 && !ep->tirggered) + { + if (rt_thread_suspend_with_flag(thread, RT_KILLABLE) == RT_EOK) + // if (rt_thread_suspend_with_flag(thread, RT_INTERRUPTIBLE) == RT_EOK) + { + if (timeout > 0) + { + rt_timer_control(&(thread->thread_timer), + RT_TIMER_CTRL_SET_TIME, + &timeout); + rt_timer_start(&(thread->thread_timer)); + } + + rt_hw_interrupt_enable(level); + + rt_schedule(); + + level = rt_hw_interrupt_disable(); + } + } + + ret = !ep->tirggered; + rt_hw_interrupt_enable(level); + + return ret; +} + +static int do_epoll(struct rt_fd_list *fl, rt_pollreq_t *req) +{ + struct dfs_file *df; + int mask = 0; + int fd = 0; + + fd = fl->epev.data.fd; + if (fd >= 0) + { + df = fd_get(fd); + if (df) + { + if (df->vnode->fops->poll) + { + req->_key = fl->epev.events | EPOLLINOUT_BITS; + mask = df->vnode->fops->poll(df, req); + } + } + + if (mask >= 0) + { + mask &= fl->epev.events; + } + } + + return mask; +} + +static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int maxevents, int timeout) +{ + struct rt_rdllist *rdllist, *pre_rdllist; + int event_num = 0; + int istimeout = 0; + int isn_add = 0; + int isfree = 0; + int mask = 0; + + while (1) + { + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + + if (ep->eventfd_num > 0) + { + rdllist = ep->rlist; + while (rdllist->next != RT_NULL) + { + isfree = 0; + isn_add = 0; + pre_rdllist = rdllist; + rdllist = rdllist->next; + if (event_num < maxevents) + { + + if (rdllist->read_event->epev.events == 0) + { + isfree = 1; + rt_wqueue_remove(&rdllist->read_event->wqn); + + } + else + { + if (rdllist->read_event->revents & EPOLLET) + { + isfree = 1; + + } + else + { + if (rdllist->exclusive) + { + rt_wqueue_remove(&rdllist->read_event->wqn); + mask = get_event(fd_get(rdllist->read_event->epev.data.fd), &rdllist->read_event->req); + if (mask & rdllist->read_event->revents) + { + rdllist->read_event->epev.events = mask; + } + else + { + isfree = 1; + isn_add = 1; + } + } + else + { + rdllist->exclusive = 1; + } + } + } + + if (!isn_add) + { + events[event_num].data.fd = rdllist->read_event->epev.data.fd; + events[event_num].events = rdllist->read_event->revents; + event_num ++; + } + + if (isfree) + { + pre_rdllist->next = rdllist->next; + rt_free(rdllist); + ep->eventfd_num --; + rdllist = pre_rdllist; + } + + } + else + { + break; + } + } + } + + rt_mutex_release(&ep->lock); + + if (event_num || istimeout) + { + ep->tirggered = 0; + break; + } + + if (epoll_wait_timeout(ep, timeout)) + { + istimeout = 1; + } + + } + + return event_num; +} + +static int do_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) +{ + struct rt_eventpoll *ep; + struct dfs_file *df; + lwp_sigset_t old_sig, new_sig; + rt_err_t ret = -EINVAL; + + if (ss) + { + memcpy(&new_sig, ss, sizeof(lwp_sigset_t)); + lwp_thread_signal_mask(rt_thread_self(), LWP_SIG_MASK_CMD_BLOCK, &new_sig, &old_sig); + } + + if ((maxevents > 0) && (epfd >=0)) + { + df = fd_get(epfd); + if (df && df->vnode) + { + ep = (struct rt_eventpoll *)df->vnode->data; + if (ep) + { + ret = epoll_do(ep, events, maxevents, timeout); + } + } + } + + if (ss) + { + lwp_thread_signal_mask(rt_thread_self(), LWP_SIG_MASK_CMD_SET_MASK, &old_sig, RT_NULL); + } + + return ret; +} + +int epoll_create(int size) +{ + return do_epoll_create(size); +} + +int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +{ + return do_epoll_ctl(epfd, op, fd, event); +} + +int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) +{ + return do_epoll_wait(epfd, events, maxevents, timeout, RT_NULL); +} + +int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) +{ + return do_epoll_wait(epfd, events, maxevents, timeout, ss); +} + +int epoll_pwait2(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) +{ + return do_epoll_wait(epfd, events, maxevents, timeout, ss); +} diff --git a/components/lwp/lwp_syscall.c b/components/lwp/lwp_syscall.c index 3dc743b1827..b9b966bead9 100644 --- a/components/lwp/lwp_syscall.c +++ b/components/lwp/lwp_syscall.c @@ -43,6 +43,7 @@ #ifdef RT_USING_DFS #include #include +#include #include #include #ifdef RT_USING_DFS_V2 @@ -5325,6 +5326,55 @@ sysret_t sys_eventfd2(unsigned int count, int flags) ret = eventfd(count, flags); return (ret < 0 ? GET_ERRNO() : ret); } +sysret_t sys_epoll_create1(int flags) +{ + int ret; + + ret = epoll_create(flags); + + return (ret < 0 ? GET_ERRNO() : ret); +} + +sysret_t sys_epoll_ctl(int fd, int op, int fd2, struct epoll_event *ev) +{ + int ret; + + if (!lwp_user_accessable((void *)ev, sizeof(struct epoll_event))) + { + return -EFAULT; + } + + ret = epoll_ctl(fd, op, fd2, ev); + + return (ret < 0 ? GET_ERRNO() : ret); +} + +sysret_t sys_epoll_pwait(int fd, + struct epoll_event *ev, + int cnt, + int to, + const sigset_t *sigs, + unsigned long sigsetsize) +{ + int ret; + + if (!lwp_user_accessable((void *)ev, sizeof(struct epoll_event))) + { + return -EFAULT; + } + + if (sigs != 0) + { + if (!lwp_user_accessable((void *)sigs, sizeof(sigset_t))) + { + return -EFAULT; + } + } + + ret = epoll_pwait(fd, ev, cnt, to, sigs); + + return (ret < 0 ? GET_ERRNO() : ret); +} static const struct rt_syscall_def func_table[] = { @@ -5558,6 +5608,9 @@ static const struct rt_syscall_def func_table[] = SYSCALL_SIGN(sys_notimpl), SYSCALL_SIGN(sys_notimpl), /* 190 */ SYSCALL_SIGN(sys_eventfd2), + SYSCALL_SIGN(sys_epoll_create1), + SYSCALL_SIGN(sys_epoll_ctl), + SYSCALL_SIGN(sys_epoll_pwait), }; const void *lwp_get_sys_api(rt_uint32_t number) From 2fadb1a0608a2b9b5891875bd92c4fbc54a84806 Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Sun, 30 Jul 2023 20:21:25 +0800 Subject: [PATCH 2/8] Modify the issue with memory deallocation --- components/libc/posix/io/epoll/epoll.c | 201 +++++++++++++++++-------- 1 file changed, 138 insertions(+), 63 deletions(-) diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 8ff7ca46ee7..34577f9988f 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -1,4 +1,3 @@ - /* * Copyright (c) 2006-2023, RT-Thread Development Team * @@ -21,8 +20,6 @@ #define EPOLL_MUTEX_NAME "EVENTEPOLL" #define EFD_SHARED_EPOLL_TYPE (EPOLL_CTL_ADD | EPOLL_CTL_DEL | EPOLL_CTL_MOD) - -#define EP_PRIVATE_BITS (EPOLLONESHOT | EPOLLET | EPOLLEXCLUSIVE) #define EPOLLINOUT_BITS (EPOLLIN | EPOLLOUT | EPOLLRDNORM | EPOLLWRNORM) #define EPOLLEXCLUSIVE_BITS (EPOLLINOUT_BITS | EPOLLERR | EPOLLHUP | \ EPOLLET | EPOLLEXCLUSIVE) @@ -69,21 +66,22 @@ static const struct dfs_file_ops epoll_fops = .poll = epoll_poll, }; -static int free_fdlist(struct rt_fd_list *fd_list) +static int free_fdlist(struct rt_fd_list *fdlist) { - struct rt_fd_list *list; + struct rt_fd_list *fre_list, *list; - if (fd_list) + if (fdlist != RT_NULL) { - while (fd_list->next != RT_NULL) + list = fdlist; + while (list->next != RT_NULL) { - list = fd_list->next; - rt_wqueue_remove(&fd_list->wqn); - rt_free(fd_list); - fd_list = list; + fre_list = list->next; + rt_wqueue_remove(&fre_list->wqn); + list->next = fre_list->next; + rt_free(fre_list); } - rt_free(fd_list); + rt_free(fdlist); } return 0; @@ -91,15 +89,16 @@ static int free_fdlist(struct rt_fd_list *fd_list) static int free_rdllist(struct rt_rdllist *rlist) { - struct rt_rdllist *list; + struct rt_rdllist *list, *fre_list; - if (rlist) + list = rlist; + if (list) { - while (rlist->next != RT_NULL) + while (list->next != RT_NULL) { - list = rlist->next; - rt_free(rlist); - rlist = list; + fre_list = list->next; + list->next = fre_list->next; + rt_free(fre_list); } rt_free(rlist); @@ -114,22 +113,26 @@ static int epoll_close(struct dfs_file *file) if (file->vnode) { - ep = file->vnode->data; - rt_mutex_detach(&ep->lock); - - if (ep) + if (file->vnode->data) { - if (ep->fdlist) + ep = file->vnode->data; + if (ep) { - free_fdlist(ep->fdlist); - } + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + if (ep->fdlist) + { + free_fdlist(ep->fdlist); + } - if (ep->rlist) - { - free_rdllist(ep->rlist); - } + if (ep->rlist) + { + free_rdllist(ep->rlist); + } - rt_free(ep); + rt_mutex_release(&ep->lock); + rt_mutex_detach(&ep->lock); + rt_free(ep); + } } } @@ -143,18 +146,22 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) int mask; int events = 0; - ep = file->vnode->data; - fdlist = ep->fdlist; - if (fdlist) + if (file->vnode->data) { - while (fdlist->next != RT_NULL) + ep = file->vnode->data; + fdlist = ep->fdlist; + if (fdlist) { - fdlist = fdlist->next; - mask = do_epoll(fdlist, &fdlist->req); - if (mask & fdlist->epev.events) + while (fdlist->next != RT_NULL) { - events |= mask | POLLIN | EPOLLRDNORM; - break; + fdlist = fdlist->next; + mask = do_epoll(fdlist, &fdlist->req); + + if (mask & fdlist->epev.events) + { + events |= mask | POLLIN | EPOLLRDNORM; + break; + } } } } @@ -164,13 +171,15 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) static int rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) { - struct rt_rdllist *rlist; + struct rt_rdllist *rlist = RT_NULL; struct rt_eventpoll *ep; int isexist = 0; int res = -1; ep = fdl->eventpoll; + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + if (ep->rlist == RT_NULL) { ep->rlist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); @@ -195,6 +204,7 @@ static int rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) if (!isexist) { + rlist = RT_NULL; rlist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); if (rlist != RT_NULL) { @@ -215,6 +225,8 @@ static int rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) ep->tirggered = 1; + rt_mutex_release(&ep->lock); + return res; } @@ -249,7 +261,6 @@ static void __eventpoll_add(rt_wqueue_t *wq, rt_pollreq_t *req) fdlist->wqn.polling_thread = ep->polling_thread; fdlist->wqn.wakeup = __wqueue_eventpoll_wake; - rt_wqueue_add(wq, &fdlist->wqn); } @@ -274,9 +285,6 @@ static void eventpoll_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep struct dfs_file *df; rt_uint32_t mask = 0; - fdlist->req._proc = __eventpoll_add; - // fdlist->revents = fdlist->epev.events; - fdlist->eventpoll = ep; fdlist->req._key = fdlist->epev.events; df = fd_get(fdlist->epev.data.fd); @@ -291,19 +299,13 @@ static void eventpoll_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep } } -static void eventpoll_remove(struct rt_fd_list *fdlist) -{ - fdlist->req._proc = __eventpoll_add; - // fdlist->revents = EPOLLEXCLUSIVE_BITS; - rt_wqueue_remove(&fdlist->wqn); -} - static void eventpoll_init(struct rt_eventpoll *ep) { ep->tirggered = 0; ep->eventfd_num = 0; ep->polling_thread = rt_thread_self(); ep->rlist = RT_NULL; + ep->fdlist = RT_NULL; } static int epoll_dfs_file_init(int fd) @@ -395,13 +397,32 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event) struct rt_eventpoll *eventpoll; rt_err_t ret = 0; - eventpoll = df->vnode->data; + if (df->vnode->data) + { + eventpoll = df->vnode->data; + } + else + { + return -1; + } + + fdlist = eventpoll->fdlist; + while (fdlist->next != RT_NULL) + { + if (fdlist->next->epev.data.fd == event->data.fd) + { + return 0; + } + fdlist = fdlist->next; + } fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); if (fdlist) { fdlist->epev.data.fd = event->data.fd; fdlist->epev.events = event->events; + fdlist->eventpoll = eventpoll; + fdlist->req._proc = __eventpoll_add; fdlist->next = eventpoll->fdlist->next; fdlist->revents = event->events; eventpoll->fdlist->next = fdlist; @@ -419,9 +440,19 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event) static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist, *fre_fd; - struct rt_eventpoll *eventpoll = df->vnode->data; + struct rt_eventpoll *eventpoll = RT_NULL; + struct rt_rdllist *rdllist, *fre_rdl; rt_err_t ret = 0; + if (df->vnode->data) + { + eventpoll = df->vnode->data; + } + else + { + return 0; + } + fdlist = eventpoll->fdlist; while (fdlist->next != RT_NULL) { @@ -429,12 +460,37 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) { fre_fd = fdlist->next; fdlist->next = fdlist->next->next; - eventpoll_remove(fre_fd); + if (fre_fd->epev.events != 0) + { + rt_wqueue_remove(&fre_fd->wqn); + } rt_free(fre_fd); break; } + else + { + fdlist = fdlist->next; + } + } - fdlist = fdlist->next; + if (eventpoll->rlist) + { + rdllist = eventpoll->rlist; + while (rdllist->next != RT_NULL) + { + if (rdllist->next->read_event->epev.data.fd == event->data.fd) + { + fre_rdl = rdllist->next; + rdllist->next = rdllist->next->next; + eventpoll->eventfd_num --; + rt_free(fre_rdl); + break; + } + else + { + rdllist = rdllist->next; + } + } } return ret; @@ -443,9 +499,18 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist; - struct rt_eventpoll *eventpoll = df->vnode->data; + struct rt_eventpoll *eventpoll = RT_NULL; rt_err_t ret = 0; + if (df->vnode->data) + { + eventpoll = df->vnode->data; + } + else + { + return -1; + } + fdlist = eventpoll->fdlist; while (fdlist->next != RT_NULL) { @@ -467,6 +532,7 @@ static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event) static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) { struct dfs_file *epdf; + struct rt_eventpoll *ep; rt_err_t ret = 0; if (op & ~EFD_SHARED_EPOLL_TYPE) @@ -475,12 +541,22 @@ static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) if ((epfd == fd) || (epfd < 0) || (fd < 0) || (event->data.fd != fd)) return -EINVAL; - // if (!(event->events & EPOLLET)) - // { - // event->events |= EPOLLEXCLUSIVE; - // } + if (!(event->events & EPOLLEXCLUSIVE_BITS)) + return -EINVAL; epdf = fd_get(epfd); + + if (epdf->vnode->data) + { + ep = epdf->vnode->data; + } + else + { + return -1; + } + + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + if (epdf) { switch (op) @@ -504,6 +580,8 @@ static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) ret = -EINVAL; } + rt_mutex_release(&ep->lock); + return ret; } @@ -523,7 +601,6 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) if (timeout != 0 && !ep->tirggered) { if (rt_thread_suspend_with_flag(thread, RT_KILLABLE) == RT_EOK) - // if (rt_thread_suspend_with_flag(thread, RT_INTERRUPTIBLE) == RT_EOK) { if (timeout > 0) { @@ -604,14 +681,12 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max { isfree = 1; rt_wqueue_remove(&rdllist->read_event->wqn); - } else { if (rdllist->read_event->revents & EPOLLET) { isfree = 1; - } else { From afaa7725904d56e23f882a077b46cbdbfdc67fde Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Sun, 30 Jul 2023 20:40:06 +0800 Subject: [PATCH 3/8] Delete extra rows --- components/libc/posix/io/epoll/epoll.c | 3 --- 1 file changed, 3 deletions(-) diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 34577f9988f..cc8f4f7452c 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -676,7 +676,6 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max rdllist = rdllist->next; if (event_num < maxevents) { - if (rdllist->read_event->epev.events == 0) { isfree = 1; @@ -725,7 +724,6 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max ep->eventfd_num --; rdllist = pre_rdllist; } - } else { @@ -746,7 +744,6 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max { istimeout = 1; } - } return event_num; From b48f56aca63cf5a8384bab358dd57200fd07f521 Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Mon, 31 Jul 2023 14:50:10 +0800 Subject: [PATCH 4/8] Add poll wake-up events, update function names, and optimize poll calls --- components/libc/posix/io/epoll/epoll.c | 246 ++++++++++++------------- 1 file changed, 118 insertions(+), 128 deletions(-) diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index cc8f4f7452c..202a204809c 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -32,7 +32,7 @@ struct rt_fd_list rt_uint32_t revents; struct epoll_event epev; rt_pollreq_t req; - struct rt_eventpoll *eventpoll; + struct rt_eventpoll *ep; struct rt_wqueue_node wqn; struct rt_fd_list *next; }; @@ -40,25 +40,26 @@ struct rt_fd_list struct rt_rdllist { int exclusive; - struct rt_fd_list *read_event; + struct rt_fd_list *rdl_event; struct rt_rdllist *next; }; struct rt_eventpoll { rt_uint32_t tirggered; + rt_wqueue_t epoll_read; rt_thread_t polling_thread; struct rt_mutex lock; struct rt_fd_list *fdlist; - int eventfd_num; - struct rt_rdllist *rlist; + int eventpoll_num; + rt_pollreq_t req; + struct rt_rdllist *rdllist; }; static int epoll_close(struct dfs_file *file); static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req); static int do_epoll(struct rt_fd_list *fl, rt_pollreq_t *req); static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); -static int get_event(struct dfs_file *df, rt_pollreq_t *req); static const struct dfs_file_ops epoll_fops = { @@ -66,19 +67,19 @@ static const struct dfs_file_ops epoll_fops = .poll = epoll_poll, }; -static int free_fdlist(struct rt_fd_list *fdlist) +static int epoll_close_fdlist(struct rt_fd_list *fdlist) { - struct rt_fd_list *fre_list, *list; + struct rt_fd_list *fre_node, *list; if (fdlist != RT_NULL) { list = fdlist; while (list->next != RT_NULL) { - fre_list = list->next; - rt_wqueue_remove(&fre_list->wqn); - list->next = fre_list->next; - rt_free(fre_list); + fre_node = list->next; + rt_wqueue_remove(&fre_node->wqn); + list->next = fre_node->next; + rt_free(fre_node); } rt_free(fdlist); @@ -87,21 +88,21 @@ static int free_fdlist(struct rt_fd_list *fdlist) return 0; } -static int free_rdllist(struct rt_rdllist *rlist) +static int epoll_close_rdllist(struct rt_rdllist *rdllist) { - struct rt_rdllist *list, *fre_list; + struct rt_rdllist *list, *fre_node; - list = rlist; + list = rdllist; if (list) { while (list->next != RT_NULL) { - fre_list = list->next; - list->next = fre_list->next; - rt_free(fre_list); + fre_node = list->next; + list->next = fre_node->next; + rt_free(fre_node); } - rt_free(rlist); + rt_free(rdllist); } return 0; @@ -121,12 +122,12 @@ static int epoll_close(struct dfs_file *file) rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); if (ep->fdlist) { - free_fdlist(ep->fdlist); + epoll_close_fdlist(ep->fdlist); } - if (ep->rlist) + if (ep->rdllist) { - free_rdllist(ep->rlist); + epoll_close_rdllist(ep->rdllist); } rt_mutex_release(&ep->lock); @@ -149,6 +150,10 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) if (file->vnode->data) { ep = file->vnode->data; + ep->req._key = req->_key; + + rt_poll_add(&ep->epoll_read, req); + fdlist = ep->fdlist; if (fdlist) { @@ -169,32 +174,37 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) return events; } -static int rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) +static int epoll_rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) { - struct rt_rdllist *rlist = RT_NULL; + struct rt_rdllist *rdllist = RT_NULL; struct rt_eventpoll *ep; int isexist = 0; int res = -1; - ep = fdl->eventpoll; + ep = fdl->ep; + + if (revents & ep->req._key) + { + rt_wqueue_wakeup(&ep->epoll_read, (void*)POLLIN); + } rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - if (ep->rlist == RT_NULL) + if (ep->rdllist == RT_NULL) { - ep->rlist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); - if (ep->rlist == RT_NULL) + ep->rdllist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); + if (ep->rdllist == RT_NULL) { return -1; } - ep->rlist->next = RT_NULL; + ep->rdllist->next = RT_NULL; } - rlist = ep->rlist; - while (rlist->next != RT_NULL) + rdllist = ep->rdllist; + while (rdllist->next != RT_NULL) { - rlist = rlist->next; - if (rlist->read_event->epev.data.fd == fdl->epev.data.fd) + rdllist = rdllist->next; + if (rdllist->rdl_event->epev.data.fd == fdl->epev.data.fd) { isexist = 1; res = 0; @@ -204,21 +214,21 @@ static int rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) if (!isexist) { - rlist = RT_NULL; - rlist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); - if (rlist != RT_NULL) + rdllist = RT_NULL; + rdllist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); + if (rdllist != RT_NULL) { - rlist->read_event = fdl; - rlist->read_event->epev.events = revents; - rlist->next = ep->rlist->next; - rlist->exclusive = 0; + rdllist->rdl_event = fdl; + rdllist->rdl_event->epev.events = revents; + rdllist->next = ep->rdllist->next; + rdllist->exclusive = 0; - ep->rlist->next = rlist; - ep->eventfd_num ++; + ep->rdllist->next = rdllist; + ep->eventpoll_num ++; res = 0; - if (rlist->read_event->revents & EPOLLONESHOT) + if (rdllist->rdl_event->revents & EPOLLONESHOT) { - rlist->read_event->epev.events = 0; + rdllist->rdl_event->epev.events = 0; } } } @@ -230,7 +240,7 @@ static int rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) return res; } -static int __wqueue_eventpoll_wake(struct rt_wqueue_node *wait, void *key) +static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) { struct rt_fd_list *fdlist; @@ -241,113 +251,93 @@ static int __wqueue_eventpoll_wake(struct rt_wqueue_node *wait, void *key) if (fdlist->epev.events) { - rdllist_add(fdlist, (rt_ubase_t)key); + epoll_rdllist_add(fdlist, (rt_ubase_t)key); } return __wqueue_default_wake(wait, key); } -static void __eventpoll_add(rt_wqueue_t *wq, rt_pollreq_t *req) +static void epoll_wqueue_add_callback(rt_wqueue_t *wq, rt_pollreq_t *req) { struct rt_fd_list *fdlist; struct rt_eventpoll *ep; fdlist = rt_container_of(req, struct rt_fd_list, req); - ep = fdlist->eventpoll; + ep = fdlist->ep; fdlist->wqn.key = req->_key; rt_list_init(&(fdlist->wqn.list)); fdlist->wqn.polling_thread = ep->polling_thread; - fdlist->wqn.wakeup = __wqueue_eventpoll_wake; + fdlist->wqn.wakeup = epoll_wqueue_callback; rt_wqueue_add(wq, &fdlist->wqn); } -static int get_event(struct dfs_file *df, rt_pollreq_t *req) +static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep) { - int mask = 0; - - if (df) - { - if (df->vnode->fops->poll) - { - req->_key = EPOLLINOUT_BITS ; - mask = df->vnode->fops->poll(df, req); - } - } - - return mask; -} - -static void eventpoll_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep) -{ - struct dfs_file *df; rt_uint32_t mask = 0; fdlist->req._key = fdlist->epev.events; - df = fd_get(fdlist->epev.data.fd); - - if (df) + mask = do_epoll(fdlist, &fdlist->req); + if (mask & fdlist->epev.events) { - mask = get_event(df, &fdlist->req); - if (mask & fdlist->epev.events) - { - rdllist_add(fdlist, mask); - } + epoll_rdllist_add(fdlist, mask); } } -static void eventpoll_init(struct rt_eventpoll *ep) +static void epoll_member_init(struct rt_eventpoll *ep) { ep->tirggered = 0; - ep->eventfd_num = 0; + ep->eventpoll_num = 0; ep->polling_thread = rt_thread_self(); - ep->rlist = RT_NULL; + ep->rdllist = RT_NULL; ep->fdlist = RT_NULL; + ep->req._key = 0; + rt_wqueue_init(&ep->epoll_read); } -static int epoll_dfs_file_init(int fd) +static int epoll_epf_init(int fd) { struct dfs_file *df; - struct rt_eventpoll *eventpoll; + struct rt_eventpoll *ep; rt_err_t ret = 0; df = fd_get(fd); if (df) { - eventpoll = (struct rt_eventpoll *)rt_malloc(sizeof(struct rt_eventpoll)); - if (eventpoll) + ep = (struct rt_eventpoll *)rt_malloc(sizeof(struct rt_eventpoll)); + if (ep) { - eventpoll_init(eventpoll); + epoll_member_init(ep); - rt_mutex_init(&eventpoll->lock, EPOLL_MUTEX_NAME, RT_IPC_FLAG_FIFO); + rt_mutex_init(&ep->lock, EPOLL_MUTEX_NAME, RT_IPC_FLAG_FIFO); df->vnode = (struct dfs_vnode *)rt_malloc(sizeof(struct dfs_vnode)); if (df->vnode) { - eventpoll->fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); - if (eventpoll->fdlist) + ep->fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); + if (ep->fdlist) { - eventpoll->fdlist->next = RT_NULL; - eventpoll->fdlist->epev.data.fd = fd; - eventpoll->fdlist->eventpoll = eventpoll; + ep->fdlist->next = RT_NULL; + ep->fdlist->epev.data.fd = fd; + ep->fdlist->ep = ep; dfs_vnode_init(df->vnode, FT_REGULAR, &epoll_fops); - df->vnode->data = eventpoll; + df->vnode->data = ep; } else { ret = -ENOMEM; rt_free(df->vnode); - rt_free(eventpoll); + rt_free(ep); } } else { ret = -ENOMEM; - rt_free(eventpoll); + rt_free(ep); } } else @@ -375,7 +365,7 @@ static int do_epoll_create(int size) if (fd >= 0) { ret = fd; - status = epoll_dfs_file_init(fd); + status = epoll_epf_init(fd); if (status < 0) { fd_release(fd); @@ -394,19 +384,19 @@ static int do_epoll_create(int size) static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist; - struct rt_eventpoll *eventpoll; + struct rt_eventpoll *ep; rt_err_t ret = 0; if (df->vnode->data) { - eventpoll = df->vnode->data; + ep = df->vnode->data; } else { return -1; } - fdlist = eventpoll->fdlist; + fdlist = ep->fdlist; while (fdlist->next != RT_NULL) { if (fdlist->next->epev.data.fd == event->data.fd) @@ -421,13 +411,13 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event) { fdlist->epev.data.fd = event->data.fd; fdlist->epev.events = event->events; - fdlist->eventpoll = eventpoll; - fdlist->req._proc = __eventpoll_add; - fdlist->next = eventpoll->fdlist->next; + fdlist->ep = ep; + fdlist->req._proc = epoll_wqueue_add_callback; + fdlist->next = ep->fdlist->next; fdlist->revents = event->events; - eventpoll->fdlist->next = fdlist; + ep->fdlist->next = fdlist; - eventpoll_install(fdlist, eventpoll); + epoll_ctl_install(fdlist, ep); } else { @@ -440,20 +430,20 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event) static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist, *fre_fd; - struct rt_eventpoll *eventpoll = RT_NULL; + struct rt_eventpoll *ep = RT_NULL; struct rt_rdllist *rdllist, *fre_rdl; rt_err_t ret = 0; if (df->vnode->data) { - eventpoll = df->vnode->data; + ep = df->vnode->data; } else { return 0; } - fdlist = eventpoll->fdlist; + fdlist = ep->fdlist; while (fdlist->next != RT_NULL) { if (fdlist->next->epev.data.fd == event->data.fd) @@ -473,16 +463,16 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) } } - if (eventpoll->rlist) + if (ep->rdllist) { - rdllist = eventpoll->rlist; + rdllist = ep->rdllist; while (rdllist->next != RT_NULL) { - if (rdllist->next->read_event->epev.data.fd == event->data.fd) + if (rdllist->next->rdl_event->epev.data.fd == event->data.fd) { fre_rdl = rdllist->next; rdllist->next = rdllist->next->next; - eventpoll->eventfd_num --; + ep->eventpoll_num --; rt_free(fre_rdl); break; } @@ -499,19 +489,19 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist; - struct rt_eventpoll *eventpoll = RT_NULL; + struct rt_eventpoll *ep = RT_NULL; rt_err_t ret = 0; if (df->vnode->data) { - eventpoll = df->vnode->data; + ep = df->vnode->data; } else { return -1; } - fdlist = eventpoll->fdlist; + fdlist = ep->fdlist; while (fdlist->next != RT_NULL) { if (fdlist->next->epev.data.fd == event->data.fd) @@ -519,7 +509,7 @@ static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event) fdlist->next->epev.events = event->events; fdlist->next->revents = event->events; rt_wqueue_remove(&fdlist->wqn); - eventpoll_install(fdlist, eventpoll); + epoll_ctl_install(fdlist, ep); break; } @@ -638,14 +628,14 @@ static int do_epoll(struct rt_fd_list *fl, rt_pollreq_t *req) { if (df->vnode->fops->poll) { - req->_key = fl->epev.events | EPOLLINOUT_BITS; + req->_key = fl->epev.events | POLLERR | POLLHUP; mask = df->vnode->fops->poll(df, req); + + if (mask < 0) + return mask; } - } - if (mask >= 0) - { - mask &= fl->epev.events; + mask &= fl->epev.events | EPOLLOUT | POLLERR; } } @@ -665,9 +655,9 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max { rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - if (ep->eventfd_num > 0) + if (ep->eventpoll_num > 0) { - rdllist = ep->rlist; + rdllist = ep->rdllist; while (rdllist->next != RT_NULL) { isfree = 0; @@ -676,14 +666,14 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max rdllist = rdllist->next; if (event_num < maxevents) { - if (rdllist->read_event->epev.events == 0) + if (rdllist->rdl_event->epev.events == 0) { isfree = 1; - rt_wqueue_remove(&rdllist->read_event->wqn); + rt_wqueue_remove(&rdllist->rdl_event->wqn); } else { - if (rdllist->read_event->revents & EPOLLET) + if (rdllist->rdl_event->revents & EPOLLET) { isfree = 1; } @@ -691,11 +681,11 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max { if (rdllist->exclusive) { - rt_wqueue_remove(&rdllist->read_event->wqn); - mask = get_event(fd_get(rdllist->read_event->epev.data.fd), &rdllist->read_event->req); - if (mask & rdllist->read_event->revents) + rt_wqueue_remove(&rdllist->rdl_event->wqn); + mask = do_epoll(rdllist->rdl_event, &rdllist->rdl_event->req); + if (mask & rdllist->rdl_event->revents) { - rdllist->read_event->epev.events = mask; + rdllist->rdl_event->epev.events = mask; } else { @@ -712,8 +702,8 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max if (!isn_add) { - events[event_num].data.fd = rdllist->read_event->epev.data.fd; - events[event_num].events = rdllist->read_event->revents; + events[event_num].data.fd = rdllist->rdl_event->epev.data.fd; + events[event_num].events = rdllist->rdl_event->revents; event_num ++; } @@ -721,7 +711,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max { pre_rdllist->next = rdllist->next; rt_free(rdllist); - ep->eventfd_num --; + ep->eventpoll_num --; rdllist = pre_rdllist; } } From 45c0d97d8f422ef0693e359719fb434a3c977e9b Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Mon, 31 Jul 2023 16:52:39 +0800 Subject: [PATCH 5/8] Add comments to improve parts of the code --- components/libc/posix/io/epoll/epoll.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 202a204809c..024f5f6e857 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -29,7 +29,7 @@ struct rt_eventpoll; /* Monitor queue */ struct rt_fd_list { - rt_uint32_t revents; + rt_uint32_t revents; /* Monitored events */ struct epoll_event epev; rt_pollreq_t req; struct rt_eventpoll *ep; @@ -39,21 +39,21 @@ struct rt_fd_list struct rt_rdllist { - int exclusive; + 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 */ struct rt_fd_list *rdl_event; struct rt_rdllist *next; }; struct rt_eventpoll { - rt_uint32_t tirggered; + 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; - int eventpoll_num; + struct rt_fd_list *fdlist; /* Monitor list */ + int eventpoll_num; /* Number of ready lists */ rt_pollreq_t req; - struct rt_rdllist *rdllist; + struct rt_rdllist *rdllist; /* ready list */ }; static int epoll_close(struct dfs_file *file); @@ -228,7 +228,7 @@ static int epoll_rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) res = 0; if (rdllist->rdl_event->revents & EPOLLONESHOT) { - rdllist->rdl_event->epev.events = 0; + rdllist->rdl_event->revents = 0; } } } @@ -248,7 +248,6 @@ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) return -1; fdlist = rt_container_of(wait, struct rt_fd_list, wqn); - if (fdlist->epev.events) { epoll_rdllist_add(fdlist, (rt_ubase_t)key); @@ -508,8 +507,8 @@ static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event) { fdlist->next->epev.events = event->events; fdlist->next->revents = event->events; - rt_wqueue_remove(&fdlist->wqn); - epoll_ctl_install(fdlist, ep); + rt_wqueue_remove(&fdlist->next->wqn); + epoll_ctl_install(fdlist->next, ep); break; } @@ -666,7 +665,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max rdllist = rdllist->next; if (event_num < maxevents) { - if (rdllist->rdl_event->epev.events == 0) + if (rdllist->rdl_event->revents == 0) { isfree = 1; rt_wqueue_remove(&rdllist->rdl_event->wqn); @@ -675,6 +674,8 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max { if (rdllist->rdl_event->revents & EPOLLET) { + rt_wqueue_remove(&rdllist->rdl_event->wqn); + do_epoll(rdllist->rdl_event, &rdllist->rdl_event->req); isfree = 1; } else @@ -703,7 +704,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max if (!isn_add) { events[event_num].data.fd = rdllist->rdl_event->epev.data.fd; - events[event_num].events = rdllist->rdl_event->revents; + events[event_num].events = rdllist->rdl_event->epev.events; event_num ++; } From 3a477148c2773ce754b6109c43b7e75beb8764ac Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Mon, 31 Jul 2023 19:15:16 +0800 Subject: [PATCH 6/8] Update the departure event returned --- components/libc/posix/io/epoll/epoll.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 024f5f6e857..b508d6542a7 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -219,10 +219,9 @@ static int epoll_rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) if (rdllist != RT_NULL) { rdllist->rdl_event = fdl; - rdllist->rdl_event->epev.events = revents; + rdllist->rdl_event->epev.events = fdl->epev.events & revents; rdllist->next = ep->rdllist->next; rdllist->exclusive = 0; - ep->rdllist->next = rdllist; ep->eventpoll_num ++; res = 0; @@ -629,7 +628,6 @@ static int do_epoll(struct rt_fd_list *fl, rt_pollreq_t *req) { req->_key = fl->epev.events | POLLERR | POLLHUP; mask = df->vnode->fops->poll(df, req); - if (mask < 0) return mask; } From 04ac55c4b1b83027cd66b3f303549dccd0af6daa Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Mon, 31 Jul 2023 22:03:39 +0800 Subject: [PATCH 7/8] Update function names --- components/libc/posix/io/epoll/epoll.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index b508d6542a7..4bc3928519f 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -58,7 +58,7 @@ struct rt_eventpoll static int epoll_close(struct dfs_file *file); static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req); -static int do_epoll(struct rt_fd_list *fl, rt_pollreq_t *req); +static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req); static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); static const struct dfs_file_ops epoll_fops = @@ -160,7 +160,7 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) while (fdlist->next != RT_NULL) { fdlist = fdlist->next; - mask = do_epoll(fdlist, &fdlist->req); + mask = epoll_get_event(fdlist, &fdlist->req); if (mask & fdlist->epev.events) { @@ -247,6 +247,7 @@ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) return -1; fdlist = rt_container_of(wait, struct rt_fd_list, wqn); + if (fdlist->epev.events) { epoll_rdllist_add(fdlist, (rt_ubase_t)key); @@ -278,7 +279,7 @@ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep fdlist->req._key = fdlist->epev.events; - mask = do_epoll(fdlist, &fdlist->req); + mask = epoll_get_event(fdlist, &fdlist->req); if (mask & fdlist->epev.events) { epoll_rdllist_add(fdlist, mask); @@ -612,7 +613,7 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) return ret; } -static int do_epoll(struct rt_fd_list *fl, rt_pollreq_t *req) +static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req) { struct dfs_file *df; int mask = 0; @@ -651,7 +652,6 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max while (1) { rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - if (ep->eventpoll_num > 0) { rdllist = ep->rdllist; @@ -673,7 +673,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max if (rdllist->rdl_event->revents & EPOLLET) { rt_wqueue_remove(&rdllist->rdl_event->wqn); - do_epoll(rdllist->rdl_event, &rdllist->rdl_event->req); + epoll_get_event(rdllist->rdl_event, &rdllist->rdl_event->req); isfree = 1; } else @@ -681,7 +681,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max if (rdllist->exclusive) { rt_wqueue_remove(&rdllist->rdl_event->wqn); - mask = do_epoll(rdllist->rdl_event, &rdllist->rdl_event->req); + mask = epoll_get_event(rdllist->rdl_event, &rdllist->rdl_event->req); if (mask & rdllist->rdl_event->revents) { rdllist->rdl_event->epev.events = mask; From ce987ccd007c07cc936ecaf90717b27952ebb5f4 Mon Sep 17 00:00:00 2001 From: zmq810150896 Date: Tue, 1 Aug 2023 11:44:40 +0800 Subject: [PATCH 8/8] Update struct names, function names, replace rt_hw_interrupt_disable with rt_spin_lock_irqsave, add epoll restrictions, --- components/libc/posix/Kconfig | 10 +- components/libc/posix/io/epoll/epoll.c | 308 ++++++++++++------------- 2 files changed, 153 insertions(+), 165 deletions(-) diff --git a/components/libc/posix/Kconfig b/components/libc/posix/Kconfig index 9328f218848..847e8e4e70d 100644 --- a/components/libc/posix/Kconfig +++ b/components/libc/posix/Kconfig @@ -31,10 +31,12 @@ if RT_USING_POSIX_FS select RT_USING_POSIX_POLL default n - config RT_USING_POSIX_EPOLL - bool "Enable I/O Multiplexing epoll " - select RT_USING_POSIX_POLL - default n + if RT_USING_SMART + config RT_USING_POSIX_EPOLL + bool "Enable I/O Multiplexing epoll " + select RT_USING_POSIX_POLL + default n + endif config RT_USING_POSIX_SOCKET bool "Enable BSD Socket I/O " diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 4bc3928519f..1b63f799293 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -24,6 +24,8 @@ #define EPOLLEXCLUSIVE_BITS (EPOLLINOUT_BITS | EPOLLERR | EPOLLHUP | \ EPOLLET | EPOLLEXCLUSIVE) +static struct rt_spinlock spinlock; + struct rt_eventpoll; /* Monitor queue */ @@ -37,11 +39,11 @@ struct rt_fd_list struct rt_fd_list *next; }; -struct rt_rdllist +struct rt_ready_list { 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 */ - struct rt_fd_list *rdl_event; - struct rt_rdllist *next; + struct rt_fd_list *rdl_event; /* rdl: ready list */ + struct rt_ready_list *next; }; struct rt_eventpoll @@ -53,13 +55,13 @@ struct rt_eventpoll struct rt_fd_list *fdlist; /* Monitor list */ int eventpoll_num; /* Number of ready lists */ rt_pollreq_t req; - struct rt_rdllist *rdllist; /* ready list */ + struct rt_ready_list *rdlist; /* ready list */ }; static int epoll_close(struct dfs_file *file); static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req); static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req); -static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event); +static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event); static const struct dfs_file_ops epoll_fops = { @@ -88,11 +90,11 @@ static int epoll_close_fdlist(struct rt_fd_list *fdlist) return 0; } -static int epoll_close_rdllist(struct rt_rdllist *rdllist) +static int epoll_close_rdlist(struct rt_ready_list *rdlist) { - struct rt_rdllist *list, *fre_node; + struct rt_ready_list *list, *fre_node; - list = rdllist; + list = rdlist; if (list) { while (list->next != RT_NULL) @@ -102,7 +104,7 @@ static int epoll_close_rdllist(struct rt_rdllist *rdllist) rt_free(fre_node); } - rt_free(rdllist); + rt_free(rdlist); } return 0; @@ -125,9 +127,9 @@ static int epoll_close(struct dfs_file *file) epoll_close_fdlist(ep->fdlist); } - if (ep->rdllist) + if (ep->rdlist) { - epoll_close_rdllist(ep->rdllist); + epoll_close_rdlist(ep->rdlist); } rt_mutex_release(&ep->lock); @@ -174,9 +176,9 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) return events; } -static int epoll_rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) +static int epoll_rdlist_add(struct rt_fd_list *fdl, rt_uint32_t revents) { - struct rt_rdllist *rdllist = RT_NULL; + struct rt_ready_list *rdlist = RT_NULL; struct rt_eventpoll *ep; int isexist = 0; int res = -1; @@ -190,21 +192,21 @@ static int epoll_rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - if (ep->rdllist == RT_NULL) + if (ep->rdlist == RT_NULL) { - ep->rdllist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); - if (ep->rdllist == RT_NULL) + ep->rdlist = (struct rt_ready_list *)rt_malloc(sizeof(struct rt_ready_list)); + if (ep->rdlist == RT_NULL) { return -1; } - ep->rdllist->next = RT_NULL; + ep->rdlist->next = RT_NULL; } - rdllist = ep->rdllist; - while (rdllist->next != RT_NULL) + rdlist = ep->rdlist; + while (rdlist->next != RT_NULL) { - rdllist = rdllist->next; - if (rdllist->rdl_event->epev.data.fd == fdl->epev.data.fd) + rdlist = rdlist->next; + if (rdlist->rdl_event->epev.data.fd == fdl->epev.data.fd) { isexist = 1; res = 0; @@ -214,20 +216,20 @@ static int epoll_rdllist_add(struct rt_fd_list *fdl, rt_uint32_t revents) if (!isexist) { - rdllist = RT_NULL; - rdllist = (struct rt_rdllist *)rt_malloc(sizeof(struct rt_rdllist)); - if (rdllist != RT_NULL) + rdlist = RT_NULL; + rdlist = (struct rt_ready_list *)rt_malloc(sizeof(struct rt_ready_list)); + if (rdlist != RT_NULL) { - rdllist->rdl_event = fdl; - rdllist->rdl_event->epev.events = fdl->epev.events & revents; - rdllist->next = ep->rdllist->next; - rdllist->exclusive = 0; - ep->rdllist->next = rdllist; + rdlist->rdl_event = fdl; + rdlist->rdl_event->epev.events = fdl->epev.events & revents; + rdlist->next = ep->rdlist->next; + rdlist->exclusive = 0; + ep->rdlist->next = rdlist; ep->eventpoll_num ++; res = 0; - if (rdllist->rdl_event->revents & EPOLLONESHOT) + if (rdlist->rdl_event->revents & EPOLLONESHOT) { - rdllist->rdl_event->revents = 0; + rdlist->rdl_event->revents = 0; } } } @@ -250,7 +252,7 @@ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) if (fdlist->epev.events) { - epoll_rdllist_add(fdlist, (rt_ubase_t)key); + epoll_rdlist_add(fdlist, (rt_ubase_t)key); } return __wqueue_default_wake(wait, key); @@ -282,7 +284,7 @@ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep mask = epoll_get_event(fdlist, &fdlist->req); if (mask & fdlist->epev.events) { - epoll_rdllist_add(fdlist, mask); + epoll_rdlist_add(fdlist, mask); } } @@ -291,10 +293,11 @@ static void epoll_member_init(struct rt_eventpoll *ep) ep->tirggered = 0; ep->eventpoll_num = 0; ep->polling_thread = rt_thread_self(); - ep->rdllist = RT_NULL; + ep->rdlist = RT_NULL; ep->fdlist = RT_NULL; ep->req._key = 0; rt_wqueue_init(&ep->epoll_read); + rt_spin_lock_init(&spinlock); } static int epoll_epf_init(int fd) @@ -348,7 +351,7 @@ static int epoll_epf_init(int fd) return ret; } -static int do_epoll_create(int size) +static int epoll_do_create(int size) { rt_err_t ret = 0; int status; @@ -384,43 +387,40 @@ static int epoll_ctl_add(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist; struct rt_eventpoll *ep; - rt_err_t ret = 0; + rt_err_t ret = -EINVAL; if (df->vnode->data) { ep = df->vnode->data; - } - else - { - return -1; - } + fdlist = ep->fdlist; + ret = 0; - fdlist = ep->fdlist; - while (fdlist->next != RT_NULL) - { - if (fdlist->next->epev.data.fd == event->data.fd) + while (fdlist->next != RT_NULL) { - return 0; + if (fdlist->next->epev.data.fd == event->data.fd) + { + return 0; + } + fdlist = fdlist->next; } - fdlist = fdlist->next; - } - fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); - if (fdlist) - { - fdlist->epev.data.fd = event->data.fd; - fdlist->epev.events = event->events; - fdlist->ep = ep; - fdlist->req._proc = epoll_wqueue_add_callback; - fdlist->next = ep->fdlist->next; - fdlist->revents = event->events; - ep->fdlist->next = fdlist; - - epoll_ctl_install(fdlist, ep); - } - else - { - ret = -ENOMEM; + fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); + if (fdlist) + { + fdlist->epev.data.fd = event->data.fd; + fdlist->epev.events = event->events; + fdlist->ep = ep; + fdlist->req._proc = epoll_wqueue_add_callback; + fdlist->next = ep->fdlist->next; + fdlist->revents = event->events; + ep->fdlist->next = fdlist; + + epoll_ctl_install(fdlist, ep); + } + else + { + ret = -ENOMEM; + } } return ret; @@ -430,56 +430,54 @@ static int epoll_ctl_del(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist, *fre_fd; struct rt_eventpoll *ep = RT_NULL; - struct rt_rdllist *rdllist, *fre_rdl; - rt_err_t ret = 0; + struct rt_ready_list *rdlist, *fre_rdl; + rt_err_t ret = -EINVAL; if (df->vnode->data) { ep = df->vnode->data; - } - else - { - return 0; - } - fdlist = ep->fdlist; - while (fdlist->next != RT_NULL) - { - if (fdlist->next->epev.data.fd == event->data.fd) + fdlist = ep->fdlist; + while (fdlist->next != RT_NULL) { - fre_fd = fdlist->next; - fdlist->next = fdlist->next->next; - if (fre_fd->epev.events != 0) + if (fdlist->next->epev.data.fd == event->data.fd) { - rt_wqueue_remove(&fre_fd->wqn); + fre_fd = fdlist->next; + fdlist->next = fdlist->next->next; + if (fre_fd->epev.events != 0) + { + rt_wqueue_remove(&fre_fd->wqn); + } + rt_free(fre_fd); + break; + } + else + { + fdlist = fdlist->next; } - rt_free(fre_fd); - break; - } - else - { - fdlist = fdlist->next; } - } - if (ep->rdllist) - { - rdllist = ep->rdllist; - while (rdllist->next != RT_NULL) + if (ep->rdlist) { - if (rdllist->next->rdl_event->epev.data.fd == event->data.fd) + rdlist = ep->rdlist; + while (rdlist->next != RT_NULL) { - fre_rdl = rdllist->next; - rdllist->next = rdllist->next->next; - ep->eventpoll_num --; - rt_free(fre_rdl); - break; - } - else - { - rdllist = rdllist->next; + if (rdlist->next->rdl_event->epev.data.fd == event->data.fd) + { + fre_rdl = rdlist->next; + rdlist->next = rdlist->next->next; + ep->eventpoll_num --; + rt_free(fre_rdl); + break; + } + else + { + rdlist = rdlist->next; + } } } + + ret = 0; } return ret; @@ -489,40 +487,38 @@ static int epoll_ctl_mod(struct dfs_file *df ,struct epoll_event *event) { struct rt_fd_list *fdlist; struct rt_eventpoll *ep = RT_NULL; - rt_err_t ret = 0; + rt_err_t ret = -EINVAL; if (df->vnode->data) { ep = df->vnode->data; - } - else - { - return -1; - } - fdlist = ep->fdlist; - while (fdlist->next != RT_NULL) - { - if (fdlist->next->epev.data.fd == event->data.fd) + fdlist = ep->fdlist; + while (fdlist->next != RT_NULL) { - fdlist->next->epev.events = event->events; - fdlist->next->revents = event->events; - rt_wqueue_remove(&fdlist->next->wqn); - epoll_ctl_install(fdlist->next, ep); - break; + if (fdlist->next->epev.data.fd == event->data.fd) + { + fdlist->next->epev.events = event->events; + fdlist->next->revents = event->events; + rt_wqueue_remove(&fdlist->next->wqn); + epoll_ctl_install(fdlist->next, ep); + break; + } + + fdlist = fdlist->next; } - fdlist = fdlist->next; + ret = 0; } return ret; } -static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) +static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) { struct dfs_file *epdf; struct rt_eventpoll *ep; - rt_err_t ret = 0; + rt_err_t ret = -EINVAL; if (op & ~EFD_SHARED_EPOLL_TYPE) return -EINVAL; @@ -538,16 +534,10 @@ static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) if (epdf->vnode->data) { ep = epdf->vnode->data; - } - else - { - return -1; - } + ret = 0; - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); - if (epdf) - { switch (op) { case EPOLL_CTL_ADD: @@ -564,10 +554,6 @@ static int do_epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) break; } } - else - { - ret = -EINVAL; - } rt_mutex_release(&ep->lock); @@ -585,7 +571,7 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) timeout = rt_tick_from_millisecond(msec); - level = rt_hw_interrupt_disable(); + level = rt_spin_lock_irqsave(&spinlock); if (timeout != 0 && !ep->tirggered) { @@ -599,16 +585,16 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) rt_timer_start(&(thread->thread_timer)); } - rt_hw_interrupt_enable(level); + rt_spin_unlock_irqrestore(&spinlock, level); rt_schedule(); - level = rt_hw_interrupt_disable(); + level = rt_spin_lock_irqsave(&spinlock); } } ret = !ep->tirggered; - rt_hw_interrupt_enable(level); + rt_spin_unlock_irqrestore(&spinlock, level); return ret; } @@ -642,7 +628,7 @@ static int epoll_get_event(struct rt_fd_list *fl, rt_pollreq_t *req) static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int maxevents, int timeout) { - struct rt_rdllist *rdllist, *pre_rdllist; + struct rt_ready_list *rdlist, *pre_rdlist; int event_num = 0; int istimeout = 0; int isn_add = 0; @@ -654,37 +640,37 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); if (ep->eventpoll_num > 0) { - rdllist = ep->rdllist; - while (rdllist->next != RT_NULL) + rdlist = ep->rdlist; + while (rdlist->next != RT_NULL) { isfree = 0; isn_add = 0; - pre_rdllist = rdllist; - rdllist = rdllist->next; + pre_rdlist = rdlist; + rdlist = rdlist->next; if (event_num < maxevents) { - if (rdllist->rdl_event->revents == 0) + if (rdlist->rdl_event->revents == 0) { isfree = 1; - rt_wqueue_remove(&rdllist->rdl_event->wqn); + rt_wqueue_remove(&rdlist->rdl_event->wqn); } else { - if (rdllist->rdl_event->revents & EPOLLET) + if (rdlist->rdl_event->revents & EPOLLET) { - rt_wqueue_remove(&rdllist->rdl_event->wqn); - epoll_get_event(rdllist->rdl_event, &rdllist->rdl_event->req); + rt_wqueue_remove(&rdlist->rdl_event->wqn); + epoll_get_event(rdlist->rdl_event, &rdlist->rdl_event->req); isfree = 1; } else { - if (rdllist->exclusive) + if (rdlist->exclusive) { - rt_wqueue_remove(&rdllist->rdl_event->wqn); - mask = epoll_get_event(rdllist->rdl_event, &rdllist->rdl_event->req); - if (mask & rdllist->rdl_event->revents) + rt_wqueue_remove(&rdlist->rdl_event->wqn); + mask = epoll_get_event(rdlist->rdl_event, &rdlist->rdl_event->req); + if (mask & rdlist->rdl_event->revents) { - rdllist->rdl_event->epev.events = mask; + rdlist->rdl_event->epev.events = mask; } else { @@ -694,24 +680,24 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max } else { - rdllist->exclusive = 1; + rdlist->exclusive = 1; } } } if (!isn_add) { - events[event_num].data.fd = rdllist->rdl_event->epev.data.fd; - events[event_num].events = rdllist->rdl_event->epev.events; + events[event_num].data.fd = rdlist->rdl_event->epev.data.fd; + events[event_num].events = rdlist->rdl_event->epev.events; event_num ++; } if (isfree) { - pre_rdllist->next = rdllist->next; - rt_free(rdllist); + pre_rdlist->next = rdlist->next; + rt_free(rdlist); ep->eventpoll_num --; - rdllist = pre_rdllist; + rdlist = pre_rdlist; } } else @@ -738,7 +724,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max return event_num; } -static int do_epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) +static int epoll_do_wait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) { struct rt_eventpoll *ep; struct dfs_file *df; @@ -774,25 +760,25 @@ static int do_epoll_wait(int epfd, struct epoll_event *events, int maxevents, in int epoll_create(int size) { - return do_epoll_create(size); + return epoll_do_create(size); } int epoll_ctl(int epfd, int op, int fd, struct epoll_event *event) { - return do_epoll_ctl(epfd, op, fd, event); + return epoll_do_ctl(epfd, op, fd, event); } int epoll_wait(int epfd, struct epoll_event *events, int maxevents, int timeout) { - return do_epoll_wait(epfd, events, maxevents, timeout, RT_NULL); + return epoll_do_wait(epfd, events, maxevents, timeout, RT_NULL); } int epoll_pwait(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) { - return do_epoll_wait(epfd, events, maxevents, timeout, ss); + return epoll_do_wait(epfd, events, maxevents, timeout, ss); } int epoll_pwait2(int epfd, struct epoll_event *events, int maxevents, int timeout, const sigset_t *ss) { - return do_epoll_wait(epfd, events, maxevents, timeout, ss); + return epoll_do_wait(epfd, events, maxevents, timeout, ss); }