Skip to content
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

rename lib_pathbuffer to lib_tempbuffer #151

Merged
merged 4 commits into from
Jan 15, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion include/limits.h
Original file line number Diff line number Diff line change
Expand Up @@ -130,7 +130,7 @@
#define _POSIX_PIPE_BUF 512
#define _POSIX_STREAM_MAX 16
#define _POSIX_TZNAME_MAX 3
#define _POSIX2_LINE_MAX 80
#define _POSIX2_LINE_MAX CONFIG_LINE_MAX

#ifdef CONFIG_SMALL_MEMORY

Expand Down
17 changes: 14 additions & 3 deletions include/nuttx/lib/lib.h
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,9 @@
#include <nuttx/fs/fs.h>
#include <nuttx/kmalloc.h>

#include <limits.h>
#include <alloca.h>

/****************************************************************************
* Pre-processor Definitions
****************************************************************************/
Expand Down Expand Up @@ -117,10 +120,18 @@ FAR struct file_struct *lib_get_stream(int fd);

unsigned long nrand(unsigned long limit);

/* Functions defined in lib_pathbuffer.c ************************************/
/* Functions defined in lib_tempbuffer.c ************************************/

#ifdef CONFIG_LIBC_TEMPBUFFER
FAR char *lib_get_tempbuffer(size_t nbytes);
void lib_put_tempbuffer(FAR char *buffer);
#else
# define lib_get_tempbuffer(n) alloca(n)
# define lib_put_tempbuffer(b)
#endif

FAR char *lib_get_pathbuffer(void);
void lib_put_pathbuffer(FAR char *buffer);
#define lib_get_pathbuffer() lib_get_tempbuffer(PATH_MAX)
#define lib_put_pathbuffer(b) lib_put_tempbuffer(b)

/* Functions defined in lib_realpath.c **************************************/

Expand Down
7 changes: 5 additions & 2 deletions libs/libc/misc/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -47,8 +47,11 @@ list(
lib_mkdirat.c
lib_utimensat.c
lib_mallopt.c
lib_getnprocs.c
lib_pathbuffer.c)
lib_getnprocs.c)

if(CONFIG_LIBC_TEMPBUFFER)
list(APPEND SRCS lib_tempbuffer.c)
endif()

# Support for platforms that do not have long long types

Expand Down
25 changes: 18 additions & 7 deletions libs/libc/misc/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -119,19 +119,30 @@ config LIBC_MEM_FD_VFS_PATH
---help---
The relative path to where memfd will exist in the tmpfs namespace.

config LIBC_MAX_PATHBUFFER
int "Maximum size of a temporary file path buffer array"
config LIBC_TEMPBUFFER
bool "Enable global temp buffer"
default !DEFAULT_SMALL
---help---
Enable this option to enable the global temp buffer, otherwise use stack variables via alloca().
If the current platform does not require a large TEMP_MAX_SIZE size support and toolchain supports alloca(),
we could turn off this option to improve performance.

if LIBC_TEMPBUFFER

config LIBC_MAX_TEMPBUFFER
int "Maximum size of a temporary file temp buffer array"
range 0 32
default 2
---help---
This value is the maximum size of the buffer that will hold the full
file path.
This value is the maximum size of the buffer that will hold the full line.

config LIBC_PATHBUFFER_MALLOC
bool "Enable malloc pathbuffer"
config LIBC_TEMPBUFFER_MALLOC
bool "Enable malloc tempbuffer"
default y
---help---
Enable malloc path buffer from the heap when pathbuffer is insufficient.
Enable malloc temp buffer from the heap when tempbuffer is insufficient.

endif # LIBC_TEMPBUFFER

config LIBC_BACKTRACE_BUFFSIZE
int "The size of backtrace record buffer"
Expand Down
6 changes: 5 additions & 1 deletion libs/libc/misc/Make.defs
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,11 @@ CSRCS += lib_getrandom.c lib_xorshift128.c lib_tea_encrypt.c lib_tea_decrypt.c
CSRCS += lib_cxx_initialize.c lib_impure.c lib_memfd.c lib_mutex.c
CSRCS += lib_fchmodat.c lib_fstatat.c lib_getfullpath.c lib_openat.c
CSRCS += lib_mkdirat.c lib_utimensat.c lib_mallopt.c
CSRCS += lib_idr.c lib_getnprocs.c lib_pathbuffer.c
CSRCS += lib_idr.c lib_getnprocs.c

ifeq ($(CONFIG_LIBC_TEMPBUFFER),y)
CSRCS += lib_tempbuffer.c
endif

# Support for platforms that do not have long long types

Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/****************************************************************************
* libs/libc/misc/lib_pathbuffer.c
* libs/libc/misc/lib_tempbuffer.c
*
* SPDX-License-Identifier: Apache-2.0
*
Expand Down Expand Up @@ -35,25 +35,31 @@
* Pre-processor definitions
****************************************************************************/

#if CONFIG_PATH_MAX > CONFIG_LINE_MAX
# define TEMP_MAX_SIZE CONFIG_PATH_MAX
#else
# define TEMP_MAX_SIZE CONFIG_LINE_MAX
#endif

/****************************************************************************
* Private Types
****************************************************************************/

struct pathbuffer_s
struct tempbuffer_s
{
spinlock_t lock; /* Lock for the buffer */
unsigned long free_bitmap; /* Bitmap of free buffer */
char buffer[CONFIG_LIBC_MAX_PATHBUFFER][PATH_MAX];
char buffer[CONFIG_LIBC_MAX_TEMPBUFFER][TEMP_MAX_SIZE];
};

/****************************************************************************
* Private Data
****************************************************************************/

static struct pathbuffer_s g_pathbuffer =
static struct tempbuffer_s g_tempbuffer =
{
SP_UNLOCKED,
(1u << CONFIG_LIBC_MAX_PATHBUFFER) - 1,
(1u << CONFIG_LIBC_MAX_TEMPBUFFER) - 1,
};

/****************************************************************************
Expand All @@ -65,56 +71,59 @@ static struct pathbuffer_s g_pathbuffer =
****************************************************************************/

/****************************************************************************
* Name: lib_get_pathbuffer
* Name: lib_get_tempbuffer
*
* Description:
* The lib_get_pathbuffer() function returns a pointer to a temporary
* The lib_get_tempbuffer() function returns a pointer to a temporary
* buffer. The buffer is allocated from a pool of pre-allocated buffers
* and if the pool is exhausted, a new buffer is allocated through
* kmm_malloc(). The size of the buffer is PATH_MAX, and must freed by
* calling lib_put_pathbuffer().
* kmm_malloc(). The size of the buffer is nbytes, and must freed by
* calling lib_put_tempbuffer().
*
* Returned Value:
* On success, lib_get_pathbuffer() returns a pointer to a temporary
* On success, lib_get_tempbuffer() returns a pointer to a temporary
* buffer. On failure, NULL is returned.
*
****************************************************************************/

FAR char *lib_get_pathbuffer(void)
FAR char *lib_get_tempbuffer(size_t nbytes)
{
irqstate_t flags;
int index;

/* Try to find a free buffer */

flags = spin_lock_irqsave(&g_pathbuffer.lock);
index = ffsl(g_pathbuffer.free_bitmap) - 1;
if (index >= 0 && index < CONFIG_LIBC_MAX_PATHBUFFER)
if (nbytes <= TEMP_MAX_SIZE)
{
g_pathbuffer.free_bitmap &= ~(1u << index);
spin_unlock_irqrestore(&g_pathbuffer.lock, flags);
return g_pathbuffer.buffer[index];
/* Try to find a free buffer */

flags = spin_lock_irqsave(&g_tempbuffer.lock);
index = ffsl(g_tempbuffer.free_bitmap) - 1;
if (index >= 0 && index < CONFIG_LIBC_MAX_TEMPBUFFER)
{
g_tempbuffer.free_bitmap &= ~(1u << index);
spin_unlock_irqrestore(&g_tempbuffer.lock, flags);
return g_tempbuffer.buffer[index];
}

spin_unlock_irqrestore(&g_tempbuffer.lock, flags);
}

spin_unlock_irqrestore(&g_pathbuffer.lock, flags);

/* If no free buffer is found, allocate a new one if
* CONFIG_LIBC_PATHBUFFER_MALLOC is enabled
* CONFIG_LIBC_TEMPBUFFER_MALLOC is enabled
*/

#ifdef CONFIG_LIBC_PATHBUFFER_MALLOC
return lib_malloc(PATH_MAX);
#ifdef CONFIG_LIBC_TEMPBUFFER_MALLOC
return lib_malloc(nbytes);
#else
return NULL;
#endif
}

/****************************************************************************
* Name: lib_put_pathbuffer
* Name: lib_put_tempbuffer
*
* Description:
* The lib_put_pathbuffer() function frees a temporary buffer that was
* allocated by lib_get_pathbuffer(). If the buffer was allocated
* The lib_put_tempbuffer() function frees a temporary buffer that was
* allocated by lib_get_tempbuffer(). If the buffer was allocated
* dynamically, it is freed by calling kmm_free(). Otherwise, the buffer
* is marked as free in the pool of pre-allocated buffers.
*
Expand All @@ -123,25 +132,25 @@ FAR char *lib_get_pathbuffer(void)
*
****************************************************************************/

void lib_put_pathbuffer(FAR char *buffer)
void lib_put_tempbuffer(FAR char *buffer)
{
irqstate_t flags;
int index;

index = (buffer - &g_pathbuffer.buffer[0][0]) / PATH_MAX;
if (index >= 0 && index < CONFIG_LIBC_MAX_PATHBUFFER)
index = (buffer - &g_tempbuffer.buffer[0][0]) / TEMP_MAX_SIZE;
if (index >= 0 && index < CONFIG_LIBC_MAX_TEMPBUFFER)
{
/* Mark the corresponding bit as free */

flags = spin_lock_irqsave(&g_pathbuffer.lock);
g_pathbuffer.free_bitmap |= 1u << index;
spin_unlock_irqrestore(&g_pathbuffer.lock, flags);
flags = spin_lock_irqsave(&g_tempbuffer.lock);
g_tempbuffer.free_bitmap |= 1u << index;
spin_unlock_irqrestore(&g_tempbuffer.lock, flags);
return;
}

/* Free the buffer if it was dynamically allocated */

#ifdef CONFIG_LIBC_PATHBUFFER_MALLOC
#ifdef CONFIG_LIBC_TEMPBUFFER_MALLOC
lib_free(buffer);
#endif
}
10 changes: 10 additions & 0 deletions sched/Kconfig
Original file line number Diff line number Diff line change
Expand Up @@ -1412,6 +1412,16 @@ config PATH_MAX
---help---
The maximum size of path name.

config LINE_MAX
int "Maximum size of line"
default 64 if DEFAULT_SMALL
default 80 if !DEFAULT_SMALL
---help---
The maximum size of line. Unless otherwise noted, the maximum length, in bytes,
of a utility's input line (either standard input or another file), when the
utility is described as processing text files. The length includes room for
the trailing newline.

endmenu # Files and I/O

menuconfig PRIORITY_INHERITANCE
Expand Down
Loading