Better sparse support.
[bertos.git] / cfg / module.h
1 /**
2  * \file
3  * <!--
4  * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
5  * This file is part of DevLib - See README.devlib for information.
6  * -->
7  *
8  * \brief Debug macros for inter-module dependency checking.
9  *
10  * These macros expand to nothing in release builds.  In debug
11  * builds, they perform run-time dependency checks for modules.
12  *
13  * The usage pattern looks like this:
14  *
15  * \code
16  * MOD_DEFINE(phaser)
17  *
18  * void phaser_init(void)
19  * {
20  *     MOD_CHECK(computer);
21  *     MOD_CHECK(warp_core);
22  *
23  *    [...charge weapons...]
24  *
25  *    MOD_INIT(phaser);
26  * }
27  *
28  * void phaser_cleanup(void)
29  * {
30  *    MOD_CLEANUP(phaser);
31  *
32  *    [...disarm phaser...]
33  * }
34  * \endcode
35  *
36  * \version $Id$
37  * \author Bernardo Innocenti <bernie@develer.com>
38  */
39 #ifndef CFG_MODULE_H
40 #define CFG_MODULE_H
41
42 #include <cfg/debug.h>
43
44 /**
45  * Declare a global variable for module dependency check.
46  *
47  * \see MOD_INIT(), MOD_CHECK()
48  */
49 #define MOD_DEFINE(module)   DB(extern bool module ## _initialized; bool module ## _initialized;)
50
51 /**
52  * Check that \a module was already initialized.
53  *
54  * Put this check just before accessing any facility
55  * provided by a module that requires prior initialization.
56  *
57  * \see MOD_INIT()
58  */
59
60 #define MOD_CHECK(module) \
61 do { \
62         DB(extern bool module ## _initialized;) \
63         ASSERT(module ## _initialized); \
64 } while (0)
65
66 /**
67  * Mark module as initialized.
68  *
69  * Marking initialization requires the global data
70  * previously defined by MOD_DEFINE().
71  *
72  * To prevent double initialization bugs, an initialized
73  * module must first be cleaned up with MOD_CLEANUP() before
74  * calling MOD_INIT() another time.
75  *
76  * \see MOD_CLEANUP(), MOD_CHECK(), MOD_DEFINE()
77  */
78 #define MOD_INIT(module) \
79 do { \
80         ASSERT(!module ## _initialized); \
81         DB(module ## _initialized = true;) \
82 } while (0)
83
84 /**
85  * Mark module as being no longer initialized.
86  *
87  * Marking initialization requires the global data
88  * previously defined by MOD_DEFINE().
89  *
90  * \see MOD_INIT(), MOD_CHECK(), MOD_DEFINE()
91  */
92 #define MOD_CLEANUP(module) \
93 do { \
94         ASSERT(module ## _initialized); \
95         DB(module ## _initialized = false;) \
96 } while (0)
97
98 #endif /* CFG_MODULE_H */
99