1/*
2 * Copyright 2008, Ingo Weinhold, ingo_weinhold@gmx.de.
3 * Distributed under the terms of the MIT License.
4 */
5#ifndef _KERNEL_DEBUG_PARANOIA_H
6#define _KERNEL_DEBUG_PARANOIA_H
7
8#include <sys/cdefs.h>
9
10#include <SupportDefs.h>
11
12#include "paranoia_config.h"
13
14
15// How to use: Include the header only from source files. Set
16// COMPONENT_PARANOIA_LEVEL before. Use the macros defined below and the
17// ParanoiaChecker class.
18
19// paranoia levels
20#define PARANOIA_NAIVE		0	/* don't do any checks */
21#define PARANOIA_SUSPICIOUS	1	/* do some checks */
22#define PARANOIA_OBSESSIVE	2	/* do a lot of checks */
23#define PARANOIA_INSANE		3	/* do all checks, also very expensive ones */
24
25// mode for set_paranoia_check()
26enum paranoia_set_check_mode {
27	PARANOIA_DONT_FAIL,			// succeed, if check for address exists or not
28	PARANOIA_FAIL_IF_EXISTS,	// fail, if check for address already exists
29	PARANOIA_FAIL_IF_MISSING	// fail, if check for address doesn't exist yet
30};
31
32
33__BEGIN_DECLS
34
35#if ENABLE_PARANOIA_CHECKS
36
37status_t	create_paranoia_check_set(const void* object,
38				const char* description);
39status_t	delete_paranoia_check_set(const void* object);
40status_t	run_paranoia_checks(const void* object);
41
42status_t	set_paranoia_check(const void* object, const void* address,
43				size_t size, paranoia_set_check_mode mode);
44status_t	remove_paranoia_check(const void* object, const void* address,
45				size_t size);
46
47#endif	// ENABLE_PARANOIA_CHECKS
48
49void		debug_paranoia_init();
50
51__END_DECLS
52
53
54#if ENABLE_PARANOIA_CHECKS && COMPONENT_PARANOIA_LEVEL
55#	define PARANOIA_ONLY(x)	x
56#	define PARANOIA_ONLY_LEVEL(level, x)				\
57		if ((level) <= (COMPONENT_PARANOIA_LEVEL)) {	\
58			x;											\
59		}
60#else
61#	define PARANOIA_ONLY(x)
62#	define PARANOIA_ONLY_LEVEL(level, x)
63#endif
64
65#define	CREATE_PARANOIA_CHECK_SET(object, description)	\
66			PARANOIA_ONLY(create_paranoia_check_set((object), (description)))
67#define	DELETE_PARANOIA_CHECK_SET(object)	\
68			PARANOIA_ONLY(delete_paranoia_check_set((object)))
69#define	RUN_PARANOIA_CHECKS(object)	\
70			PARANOIA_ONLY(run_paranoia_checks((object)))
71
72#define	ADD_PARANOIA_CHECK(level, object, address, size)		\
73			PARANOIA_ONLY_LEVEL((level),						\
74				set_paranoia_check((object), (address), (size), \
75					PARANOIA_FAIL_IF_EXISTS))
76#define	UPDATE_PARANOIA_CHECK(level, object, address, size)		\
77			PARANOIA_ONLY_LEVEL((level),						\
78				set_paranoia_check((object), (address), (size), \
79					PARANOIA_FAIL_IF_MISSING))
80#define	SET_PARANOIA_CHECK(level, object, address, size)		\
81			PARANOIA_ONLY_LEVEL((level),						\
82				set_paranoia_check((object), (address), (size), \
83					PARANOIA_DONT_FAIL))
84#define	REMOVE_PARANOIA_CHECK(level, object, address, size)		\
85			PARANOIA_ONLY_LEVEL((level),						\
86				remove_paranoia_check((object), (address), (size)))
87
88
89#ifdef __cplusplus
90
91class ParanoiaChecker {
92public:
93	inline ParanoiaChecker(const void* object)
94	{
95		PARANOIA_ONLY(fObject = object);
96		RUN_PARANOIA_CHECKS(fObject);
97	}
98
99	inline ~ParanoiaChecker()
100	{
101		PARANOIA_ONLY(
102			if (fObject != NULL)
103				RUN_PARANOIA_CHECKS(fObject);
104		)
105	}
106
107	inline void Disable()
108	{
109		PARANOIA_ONLY(fObject = NULL);
110	}
111
112private:
113	PARANOIA_ONLY(
114		const void*	fObject;
115	)
116};
117
118#endif	// __cplusplus
119
120
121#endif	// _KERNEL_DEBUG_PARANOIA_H
122