-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
drivers/serial/serial.c: adapt to the iovec-based api #14898
base: master
Are you sure you want to change the base?
Changes from 1 commit
2ef0982
e8e16f8
1b1fbc4
9cd9923
7e31a26
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,10 +40,8 @@ | |
* Private Function Prototypes | ||
****************************************************************************/ | ||
|
||
static ssize_t devnull_readv(FAR struct file *filep, | ||
FAR const struct uio *uio); | ||
static ssize_t devnull_writev(FAR struct file *filep, | ||
FAR const struct uio *uio); | ||
static ssize_t devnull_readv(FAR struct file *filep, FAR struct uio *uio); | ||
static ssize_t devnull_writev(FAR struct file *filep, FAR struct uio *uio); | ||
static int devnull_poll(FAR struct file *filep, FAR struct pollfd *fds, | ||
bool setup); | ||
|
||
|
@@ -74,8 +72,7 @@ static const struct file_operations g_devnull_fops = | |
* Name: devnull_readv | ||
****************************************************************************/ | ||
|
||
static ssize_t devnull_readv(FAR struct file *filep, | ||
FAR const struct uio *uio) | ||
static ssize_t devnull_readv(FAR struct file *filep, FAR struct uio *uio) | ||
{ | ||
UNUSED(filep); | ||
UNUSED(uio); | ||
|
@@ -87,12 +84,17 @@ static ssize_t devnull_readv(FAR struct file *filep, | |
* Name: devnull_writev | ||
****************************************************************************/ | ||
|
||
static ssize_t devnull_writev(FAR struct file *filep, | ||
FAR const struct uio *uio) | ||
static ssize_t devnull_writev(FAR struct file *filep, FAR struct uio *uio) | ||
{ | ||
UNUSED(filep); | ||
|
||
return uio_total_len(uio); /* Say that everything was written */ | ||
ssize_t ret = uio_total_len(uio); /* Say that everything was written */ | ||
if (ret >= 0) | ||
{ | ||
uio_advance(uio, ret); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we advance one by one to avoid iterate the vector twice |
||
} | ||
|
||
return ret; | ||
} | ||
|
||
/**************************************************************************** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -40,10 +40,8 @@ | |
* Private Function Prototypes | ||
****************************************************************************/ | ||
|
||
static ssize_t devzero_readv(FAR struct file *filep, | ||
FAR const struct uio *uio); | ||
static ssize_t devzero_writev(FAR struct file *filep, | ||
FAR const struct uio *uio); | ||
static ssize_t devzero_readv(FAR struct file *filep, FAR struct uio *uio); | ||
static ssize_t devzero_writev(FAR struct file *filep, FAR struct uio *uio); | ||
static int devzero_poll(FAR struct file *filep, FAR struct pollfd *fds, | ||
bool setup); | ||
|
||
|
@@ -74,8 +72,7 @@ static const struct file_operations g_devzero_fops = | |
* Name: devzero_readv | ||
****************************************************************************/ | ||
|
||
static ssize_t devzero_readv(FAR struct file *filep, | ||
FAR const struct uio *uio) | ||
static ssize_t devzero_readv(FAR struct file *filep, FAR struct uio *uio) | ||
{ | ||
ssize_t total = uio_total_len(uio); | ||
FAR const struct iovec *iov = uio->uio_iov; | ||
|
@@ -94,19 +91,27 @@ static ssize_t devzero_readv(FAR struct file *filep, | |
memset(iov[i].iov_base, 0, iov[i].iov_len); | ||
} | ||
|
||
uio_advance(uio, total); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we advance one by one to avoid iterate the vector three times |
||
|
||
return total; | ||
} | ||
|
||
/**************************************************************************** | ||
* Name: devzero_writev | ||
****************************************************************************/ | ||
|
||
static ssize_t devzero_writev(FAR struct file *filep, | ||
FAR const struct uio *uio) | ||
static ssize_t devzero_writev(FAR struct file *filep, FAR struct uio *uio) | ||
{ | ||
ssize_t total; | ||
UNUSED(filep); | ||
|
||
return uio_total_len(uio); | ||
total = uio_total_len(uio); | ||
if (total >= 0) | ||
{ | ||
uio_advance(uio, total); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we advance one by one to avoid iterate the vector twice |
||
} | ||
|
||
return total; | ||
} | ||
|
||
/**************************************************************************** | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -50,8 +50,7 @@ | |
* | ||
****************************************************************************/ | ||
|
||
static ssize_t file_readv_compat(FAR struct file *filep, | ||
FAR const struct uio *uio) | ||
static ssize_t file_readv_compat(FAR struct file *filep, FAR struct uio *uio) | ||
{ | ||
FAR const struct iovec *iov = uio->uio_iov; | ||
int iovcnt = uio->uio_iovcnt; | ||
|
@@ -102,6 +101,11 @@ static ssize_t file_readv_compat(FAR struct file *filep, | |
remaining -= nread; | ||
} | ||
|
||
if (ntotal >= 0) | ||
{ | ||
uio_advance(uio, ntotal); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. what's benefit to update the offset in one of uio entry There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it eases logic like:
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. and maybe can help things like restart on EINTR in future. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. can we advance in the loop to avoid iterate the vector twice There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. yes, we can. i feel it's one of the last things to optimize though. |
||
} | ||
|
||
return ntotal; | ||
} | ||
|
||
|
@@ -130,7 +134,7 @@ static ssize_t file_readv_compat(FAR struct file *filep, | |
* | ||
****************************************************************************/ | ||
|
||
ssize_t file_readv(FAR struct file *filep, FAR const struct uio *uio) | ||
ssize_t file_readv(FAR struct file *filep, FAR struct uio *uio) | ||
{ | ||
FAR struct inode *inode; | ||
ssize_t ret = -EBADF; | ||
|
@@ -207,6 +211,7 @@ ssize_t file_read(FAR struct file *filep, FAR void *buf, size_t nbytes) | |
|
||
iov.iov_base = buf; | ||
iov.iov_len = nbytes; | ||
uio_init(&uio); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should we add There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. i guess we can. let me think a bit. |
||
uio.uio_iov = &iov; | ||
uio.uio_iovcnt = 1; | ||
return file_readv(filep, &uio); | ||
|
@@ -251,6 +256,7 @@ ssize_t nx_readv(int fd, FAR const struct iovec *iov, int iovcnt) | |
|
||
/* Then let file_readv do all of the work. */ | ||
|
||
uio_init(&uio); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
uio.uio_iov = iov; | ||
uio.uio_iovcnt = iovcnt; | ||
ret = file_readv(filep, &uio); | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,18 +51,69 @@ ssize_t uio_total_len(FAR const struct uio *uio) | |
{ | ||
const struct iovec *iov = uio->uio_iov; | ||
int iovcnt = uio->uio_iovcnt; | ||
size_t offset_in_iov = uio->uio_offset_in_iov; | ||
size_t len = 0; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. change ssIze_t There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. it can be ssize_t, sure. otoh, writing code with signed arithmetic uses my brain cycles more. let me think a bit. |
||
int i; | ||
|
||
for (i = 0; i < iovcnt; i++) | ||
{ | ||
if (SSIZE_MAX - len < iov[i].iov_len) | ||
DEBUGASSERT(offset_in_iov <= iov[i].iov_len); | ||
if (SSIZE_MAX - len < iov[i].iov_len - offset_in_iov) | ||
{ | ||
return -EOVERFLOW; | ||
} | ||
|
||
len += iov[i].iov_len; | ||
len += iov[i].iov_len - offset_in_iov; | ||
offset_in_iov = 0; | ||
xiaoxiang781216 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
return len; | ||
} | ||
|
||
/**************************************************************************** | ||
* Name: uio_advance | ||
* | ||
* Description: | ||
* Advance the pointer/offset in uio by the specified amount. | ||
* | ||
****************************************************************************/ | ||
|
||
void uio_advance(FAR struct uio *uio, size_t sz) | ||
{ | ||
FAR const struct iovec *iov = uio->uio_iov; | ||
int iovcnt = uio->uio_iovcnt; | ||
size_t offset_in_iov = uio->uio_offset_in_iov; | ||
|
||
DEBUGASSERT(sz <= uio_total_len(uio)); | ||
while (iovcnt > 0) | ||
{ | ||
DEBUGASSERT(offset_in_iov <= iov->iov_len); | ||
if (sz < iov->iov_len - offset_in_iov) | ||
{ | ||
offset_in_iov += sz; | ||
break; | ||
} | ||
|
||
sz -= iov->iov_len; | ||
iov++; | ||
xiaoxiang781216 marked this conversation as resolved.
Show resolved
Hide resolved
|
||
iovcnt--; | ||
offset_in_iov = 0; | ||
} | ||
|
||
uio->uio_iov = iov; | ||
uio->uio_iovcnt = iovcnt; | ||
uio->uio_offset_in_iov = offset_in_iov; | ||
} | ||
|
||
/**************************************************************************** | ||
* Name: uio_init | ||
* | ||
* Description: | ||
* Initialize the uio structure with reasonable default values. | ||
* | ||
****************************************************************************/ | ||
|
||
void uio_init(FAR struct uio *uio) | ||
{ | ||
memset(uio, 0, sizeof(*uio)); | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -51,7 +51,7 @@ | |
****************************************************************************/ | ||
|
||
static ssize_t file_writev_compat(FAR struct file *filep, | ||
FAR const struct uio *uio) | ||
FAR struct uio *uio) | ||
{ | ||
FAR const struct iovec *iov = uio->uio_iov; | ||
int iovcnt = uio->uio_iovcnt; | ||
|
@@ -102,6 +102,11 @@ static ssize_t file_writev_compat(FAR struct file *filep, | |
remaining -= nwritten; | ||
} | ||
|
||
if (ntotal >= 0) | ||
{ | ||
uio_advance(uio, ntotal); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. move into for loop |
||
} | ||
|
||
return ntotal; | ||
} | ||
|
||
|
@@ -133,7 +138,7 @@ static ssize_t file_writev_compat(FAR struct file *filep, | |
* | ||
****************************************************************************/ | ||
|
||
ssize_t file_writev(FAR struct file *filep, FAR const struct uio *uio) | ||
ssize_t file_writev(FAR struct file *filep, FAR struct uio *uio) | ||
{ | ||
FAR struct inode *inode; | ||
ssize_t ret = -EBADF; | ||
|
@@ -205,6 +210,7 @@ ssize_t file_write(FAR struct file *filep, FAR const void *buf, | |
|
||
iov.iov_base = (FAR void *)buf; | ||
iov.iov_len = nbytes; | ||
uio_init(&uio); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
uio.uio_iov = &iov; | ||
uio.uio_iovcnt = 1; | ||
return file_writev(filep, &uio); | ||
|
@@ -252,6 +258,7 @@ ssize_t nx_writev(int fd, FAR const struct iovec *iov, int iovcnt) | |
* index. Note that file_writev() will return the errno on failure. | ||
*/ | ||
|
||
uio_init(&uio); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
uio.uio_iov = iov; | ||
uio.uio_iovcnt = iovcnt; | ||
ret = file_writev(filep, &uio); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
can we advance one by one to avoid iterate the vector twice