summaryrefslogtreecommitdiffstats
path: root/src/include
diff options
context:
space:
mode:
authorPatrick Williams <iawillia@us.ibm.com>2011-06-24 10:13:59 -0500
committerA. Patrick Williams III <iawillia@us.ibm.com>2011-07-06 13:32:14 -0500
commit9ada6b493e33fe43057b03897d57f2ad931d219f (patch)
treebbf89ebdb16bf9b1fe2b466979d610835e8e58fb /src/include
parent6c77e26e9454c6753d989f33430c4e361f6ff003 (diff)
downloadtalos-hostboot-9ada6b493e33fe43057b03897d57f2ad931d219f.tar.gz
talos-hostboot-9ada6b493e33fe43057b03897d57f2ad931d219f.zip
Improve assert handling and options.
- Allow a custom assert trace as an optional parameter. - Call a trace function instead of printk for most cases. - Provide a critical library assert (for syslibs, trace, etc.) - Provide a kassert function for kernel code. Change-Id: If24d57d0832a587258503b3fd0046c21da3712b5 Reviewed-on: http://gfw160.austin.ibm.com:8080/gerrit/159 Tested-by: Jenkins Server Reviewed-by: Andrew J. Geissler <andrewg@us.ibm.com> Reviewed-by: CAMVAN T. NGUYEN <ctnguyen@us.ibm.com>
Diffstat (limited to 'src/include')
-rw-r--r--src/include/assert.h150
-rw-r--r--src/include/builtins.h12
2 files changed, 152 insertions, 10 deletions
diff --git a/src/include/assert.h b/src/include/assert.h
index 13888bee8..a8f3fb664 100644
--- a/src/include/assert.h
+++ b/src/include/assert.h
@@ -1,27 +1,159 @@
-#include <builtins.h>
-
+/** @file assert.h
+ * @brief Define the interfaces for the standard 'assert' macros.
+ *
+ * There are four different assert types provided now:
+ * Standard assert behavior:
+ * assert(foo)
+ *
+ * Standard assert behavior with a custom trace message:
+ * assert(foo, "This is a trace %d", 1234)
+ *
+ * Critical assert, which should only be used by system libraries or
+ * code paths which cannot use trace or error logging:
+ * crit_assert(foo)
+ *
+ * Kernel assert:
+ * kassert(foo)
+ *
+ * Most code should use the standard asserts. Kernel code must use kassert
+ * exclusively. Usage of the critical assert should be limited to system
+ * library code (/src/lib, /src/sys) or init service, trace and error log.
+ */
#ifndef _ASSERT_H
#define _ASSERT_H
+#include <builtins.h>
+
+#ifdef __HOSTBOOT_MODULE // Only allow traced assert in module code.
+#include <trace/interface.H>
+namespace TRACE { extern trace_desc_t* g_assertTraceBuffer; };
+#endif
+
#ifdef __cplusplus
extern "C"
{
#endif
+/** @enum AssertBehavior
+ * @brief Types of assert behavior used by the internal __assert function.
+ */
+enum AssertBehavior
+{
+ /** Standard assert, custom trace already done. */
+ ASSERT_TRACE_DONE,
+ /** Standard assert, no custom trace. */
+ ASSERT_TRACE_NOTDONE,
+ /** Critical / System library assert. */
+ ASSERT_CRITICAL,
+ /** Kernel-level assert. */
+ ASSERT_KERNEL,
+};
+
+/** @fn __assert
+ * @brief Internal function utilized by assert macros to commonize handling.
+ *
+ * @param[in] i_assertb - Internal enumeration used by macros to communicate
+ * desired behavior.
+ * @param[in] i_line - Line number at which the assert macro was called.
+ *
+ * Current Behaviors:
+ * User-space application - A trace is created, either a custom one
+ * provided by the caller or a common one
+ * determined by the trace callback hook, and
+ * the asserting task is ended.
+ *
+ * Critical library - A printk is performed, similar in structure to the
+ * traces, and the user task is ended.
+ *
+ * Kernel - A printk is performed and a while(1) loop is entered to cease
+ * user-space dispatching.
+ */
NO_RETURN
-void __assert(bool expr, const char *exprStr, const char *file, int line);
+void __assert(AssertBehavior i_assertb, int i_line);
+
+#ifdef __HOSTBOOT_MODULE // Only allow traced assert in module code.
-#define assert(expr) \
+// Macro tricks to determine if there is a custom string.
+#define __ASSERT_HAS_TRACE_(_1, _2, ...) _2
+#define __ASSERT_HAS_TRACE(...) __ASSERT_HAS_TRACE_(0, ##__VA_ARGS__, 0)
+
+/**
+ * @brief Macro to do the custom trace if one is provided.
+ *
+ * This results in larger code size of the caller to call the trace routines
+ * but may provide additional debug information.
+ *
+ * The "code" here will be compiled down to nothing or a single trace call by
+ * the optimizer. Search for "Constant Folding" for compiler background.
+ */
+#define __ASSERT_DO_TRACE(expr, ...) { \
+ int __assert_unused_var = 0; \
+ __assert_unused_var += (__ASSERT_HAS_TRACE(__VA_ARGS__) ? \
+ TRACFCOMP(TRACE::g_assertTraceBuffer, \
+ "Assertion [ " #expr " ] failed; " __VA_ARGS__),1 \
+ : 0); \
+ }
+
+/**
+ * @brief Standard assert macro.
+ *
+ * Verfies condition, calls custom trace if provided, and calls internal
+ * __assert function for remainder of common assert behavior.
+ */
+#define assert(expr,...) \
{\
- if (!(expr))\
+ if (unlikely(!(expr)))\
{\
- __assert((expr), #expr, __FILE__, __LINE__);\
+ __ASSERT_DO_TRACE(expr, __VA_ARGS__); \
+ __assert((__ASSERT_HAS_TRACE(__VA_ARGS__) ? \
+ ASSERT_TRACE_DONE : ASSERT_TRACE_NOTDONE),\
+ __LINE__);\
}\
-}\
+}
+
+#else // Only allow kernel assert in non-module code.
-#ifdef NDEBUG
+/**
+ * @brief Kernel assert macro.
+ *
+ * Verifies condition and calls __assert function for common behavior.
+ */
+#define kassert(expr) \
+{\
+ if (unlikely(!(expr)))\
+ {\
+ __assert(ASSERT_KERNEL, __LINE__);\
+ }\
+}
+
+#endif // ifdef __HOSTBOOT_MODULE
+
+// Allow critical assert anywhere.
+/**
+ * @brief Critical assert macro.
+ *
+ * Verifies condition and calls __assert function for common behavior.
+ */
+#define crit_assert(expr) \
+{\
+ if (unlikely(!(expr)))\
+ {\
+ __assert(ASSERT_CRITICAL, __LINE__);\
+ }\
+}
+
+
+
+#ifdef NDEBUG // Empty macro definitions for when NDEBUG is defined.
+#ifdef MODULE
#undef assert
-#define assert(expr) { }
+#define assert(expr,...) { }
+#else
+#undef kassert
+#define kassert(expr) { }
+#endif
+#undef crit_assert
+#define crit_assert(expr,...) { }
#endif
#ifdef __cplusplus
diff --git a/src/include/builtins.h b/src/include/builtins.h
index 07b185697..54b7dc768 100644
--- a/src/include/builtins.h
+++ b/src/include/builtins.h
@@ -45,6 +45,16 @@ extern "C"
#define PACKED __attribute__((packed))
/**
+ * Compiler hint for branch conditions. "condition is likely to be true"
+ */
+#define likely(expr) __builtin_expect((expr),1)
+
+/**
+ * Compiler hint for branch conditions. "condition is likely to be false"
+ */
+#define unlikely(expr) __builtin_expect((expr),0)
+
+/**
* Get the value of the link register
*
* @return the value of the link register
@@ -52,7 +62,7 @@ extern "C"
ALWAYS_INLINE
static inline void *linkRegister()
{
- return __builtin_return_address(1);
+ return __builtin_return_address(0);
}
/**
OpenPOWER on IntegriCloud