rpmsgfs: improve file read & write performance
Signed-off-by: ligd <liguiding1@xiaomi.com>
This commit is contained in:
parent
344a9bc838
commit
837c15dcb6
@ -26,6 +26,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
|
#include <sys/uio.h>
|
||||||
|
|
||||||
#include <nuttx/kmalloc.h>
|
#include <nuttx/kmalloc.h>
|
||||||
#include <nuttx/fs/ioctl.h>
|
#include <nuttx/fs/ioctl.h>
|
||||||
@ -48,9 +49,9 @@ struct rpmsgfs_s
|
|||||||
|
|
||||||
struct rpmsgfs_cookie_s
|
struct rpmsgfs_cookie_s
|
||||||
{
|
{
|
||||||
sem_t sem;
|
sem_t sem;
|
||||||
int result;
|
int result;
|
||||||
FAR void *data;
|
FAR void *data;
|
||||||
};
|
};
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
@ -148,14 +149,19 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
|
|||||||
FAR struct rpmsgfs_cookie_s *cookie =
|
FAR struct rpmsgfs_cookie_s *cookie =
|
||||||
(struct rpmsgfs_cookie_s *)(uintptr_t)header->cookie;
|
(struct rpmsgfs_cookie_s *)(uintptr_t)header->cookie;
|
||||||
FAR struct rpmsgfs_read_s *rsp = data;
|
FAR struct rpmsgfs_read_s *rsp = data;
|
||||||
|
FAR struct iovec *read = cookie->data;
|
||||||
|
|
||||||
cookie->result = header->result;
|
cookie->result = header->result;
|
||||||
if (cookie->result > 0)
|
if (cookie->result > 0)
|
||||||
{
|
{
|
||||||
memcpy(cookie->data, rsp->buf, cookie->result);
|
memcpy(read->iov_base + read->iov_len, rsp->buf, cookie->result);
|
||||||
|
read->iov_len += cookie->result;
|
||||||
}
|
}
|
||||||
|
|
||||||
rpmsg_post(ept, &cookie->sem);
|
if (cookie->result <= 0 || read->iov_len >= rsp->count)
|
||||||
|
{
|
||||||
|
rpmsg_post(ept, &cookie->sem);
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
@ -434,38 +440,60 @@ int rpmsgfs_client_close(FAR void *handle, int fd)
|
|||||||
ssize_t rpmsgfs_client_read(FAR void *handle, int fd,
|
ssize_t rpmsgfs_client_read(FAR void *handle, int fd,
|
||||||
FAR void *buf, size_t count)
|
FAR void *buf, size_t count)
|
||||||
{
|
{
|
||||||
size_t read = 0;
|
FAR struct rpmsgfs_s *priv = handle;
|
||||||
|
struct iovec read =
|
||||||
|
{
|
||||||
|
.iov_base = buf,
|
||||||
|
.iov_len = 0,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct rpmsgfs_cookie_s cookie;
|
||||||
|
struct rpmsgfs_read_s msg;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
while (read < count)
|
memset(&cookie, 0, sizeof(cookie));
|
||||||
|
|
||||||
|
nxsem_init(&cookie.sem, 0, 0);
|
||||||
|
nxsem_set_protocol(&cookie.sem, SEM_PRIO_NONE);
|
||||||
|
cookie.data = &read;
|
||||||
|
|
||||||
|
msg.header.command = RPMSGFS_READ;
|
||||||
|
msg.header.result = -ENXIO;
|
||||||
|
msg.header.cookie = (uintptr_t)&cookie;
|
||||||
|
msg.fd = fd;
|
||||||
|
msg.count = count;
|
||||||
|
|
||||||
|
ret = rpmsg_send(&priv->ept, &msg, sizeof(msg));
|
||||||
|
if (ret < 0)
|
||||||
{
|
{
|
||||||
struct rpmsgfs_read_s msg =
|
goto out;
|
||||||
{
|
|
||||||
.fd = fd,
|
|
||||||
.count = count - read,
|
|
||||||
};
|
|
||||||
|
|
||||||
ret = rpmsgfs_send_recv(handle, RPMSGFS_READ, true,
|
|
||||||
(FAR struct rpmsgfs_header_s *)&msg, sizeof(msg), buf);
|
|
||||||
if (ret <= 0)
|
|
||||||
{
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
read += ret;
|
|
||||||
buf += ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return read ? read : ret;
|
ret = rpmsg_wait(&priv->ept, &cookie.sem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cookie.result;
|
||||||
|
|
||||||
|
out:
|
||||||
|
nxsem_destroy(&cookie.sem);
|
||||||
|
return read.iov_len ? read.iov_len : ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ssize_t rpmsgfs_client_write(FAR void *handle, int fd,
|
ssize_t rpmsgfs_client_write(FAR void *handle, int fd,
|
||||||
FAR const void *buf, size_t count)
|
FAR const void *buf, size_t count)
|
||||||
{
|
{
|
||||||
FAR struct rpmsgfs_s *priv = handle;
|
FAR struct rpmsgfs_s *priv = handle;
|
||||||
|
struct rpmsgfs_cookie_s cookie;
|
||||||
size_t written = 0;
|
size_t written = 0;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
|
|
||||||
|
memset(&cookie, 0, sizeof(cookie));
|
||||||
|
nxsem_init(&cookie.sem, 0, 0);
|
||||||
|
nxsem_set_protocol(&cookie.sem, SEM_PRIO_NONE);
|
||||||
|
|
||||||
while (written < count)
|
while (written < count)
|
||||||
{
|
{
|
||||||
FAR struct rpmsgfs_write_s *msg;
|
FAR struct rpmsgfs_write_s *msg;
|
||||||
@ -475,31 +503,46 @@ ssize_t rpmsgfs_client_write(FAR void *handle, int fd,
|
|||||||
if (!msg)
|
if (!msg)
|
||||||
{
|
{
|
||||||
ret = -ENOMEM;
|
ret = -ENOMEM;
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
space -= sizeof(*msg);
|
space -= sizeof(*msg);
|
||||||
if (space > count - written)
|
if (space >= count - written)
|
||||||
{
|
{
|
||||||
space = count - written;
|
space = count - written;
|
||||||
|
msg->header.cookie = (uintptr_t)&cookie;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
msg->header.cookie = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->fd = fd;
|
msg->header.command = RPMSGFS_WRITE;
|
||||||
msg->count = space;
|
msg->header.result = -ENXIO;
|
||||||
|
msg->fd = fd;
|
||||||
|
msg->count = space;
|
||||||
memcpy(msg->buf, buf + written, space);
|
memcpy(msg->buf, buf + written, space);
|
||||||
|
|
||||||
ret = rpmsgfs_send_recv(priv, RPMSGFS_WRITE, false,
|
ret = rpmsg_send_nocopy(&priv->ept, msg, sizeof(*msg) + space);
|
||||||
(FAR struct rpmsgfs_header_s *)msg,
|
if (ret < 0)
|
||||||
sizeof(*msg) + space, NULL);
|
|
||||||
if (ret <= 0)
|
|
||||||
{
|
{
|
||||||
break;
|
goto out;
|
||||||
}
|
}
|
||||||
|
|
||||||
written += ret;
|
written += space;
|
||||||
}
|
}
|
||||||
|
|
||||||
return written ? written : ret;
|
ret = rpmsg_wait(&priv->ept, &cookie.sem);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
goto out;
|
||||||
|
}
|
||||||
|
|
||||||
|
ret = cookie.result;
|
||||||
|
|
||||||
|
out:
|
||||||
|
nxsem_destroy(&cookie.sem);
|
||||||
|
return ret < 0 ? ret : count;
|
||||||
}
|
}
|
||||||
|
|
||||||
off_t rpmsgfs_client_lseek(FAR void *handle, int fd,
|
off_t rpmsgfs_client_lseek(FAR void *handle, int fd,
|
||||||
|
@ -370,30 +370,44 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
|
|||||||
FAR struct rpmsgfs_read_s *rsp;
|
FAR struct rpmsgfs_read_s *rsp;
|
||||||
FAR struct file *filep;
|
FAR struct file *filep;
|
||||||
int ret = -ENOENT;
|
int ret = -ENOENT;
|
||||||
|
size_t read = 0;
|
||||||
uint32_t space;
|
uint32_t space;
|
||||||
|
|
||||||
rsp = rpmsg_get_tx_payload_buffer(ept, &space, true);
|
|
||||||
if (!rsp)
|
|
||||||
{
|
|
||||||
return -ENOMEM;
|
|
||||||
}
|
|
||||||
|
|
||||||
*rsp = *msg;
|
|
||||||
|
|
||||||
space -= sizeof(*msg);
|
|
||||||
if (space > msg->count)
|
|
||||||
{
|
|
||||||
space = msg->count;
|
|
||||||
}
|
|
||||||
|
|
||||||
filep = rpmsgfs_get_file(priv, msg->fd);
|
filep = rpmsgfs_get_file(priv, msg->fd);
|
||||||
if (filep != NULL)
|
|
||||||
|
while (read < msg->count)
|
||||||
{
|
{
|
||||||
ret = file_read(filep, rsp->buf, space);
|
rsp = rpmsg_get_tx_payload_buffer(ept, &space, true);
|
||||||
|
if (!rsp)
|
||||||
|
{
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
|
*rsp = *msg;
|
||||||
|
|
||||||
|
space -= sizeof(*msg);
|
||||||
|
if (space > msg->count - read)
|
||||||
|
{
|
||||||
|
space = msg->count - read;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (filep != NULL)
|
||||||
|
{
|
||||||
|
ret = file_read(filep, rsp->buf, space);
|
||||||
|
}
|
||||||
|
|
||||||
|
rsp->header.result = ret;
|
||||||
|
rpmsg_send_nocopy(ept, rsp, (ret < 0 ? 0 : ret) + sizeof(*rsp));
|
||||||
|
|
||||||
|
if (ret <= 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
read += ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
rsp->header.result = ret;
|
return 0;
|
||||||
return rpmsg_send_nocopy(ept, rsp, (ret < 0 ? 0 : ret) + sizeof(*rsp));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpmsgfs_write_handler(FAR struct rpmsg_endpoint *ept,
|
static int rpmsgfs_write_handler(FAR struct rpmsg_endpoint *ept,
|
||||||
@ -407,11 +421,27 @@ static int rpmsgfs_write_handler(FAR struct rpmsg_endpoint *ept,
|
|||||||
filep = rpmsgfs_get_file(priv, msg->fd);
|
filep = rpmsgfs_get_file(priv, msg->fd);
|
||||||
if (filep != NULL)
|
if (filep != NULL)
|
||||||
{
|
{
|
||||||
ret = file_write(filep, msg->buf, msg->count);
|
size_t written = 0;
|
||||||
|
|
||||||
|
while (written < msg->count)
|
||||||
|
{
|
||||||
|
ret = file_write(filep, msg->buf + written, msg->count - written);
|
||||||
|
if (ret < 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
written += ret;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
msg->header.result = ret;
|
if (msg->header.cookie != 0)
|
||||||
return rpmsg_send(ept, msg, sizeof(*msg));
|
{
|
||||||
|
msg->header.result = ret;
|
||||||
|
rpmsg_send(ept, msg, sizeof(*msg));
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rpmsgfs_lseek_handler(FAR struct rpmsg_endpoint *ept,
|
static int rpmsgfs_lseek_handler(FAR struct rpmsg_endpoint *ept,
|
||||||
|
Loading…
Reference in New Issue
Block a user