From: Lucas De Marchi Date: Tue, 6 Dec 2011 05:38:37 +0000 (-0200) Subject: Maintain a pool of modules alive X-Git-Tag: v1~83 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=fd186ae9965d1c43c65435af29ee06648c30e06c;p=thirdparty%2Fkmod.git Maintain a pool of modules alive Based on previous implementation by Gustavo Sverzut Barbieri --- diff --git a/libkmod/libkmod-module.c b/libkmod/libkmod-module.c index 9c8a627a..432f453f 100644 --- a/libkmod/libkmod-module.c +++ b/libkmod/libkmod-module.c @@ -144,6 +144,12 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, path_to_modname(name, name_norm, &namelen); + m = kmod_pool_get_module(ctx, name_norm); + if (m != NULL) { + *mod = kmod_module_ref(m); + return 0; + } + m = calloc(1, sizeof(*m) + namelen + 1); if (m == NULL) { free(m); @@ -154,6 +160,8 @@ KMOD_EXPORT int kmod_module_new_from_name(struct kmod_ctx *ctx, memcpy(m->name, name_norm, namelen + 1); m->refcount = 1; + kmod_pool_add_module(ctx, m); + *mod = m; return 0; @@ -178,6 +186,12 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx, path_to_modname(path, name, &namelen); + m = kmod_pool_get_module(ctx, name); + if (m != NULL) { + *mod = kmod_module_ref(m); + return 0; + } + m = calloc(1, sizeof(*m) + namelen + 1); if (m == NULL) return -errno; @@ -193,6 +207,8 @@ KMOD_EXPORT int kmod_module_new_from_path(struct kmod_ctx *ctx, memcpy(m->name, name, namelen); m->refcount = 1; + kmod_pool_add_module(ctx, m); + *mod = m; return 0; diff --git a/libkmod/libkmod-private.h b/libkmod/libkmod-private.h index 5479cc95..f1e03500 100644 --- a/libkmod/libkmod-private.h +++ b/libkmod/libkmod-private.h @@ -66,12 +66,19 @@ struct kmod_list *kmod_list_append_list(struct kmod_list *list1, struct kmod_lis /* libkmod.c */ const char *kmod_get_dirname(const struct kmod_ctx *ctx) __attribute__((nonnull(1))); + int kmod_lookup_alias_from_config(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); int kmod_lookup_alias_from_symbols_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); int kmod_lookup_alias_from_aliases_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); int kmod_lookup_alias_from_moddep_file(struct kmod_ctx *ctx, const char *name, struct kmod_list **list) __attribute__((nonnull(1, 2, 3))); + char *kmod_search_moddep(struct kmod_ctx *ctx, const char *name) __attribute__((nonnull(1,2))); +struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx, const char *name) __attribute__((nonnull(1,2))); +void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod) __attribute__((nonnull(1,2))); +void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod) __attribute__((nonnull(1,2))); + + /* libkmod-config.c */ struct kmod_config { struct kmod_ctx *ctx; diff --git a/libkmod/libkmod.c b/libkmod/libkmod.c index 248203b3..fa1fdbbb 100644 --- a/libkmod/libkmod.c +++ b/libkmod/libkmod.c @@ -33,6 +33,9 @@ #include "libkmod-private.h" #include "libkmod-index.h" +#define KMOD_HASH_SIZE (256) +#define KMOD_LRU_MAX (128) + /** * SECTION:libkmod * @short_description: libkmod context @@ -55,6 +58,7 @@ struct kmod_ctx { const void *userdata; char *dirname; struct kmod_config *config; + struct kmod_hash *modules_by_name; }; void kmod_log(struct kmod_ctx *ctx, @@ -181,16 +185,26 @@ KMOD_EXPORT struct kmod_ctx *kmod_new(const char *dirname) err = kmod_config_new(ctx, &ctx->config); if (err < 0) { - ERR(ctx, "could not create config"); - free(ctx->dirname); - free(ctx); - return NULL; + ERR(ctx, "could not create config\n"); + goto fail; + } + + ctx->modules_by_name = kmod_hash_new(KMOD_HASH_SIZE, NULL); + if (ctx->modules_by_name == NULL) { + ERR(ctx, "could not create by-name hash\n"); + goto fail; } INFO(ctx, "ctx %p created\n", ctx); DBG(ctx, "log_priority=%d\n", ctx->log_priority); return ctx; + +fail: + free(ctx->modules_by_name); + free(ctx->dirname); + free(ctx); + return NULL; } /** @@ -225,6 +239,7 @@ KMOD_EXPORT struct kmod_ctx *kmod_unref(struct kmod_ctx *ctx) if (--ctx->refcount > 0) return ctx; INFO(ctx, "context %p released\n", ctx); + kmod_hash_free(ctx->modules_by_name); free(ctx->dirname); if (ctx->config) kmod_config_free(ctx->config); @@ -276,6 +291,35 @@ KMOD_EXPORT void kmod_set_log_priority(struct kmod_ctx *ctx, int priority) ctx->log_priority = priority; } +struct kmod_module *kmod_pool_get_module(struct kmod_ctx *ctx, + const char *name) +{ + struct kmod_module *mod; + + mod = kmod_hash_find(ctx->modules_by_name, name); + + DBG(ctx, "get module name='%s' found=%p\n", name, mod); + + return mod; +} + +void kmod_pool_add_module(struct kmod_ctx *ctx, struct kmod_module *mod) +{ + const char *name = kmod_module_get_name(mod); + + DBG(ctx, "add %p name='%s'\n", mod, name); + + kmod_hash_add(ctx->modules_by_name, name, mod); +} + +void kmod_pool_del_module(struct kmod_ctx *ctx, struct kmod_module *mod) +{ + const char *name = kmod_module_get_name(mod); + + DBG(ctx, "del %p name='%s'\n", mod, name); + + kmod_hash_del(ctx->modules_by_name, name); +} static int kmod_lookup_alias_from_alias_bin(struct kmod_ctx *ctx, const char *file,