Simplified buffers management.

git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15589 27425a3e-05d8-49a3-a47f-9c15f0e5edd8
This commit is contained in:
Giovanni Di Sirio 2022-04-20 13:15:53 +00:00
parent 096495bda8
commit a94c13c652
5 changed files with 93 additions and 110 deletions

View File

@ -351,11 +351,13 @@ static msg_t reloc_entry(elf_load_context_t *ctxp,
static msg_t reloc_section(elf_load_context_t *ctxp,
elf_section_info_t *esip) {
vfs_shared_buffer_t *shbuf;
elf32_rel_t *rbuf;
size_t size, done_size, remaining_size;
msg_t ret;
rbuf = (elf32_rel_t *)(void *)vfs_buffer_take();
shbuf = vfs_buffer_take();
rbuf = (elf32_rel_t *)(void *)shbuf->bigbuf;
/* Reading the relocation section data.*/
remaining_size = esip->rel_size;
@ -365,8 +367,8 @@ static msg_t reloc_section(elf_load_context_t *ctxp,
/* Reading relocation data using buffers in order to not make continuous
calls to the FS which could be unbuffered.*/
if (remaining_size > VFS_BUFFERS_SIZE) {
size = VFS_BUFFERS_SIZE;
if (remaining_size > VFS_BUFFER_SIZE) {
size = VFS_BUFFER_SIZE;
}
else {
size = remaining_size;
@ -392,7 +394,7 @@ static msg_t reloc_section(elf_load_context_t *ctxp,
done_size += size;
}
vfs_buffer_release((char *)rbuf);
vfs_buffer_release(shbuf);
return ret;
}

View File

@ -274,6 +274,7 @@ off_t sb_posix_lseek(int fd, off_t offset, int whence) {
ssize_t sb_posix_getdents(int fd, void *buf, size_t count) {
sb_class_t *sbp = (sb_class_t *)chThdGetSelfX()->ctx.syscall.p;
vfs_shared_buffer_t *shbuf;
vfs_direntry_info_t *dip;
msg_t ret;
@ -289,7 +290,8 @@ ssize_t sb_posix_getdents(int fd, void *buf, size_t count) {
return (ssize_t)CH_RET_ENOTDIR;
}
dip = (vfs_direntry_info_t *)(void *)vfs_buffer_take();
shbuf = vfs_buffer_take();
dip = (vfs_direntry_info_t *)(void *)shbuf->bigbuf;
do {
size_t n;
@ -317,7 +319,7 @@ ssize_t sb_posix_getdents(int fd, void *buf, size_t count) {
} while (false);
vfs_buffer_release((char *)dip);
vfs_buffer_release(shbuf);
return (ssize_t)ret;
}

View File

@ -327,23 +327,23 @@ static msg_t open_absolute_file(vfs_overlay_driver_c *drvp,
}
static msg_t drv_set_cwd(void *instance, const char *path) {
char *buf;
vfs_shared_buffer_t *shbuf;
msg_t ret;
/* Taking a path buffer from the pool.*/
buf = vfs_buffer_take();
shbuf = vfs_buffer_take();
do {
vfs_overlay_driver_c *drvp = (vfs_overlay_driver_c *)instance;
vfs_directory_node_c *vdnp;
size_t path_offset;
ret = build_absolute_path(drvp, buf, path);
ret = build_absolute_path(drvp, shbuf->path.buf1, path);
CH_BREAK_ON_ERROR(ret);
/* Trying to access the directory in order to validate the
combined path. Note, it can modify the path in the buffer.*/
ret = open_absolute_dir(drvp, buf, &vdnp);
ret = open_absolute_dir(drvp, shbuf->path.buf1, &vdnp);
CH_BREAK_ON_ERROR(ret);
vdnp->vmt->release((void *)vdnp);
path_offset = (size_t)ret;
@ -359,12 +359,12 @@ static msg_t drv_set_cwd(void *instance, const char *path) {
}
/* Copying the validated path into the CWD buffer.*/
strcpy(drvp->path_cwd, buf + path_offset);
strcpy(drvp->path_cwd, shbuf->path.buf1 + path_offset);
} while (false);
/* Buffer returned.*/
vfs_buffer_release(buf);
vfs_buffer_release(shbuf);
return ret;
}
@ -381,22 +381,22 @@ static msg_t drv_get_cwd(void *instance, char *buf, size_t size) {
}
static msg_t drv_stat(void *instance, const char *path, vfs_stat_t *sp) {
vfs_shared_buffer_t *shbuf;
msg_t ret;
char *buf;
/* Taking a path buffer from the pool.*/
buf = vfs_buffer_take();
shbuf = vfs_buffer_take();
do {
vfs_overlay_driver_c *drvp = (vfs_overlay_driver_c *)instance;
const char *scanpath;
/* Building the absolute path based on current directory.*/
ret = build_absolute_path(drvp, buf, path);
ret = build_absolute_path(drvp, shbuf->path.buf1, path);
CH_BREAK_ON_ERROR(ret);
/* Skipping the root separator.*/
scanpath = buf + 1;
scanpath = shbuf->path.buf1 + 1;
/* If it is not root checking among mounted drivers.*/
if (*scanpath != '\0') {
@ -417,7 +417,7 @@ static msg_t drv_stat(void *instance, const char *path, vfs_stat_t *sp) {
/* Processing the prefix, if defined.*/
if (drvp->path_prefix != NULL) {
if (path_prepend(buf,
if (path_prepend(shbuf->path.buf1,
drvp->path_prefix,
VFS_CFG_PATHLEN_MAX + 1) == (size_t)0) {
ret = CH_RET_ENAMETOOLONG;
@ -426,7 +426,8 @@ static msg_t drv_stat(void *instance, const char *path, vfs_stat_t *sp) {
}
/* Passing the combined path to the overlaid driver.*/
ret = drvp->overlaid_drv->vmt->stat((void *)drvp->overlaid_drv, buf, sp);
ret = drvp->overlaid_drv->vmt->stat((void *)drvp->overlaid_drv,
shbuf->path.buf1, sp);
}
else {
ret = CH_RET_ENOENT;
@ -434,7 +435,7 @@ static msg_t drv_stat(void *instance, const char *path, vfs_stat_t *sp) {
} while (false);
/* Buffer returned.*/
vfs_buffer_release(buf);
vfs_buffer_release(shbuf);
return ret;
}
@ -442,20 +443,20 @@ static msg_t drv_stat(void *instance, const char *path, vfs_stat_t *sp) {
static msg_t drv_open_dir(void *instance,
const char *path,
vfs_directory_node_c **vdnpp) {
vfs_shared_buffer_t *shbuf;
msg_t ret;
char *buf;
/* Taking a path buffer from the pool.*/
buf = vfs_buffer_take();
shbuf = vfs_buffer_take();
do {
vfs_overlay_driver_c *drvp = (vfs_overlay_driver_c *)instance;
/* Building the absolute path based on current directory.*/
ret = build_absolute_path(drvp, buf, path);
ret = build_absolute_path(drvp, shbuf->path.buf1, path);
CH_BREAK_ON_ERROR(ret);
ret = open_absolute_dir(drvp, buf, vdnpp);
ret = open_absolute_dir(drvp, shbuf->path.buf1, vdnpp);
CH_BREAK_ON_ERROR(ret);
/* Required because the offset returned by open_absolute_dir().*/
@ -463,7 +464,7 @@ static msg_t drv_open_dir(void *instance,
} while (false);
/* Buffer returned.*/
vfs_buffer_release(buf);
vfs_buffer_release(shbuf);
return ret;
}
@ -472,24 +473,24 @@ static msg_t drv_open_file(void *instance,
const char *path,
int flags,
vfs_file_node_c **vfnpp) {
vfs_shared_buffer_t *shbuf;
msg_t ret;
char *buf;
/* Taking a path buffer from the pool.*/
buf = vfs_buffer_take();
shbuf = vfs_buffer_take();
do {
vfs_overlay_driver_c *drvp = (vfs_overlay_driver_c *)instance;
/* Building the absolute path based on current directory.*/
ret = build_absolute_path(drvp, buf, path);
ret = build_absolute_path(drvp, shbuf->path.buf1, path);
CH_BREAK_ON_ERROR(ret);
ret = open_absolute_file(drvp, buf, flags, vfnpp);
ret = open_absolute_file(drvp, shbuf->path.buf1, flags, vfnpp);
} while (false);
/* Buffer returned.*/
vfs_buffer_release(buf);
vfs_buffer_release(shbuf);
return ret;
}
@ -526,22 +527,22 @@ static msg_t drv_overlaid_path_call(vfs_overlay_driver_c *drvp,
}
msg_t drv_unlink(void *instance, const char *path) {
vfs_shared_buffer_t *shbuf;
msg_t ret;
char *buf;
/* Taking a path buffer from the pool.*/
buf = vfs_buffer_take();
shbuf = vfs_buffer_take();
do {
vfs_overlay_driver_c *drvp = (vfs_overlay_driver_c *)instance;
const char *scanpath;
/* Building the absolute path based on current directory.*/
ret = build_absolute_path(drvp, buf, path);
ret = build_absolute_path(drvp, shbuf->path.buf1, path);
CH_BREAK_ON_ERROR(ret);
/* Skipping the root separator.*/
scanpath = buf + 1;
scanpath = shbuf->path.buf1 + 1;
/* If it is the root.*/
if (*scanpath == '\0') {
@ -558,28 +559,24 @@ msg_t drv_unlink(void *instance, const char *path) {
}
else {
/* Passing the request to the overlaid driver, if any.*/
ret = drv_overlaid_path_call(drvp, buf, drvp->overlaid_drv->vmt->unlink);
ret = drv_overlaid_path_call(drvp, shbuf->path.buf1,
drvp->overlaid_drv->vmt->unlink);
}
}
} while (false);
/* Buffer returned.*/
vfs_buffer_release(buf);
vfs_buffer_release(shbuf);
return ret;
}
msg_t drv_rename(void *instance, const char *oldpath, const char *newpath) {
msg_t ret;
char *oldbuf, *newbuf;
vfs_shared_buffer_t *shbuf;
/* Taking a path buffer from the pool.*/
oldbuf = vfs_buffer_take();
newbuf = vfs_buffer_alloc();
if (newbuf == NULL) {
vfs_buffer_release(oldbuf);
return CH_RET_ENOMEM;
}
shbuf = vfs_buffer_take();
do {
msg_t oldret, newret;
@ -588,14 +585,14 @@ msg_t drv_rename(void *instance, const char *oldpath, const char *newpath) {
const char *op, *np;
/* Building the absolute paths based on current directory.*/
ret = build_absolute_path(drvp, oldbuf, oldpath);
ret = build_absolute_path(drvp, shbuf->path.buf1, oldpath);
CH_BREAK_ON_ERROR(ret);
ret = build_absolute_path(drvp, newbuf, newpath);
ret = build_absolute_path(drvp, shbuf->path.buf2, newpath);
CH_BREAK_ON_ERROR(ret);
/* Skipping root separators.*/
op = oldbuf + 1;
np = newbuf + 1;
op = shbuf->path.buf1 + 1;
np = shbuf->path.buf2 + 1;
/* Searching for a match among registered drivers.*/
oldret = match_driver(drvp, &op, &olddp);
@ -621,13 +618,13 @@ msg_t drv_rename(void *instance, const char *oldpath, const char *newpath) {
/* Processing the prefix, if defined.*/
if (drvp->path_prefix != NULL) {
if (path_prepend(oldbuf,
if (path_prepend(shbuf->path.buf1,
drvp->path_prefix,
VFS_CFG_PATHLEN_MAX + 1) == (size_t)0) {
ret = CH_RET_ENAMETOOLONG;
break;
}
if (path_prepend(newbuf,
if (path_prepend(shbuf->path.buf2,
drvp->path_prefix,
VFS_CFG_PATHLEN_MAX + 1) == (size_t)0) {
ret = CH_RET_ENAMETOOLONG;
@ -637,7 +634,8 @@ msg_t drv_rename(void *instance, const char *oldpath, const char *newpath) {
/* Passing the combined path to the overlaid driver.*/
ret = drvp->overlaid_drv->vmt->rename((void *)drvp->overlaid_drv,
oldbuf, newbuf);
shbuf->path.buf1,
shbuf->path.buf2);
}
}
else {
@ -647,29 +645,28 @@ msg_t drv_rename(void *instance, const char *oldpath, const char *newpath) {
} while (false);
/* Buffers returned, note, in reverse order.*/
vfs_buffer_free(newbuf);
vfs_buffer_release(oldbuf);
vfs_buffer_release(shbuf);
return ret;
}
msg_t drv_mkdir(void *instance, const char *path, vfs_mode_t mode) {
vfs_shared_buffer_t *shbuf;
msg_t ret;
char *buf;
/* Taking a path buffer from the pool.*/
buf = vfs_buffer_take();
shbuf = vfs_buffer_take();
do {
vfs_overlay_driver_c *drvp = (vfs_overlay_driver_c *)instance;
const char *scanpath;
/* Building the absolute path based on current directory.*/
ret = build_absolute_path(drvp, buf, path);
ret = build_absolute_path(drvp, shbuf->path.buf1, path);
CH_BREAK_ON_ERROR(ret);
/* Skipping the root separator.*/
scanpath = buf + 1;
scanpath = shbuf->path.buf1 + 1;
/* If it is the root.*/
if (*scanpath == '\0') {
@ -691,7 +688,7 @@ msg_t drv_mkdir(void *instance, const char *path, vfs_mode_t mode) {
/* Processing the prefix, if defined.*/
if (drvp->path_prefix != NULL) {
if (path_prepend(buf,
if (path_prepend(shbuf->path.buf1,
drvp->path_prefix,
VFS_CFG_PATHLEN_MAX + 1) == (size_t)0) {
ret = CH_RET_ENAMETOOLONG;
@ -700,7 +697,8 @@ msg_t drv_mkdir(void *instance, const char *path, vfs_mode_t mode) {
}
/* Passing the combined path to the overlaid driver.*/
ret = drvp->overlaid_drv->vmt->mkdir((void *)drvp->overlaid_drv, buf, mode);
ret = drvp->overlaid_drv->vmt->mkdir((void *)drvp->overlaid_drv,
shbuf->path.buf1, mode);
}
else {
ret = CH_RET_ENOENT;
@ -710,28 +708,28 @@ msg_t drv_mkdir(void *instance, const char *path, vfs_mode_t mode) {
} while (false);
/* Buffer returned.*/
vfs_buffer_release(buf);
vfs_buffer_release(shbuf);
return ret;
}
msg_t drv_rmdir(void *instance, const char *path) {
vfs_shared_buffer_t *shbuf;
msg_t ret;
char *buf;
/* Taking a path buffer from the pool.*/
buf = vfs_buffer_take();
shbuf = vfs_buffer_take();
do {
vfs_overlay_driver_c *drvp = (vfs_overlay_driver_c *)instance;
const char *scanpath;
/* Building the absolute path based on current directory.*/
ret = build_absolute_path(drvp, buf, path);
ret = build_absolute_path(drvp, shbuf->path.buf1, path);
CH_BREAK_ON_ERROR(ret);
/* Skipping the root separator.*/
scanpath = buf + 1;
scanpath = shbuf->path.buf1 + 1;
/* If it is the root.*/
if (*scanpath == '\0') {
@ -748,13 +746,14 @@ msg_t drv_rmdir(void *instance, const char *path) {
}
else {
/* Passing the request to the overlaid driver, if any.*/
ret = drv_overlaid_path_call(drvp, buf, drvp->overlaid_drv->vmt->rmdir);
ret = drv_overlaid_path_call(drvp, shbuf->path.buf1,
drvp->overlaid_drv->vmt->rmdir);
}
}
} while (false);
/* Buffer returned.*/
vfs_buffer_release(buf);
vfs_buffer_release(shbuf);
return ret;
}

View File

@ -36,7 +36,7 @@
/**
* @brief Size of the shared buffers.
*/
#define VFS_BUFFERS_SIZE (VFS_CFG_PATHLEN_MAX + 1)
#define VFS_BUFFER_SIZE ((VFS_CFG_PATHLEN_MAX + 1) * 2)
/*===========================================================================*/
/* Module pre-compile time settings. */
@ -50,6 +50,17 @@
/* Module data structures and types. */
/*===========================================================================*/
/**
* @brief Type of a shared buffer structure.
*/
typedef union vfs_shared_buffer {
struct {
char buf1[VFS_CFG_PATHLEN_MAX + 1];
char buf2[VFS_CFG_PATHLEN_MAX + 1];
} path;
char bigbuf[VFS_BUFFER_SIZE];
} vfs_shared_buffer_t;
/*===========================================================================*/
/* Module macros. */
/*===========================================================================*/
@ -62,10 +73,8 @@
extern "C" {
#endif
void __vfs_buffers_init(void);
char *vfs_buffer_take(void);
void vfs_buffer_release(char *buf);
char *vfs_buffer_alloc(void);
void vfs_buffer_free(char *buf);
vfs_shared_buffer_t *vfs_buffer_take(void);
void vfs_buffer_release(vfs_shared_buffer_t *shbuf);
#ifdef __cplusplus
}
#endif

View File

@ -50,16 +50,11 @@ static struct {
/**
* @brief Guarded pool of path buffers.
*/
guarded_memory_pool_t path_buffers1_pool;
/**
* @brief Normal pool of path buffers.
*/
memory_pool_t path_buffers2_pool;
guarded_memory_pool_t buffers_pool;
/**
* @brief Shared path buffers.
*/
char path_buffers1[VFS_CFG_PATHBUFS_NUM]
[VFS_BUFFERS_SIZE];
vfs_shared_buffer_t buffers[VFS_CFG_PATHBUFS_NUM];
} vfs_buffers_static;
/*===========================================================================*/
@ -77,14 +72,11 @@ static struct {
*/
void __vfs_buffers_init(void) {
chGuardedPoolObjectInit(&vfs_buffers_static.path_buffers1_pool,
VFS_BUFFERS_SIZE);
chGuardedPoolLoadArray(&vfs_buffers_static.path_buffers1_pool,
&vfs_buffers_static.path_buffers1[0],
chGuardedPoolObjectInit(&vfs_buffers_static.buffers_pool,
sizeof (vfs_shared_buffer_t));
chGuardedPoolLoadArray(&vfs_buffers_static.buffers_pool,
&vfs_buffers_static.buffers[0],
VFS_CFG_PATHBUFS_NUM);
chPoolObjectInit(&vfs_buffers_static.path_buffers2_pool,
VFS_BUFFERS_SIZE,
chCoreAllocAlignedI);
}
/**
@ -92,41 +84,20 @@ void __vfs_buffers_init(void) {
*
* @return Pointer to the taken buffer.
*/
char *vfs_buffer_take(void) {
vfs_shared_buffer_t *vfs_buffer_take(void) {
return (char *)chGuardedPoolAllocTimeout(&vfs_buffers_static.path_buffers1_pool,
TIME_INFINITE);
return (vfs_shared_buffer_t *)chGuardedPoolAllocTimeout(&vfs_buffers_static.buffers_pool,
TIME_INFINITE);
}
/**
* @brief Releases a path buffer into the fixed pool.
*
* @param[in] buf Buffer to be released.
* @param[in] shbuf Buffer to be released.
*/
void vfs_buffer_release(char *buf) {
void vfs_buffer_release(vfs_shared_buffer_t *shbuf) {
chGuardedPoolFree(&vfs_buffers_static.path_buffers1_pool, (void *)buf);
}
/**
* @brief Allocates a path buffer from the dynamic pool.
*
* @return Pointer to the allocated buffer.
* @retval NULL If the buffer allocation failed.
*/
char *vfs_buffer_alloc(void) {
return (char *)chPoolAlloc(&vfs_buffers_static.path_buffers2_pool);
}
/**
* @brief Frees a path buffer into the dynamic pool.
*
* @param[in] buf Buffer to be freed.
*/
void vfs_buffer_free(char *buf) {
chPoolFree(&vfs_buffers_static.path_buffers2_pool, (void *)buf);
chGuardedPoolFree(&vfs_buffers_static.buffers_pool, (void *)shbuf);
}
/** @} */