]>
Commit | Line | Data |
---|---|---|
0bfe3ca5 AL |
1 | /* |
2 | * QEMU Module Infrastructure | |
3 | * | |
4 | * Copyright IBM, Corp. 2009 | |
5 | * | |
6 | * Authors: | |
7 | * Anthony Liguori <aliguori@us.ibm.com> | |
8 | * | |
9 | * This work is licensed under the terms of the GNU GPL, version 2. See | |
10 | * the COPYING file in the top-level directory. | |
11 | * | |
12 | */ | |
13 | ||
14 | #include "qemu-common.h" | |
15 | #include "sys-queue.h" | |
16 | #include "module.h" | |
17 | ||
18 | typedef struct ModuleEntry | |
19 | { | |
20 | module_init_type type; | |
21 | void (*init)(void); | |
22 | TAILQ_ENTRY(ModuleEntry) node; | |
23 | } ModuleEntry; | |
24 | ||
25 | typedef struct ModuleTypeList | |
26 | { | |
27 | module_init_type type; | |
28 | TAILQ_HEAD(, ModuleEntry) entry_list; | |
29 | TAILQ_ENTRY(ModuleTypeList) node; | |
30 | } ModuleTypeList; | |
31 | ||
32 | static TAILQ_HEAD(, ModuleTypeList) init_type_list; | |
33 | ||
34 | static ModuleTypeList *find_type_or_alloc(module_init_type type, int alloc) | |
35 | { | |
36 | ModuleTypeList *n; | |
37 | ||
38 | TAILQ_FOREACH(n, &init_type_list, node) { | |
39 | if (type >= n->type) | |
40 | break; | |
41 | } | |
42 | ||
43 | if (!n || n->type != type) { | |
44 | ModuleTypeList *o; | |
45 | ||
46 | if (!alloc) | |
47 | return NULL; | |
48 | ||
49 | o = qemu_mallocz(sizeof(*o)); | |
50 | o->type = type; | |
51 | TAILQ_INIT(&o->entry_list); | |
52 | ||
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 | } | |
58 | ||
59 | n = o; | |
60 | } | |
61 | ||
62 | return n; | |
63 | } | |
64 | ||
65 | void register_module_init(void (*fn)(void), module_init_type type) | |
66 | { | |
67 | ModuleEntry *e; | |
68 | ModuleTypeList *l; | |
69 | ||
70 | e = qemu_mallocz(sizeof(*e)); | |
71 | e->init = fn; | |
72 | ||
73 | l = find_type_or_alloc(type, 1); | |
74 | ||
75 | TAILQ_INSERT_TAIL(&l->entry_list, e, node); | |
76 | } | |
77 | ||
78 | void module_call_init(module_init_type type) | |
79 | { | |
80 | ModuleTypeList *l; | |
81 | ModuleEntry *e; | |
82 | ||
83 | l = find_type_or_alloc(type, 0); | |
84 | if (!l) { | |
85 | return; | |
86 | } | |
87 | ||
88 | TAILQ_FOREACH(e, &l->entry_list, node) { | |
89 | e->init(); | |
90 | } | |
91 | } |