kernel hashtable.h哈希表的动态大小

时间:2016-02-22 17:06:28

标签: c kernel

我写过使用<的模块。 linux / hashtable.h>目前,它工作得非常好,但是我想将它从静态哈希表大小更改为可配置的大小。

我应该如何更改初始化:

DEFINE_HASHTABLE(my_hash_table, 10);

是动态的,所以当模块加载为参数

时,我可以传递哈希表的大小

我试过了 struct hlist_head* my_hash_table及其相应的kmallocs(),但没有成功,并给我这些错误:

include/linux/bug.h:33:45: error: negative width in bit-field ‘<anonymous>’
 #define BUILD_BUG_ON_ZERO(e) (sizeof(struct { int:-!!(e); }))
                                             ^

include/linux/hashtable.h:27:35: note: in definition of macro ‘hash_min’
  (sizeof(val) <= 4 ? hash_32(val, bits) : hash_long(val, bits))
                                   ^

include/linux/hashtable.h:23:25: note: in expansion of macro ‘ilog2’
 #define HASH_BITS(name) ilog2(HASH_SIZE(name))
                         ^

include/linux/compiler-gcc.h:44:28: note: in expansion of macro ‘BUILD_BUG_ON_ZERO’
 #define __must_be_array(a) BUILD_BUG_ON_ZERO(__same_type((a), &(a)[0]))
                            ^

include/linux/kernel.h:54:59: note: in expansion of macro ‘__must_be_array’
 #define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
                                                           ^

include/linux/hashtable.h:22:26: note: in expansion of macro ‘ARRAY_SIZE’
 #define HASH_SIZE(name) (ARRAY_SIZE(name))
                          ^

include/linux/hashtable.h:23:31: note: in expansion of macro ‘HASH_SIZE’
 #define HASH_BITS(name) ilog2(HASH_SIZE(name))
                               ^

include/linux/hashtable.h:56:48: note: in expansion of macro ‘HASH_BITS’
  hlist_add_head(node, &hashtable[hash_min(key, HASH_BITS(hashtable))])
                                                ^

HashTable.c:103:9: note: in expansion of macro ‘hash_add’
         hash_add(my_hash_table, &entry->entry, entry->hashed_key);

2 个答案:

答案 0 :(得分:2)

内核已经支持“动态”哈希表。它被称为 - 相对论哈希表。更多信息和解释如何工作/如何使用它可以在以下非常好的LWN文章中找到:Part 1Part 2

答案 1 :(得分:0)

为了改变......

DEFINE_HASHTABLE(my_hash_table, 10);

...对于动态分配的等价物,你会使用这样的东西:

#define MY_HT_SZ 1024

struct hlist_head *my_hash_table;
int i;

my_hash_table = kmalloc(MY_HT_SZ * sizeof(struct hlist_head), GFP_KERNEL);

if (!my_hash_table)
    goto error_handler;

for (i = 0; i < MY_HT_SZ; i++)
    INIT_HLIST_HEAD(&my_hash_table[i]);