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 <stdio.h>
|
||||
#include <sys/uio.h>
|
||||
|
||||
#include <nuttx/kmalloc.h>
|
||||
#include <nuttx/fs/ioctl.h>
|
||||
@ -48,9 +49,9 @@ struct rpmsgfs_s
|
||||
|
||||
struct rpmsgfs_cookie_s
|
||||
{
|
||||
sem_t sem;
|
||||
int result;
|
||||
FAR void *data;
|
||||
sem_t sem;
|
||||
int result;
|
||||
FAR void *data;
|
||||
};
|
||||
|
||||
/****************************************************************************
|
||||
@ -148,14 +149,19 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR struct rpmsgfs_cookie_s *cookie =
|
||||
(struct rpmsgfs_cookie_s *)(uintptr_t)header->cookie;
|
||||
FAR struct rpmsgfs_read_s *rsp = data;
|
||||
FAR struct iovec *read = cookie->data;
|
||||
|
||||
cookie->result = header->result;
|
||||
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;
|
||||
}
|
||||
@ -434,38 +440,60 @@ int rpmsgfs_client_close(FAR void *handle, int fd)
|
||||
ssize_t rpmsgfs_client_read(FAR void *handle, int fd,
|
||||
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;
|
||||
|
||||
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 =
|
||||
{
|
||||
.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;
|
||||
goto out;
|
||||
}
|
||||
|
||||
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,
|
||||
FAR const void *buf, size_t count)
|
||||
{
|
||||
FAR struct rpmsgfs_s *priv = handle;
|
||||
struct rpmsgfs_cookie_s cookie;
|
||||
size_t written = 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)
|
||||
{
|
||||
FAR struct rpmsgfs_write_s *msg;
|
||||
@ -475,31 +503,46 @@ ssize_t rpmsgfs_client_write(FAR void *handle, int fd,
|
||||
if (!msg)
|
||||
{
|
||||
ret = -ENOMEM;
|
||||
break;
|
||||
goto out;
|
||||
}
|
||||
|
||||
space -= sizeof(*msg);
|
||||
if (space > count - written)
|
||||
if (space >= count - written)
|
||||
{
|
||||
space = count - written;
|
||||
msg->header.cookie = (uintptr_t)&cookie;
|
||||
}
|
||||
else
|
||||
{
|
||||
msg->header.cookie = 0;
|
||||
}
|
||||
|
||||
msg->fd = fd;
|
||||
msg->count = space;
|
||||
msg->header.command = RPMSGFS_WRITE;
|
||||
msg->header.result = -ENXIO;
|
||||
msg->fd = fd;
|
||||
msg->count = space;
|
||||
memcpy(msg->buf, buf + written, space);
|
||||
|
||||
ret = rpmsgfs_send_recv(priv, RPMSGFS_WRITE, false,
|
||||
(FAR struct rpmsgfs_header_s *)msg,
|
||||
sizeof(*msg) + space, NULL);
|
||||
if (ret <= 0)
|
||||
ret = rpmsg_send_nocopy(&priv->ept, msg, sizeof(*msg) + space);
|
||||
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,
|
||||
|
@ -370,30 +370,44 @@ static int rpmsgfs_read_handler(FAR struct rpmsg_endpoint *ept,
|
||||
FAR struct rpmsgfs_read_s *rsp;
|
||||
FAR struct file *filep;
|
||||
int ret = -ENOENT;
|
||||
size_t read = 0;
|
||||
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);
|
||||
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 rpmsg_send_nocopy(ept, rsp, (ret < 0 ? 0 : ret) + sizeof(*rsp));
|
||||
return 0;
|
||||
}
|
||||
|
||||
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);
|
||||
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;
|
||||
return rpmsg_send(ept, msg, sizeof(*msg));
|
||||
if (msg->header.cookie != 0)
|
||||
{
|
||||
msg->header.result = ret;
|
||||
rpmsg_send(ept, msg, sizeof(*msg));
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int rpmsgfs_lseek_handler(FAR struct rpmsg_endpoint *ept,
|
||||
|
Loading…
Reference in New Issue
Block a user