Commit f7897430950ee94fb2dc4d6a5ca658d4909d9d85
1 parent
4af39611
Fix module initialization when more than 1 class is in use
Now that we're using enums for module types, it makes no sense to bother keeping a list of module types when we know exactly how many they are. Switching to an array simplifies the code and eliminates the aforementioned bug. Signed-off-by: Anthony Liguori <aliguori@us.ibm.com>
Showing
2 changed files
with
26 additions
and
36 deletions
module.c
... | ... | @@ -22,44 +22,36 @@ typedef struct ModuleEntry |
22 | 22 | TAILQ_ENTRY(ModuleEntry) node; |
23 | 23 | } ModuleEntry; |
24 | 24 | |
25 | -typedef struct ModuleTypeList | |
26 | -{ | |
27 | - module_init_type type; | |
28 | - TAILQ_HEAD(, ModuleEntry) entry_list; | |
29 | - TAILQ_ENTRY(ModuleTypeList) node; | |
30 | -} ModuleTypeList; | |
25 | +typedef TAILQ_HEAD(, ModuleEntry) ModuleTypeList; | |
31 | 26 | |
32 | -static TAILQ_HEAD(, ModuleTypeList) init_type_list; | |
27 | +static ModuleTypeList init_type_list[MODULE_INIT_MAX]; | |
33 | 28 | |
34 | -static ModuleTypeList *find_type_or_alloc(module_init_type type, int alloc) | |
29 | +static void init_types(void) | |
35 | 30 | { |
36 | - ModuleTypeList *n; | |
31 | + static int inited; | |
32 | + int i; | |
37 | 33 | |
38 | - TAILQ_FOREACH(n, &init_type_list, node) { | |
39 | - if (type >= n->type) | |
40 | - break; | |
34 | + if (inited) { | |
35 | + return; | |
41 | 36 | } |
42 | 37 | |
43 | - if (!n || n->type != type) { | |
44 | - ModuleTypeList *o; | |
38 | + for (i = 0; i < MODULE_INIT_MAX; i++) { | |
39 | + TAILQ_INIT(&init_type_list[i]); | |
40 | + } | |
45 | 41 | |
46 | - if (!alloc) | |
47 | - return NULL; | |
42 | + inited = 1; | |
43 | +} | |
48 | 44 | |
49 | - o = qemu_mallocz(sizeof(*o)); | |
50 | - o->type = type; | |
51 | - TAILQ_INIT(&o->entry_list); | |
52 | 45 | |
53 | - if (n) { | |
54 | - TAILQ_INSERT_AFTER(&init_type_list, n, o, node); | |
55 | - } else { | |
56 | - TAILQ_INSERT_HEAD(&init_type_list, o, node); | |
57 | - } | |
46 | +static ModuleTypeList *find_type(module_init_type type) | |
47 | +{ | |
48 | + ModuleTypeList *l; | |
58 | 49 | |
59 | - n = o; | |
60 | - } | |
50 | + init_types(); | |
51 | + | |
52 | + l = &init_type_list[type]; | |
61 | 53 | |
62 | - return n; | |
54 | + return l; | |
63 | 55 | } |
64 | 56 | |
65 | 57 | void register_module_init(void (*fn)(void), module_init_type type) |
... | ... | @@ -70,9 +62,9 @@ void register_module_init(void (*fn)(void), module_init_type type) |
70 | 62 | e = qemu_mallocz(sizeof(*e)); |
71 | 63 | e->init = fn; |
72 | 64 | |
73 | - l = find_type_or_alloc(type, 1); | |
65 | + l = find_type(type); | |
74 | 66 | |
75 | - TAILQ_INSERT_TAIL(&l->entry_list, e, node); | |
67 | + TAILQ_INSERT_TAIL(l, e, node); | |
76 | 68 | } |
77 | 69 | |
78 | 70 | void module_call_init(module_init_type type) |
... | ... | @@ -80,12 +72,9 @@ void module_call_init(module_init_type type) |
80 | 72 | ModuleTypeList *l; |
81 | 73 | ModuleEntry *e; |
82 | 74 | |
83 | - l = find_type_or_alloc(type, 0); | |
84 | - if (!l) { | |
85 | - return; | |
86 | - } | |
75 | + l = find_type(type); | |
87 | 76 | |
88 | - TAILQ_FOREACH(e, &l->entry_list, node) { | |
77 | + TAILQ_FOREACH(e, l, node) { | |
89 | 78 | e->init(); |
90 | 79 | } |
91 | 80 | } | ... | ... |
module.h
... | ... | @@ -17,12 +17,13 @@ |
17 | 17 | /* This should not be used directly. Use block_init etc. instead. */ |
18 | 18 | #define module_init(function, type) \ |
19 | 19 | static void __attribute__((constructor)) do_qemu_init_ ## function(void) { \ |
20 | - register_module_init(function, type); \ | |
20 | + register_module_init(function, type); \ | |
21 | 21 | } |
22 | 22 | |
23 | 23 | typedef enum { |
24 | 24 | MODULE_INIT_BLOCK, |
25 | - MODULE_INIT_DEVICE | |
25 | + MODULE_INIT_DEVICE, | |
26 | + MODULE_INIT_MAX | |
26 | 27 | } module_init_type; |
27 | 28 | |
28 | 29 | #define block_init(function) module_init(function, MODULE_INIT_BLOCK) | ... | ... |