libfdt: Add FDT_CREATE_FLAG_NO_NAME_DEDUP flag that trades size for speed

Searching for duplicate names scales O(n^2) with the number of names
added to a fdt, which can cause a noticable slowdown with larger device
trees and very slow CPU cores.

Add FDT_CREATE_FLAG_NO_NAME_DEDUP that allow the caller to trade fdt size
for speed in the creation process.

Signed-off-by: Nicholas Piggin <npiggin@gmail.com>
Message-Id: <20190509094122.834-4-npiggin@gmail.com>
Signed-off-by: David Gibson <david@gibson.dropbear.id.au>
This commit is contained in:
Nicholas Piggin
2019-05-09 19:41:22 +10:00
committed by David Gibson
parent fbb62754ce
commit ce01b21098
4 changed files with 84 additions and 34 deletions

View File

@@ -114,14 +114,19 @@ int main(int argc, char *argv[])
void *place;
const char place_str[] = "this is a placeholder string\0string2";
int place_len = sizeof(place_str);
int create_flags;
test_init(argc, argv);
if (argc == 1) {
alloc_mode = FIXED;
size = SPACE;
} else if (argc == 2) {
if (streq(argv[1], "resize")) {
alloc_mode = FIXED;
size = SPACE;
create_flags = 0;
if (argc == 2 || argc == 3) {
if (streq(argv[1], "fixed")) {
alloc_mode = FIXED;
size = SPACE;
} else if (streq(argv[1], "resize")) {
alloc_mode = REALLOC;
size = 0;
} else if (streq(argv[1], "realloc")) {
@@ -140,12 +145,36 @@ int main(int argc, char *argv[])
CONFIG("Bad allocation mode \"%s\" specified",
argv[1]);
}
} else {
CONFIG("sw_tree1 <dtb file> [<allocation mode>]");
}
if (argc == 3) {
char *str = argv[2], *saveptr, *tok;
bool default_flag = false;
while ((tok = strtok_r(str, ",", &saveptr)) != NULL) {
str = NULL;
if (streq(tok, "default")) {
default_flag = true;
} else if (streq(tok, "no_name_dedup")) {
create_flags |= FDT_CREATE_FLAG_NO_NAME_DEDUP;
} else if (streq(tok, "bad")) {
create_flags |= 0xffffffff;
} else {
CONFIG("Bad creation flags \"%s\" specified",
argv[2]);
}
}
if (default_flag && create_flags != 0)
CONFIG("Bad creation flags \"%s\" specified",
argv[2]);
}
if (argc > 3) {
CONFIG("sw_tree1 [<allocation mode>] [<create flags>]");
}
fdt = xmalloc(size);
CHECK(fdt_create(fdt, size));
CHECK(fdt_create_with_flags(fdt, size, create_flags));
created = true;