Reduce the memory allocation using json_memhead & main_memhead

(cherry picked from commit d17f7f23fa)
This commit is contained in:
Amin Ben Ramdhane 2022-07-27 11:48:42 +01:00 committed by Vivek Kumar Dutta
parent a18a919de0
commit 6a5a73ecc4
3 changed files with 48 additions and 46 deletions

View file

@ -12,6 +12,7 @@
#include "dmdynamicjson.h" #include "dmdynamicjson.h"
#include "dmentry.h" #include "dmentry.h"
#define MAX_DM_LENGTH (1024)
#define json_object_get_string(x) (char *)json_object_get_string(x) #define json_object_get_string(x) (char *)json_object_get_string(x)
static LIST_HEAD(loaded_json_files); static LIST_HEAD(loaded_json_files);
@ -145,10 +146,9 @@ int free_json_dynamic_arrays(DMOBJ *dm_entryobj)
return 0; return 0;
} }
static char *find_prefix_obj(char *full_obj) static void find_prefix_obj(char *full_obj, char *prefix_obj, size_t len)
{ {
int last_occurent = 0, occur = 0; int last_occurent = 0, occur = 0;
char *prefix_obj = "";
char *full_object = replace_str(full_obj, ".{i}.", "."); char *full_object = replace_str(full_obj, ".{i}.", ".");
for (int i = 0; full_object[i] != 0; i++) { for (int i = 0; full_object[i] != 0; i++) {
@ -160,16 +160,13 @@ static char *find_prefix_obj(char *full_obj)
} }
*(full_object + last_occurent + 1) = 0; *(full_object + last_occurent + 1) = 0;
prefix_obj = dm_dynamic_strdup(&json_memhead, full_object); snprintf(prefix_obj, len, "%s", full_object);
dmfree(full_object); dmfree(full_object);
return prefix_obj;
} }
static char *find_current_obj(char *full_obj) static void find_current_obj(char *full_obj, char *curr_obj, size_t len)
{ {
int last_occurent = 0, occur = 0; int last_occurent = 0, occur = 0;
char *curr_obj = "";
char *full_object = replace_str(full_obj, ".{i}.", "."); char *full_object = replace_str(full_obj, ".{i}.", ".");
for (int i = 0; full_object[i] != 0; i++) { for (int i = 0; full_object[i] != 0; i++) {
@ -181,32 +178,26 @@ static char *find_current_obj(char *full_obj)
} }
full_object[occur] = 0; full_object[occur] = 0;
curr_obj = dm_dynamic_strdup(&json_memhead, full_object + last_occurent + 1); snprintf(curr_obj, len, "%s", full_object + last_occurent + 1);
dmfree(full_object); dmfree(full_object);
return curr_obj;
} }
static char *generate_path_without_instance(char *full_obj, bool is_obj) static void generate_path_without_instance(char *full_obj, bool is_obj, char *obj_path, size_t len)
{ {
char *pch = NULL, *pchr = NULL; char *pch = NULL, *pchr = NULL;
char buf[1024] = {0}; char str[MAX_DM_LENGTH] = {0};
int pos = 0; int pos = 0;
char *str = dm_dynamic_strdup(&json_memhead, full_obj); snprintf(str, MAX_DM_LENGTH, "%s", full_obj);
for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) {
if (DM_STRTOL(pch) == 0 && strcmp(pch, "{i}") != 0) { if (DM_STRTOL(pch) == 0 && strcmp(pch, "{i}") != 0) {
pos += snprintf(buf + pos, sizeof(buf) - pos, "%s.", pch); pos += snprintf(obj_path + pos, len - pos, "%s.", pch);
} }
} }
if (pos && !is_obj) if (pos && !is_obj)
buf[pos - 1] = 0; obj_path[pos - 1] = 0;
dmfree(str);
return dm_dynamic_strdup(&json_memhead, buf);
} }
static int get_index_of_available_entry(DMOBJ *jentryobj) static int get_index_of_available_entry(DMOBJ *jentryobj)
@ -373,9 +364,10 @@ static int browse_obj(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data,
struct json_object *mapping_obj = NULL; struct json_object *mapping_obj = NULL;
struct json_object *mapping_0 = NULL; struct json_object *mapping_0 = NULL;
struct json_object *type = NULL; struct json_object *type = NULL;
char obj[MAX_DM_LENGTH] = {0};
int json_version = JSON_VERSION_0; int json_version = JSON_VERSION_0;
char *obj = generate_path_without_instance(parent_node->current_object, true); generate_path_without_instance(parent_node->current_object, true, obj, MAX_DM_LENGTH);
list_for_each_entry(pobj, &json_list, list) { list_for_each_entry(pobj, &json_list, list) {
if (DM_STRCMP(pobj->name, obj) == 0) { if (DM_STRCMP(pobj->name, obj) == 0) {
mapping_obj = pobj->data; mapping_obj = pobj->data;
@ -392,7 +384,7 @@ static int browse_obj(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data,
} }
if (type && strcmp(json_object_get_string(type), "uci") == 0) { if (type && strcmp(json_object_get_string(type), "uci") == 0) {
char buf_instance[64], buf_alias[64], *object = NULL; char buf_instance[128], buf_alias[128], object[64] = {0};
struct json_object *uci_obj = NULL; struct json_object *uci_obj = NULL;
struct json_object *file = NULL; struct json_object *file = NULL;
struct json_object *section = NULL; struct json_object *section = NULL;
@ -408,7 +400,7 @@ static int browse_obj(struct dmctx *dmctx, DMNODE *parent_node, void *prev_data,
json_object_object_get_ex(section, "type", &section_type); json_object_object_get_ex(section, "type", &section_type);
json_object_object_get_ex(uci_obj, "dmmapfile", &dmmap_file); json_object_object_get_ex(uci_obj, "dmmapfile", &dmmap_file);
object = find_current_obj(parent_node->current_object); find_current_obj(parent_node->current_object, object, sizeof(object));
snprintf(buf_instance, sizeof(buf_instance), "%s_instance", object); snprintf(buf_instance, sizeof(buf_instance), "%s_instance", object);
snprintf(buf_alias, sizeof(buf_alias), "%s_alias", object); snprintf(buf_alias, sizeof(buf_alias), "%s_alias", object);
for (int i = 0; buf_instance[i]; i++) for (int i = 0; buf_instance[i]; i++)
@ -494,9 +486,10 @@ static int add_obj(char *refparam, struct dmctx *ctx, void *data, char **instanc
struct json_object *mapping_obj = NULL; struct json_object *mapping_obj = NULL;
struct json_object *mapping_0 = NULL; struct json_object *mapping_0 = NULL;
struct json_object *obj_type = NULL; struct json_object *obj_type = NULL;
char obj[MAX_DM_LENGTH] = {0};
int json_version = JSON_VERSION_0; int json_version = JSON_VERSION_0;
char *obj = generate_path_without_instance(refparam, true); generate_path_without_instance(refparam, true, obj, MAX_DM_LENGTH);
list_for_each_entry(pobj, &json_list, list) { list_for_each_entry(pobj, &json_list, list) {
if (DM_STRCMP(pobj->name, obj) == 0) { if (DM_STRCMP(pobj->name, obj) == 0) {
mapping_obj = pobj->data; mapping_obj = pobj->data;
@ -518,7 +511,7 @@ static int add_obj(char *refparam, struct dmctx *ctx, void *data, char **instanc
struct json_object *section = NULL; struct json_object *section = NULL;
struct json_object *section_type = NULL; struct json_object *section_type = NULL;
struct json_object *dmmap_file = NULL; struct json_object *dmmap_file = NULL;
char *object = NULL; char object[64] = {0};
char buf_instance[128]; char buf_instance[128];
char sec_name[128]; char sec_name[128];
@ -528,7 +521,7 @@ static int add_obj(char *refparam, struct dmctx *ctx, void *data, char **instanc
json_object_object_get_ex(section, "type", &section_type); json_object_object_get_ex(section, "type", &section_type);
json_object_object_get_ex(uci_obj, "dmmapfile", &dmmap_file); json_object_object_get_ex(uci_obj, "dmmapfile", &dmmap_file);
object = find_current_obj(refparam); find_current_obj(refparam, object, sizeof(object));
snprintf(buf_instance, sizeof(buf_instance), "%s_instance", object); snprintf(buf_instance, sizeof(buf_instance), "%s_instance", object);
snprintf(sec_name, sizeof(sec_name), "%s%s_%s", data ? section_name((struct uci_section *)data) : "", object, *instance); snprintf(sec_name, sizeof(sec_name), "%s%s_%s", data ? section_name((struct uci_section *)data) : "", object, *instance);
@ -561,9 +554,10 @@ static int delete_obj(char *refparam, struct dmctx *ctx, void *data, char *insta
struct json_object *mapping_obj = NULL; struct json_object *mapping_obj = NULL;
struct json_object *mapping_0 = NULL; struct json_object *mapping_0 = NULL;
struct json_object *type_obj = NULL; struct json_object *type_obj = NULL;
char obj[MAX_DM_LENGTH] = {0};
int json_version = JSON_VERSION_0; int json_version = JSON_VERSION_0;
char *obj = generate_path_without_instance(refparam, true); generate_path_without_instance(refparam, true, obj, MAX_DM_LENGTH);
list_for_each_entry(pobj, &json_list, list) { list_for_each_entry(pobj, &json_list, list) {
if (DM_STRCMP(pobj->name, obj) == 0) { if (DM_STRCMP(pobj->name, obj) == 0) {
mapping_obj = pobj->data; mapping_obj = pobj->data;
@ -901,9 +895,10 @@ static int getvalue_param(char *refparam, struct dmctx *ctx, void *data, char *i
{ {
struct dm_json_obj *pleaf = NULL; struct dm_json_obj *pleaf = NULL;
json_object *param_obj = NULL; json_object *param_obj = NULL;
char obj[MAX_DM_LENGTH] = {0};
int json_version = JSON_VERSION_0; int json_version = JSON_VERSION_0;
char *obj = generate_path_without_instance(refparam, false); generate_path_without_instance(refparam, false, obj, MAX_DM_LENGTH);
list_for_each_entry(pleaf, &json_list, list) { list_for_each_entry(pleaf, &json_list, list) {
if (DM_STRCMP(pleaf->name, obj) == 0) { if (DM_STRCMP(pleaf->name, obj) == 0) {
param_obj = pleaf->data; param_obj = pleaf->data;
@ -977,9 +972,10 @@ static int ubus_set_operate(json_object *mapping_obj, int json_version, char *re
static int linker_obj(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker) static int linker_obj(char *refparam, struct dmctx *dmctx, void *data, char *instance, char **linker)
{ {
struct dm_json_obj *pobj = NULL; struct dm_json_obj *pobj = NULL;
char obj[MAX_DM_LENGTH] = {0};
const char **keys = NULL; const char **keys = NULL;
char *obj = generate_path_without_instance(refparam, true); generate_path_without_instance(refparam, true, obj, MAX_DM_LENGTH);
list_for_each_entry(pobj, &json_list, list) { list_for_each_entry(pobj, &json_list, list) {
if (DM_STRCMP(pobj->name, obj) == 0) { if (DM_STRCMP(pobj->name, obj) == 0) {
keys = pobj->event_arg.param; keys = pobj->event_arg.param;
@ -1000,9 +996,10 @@ static int linker_obj(char *refparam, struct dmctx *dmctx, void *data, char *ins
static int getcommand_param(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) static int getcommand_param(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{ {
struct dm_json_obj *leaf = NULL; struct dm_json_obj *leaf = NULL;
char obj[MAX_DM_LENGTH] = {0};
bool found = false; bool found = false;
char *obj = generate_path_without_instance(refparam, false); generate_path_without_instance(refparam, false, obj, MAX_DM_LENGTH);
list_for_each_entry(leaf, &json_list, list) { list_for_each_entry(leaf, &json_list, list) {
if (DM_STRCMP(leaf->name, obj) == 0) { if (DM_STRCMP(leaf->name, obj) == 0) {
found = true; found = true;
@ -1023,9 +1020,10 @@ static int setcommand_param(char *refparam, struct dmctx *ctx, void *data, char
{ {
struct dm_json_obj *leaf_node = NULL; struct dm_json_obj *leaf_node = NULL;
struct json_object *p_obj = NULL, *map_arr = NULL, *map_obj = NULL, *type = NULL; struct json_object *p_obj = NULL, *map_arr = NULL, *map_obj = NULL, *type = NULL;
char obj[MAX_DM_LENGTH] = {0};
int json_version = JSON_VERSION_0; int json_version = JSON_VERSION_0;
char *obj = generate_path_without_instance(refparam, false); generate_path_without_instance(refparam, false, obj, MAX_DM_LENGTH);
list_for_each_entry(leaf_node, &json_list, list) { list_for_each_entry(leaf_node, &json_list, list) {
if (DM_STRCMP(leaf_node->name, obj) == 0) { if (DM_STRCMP(leaf_node->name, obj) == 0) {
p_obj = leaf_node->data; p_obj = leaf_node->data;
@ -1058,9 +1056,10 @@ static int setcommand_param(char *refparam, struct dmctx *ctx, void *data, char
static int getevent_param(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) static int getevent_param(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{ {
struct dm_json_obj *leaf = NULL; struct dm_json_obj *leaf = NULL;
char obj[MAX_DM_LENGTH] = {0};
bool found = false; bool found = false;
char *obj = generate_path_without_instance(refparam, false); generate_path_without_instance(refparam, false, obj, MAX_DM_LENGTH);
list_for_each_entry(leaf, &json_list, list) { list_for_each_entry(leaf, &json_list, list) {
if (DM_STRCMP(leaf->name, obj) == 0) { if (DM_STRCMP(leaf->name, obj) == 0) {
found = true; found = true;
@ -1463,9 +1462,10 @@ static int setvalue_param(char *refparam, struct dmctx *ctx, void *data, char *i
{ {
struct dm_json_obj *pleaf = NULL; struct dm_json_obj *pleaf = NULL;
json_object *param_obj = NULL; json_object *param_obj = NULL;
char obj[MAX_DM_LENGTH] = {0};
int json_version = JSON_VERSION_0; int json_version = JSON_VERSION_0;
char *obj = generate_path_without_instance(refparam, false); generate_path_without_instance(refparam, false, obj, MAX_DM_LENGTH);
list_for_each_entry(pleaf, &json_list, list) { list_for_each_entry(pleaf, &json_list, list) {
if (DM_STRCMP(pleaf->name, obj) == 0) { if (DM_STRCMP(pleaf->name, obj) == 0) {
param_obj = pleaf->data; param_obj = pleaf->data;
@ -1730,17 +1730,19 @@ static void parse_obj(char *object, json_object *jobj, DMOBJ *pobj, int index, i
DMOBJ *next_obj = NULL; DMOBJ *next_obj = NULL;
DMLEAF *next_leaf = NULL; DMLEAF *next_leaf = NULL;
char **keys_p = NULL; char **keys_p = NULL;
char curr_obj[128] = {0};
count_obj_param_under_jsonobj(jobj, &obj_number, &param_number); count_obj_param_under_jsonobj(jobj, &obj_number, &param_number);
char *obj_path = replace_str(object, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX); char *obj_path = replace_str(object, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
char *full_obj = replace_str(obj_path, ".{i}.", "."); char *full_obj = replace_str(obj_path, ".{i}.", ".");
char *curr_obj = find_current_obj(full_obj); find_current_obj(full_obj, curr_obj, sizeof(curr_obj));
dmfree(obj_path);
if (!pobj) if (!pobj)
return; return;
//OBJ //OBJ
pobj[index].obj = curr_obj; pobj[index].obj = dm_dynamic_strdup(&json_memhead, curr_obj);
//nextobj //nextobj
if (obj_number != 0) if (obj_number != 0)
@ -1866,9 +1868,10 @@ int load_json_dynamic_arrays(struct dmctx *ctx)
} }
DMOBJ *dm_entryobj = NULL; DMOBJ *dm_entryobj = NULL;
char obj_prefix[MAX_DM_LENGTH] = {0};
char *obj_path = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX); char *obj_path = replace_str(key, "{BBF_VENDOR_PREFIX}", BBF_VENDOR_PREFIX);
char *obj_prefix = find_prefix_obj(obj_path); find_prefix_obj(obj_path, obj_prefix, MAX_DM_LENGTH);
bool obj_exists = find_root_entry(ctx, obj_prefix, &dm_entryobj); bool obj_exists = find_root_entry(ctx, obj_prefix, &dm_entryobj);
if (obj_exists == 0 || !dm_entryobj) if (obj_exists == 0 || !dm_entryobj)

View file

@ -119,31 +119,28 @@ static bool operate_find_root_entry(struct dmctx *ctx, char *in_param, DMOBJ **r
} }
static char *get_path_without_instance(char *path) static void get_path_without_instance(char *path, char *operate_path, size_t len)
{ {
char *pch = NULL, *pchr = NULL; char *pch = NULL, *pchr = NULL;
char res_path[512] = {0}; char str[1024] = {0};
unsigned pos = 0; unsigned pos = 0;
char *str = dm_dynamic_strdup(&library_memhead, path); snprintf(str, sizeof(str), "%s", path);
res_path[0] = 0; operate_path[0] = 0;
for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) { for (pch = strtok_r(str, ".", &pchr); pch != NULL; pch = strtok_r(NULL, ".", &pchr)) {
if (DM_STRTOL(pch) == 0 && strcmp(pch, "{i}") != 0) if (DM_STRTOL(pch) == 0 && strcmp(pch, "{i}") != 0)
pos += snprintf(&res_path[pos], sizeof(res_path) - pos, "%s%s", pch, (pchr != NULL && *pchr != '\0') ? "." : ""); pos += snprintf(&operate_path[pos], len - pos, "%s%s", pch, (pchr != NULL && *pchr != '\0') ? "." : "");
} }
dmfree(str);
return dm_dynamic_strdup(&library_memhead, res_path);
} }
static int get_dynamic_operate_args(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value) static int get_dynamic_operate_args(char *refparam, struct dmctx *ctx, void *data, char *instance, char **value)
{ {
struct dynamic_operate *dyn_operate = NULL; struct dynamic_operate *dyn_operate = NULL;
operation_args *operate_args = NULL; operation_args *operate_args = NULL;
char operate_path[1024] = {0};
char *operate_path = get_path_without_instance(refparam); get_path_without_instance(refparam, operate_path, sizeof(operate_path));
list_for_each_entry(dyn_operate, &dynamic_operate_list, list) { list_for_each_entry(dyn_operate, &dynamic_operate_list, list) {
if (DM_STRCMP(dyn_operate->operate_path, operate_path) == 0) { if (DM_STRCMP(dyn_operate->operate_path, operate_path) == 0) {
operate_args = (operation_args *)dyn_operate->operate_args; operate_args = (operation_args *)dyn_operate->operate_args;
@ -159,8 +156,9 @@ static int dynamic_operate_leaf(char *refparam, struct dmctx *ctx, void *data, c
{ {
struct dynamic_operate *dyn_operate = NULL; struct dynamic_operate *dyn_operate = NULL;
operation operate_func = NULL; operation operate_func = NULL;
char operate_path[1024] = {0};
char *operate_path = get_path_without_instance(refparam); get_path_without_instance(refparam, operate_path, sizeof(operate_path));
list_for_each_entry(dyn_operate, &dynamic_operate_list, list) { list_for_each_entry(dyn_operate, &dynamic_operate_list, list) {
if (DM_STRCMP(dyn_operate->operate_path, operate_path) == 0) { if (DM_STRCMP(dyn_operate->operate_path, operate_path) == 0) {
operate_func = (operation)dyn_operate->operate; operate_func = (operation)dyn_operate->operate;

View file

@ -130,6 +130,7 @@ static void check_killed_process(void)
continue; continue;
list_del(&entry->list); list_del(&entry->list);
dmfree(entry);
} }
} }