diff options
| author | rcitachi <[email protected]> | 2023-11-28 13:56:06 +0800 |
|---|---|---|
| committer | GitHub <[email protected]> | 2023-11-28 13:56:06 +0800 |
| commit | c06f4e98fce6c86ef412aa70c1f31c971a9d61a9 (patch) | |
| tree | c50f5cab5570e7ee1df636f1ecf4b15723de43e9 /components/libc | |
| parent | 265b79d953ec8e640b1aedb5feaa0c1c77b340ef (diff) | |
[SAL] Update SAL,Add socketpair sendmsg recvmsg function (#8293)
Diffstat (limited to 'components/libc')
| -rw-r--r-- | components/libc/posix/io/epoll/epoll.c | 303 | ||||
| -rw-r--r-- | components/libc/posix/io/poll/poll.h | 47 |
2 files changed, 156 insertions, 194 deletions
diff --git a/components/libc/posix/io/epoll/epoll.c b/components/libc/posix/io/epoll/epoll.c index 7c33d775a2..881b9ac027 100644 --- a/components/libc/posix/io/epoll/epoll.c +++ b/components/libc/posix/io/epoll/epoll.c @@ -24,8 +24,6 @@ #define EPOLLEXCLUSIVE_BITS (EPOLLINOUT_BITS | EPOLLERR | EPOLLHUP | \ EPOLLET | EPOLLEXCLUSIVE) -static struct rt_spinlock spinlock; - struct rt_eventpoll; /* Monitor queue */ @@ -36,15 +34,10 @@ struct rt_fd_list 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 */ int fd; struct rt_fd_list *next; -}; - -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; /* rdl: ready list */ - struct rt_ready_list *next; + rt_slist_t rdl_node; }; struct rt_eventpoll @@ -56,7 +49,8 @@ struct rt_eventpoll struct rt_fd_list *fdlist; /* Monitor list */ int eventpoll_num; /* Number of ready lists */ rt_pollreq_t req; - struct rt_ready_list *rdlist; /* ready list */ + struct rt_spinlock spinlock; + rt_slist_t rdl_head; }; static int epoll_close(struct dfs_file *file); @@ -80,32 +74,14 @@ static int epoll_close_fdlist(struct rt_fd_list *fdlist) while (list->next != RT_NULL) { fre_node = list->next; - rt_wqueue_remove(&fre_node->wqn); - list->next = fre_node->next; - rt_free(fre_node); - } - - rt_free(fdlist); - } - - return 0; -} + if (fre_node->wqn.wqueue) + rt_wqueue_remove(&fre_node->wqn); -static int epoll_close_rdlist(struct rt_ready_list *rdlist) -{ - struct rt_ready_list *list, *fre_node; - - list = rdlist; - if (list) - { - while (list->next != RT_NULL) - { - fre_node = list->next; list->next = fre_node->next; rt_free(fre_node); } - rt_free(rdlist); + rt_free(fdlist); } return 0; @@ -131,11 +107,6 @@ static int epoll_close(struct dfs_file *file) epoll_close_fdlist(ep->fdlist); } - if (ep->rdlist) - { - epoll_close_rdlist(ep->rdlist); - } - rt_mutex_release(&ep->lock); rt_mutex_detach(&ep->lock); rt_free(ep); @@ -149,8 +120,6 @@ static int epoll_close(struct dfs_file *file) 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; if (file->vnode->data) @@ -158,101 +127,41 @@ static int epoll_poll(struct dfs_file *file, struct rt_pollreq *req) ep = file->vnode->data; ep->req._key = req->_key; + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); rt_poll_add(&ep->epoll_read, req); - fdlist = ep->fdlist; - if (fdlist) - { - while (fdlist->next != RT_NULL) - { - fdlist = fdlist->next; - mask = epoll_get_event(fdlist, &fdlist->req); - - if (mask & fdlist->revents) - { - events |= mask | POLLIN | EPOLLRDNORM; - break; - } - } - } - } - - return events; -} - -static int epoll_rdlist_add(struct rt_fd_list *fdl, rt_uint32_t revents) -{ - struct rt_ready_list *rdlist = RT_NULL; - struct rt_eventpoll *ep; - int isexist = 0; - int res = -1; - - ep = fdl->ep; - - if (revents & ep->req._key) - { - rt_wqueue_wakeup(&ep->epoll_read, (void*)POLLIN); - } + rt_spin_lock(&ep->spinlock); - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + if (!rt_slist_isempty(&ep->rdl_head)) + events |= POLLIN | EPOLLRDNORM | POLLOUT; - if (ep->rdlist == RT_NULL) - { - ep->rdlist = (struct rt_ready_list *)rt_malloc(sizeof(struct rt_ready_list)); - if (ep->rdlist == RT_NULL) - { - return -1; - } - ep->rdlist->next = RT_NULL; - } - - rdlist = ep->rdlist; - while (rdlist->next != RT_NULL) - { - rdlist = rdlist->next; - if (rdlist->rdl_event->fd == fdl->fd) - { - isexist = 1; - res = 0; - break; - } - } - - if (!isexist) - { - rdlist = RT_NULL; - rdlist = (struct rt_ready_list *)rt_malloc(sizeof(struct rt_ready_list)); - if (rdlist != RT_NULL) - { - rdlist->rdl_event = fdl; - rdlist->rdl_event->epev.events = fdl->revents & revents; - rdlist->next = ep->rdlist->next; - rdlist->exclusive = 0; - ep->rdlist->next = rdlist; - ep->eventpoll_num ++; - res = 0; - } + rt_spin_unlock(&ep->spinlock); + rt_mutex_release(&ep->lock); } - ep->tirggered = 1; - - rt_mutex_release(&ep->lock); - - return res; + return events; } static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key) { struct rt_fd_list *fdlist; + struct rt_eventpoll *ep; if (key && !((rt_ubase_t)key & wait->key)) return -1; fdlist = rt_container_of(wait, struct rt_fd_list, wqn); - if (fdlist->revents) + ep = fdlist->ep; + if (ep) { - epoll_rdlist_add(fdlist, (rt_ubase_t)key); + rt_spin_lock(&ep->spinlock); + rt_slist_append(&ep->rdl_head, &fdlist->rdl_node); + fdlist->exclusive = 0; + ep->tirggered = 1; + ep->eventpoll_num ++; + rt_wqueue_wakeup(&ep->epoll_read, (void *)POLLIN); + rt_spin_unlock(&ep->spinlock); } return __wqueue_default_wake(wait, key); @@ -285,7 +194,17 @@ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep if (mask & fdlist->revents) { - epoll_rdlist_add(fdlist, mask); + if (ep) + { + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + rt_spin_lock(&ep->spinlock); + rt_slist_append(&ep->rdl_head, &fdlist->rdl_node); + fdlist->exclusive = 0; + ep->tirggered = 1; + ep->eventpoll_num ++; + rt_spin_unlock(&ep->spinlock); + rt_mutex_release(&ep->lock); + } } } @@ -294,11 +213,12 @@ static void epoll_member_init(struct rt_eventpoll *ep) ep->tirggered = 0; ep->eventpoll_num = 0; ep->polling_thread = rt_thread_self(); - ep->rdlist = RT_NULL; ep->fdlist = RT_NULL; ep->req._key = 0; + rt_slist_init(&(ep->rdl_head)); rt_wqueue_init(&ep->epoll_read); - rt_spin_lock_init(&spinlock); + rt_mutex_init(&ep->lock, EPOLL_MUTEX_NAME, RT_IPC_FLAG_FIFO); + rt_spin_lock_init(&ep->spinlock); } static int epoll_epf_init(int fd) @@ -316,8 +236,6 @@ static int epoll_epf_init(int fd) { epoll_member_init(ep); - rt_mutex_init(&ep->lock, EPOLL_MUTEX_NAME, RT_IPC_FLAG_FIFO); - #ifdef RT_USING_DFS_V2 df->fops = &epoll_fops; #endif @@ -331,8 +249,10 @@ static int epoll_epf_init(int fd) ep->fdlist->next = RT_NULL; ep->fdlist->fd = fd; ep->fdlist->ep = ep; + ep->fdlist->exclusive = 0; dfs_vnode_init(df->vnode, FT_REGULAR, &epoll_fops); df->vnode->data = ep; + rt_slist_init(&ep->fdlist->rdl_node); } else { @@ -400,26 +320,33 @@ static int epoll_ctl_add(struct dfs_file *df, int fd, struct epoll_event *event) fdlist = ep->fdlist; ret = 0; + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); while (fdlist->next != RT_NULL) { if (fdlist->next->fd == fd) { + rt_mutex_release(&ep->lock); return 0; } fdlist = fdlist->next; } + rt_mutex_release(&ep->lock); fdlist = (struct rt_fd_list *)rt_malloc(sizeof(struct rt_fd_list)); if (fdlist) { fdlist->fd = fd; memcpy(&fdlist->epev.data, &event->data, sizeof(event->data)); - fdlist->epev.events = event->events; + fdlist->epev.events = 0; fdlist->ep = ep; + fdlist->exclusive = 0; fdlist->req._proc = epoll_wqueue_add_callback; - fdlist->next = ep->fdlist->next; fdlist->revents = event->events; + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + fdlist->next = ep->fdlist->next; ep->fdlist->next = fdlist; + rt_mutex_release(&ep->lock); + rt_slist_init(&fdlist->rdl_node); epoll_ctl_install(fdlist, ep); } @@ -434,53 +361,48 @@ static int epoll_ctl_add(struct dfs_file *df, int fd, struct epoll_event *event) static int epoll_ctl_del(struct dfs_file *df, int fd) { - struct rt_fd_list *fdlist, *fre_fd; + struct rt_fd_list *fdlist, *fre_fd, *rdlist; struct rt_eventpoll *ep = RT_NULL; - struct rt_ready_list *rdlist, *fre_rdl; + rt_slist_t *node = RT_NULL; rt_err_t ret = -EINVAL; if (df->vnode->data) { ep = df->vnode->data; - fdlist = ep->fdlist; - while (fdlist->next != RT_NULL) + if (ep) { - if (fdlist->next->fd == fd) + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + rt_spin_lock(&ep->spinlock); + rt_slist_for_each(node, &ep->rdl_head) { - 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; + rdlist = rt_slist_entry(node, struct rt_fd_list, rdl_node); + if (rdlist->fd == fd) + rt_slist_remove(&ep->rdl_head, node); } - else - { - fdlist = fdlist->next; - } - } + rt_spin_unlock(&ep->spinlock); - if (ep->rdlist) - { - rdlist = ep->rdlist; - while (rdlist->next != RT_NULL) + fdlist = ep->fdlist; + while (fdlist->next != RT_NULL) { - if (rdlist->next->rdl_event->fd == fd) + if (fdlist->next->fd == fd) { - fre_rdl = rdlist->next; - rdlist->next = rdlist->next->next; - ep->eventpoll_num --; - rt_free(fre_rdl); + fre_fd = fdlist->next; + fdlist->next = fdlist->next->next; + + if (fre_fd->wqn.wqueue) + rt_wqueue_remove(&fre_fd->wqn); + + rt_free(fre_fd); break; } else { - rdlist = rdlist->next; + fdlist = fdlist->next; } } + + rt_mutex_release(&ep->lock); } ret = 0; @@ -504,9 +426,13 @@ static int epoll_ctl_mod(struct dfs_file *df, int fd, struct epoll_event *event) { if (fdlist->next->fd == fd) { + rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); memcpy(&fdlist->next->epev.data, &event->data, sizeof(event->data)); fdlist->next->revents = event->events; - rt_wqueue_remove(&fdlist->next->wqn); + if (fdlist->next->wqn.wqueue) + rt_wqueue_remove(&fdlist->next->wqn); + + rt_mutex_release(&ep->lock); epoll_ctl_install(fdlist->next, ep); break; } @@ -538,10 +464,14 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) return -1; } - if (!(event->events & EPOLLEXCLUSIVE_BITS)) + if (!(op & EPOLL_CTL_DEL)) { - rt_set_errno(EINVAL); - return -1; + if (!(event->events & EPOLLEXCLUSIVE_BITS)) + { + rt_set_errno(EINVAL); + return -1; + } + event->events |= EPOLLERR | EPOLLHUP; } if (!fd_get(fd)) @@ -555,8 +485,6 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) if (epdf->vnode->data) { ep = epdf->vnode->data; - event->events |= EPOLLERR | EPOLLHUP; - rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); switch (op) { @@ -583,8 +511,6 @@ static int epoll_do_ctl(int epfd, int op, int fd, struct epoll_event *event) { ep->polling_thread = rt_thread_self(); } - - rt_mutex_release(&ep->lock); } return ret; @@ -601,7 +527,7 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) timeout = rt_tick_from_millisecond(msec); - level = rt_spin_lock_irqsave(&spinlock); + level = rt_spin_lock_irqsave(&ep->spinlock); if (timeout != 0 && !ep->tirggered) { @@ -615,16 +541,16 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec) rt_timer_start(&(thread->thread_timer)); } - rt_spin_unlock_irqrestore(&spinlock, level); + rt_spin_unlock_irqrestore(&ep->spinlock, level); rt_schedule(); - level = rt_spin_lock_irqsave(&spinlock); + level = rt_spin_lock_irqsave(&ep->spinlock); } } ret = !ep->tirggered; - rt_spin_unlock_irqrestore(&spinlock, level); + rt_spin_unlock_irqrestore(&ep->spinlock, level); return ret; } @@ -658,7 +584,8 @@ 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_ready_list *rdlist, *pre_rdlist; + struct rt_fd_list *rdlist; + rt_slist_t *node = RT_NULL; int event_num = 0; int istimeout = 0; int isn_add = 0; @@ -668,23 +595,29 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max while (1) { rt_mutex_take(&ep->lock, RT_WAITING_FOREVER); + rt_spin_lock(&ep->spinlock); if (ep->eventpoll_num > 0) { - rdlist = ep->rdlist; - while (rdlist->next != RT_NULL) + rt_slist_for_each(node,&ep->rdl_head) { + rdlist = rt_slist_entry(node, struct rt_fd_list, rdl_node); + + rt_spin_unlock(&ep->spinlock); + isfree = 0; isn_add = 0; - pre_rdlist = rdlist; - rdlist = rdlist->next; if (event_num < maxevents) { - rt_wqueue_remove(&rdlist->rdl_event->wqn); - mask = epoll_get_event(rdlist->rdl_event, &rdlist->rdl_event->req); + if (rdlist->wqn.wqueue) + { + rt_wqueue_remove(&rdlist->wqn); + } + + mask = epoll_get_event(rdlist, &rdlist->req); - if (mask & rdlist->rdl_event->revents) + if (mask & rdlist->revents) { - rdlist->rdl_event->epev.events = mask & rdlist->rdl_event->revents; + rdlist->epev.events = mask & rdlist->revents; } else { @@ -692,54 +625,64 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max isn_add = 1; } - if (rdlist->rdl_event->revents & EPOLLONESHOT) + if (rdlist->revents & EPOLLONESHOT) { - rdlist->rdl_event->revents = 0; + rdlist->revents = 0; isfree = 1; - rt_wqueue_remove(&rdlist->rdl_event->wqn); + if (rdlist->wqn.wqueue) + rt_wqueue_remove(&rdlist->wqn); } else { - if (rdlist->rdl_event->revents & EPOLLET) + if (rdlist->revents & EPOLLET) { isfree = 1; } else { + rt_spin_lock(&ep->spinlock); if (rdlist->exclusive != 1) { rdlist->exclusive = 1; } + rt_spin_unlock(&ep->spinlock); } } if (!isn_add) { - memcpy(&events[event_num], &rdlist->rdl_event->epev, sizeof(rdlist->rdl_event->epev)); + memcpy(&events[event_num], &rdlist->epev, sizeof(rdlist->epev)); event_num ++; } if (isfree) { - pre_rdlist->next = rdlist->next; - rt_free(rdlist); + rt_spin_lock(&ep->spinlock); ep->eventpoll_num --; - rdlist = pre_rdlist; + rt_slist_remove(&ep->rdl_head, &rdlist->rdl_node); + rt_spin_unlock(&ep->spinlock); } } else { + rt_spin_lock(&ep->spinlock); break; } + + rt_spin_lock(&ep->spinlock); } } + rt_spin_unlock(&ep->spinlock); rt_mutex_release(&ep->lock); if (event_num || istimeout) { + rt_spin_lock(&ep->spinlock); ep->tirggered = 0; - break; + rt_spin_unlock(&ep->spinlock); + if ((timeout >= 0) || (event_num > 0)) + break; } if (epoll_wait_timeout(ep, timeout)) diff --git a/components/libc/posix/io/poll/poll.h b/components/libc/posix/io/poll/poll.h index 0fccd48b0d..7b710cd14e 100644 --- a/components/libc/posix/io/poll/poll.h +++ b/components/libc/posix/io/poll/poll.h @@ -15,28 +15,47 @@ extern "C" { #endif +#ifdef RT_USING_MUSLLIBC #if !defined(POLLIN) && !defined(POLLOUT) -#define POLLIN (0x01) -#define POLLRDNORM (0x01) -#define POLLRDBAND (0x01) -#define POLLPRI (0x01) - -#define POLLOUT (0x02) -#define POLLWRNORM (0x02) -#define POLLWRBAND (0x02) - -#define POLLERR (0x04) -#define POLLHUP (0x08) -#define POLLNVAL (0x10) - +#define POLLIN 0x001 +#define POLLPRI 0x002 +#define POLLOUT 0x004 +#define POLLERR 0x008 +#define POLLHUP 0x010 +#define POLLNVAL 0x020 +#define POLLRDNORM 0x040 +#define POLLRDBAND 0x080 +#define POLLWRNORM 0x100 +#define POLLWRBAND 0x200 +typedef unsigned int nfds_t; +struct pollfd +{ + int fd; + short events; + short revents; +}; +#endif +#else +#if !defined(POLLIN) && !defined(POLLOUT) +#define POLLIN 0x1 +#define POLLOUT 0x2 +#define POLLERR 0x4 +#define POLLNVAL 0x8 +/* Below values are unimplemented */ +#define POLLRDNORM 0x10 +#define POLLRDBAND 0x20 +#define POLLPRI 0x40 +#define POLLWRNORM 0x80 +#define POLLWRBAND 0x100 +#define POLLHUP 0x200 typedef unsigned int nfds_t; - struct pollfd { int fd; short events; short revents; }; +#endif #endif /* !defined(POLLIN) && !defined(POLLOUT) */ #define POLLMASK_DEFAULT (POLLIN | POLLOUT | POLLRDNORM | POLLWRNORM) |
