diff options
author | Timo Teräs | 2015-11-05 18:54:55 +0100 |
---|---|---|
committer | Denys Vlasenko | 2015-11-05 18:54:55 +0100 |
commit | 48dc80bbba994eee24ed94ae4532a1cce76d7cb7 (patch) | |
tree | 051e7aacf5538ffc07310bb4261a693a047311d2 /modutils/modutils.c | |
parent | 34adecc2b049f6941c5e075ffb58fe2183823da3 (diff) | |
download | busybox-48dc80bbba994eee24ed94ae4532a1cce76d7cb7.zip busybox-48dc80bbba994eee24ed94ae4532a1cce76d7cb7.tar.gz |
modutils: merge module_entry and module_info to common
This merges the in-memory module info structures of modprobe
and depmod. This allows sharing hashing by modulename code
improving depmod runtime with almost factor of 2x.
function old new delta
get_or_add_modentry - 17 +17
do_modprobe 590 601 +11
moddb_get_or_create - 10 +10
load_modules_dep 195 205 +10
moddb_get - 7 +7
add_probe 81 78 -3
modprobe_main 721 714 -7
depmod_main 553 543 -10
config_file_action 434 421 -13
helper_get_module 160 144 -16
parse_module 343 320 -23
order_dep_list 105 82 -23
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 2/7 up/down: 55/-95) Total: -40 bytes
Signed-off-by: Timo Teräs <timo.teras@iki.fi>
Signed-off-by: Denys Vlasenko <vda.linux@googlemail.com>
Diffstat (limited to 'modutils/modutils.c')
-rw-r--r-- | modutils/modutils.c | 51 |
1 files changed, 51 insertions, 0 deletions
diff --git a/modutils/modutils.c b/modutils/modutils.c index ef4134a..8e9eef7 100644 --- a/modutils/modutils.c +++ b/modutils/modutils.c @@ -16,6 +16,57 @@ extern int delete_module(const char *module, unsigned int flags); # define delete_module(mod, flags) syscall(__NR_delete_module, mod, flags) #endif +static module_entry *helper_get_module(module_db *db, const char *module, int create) +{ + char modname[MODULE_NAME_LEN]; + struct module_entry *e; + unsigned i, hash; + + filename2modname(module, modname); + + hash = 0; + for (i = 0; modname[i]; i++) + hash = ((hash << 5) + hash) + modname[i]; + hash %= MODULE_HASH_SIZE; + + for (e = db->buckets[hash]; e; e = e->next) + if (strcmp(e->modname, modname) == 0) + return e; + if (!create) + return NULL; + + e = xzalloc(sizeof(*e)); + e->modname = xstrdup(modname); + e->next = db->buckets[hash]; + db->buckets[hash] = e; + e->dnext = e->dprev = e; + + return e; +} +module_entry* FAST_FUNC moddb_get(module_db *db, const char *module) +{ + return helper_get_module(db, module, 0); +} +module_entry* FAST_FUNC moddb_get_or_create(module_db *db, const char *module) +{ + return helper_get_module(db, module, 1); +} + +void FAST_FUNC moddb_free(module_db *db) +{ + module_entry *e, *n; + unsigned i; + + for (i = 0; i < MODULE_HASH_SIZE; i++) { + for (e = db->buckets[i]; e; e = n) { + n = e->next; + free(e->name); + free(e->modname); + free(e); + } + } +} + void FAST_FUNC replace(char *s, char what, char with) { while (*s) { |