From a94c13c6520f0d53076c78d4893db41d69ec9f89 Mon Sep 17 00:00:00 2001 From: Giovanni Di Sirio Date: Wed, 20 Apr 2022 13:15:53 +0000 Subject: [PATCH] Simplified buffers management. git-svn-id: svn://svn.code.sf.net/p/chibios/svn/trunk@15589 27425a3e-05d8-49a3-a47f-9c15f0e5edd8 --- os/sb/host/sbelf.c | 10 ++- os/sb/host/sbposix.c | 6 +- os/vfs/drivers/overlay/drvoverlay.c | 115 ++++++++++++++-------------- os/vfs/include/vfsbuffers.h | 19 +++-- os/vfs/src/vfsbuffers.c | 53 +++---------- 5 files changed, 93 insertions(+), 110 deletions(-) diff --git a/os/sb/host/sbelf.c b/os/sb/host/sbelf.c index 573a70e8d..ecf297176 100644 --- a/os/sb/host/sbelf.c +++ b/os/sb/host/sbelf.c @@ -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; } diff --git a/os/sb/host/sbposix.c b/os/sb/host/sbposix.c index a2d76e812..d26a39da1 100644 --- a/os/sb/host/sbposix.c +++ b/os/sb/host/sbposix.c @@ -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; } diff --git a/os/vfs/drivers/overlay/drvoverlay.c b/os/vfs/drivers/overlay/drvoverlay.c index 7ef6f421f..a8c649d75 100644 --- a/os/vfs/drivers/overlay/drvoverlay.c +++ b/os/vfs/drivers/overlay/drvoverlay.c @@ -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; } diff --git a/os/vfs/include/vfsbuffers.h b/os/vfs/include/vfsbuffers.h index a8fecb897..7748eca26 100644 --- a/os/vfs/include/vfsbuffers.h +++ b/os/vfs/include/vfsbuffers.h @@ -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 diff --git a/os/vfs/src/vfsbuffers.c b/os/vfs/src/vfsbuffers.c index e6b9af4bc..c42e11a58 100644 --- a/os/vfs/src/vfsbuffers.c +++ b/os/vfs/src/vfsbuffers.c @@ -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); } /** @} */