From d77b53957ce67ae380132ec154ea9fd2f986ca19 Mon Sep 17 00:00:00 2001 From: wangbowen6 Date: Thu, 9 Feb 2023 14:59:03 +0800 Subject: [PATCH] sched/env: add tg_envc in task_group_s to avoid some loops in code this commit optimize the env api speed Signed-off-by: wangbowen6 --- include/nuttx/sched.h | 3 ++- sched/environ/env_dup.c | 2 ++ sched/environ/env_findvar.c | 4 ++-- sched/environ/env_foreach.c | 4 +++- sched/environ/env_getenv.c | 2 +- sched/environ/env_release.c | 1 + sched/environ/env_removevar.c | 24 ++++++++++++++---------- sched/environ/env_setenv.c | 17 +++++++++-------- sched/environ/env_unsetenv.c | 2 +- sched/environ/environ.h | 4 ++-- 10 files changed, 37 insertions(+), 26 deletions(-) diff --git a/include/nuttx/sched.h b/include/nuttx/sched.h index ebb9ba5c11..afddefcecb 100644 --- a/include/nuttx/sched.h +++ b/include/nuttx/sched.h @@ -496,7 +496,8 @@ struct task_group_s #ifndef CONFIG_DISABLE_ENVIRON /* Environment variables **************************************************/ - FAR char **tg_envp; /* Allocated environment strings */ + FAR char **tg_envp; /* Allocated environment strings */ + ssize_t tg_envc; /* Number of environment strings */ #endif #ifndef CONFIG_DISABLE_POSIX_TIMERS diff --git a/sched/environ/env_dup.c b/sched/environ/env_dup.c index 5c65b23325..c588aa8376 100644 --- a/sched/environ/env_dup.c +++ b/sched/environ/env_dup.c @@ -87,6 +87,8 @@ int env_dup(FAR struct task_group_s *group, FAR char * const *envcp) envc++; } + group->tg_envc = envc; + /* A special case is that the parent has an "empty" environment * allocation, i.e., there is an allocation in place but it * contains no variable definitions and, hence, envc == 0. diff --git a/sched/environ/env_findvar.c b/sched/environ/env_findvar.c index dfeb8efcad..e529884300 100644 --- a/sched/environ/env_findvar.c +++ b/sched/environ/env_findvar.c @@ -83,9 +83,9 @@ static bool env_cmpname(const char *pszname, const char *peqname) * ****************************************************************************/ -int env_findvar(FAR struct task_group_s *group, FAR const char *pname) +ssize_t env_findvar(FAR struct task_group_s *group, FAR const char *pname) { - int i; + ssize_t i; /* Verify input parameters */ diff --git a/sched/environ/env_foreach.c b/sched/environ/env_foreach.c index 176cb5084d..04a5755967 100644 --- a/sched/environ/env_foreach.c +++ b/sched/environ/env_foreach.c @@ -66,7 +66,7 @@ int env_foreach(FAR struct task_group_s *group, FAR void *arg) { int ret = OK; - int i; + size_t i; /* Verify input parameters */ @@ -93,6 +93,8 @@ int env_foreach(FAR struct task_group_s *group, } } + DEBUGASSERT(ret != OK || group->tg_envc == i); + return ret; } diff --git a/sched/environ/env_getenv.c b/sched/environ/env_getenv.c index 19bcca8228..624b23c9a3 100644 --- a/sched/environ/env_getenv.c +++ b/sched/environ/env_getenv.c @@ -61,7 +61,7 @@ FAR char *getenv(FAR const char *name) FAR struct tcb_s *rtcb; FAR struct task_group_s *group; FAR char *pvalue = NULL; - int ret = OK; + ssize_t ret = OK; /* Verify that a string was passed */ diff --git a/sched/environ/env_release.c b/sched/environ/env_release.c index e9089a0819..9d4e510570 100644 --- a/sched/environ/env_release.c +++ b/sched/environ/env_release.c @@ -84,6 +84,7 @@ void env_release(FAR struct task_group_s *group) */ group->tg_envp = NULL; + group->tg_envc = 0; } #endif /* CONFIG_DISABLE_ENVIRON */ diff --git a/sched/environ/env_removevar.c b/sched/environ/env_removevar.c index f7afa192d1..93a10b0270 100644 --- a/sched/environ/env_removevar.c +++ b/sched/environ/env_removevar.c @@ -59,27 +59,30 @@ * ****************************************************************************/ -void env_removevar(FAR struct task_group_s *group, int index) +void env_removevar(FAR struct task_group_s *group, ssize_t index) { - DEBUGASSERT(group != NULL && index >= 0); + DEBUGASSERT(group != NULL && index >= 0 && index < group->tg_envc); /* Free the allocate environment string */ group_free(group, group->tg_envp[index]); - /* Move all of the environment strings after the removed one 'down.' - * this is inefficient, but robably not high duty. - */ + /* Exchange the last env and the index env */ - do + group->tg_envc--; + if (index == group->tg_envc) { - group->tg_envp[index] = group->tg_envp[index + 1]; + group->tg_envp[index] = NULL; + } + else + { + group->tg_envp[index] = group->tg_envp[group->tg_envc]; + group->tg_envp[group->tg_envc] = NULL; } - while (group->tg_envp[++index] != NULL); /* Free the old environment (if there was one) */ - if (index == 1) + if (group->tg_envc == 0) { group_free(group, group->tg_envp); group->tg_envp = NULL; @@ -89,7 +92,8 @@ void env_removevar(FAR struct task_group_s *group, int index) /* Reallocate the environment to reclaim a little memory */ group->tg_envp = group_realloc(group, group->tg_envp, - sizeof(*group->tg_envp) * (index + 1)); + sizeof(*group->tg_envp) * + (group->tg_envc + 1)); DEBUGASSERT(group->tg_envp != NULL); } } diff --git a/sched/environ/env_setenv.c b/sched/environ/env_setenv.c index 979ab500c4..e4a0b12c8e 100644 --- a/sched/environ/env_setenv.c +++ b/sched/environ/env_setenv.c @@ -71,9 +71,9 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) FAR struct task_group_s *group; FAR char *pvar; FAR char **envp; - int envc = 0; + ssize_t envc = 0; + ssize_t ret = OK; int varlen; - int ret = OK; /* Verify input parameter */ @@ -134,6 +134,10 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) env_removevar(group, ret); } + /* Check current envirments count */ + + DEBUGASSERT(group->tg_envc < SSIZE_MAX); + /* Get the size of the new name=value string. * The +2 is for the '=' and for null terminator */ @@ -151,11 +155,7 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) if (group->tg_envp) { - while (group->tg_envp[envc] != NULL) - { - envc++; - } - + envc = group->tg_envc; envp = group_realloc(group, group->tg_envp, sizeof(*envp) * (envc + 2)); if (envp == NULL) @@ -177,9 +177,10 @@ int setenv(FAR const char *name, FAR const char *value, int overwrite) envp[envc++] = pvar; envp[envc] = NULL; - /* Save the new buffer */ + /* Save the new buffer and count */ group->tg_envp = envp; + group->tg_envc = envc; /* Now, put the new name=value string into the environment buffer */ diff --git a/sched/environ/env_unsetenv.c b/sched/environ/env_unsetenv.c index 62f9fd8a99..8e18b29229 100644 --- a/sched/environ/env_unsetenv.c +++ b/sched/environ/env_unsetenv.c @@ -61,7 +61,7 @@ int unsetenv(FAR const char *name) { FAR struct tcb_s *rtcb = this_task(); FAR struct task_group_s *group = rtcb->group; - int idx; + ssize_t idx; DEBUGASSERT(group); diff --git a/sched/environ/environ.h b/sched/environ/environ.h index 15aeceb0f5..615306c736 100644 --- a/sched/environ/environ.h +++ b/sched/environ/environ.h @@ -120,7 +120,7 @@ void env_release(FAR struct task_group_s *group); * ****************************************************************************/ -int env_findvar(FAR struct task_group_s *group, FAR const char *pname); +ssize_t env_findvar(FAR struct task_group_s *group, FAR const char *pname); /**************************************************************************** * Name: env_removevar @@ -143,7 +143,7 @@ int env_findvar(FAR struct task_group_s *group, FAR const char *pname); * ****************************************************************************/ -void env_removevar(FAR struct task_group_s *group, int index); +void env_removevar(FAR struct task_group_s *group, ssize_t index); #undef EXTERN #ifdef __cplusplus