mirror of
https://github.com/RT-Thread/rt-thread.git
synced 2026-09-20 17:44:20 +08:00
sync smart & dfs (#8672)
Signed-off-by: xqyjlj <xqyjlj@126.com> Signed-off-by: Shell <smokewood@qq.com> Co-authored-by: xqyjlj <xqyjlj@126.com>
This commit is contained in:
@@ -25,6 +25,7 @@
|
||||
* 2023-08-12 Meco Man re-implement RT-Thread lightweight timezone API
|
||||
* 2023-09-15 xqyjlj perf rt_hw_interrupt_disable/enable
|
||||
* 2023-10-23 Shell add lock for _g_timerid
|
||||
* 2023-11-16 Shell Fixup of nanosleep if previous call was interrupted
|
||||
*/
|
||||
|
||||
#include "sys/time.h"
|
||||
@@ -544,20 +545,24 @@ int nanosleep(const struct timespec *rqtp, struct timespec *rmtp)
|
||||
unsigned long ns = rqtp->tv_sec * NANOSECOND_PER_SECOND + rqtp->tv_nsec;
|
||||
rt_ktime_boottime_get_ns(&old_ts);
|
||||
rt_ktime_hrtimer_ndelay(ns);
|
||||
if (rt_get_errno() == -RT_EINTR)
|
||||
if (rt_get_errno() == RT_EINTR)
|
||||
{
|
||||
if (rmtp)
|
||||
{
|
||||
rt_base_t rsec, rnsec;
|
||||
rt_ktime_boottime_get_ns(&new_ts);
|
||||
|
||||
rmtp->tv_sec = 0;
|
||||
rmtp->tv_nsec =
|
||||
(old_ts.tv_nsec + ns) - ((new_ts.tv_sec - old_ts.tv_sec) * NANOSECOND_PER_SECOND + new_ts.tv_nsec);
|
||||
|
||||
if (rmtp->tv_nsec > NANOSECOND_PER_SECOND)
|
||||
rsec = old_ts.tv_sec + rqtp->tv_sec - new_ts.tv_sec;
|
||||
rnsec = old_ts.tv_nsec + rqtp->tv_nsec - new_ts.tv_nsec;
|
||||
if (rnsec < 0)
|
||||
{
|
||||
rmtp->tv_nsec %= NANOSECOND_PER_SECOND;
|
||||
rmtp->tv_sec += rmtp->tv_nsec / NANOSECOND_PER_SECOND;
|
||||
rmtp->tv_sec = rsec - 1;
|
||||
rmtp->tv_nsec = NANOSECOND_PER_SECOND + rnsec;
|
||||
}
|
||||
else
|
||||
{
|
||||
rmtp->tv_sec = rsec;
|
||||
rmtp->tv_nsec = rnsec;
|
||||
}
|
||||
}
|
||||
rt_set_errno(EINTR);
|
||||
|
||||
@@ -32,9 +32,13 @@ extern "C" {
|
||||
|
||||
#define DT_UNKNOWN 0x00
|
||||
#define DT_FIFO 0x01
|
||||
#define DT_SYMLINK 0x03
|
||||
#define DT_CHR 0x02
|
||||
#define DT_DIR 0x04
|
||||
#define DT_BLK 0x06
|
||||
#define DT_REG 0x08
|
||||
#define DT_LNK 0x0a
|
||||
#define DT_SOCK 0x0c
|
||||
#define DT_SYMLINK DT_LNK
|
||||
|
||||
#ifndef HAVE_DIR_STRUCTURE
|
||||
#define HAVE_DIR_STRUCTURE
|
||||
|
||||
@@ -15,6 +15,10 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#ifdef RT_USING_MUSLLIBC
|
||||
#include_next <sys/ioctl.h>
|
||||
#else
|
||||
|
||||
struct winsize
|
||||
{
|
||||
unsigned short ws_row;
|
||||
@@ -23,9 +27,6 @@ struct winsize
|
||||
unsigned short ws_ypixel;
|
||||
};
|
||||
|
||||
#ifdef RT_USING_MUSLLIBC
|
||||
#include <bits/ioctl.h>
|
||||
#else
|
||||
/*
|
||||
* Direction bits, which any architecture can choose to override
|
||||
* before including this file.
|
||||
|
||||
@@ -19,6 +19,8 @@
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
#define _POSIX_VDISABLE 0
|
||||
|
||||
#define STDIN_FILENO 0 /* standard input file descriptor */
|
||||
#define STDOUT_FILENO 1 /* standard output file descriptor */
|
||||
#define STDERR_FILENO 2 /* standard error file descriptor */
|
||||
|
||||
@@ -13,12 +13,37 @@
|
||||
|
||||
#include_next <fcntl.h>
|
||||
|
||||
#ifndef O_DIRECTORY
|
||||
#define O_DIRECTORY 0x200000
|
||||
#endif
|
||||
#define O_CREAT 0100
|
||||
#define O_EXCL 0200
|
||||
#define O_NOCTTY 0400
|
||||
#define O_TRUNC 01000
|
||||
#define O_APPEND 02000
|
||||
#define O_NONBLOCK 04000
|
||||
#define O_DSYNC 010000
|
||||
#define O_SYNC 04010000
|
||||
#define O_RSYNC 04010000
|
||||
#define O_DIRECTORY 040000
|
||||
#define O_NOFOLLOW 0100000
|
||||
#define O_CLOEXEC 02000000
|
||||
|
||||
#define O_ASYNC 020000
|
||||
#define O_DIRECT 0200000
|
||||
#define O_LARGEFILE 0400000
|
||||
#define O_NOATIME 01000000
|
||||
#define O_PATH 010000000
|
||||
#define O_TMPFILE 020040000
|
||||
#define O_NDELAY O_NONBLOCK
|
||||
|
||||
#ifndef O_BINARY
|
||||
#define O_BINARY 0x10000
|
||||
#define O_BINARY 00
|
||||
#endif
|
||||
|
||||
#ifndef O_SEARCH
|
||||
#define O_SEARCH O_PATH
|
||||
#endif /* O_SEARCH */
|
||||
|
||||
#ifndef O_EXEC
|
||||
#define O_EXEC O_PATH
|
||||
#endif /* O_EXEC */
|
||||
|
||||
#endif
|
||||
|
||||
@@ -27,7 +27,7 @@ if RT_USING_POSIX_FS
|
||||
select RT_USING_POSIX_POLL
|
||||
default y if RT_USING_SMART
|
||||
default n
|
||||
|
||||
|
||||
config RT_USING_POSIX_EVENTFD
|
||||
bool "Enable I/O event eventfd <sys/eventfd.h>"
|
||||
select RT_USING_POSIX_POLL
|
||||
|
||||
@@ -4,9 +4,14 @@
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*
|
||||
* Change Logs:
|
||||
* Date Author Notes
|
||||
* 2023-07-29 zmq810150896 first version
|
||||
* 2024/03/26 TroyMitchelle Add comments for all functions, members within structure members and fix incorrect naming of triggered
|
||||
* Date Author Notes
|
||||
* 2023-07-29 zmq810150896 first version
|
||||
* 2024/03/26 TroyMitchelle Add comments for all functions, members within structure members and fix incorrect naming of triggered
|
||||
* 2023-12-14 Shell When poll goes to sleep before the waitqueue has added a
|
||||
* record and finished enumerating all the fd's, it may be
|
||||
* incorrectly woken up. This is basically because the poll
|
||||
* mechanism wakeup algorithm does not correctly distinguish
|
||||
* the current wait state.
|
||||
*/
|
||||
|
||||
#include <rtthread.h>
|
||||
@@ -27,6 +32,12 @@
|
||||
|
||||
struct rt_eventpoll;
|
||||
|
||||
enum rt_epoll_status {
|
||||
RT_EPOLL_STAT_INIT,
|
||||
RT_EPOLL_STAT_TRIG,
|
||||
RT_EPOLL_STAT_WAITING,
|
||||
};
|
||||
|
||||
/* Monitor queue */
|
||||
struct rt_fd_list
|
||||
{
|
||||
@@ -44,15 +55,15 @@ struct rt_fd_list
|
||||
|
||||
struct rt_eventpoll
|
||||
{
|
||||
rt_uint32_t triggered; /**< 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 */
|
||||
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 */
|
||||
enum rt_epoll_status status; /* the waited thread whether triggered */
|
||||
};
|
||||
|
||||
static int epoll_close(struct dfs_file *file);
|
||||
@@ -85,8 +96,7 @@ static int epoll_close_fdlist(struct rt_fd_list *fdlist)
|
||||
while (list->next != RT_NULL)
|
||||
{
|
||||
fre_node = list->next;
|
||||
if (fre_node->wqn.wqueue)
|
||||
rt_wqueue_remove(&fre_node->wqn);
|
||||
rt_wqueue_remove(&fre_node->wqn);
|
||||
|
||||
list->next = fre_node->next;
|
||||
rt_free(fre_node);
|
||||
@@ -188,13 +198,14 @@ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key)
|
||||
struct rt_fd_list *fdlist;
|
||||
struct rt_eventpoll *ep;
|
||||
rt_base_t level;
|
||||
int is_waiting = 0;
|
||||
|
||||
if (key && !((rt_ubase_t)key & wait->key))
|
||||
return -1;
|
||||
|
||||
fdlist = rt_container_of(wait, struct rt_fd_list, wqn);
|
||||
|
||||
ep = fdlist->ep;
|
||||
|
||||
if (ep)
|
||||
{
|
||||
level = rt_spin_lock_irqsave(&ep->spinlock);
|
||||
@@ -203,16 +214,21 @@ static int epoll_wqueue_callback(struct rt_wqueue_node *wait, void *key)
|
||||
rt_slist_append(&ep->rdl_head, &fdlist->rdl_node);
|
||||
fdlist->exclusive = 0;
|
||||
fdlist->is_rdl_node = RT_TRUE;
|
||||
ep->triggered = 1;
|
||||
ep->eventpoll_num++;
|
||||
is_waiting = (ep->status == RT_EPOLL_STAT_WAITING);
|
||||
ep->status = RT_EPOLL_STAT_TRIG;
|
||||
rt_wqueue_wakeup(&ep->epoll_read, (void *)POLLIN);
|
||||
}
|
||||
rt_spin_unlock_irqrestore(&ep->spinlock, level);
|
||||
}
|
||||
|
||||
return __wqueue_default_wake(wait, key);
|
||||
}
|
||||
if (is_waiting)
|
||||
{
|
||||
return __wqueue_default_wake(wait, key);
|
||||
}
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Adds a callback function to the wait queue associated with epoll.
|
||||
@@ -265,8 +281,8 @@ 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->triggered = 1;
|
||||
ep->eventpoll_num++;
|
||||
ep->status = RT_EPOLL_STAT_TRIG;
|
||||
ep->eventpoll_num ++;
|
||||
rt_spin_unlock_irqrestore(&ep->spinlock, level);
|
||||
rt_mutex_release(&ep->lock);
|
||||
}
|
||||
@@ -282,7 +298,7 @@ static void epoll_ctl_install(struct rt_fd_list *fdlist, struct rt_eventpoll *ep
|
||||
*/
|
||||
static void epoll_member_init(struct rt_eventpoll *ep)
|
||||
{
|
||||
ep->triggered = 0;
|
||||
ep->status = RT_EPOLL_STAT_INIT;
|
||||
ep->eventpoll_num = 0;
|
||||
ep->polling_thread = rt_thread_self();
|
||||
ep->fdlist = RT_NULL;
|
||||
@@ -678,7 +694,7 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec)
|
||||
|
||||
level = rt_spin_lock_irqsave(&ep->spinlock);
|
||||
|
||||
if (timeout != 0 && !ep->triggered)
|
||||
if (timeout != 0 && ep->status != RT_EPOLL_STAT_TRIG)
|
||||
{
|
||||
if (rt_thread_suspend_with_flag(thread, RT_KILLABLE) == RT_EOK)
|
||||
{
|
||||
@@ -690,15 +706,19 @@ static int epoll_wait_timeout(struct rt_eventpoll *ep, int msec)
|
||||
rt_timer_start(&(thread->thread_timer));
|
||||
}
|
||||
|
||||
ep->status = RT_EPOLL_STAT_WAITING;
|
||||
|
||||
rt_spin_unlock_irqrestore(&ep->spinlock, level);
|
||||
|
||||
rt_schedule();
|
||||
|
||||
level = rt_spin_lock_irqsave(&ep->spinlock);
|
||||
if (ep->status == RT_EPOLL_STAT_WAITING)
|
||||
ep->status = RT_EPOLL_STAT_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
ret = !ep->triggered;
|
||||
ret = !(ep->status == RT_EPOLL_STAT_TRIG);
|
||||
rt_spin_unlock_irqrestore(&ep->spinlock, level);
|
||||
|
||||
return ret;
|
||||
@@ -867,7 +887,7 @@ static int epoll_do(struct rt_eventpoll *ep, struct epoll_event *events, int max
|
||||
if (event_num || istimeout)
|
||||
{
|
||||
level = rt_spin_lock_irqsave(&ep->spinlock);
|
||||
ep->triggered = 0;
|
||||
ep->status = RT_EPOLL_STAT_INIT;
|
||||
rt_spin_unlock_irqrestore(&ep->spinlock, level);
|
||||
if ((timeout >= 0) || (event_num > 0))
|
||||
break;
|
||||
|
||||
@@ -7,6 +7,12 @@
|
||||
* Date Author Notes
|
||||
* 2016-12-28 Bernard first version
|
||||
* 2018-03-09 Bernard Add protection for pt->triggered.
|
||||
* 2023-12-04 Shell Fix return code and error verification
|
||||
* 2023-12-14 Shell When poll goes to sleep before the waitqueue has added a
|
||||
* record and finished enumerating all the fd's, it may be
|
||||
* incorrectly woken up. This is basically because the poll
|
||||
* mechanism wakeup algorithm does not correctly distinguish
|
||||
* the current wait state.
|
||||
*/
|
||||
|
||||
#include <stdint.h>
|
||||
@@ -16,11 +22,16 @@
|
||||
#include "poll.h"
|
||||
|
||||
struct rt_poll_node;
|
||||
enum rt_poll_status {
|
||||
RT_POLL_STAT_INIT,
|
||||
RT_POLL_STAT_TRIG,
|
||||
RT_POLL_STAT_WAITING,
|
||||
};
|
||||
|
||||
struct rt_poll_table
|
||||
{
|
||||
rt_pollreq_t req;
|
||||
rt_uint32_t triggered; /* the waited thread whether triggered */
|
||||
enum rt_poll_status status; /* the waited thread whether triggered */
|
||||
rt_thread_t polling_thread;
|
||||
struct rt_poll_node *nodes;
|
||||
};
|
||||
@@ -36,15 +47,25 @@ static RT_DEFINE_SPINLOCK(_spinlock);
|
||||
|
||||
static int __wqueue_pollwake(struct rt_wqueue_node *wait, void *key)
|
||||
{
|
||||
rt_ubase_t level;
|
||||
struct rt_poll_node *pn;
|
||||
int is_waiting;
|
||||
|
||||
if (key && !((rt_ubase_t)key & wait->key))
|
||||
return -1;
|
||||
|
||||
pn = rt_container_of(wait, struct rt_poll_node, wqn);
|
||||
pn->pt->triggered = 1;
|
||||
|
||||
return __wqueue_default_wake(wait, key);
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
is_waiting = (pn->pt->status == RT_POLL_STAT_WAITING);
|
||||
|
||||
pn->pt->status = RT_POLL_STAT_TRIG;
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
if (is_waiting)
|
||||
return __wqueue_default_wake(wait, key);
|
||||
|
||||
return -1;
|
||||
}
|
||||
|
||||
static void _poll_add(rt_wqueue_t *wq, rt_pollreq_t *req)
|
||||
@@ -71,7 +92,7 @@ static void _poll_add(rt_wqueue_t *wq, rt_pollreq_t *req)
|
||||
static void poll_table_init(struct rt_poll_table *pt)
|
||||
{
|
||||
pt->req._proc = _poll_add;
|
||||
pt->triggered = 0;
|
||||
pt->status = RT_POLL_STAT_INIT;
|
||||
pt->nodes = RT_NULL;
|
||||
pt->polling_thread = rt_thread_self();
|
||||
}
|
||||
@@ -89,7 +110,7 @@ static int poll_wait_timeout(struct rt_poll_table *pt, int msec)
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
|
||||
if (timeout != 0 && !pt->triggered)
|
||||
if (timeout != 0 && pt->status != RT_POLL_STAT_TRIG)
|
||||
{
|
||||
if (rt_thread_suspend_with_flag(thread, RT_INTERRUPTIBLE) == RT_EOK)
|
||||
{
|
||||
@@ -99,17 +120,31 @@ static int poll_wait_timeout(struct rt_poll_table *pt, int msec)
|
||||
RT_TIMER_CTRL_SET_TIME,
|
||||
&timeout);
|
||||
rt_timer_start(&(thread->thread_timer));
|
||||
rt_set_errno(RT_ETIMEOUT);
|
||||
}
|
||||
|
||||
else
|
||||
{
|
||||
rt_set_errno(0);
|
||||
}
|
||||
pt->status = RT_POLL_STAT_WAITING;
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
rt_schedule();
|
||||
|
||||
level = rt_spin_lock_irqsave(&_spinlock);
|
||||
if (pt->status == RT_POLL_STAT_WAITING)
|
||||
pt->status = RT_POLL_STAT_INIT;
|
||||
}
|
||||
}
|
||||
|
||||
ret = !pt->triggered;
|
||||
ret = rt_get_errno();
|
||||
if (ret == RT_EINTR)
|
||||
ret = -RT_EINTR;
|
||||
else if (pt->status == RT_POLL_STAT_TRIG)
|
||||
ret = RT_EOK;
|
||||
else
|
||||
ret = -RT_ETIMEOUT;
|
||||
|
||||
rt_spin_unlock_irqrestore(&_spinlock, level);
|
||||
|
||||
return ret;
|
||||
@@ -170,7 +205,7 @@ static int poll_do(struct pollfd *fds, nfds_t nfds, struct rt_poll_table *pt, in
|
||||
{
|
||||
pf = fds;
|
||||
num = 0;
|
||||
pt->triggered = 0;
|
||||
pt->status = RT_POLL_STAT_INIT;
|
||||
|
||||
for (n = 0; n < nfds; n ++)
|
||||
{
|
||||
@@ -194,8 +229,13 @@ static int poll_do(struct pollfd *fds, nfds_t nfds, struct rt_poll_table *pt, in
|
||||
if (num || istimeout)
|
||||
break;
|
||||
|
||||
if (poll_wait_timeout(pt, msec))
|
||||
ret = poll_wait_timeout(pt, msec);
|
||||
if (ret == -RT_EINTR)
|
||||
return -EINTR;
|
||||
else if (ret == -RT_ETIMEOUT)
|
||||
istimeout = 1;
|
||||
else
|
||||
istimeout = 0;
|
||||
}
|
||||
|
||||
return num;
|
||||
|
||||
@@ -36,6 +36,20 @@ struct termios {
|
||||
speed_t __c_ospeed;
|
||||
};
|
||||
|
||||
#ifndef NCC
|
||||
#define NCC 8
|
||||
|
||||
struct termio
|
||||
{
|
||||
unsigned short c_iflag; /* input mode flags */
|
||||
unsigned short c_oflag; /* output mode flags */
|
||||
unsigned short c_cflag; /* control mode flags */
|
||||
unsigned short c_lflag; /* local mode flags */
|
||||
unsigned char c_line; /* line discipline */
|
||||
unsigned char c_cc[NCC]; /* control characters */
|
||||
};
|
||||
#endif
|
||||
|
||||
/* c_cc characters */
|
||||
#define VINTR 0
|
||||
#define VQUIT 1
|
||||
|
||||
Reference in New Issue
Block a user