From: Simon Kuenzer Date: Mon, 25 May 2020 01:44:01 +0000 (+0200) Subject: lib/ukdebug: Provide `uk_printd_once()`, `uk_printk_once()` X-Git-Tag: RELEASE-0.6~225 X-Git-Url: http://xenbits.xensource.com/gitweb?a=commitdiff_plain;h=82c1d85ec6985f581d885e0409f26aca2f28196a;p=unikraft%2Funikraft.git lib/ukdebug: Provide `uk_printd_once()`, `uk_printk_once()` This commit introduces debug and kernel print helpers that print a message just once. Any successive call of the same location of a message will produce no output: `uk_printd_once()` and `uk_printk_once()`, as well as `uk_pr_crit_once()`, `uk_pr_err_once()`, `uk_pr_warn_once()`, and `uk_pr_info_once()`. This can be used to limit the amount of shown messages. This commit updates the macro `WARN_STUBBED()`. Since the functionality of printing once is made generally available, the macro is based on `uk_pr_warn_once()`. In order to be inline with the Unikraft naming scheme and reducing the risk of naming conflicts, the macro is also introduced under the name `UK_WARN_STUBBED()`. `WARN_STUBBED()` should be considered as deprecated. Signed-off-by: Simon Kuenzer Reviewed-by: Razvan Deaconescu Tested-by: Unikraft CI GitHub-Pull-Request: #172 --- diff --git a/lib/ukdebug/include/uk/print.h b/lib/ukdebug/include/uk/print.h index c3c95f411..f978f9d69 100644 --- a/lib/ukdebug/include/uk/print.h +++ b/lib/ukdebug/include/uk/print.h @@ -37,6 +37,7 @@ #define __UKDEBUG_PRINT_H__ #include +#include #include #include @@ -87,11 +88,31 @@ void _uk_printd(const char *libname, const char *srcname, __LINE__, (fmt), ap); \ } while (0) +#define uk_vprintd_once(fmt, ap) \ + do { \ + static int __x; \ + if (unlikely(!__x)) { \ + _uk_vprintd(__STR_LIBNAME__, __STR_BASENAME__, \ + __LINE__, (fmt), ap); \ + __x = 1; \ + } \ + } while (0) + #define uk_printd(fmt, ...) \ do { \ _uk_printd(__STR_LIBNAME__, __STR_BASENAME__, \ __LINE__, (fmt), ##__VA_ARGS__); \ } while (0) + +#define uk_printd_once(fmt, ...) \ + do { \ + static int __x; \ + if (unlikely(!__x)) { \ + _uk_printd(__STR_LIBNAME__, __STR_BASENAME__, \ + __LINE__, (fmt), ##__VA_ARGS__); \ + __x = 1; \ + } \ + } while (0) #else static inline void uk_vprintd(const char *fmt __unused, va_list ap __unused) {} @@ -99,6 +120,14 @@ static inline void uk_vprintd(const char *fmt __unused, va_list ap __unused) static inline void uk_printd(const char *fmt, ...) __printf(1, 2); static inline void uk_printd(const char *fmt __unused, ...) {} + +static inline void uk_vprintd_once(const char *fmt __unused, + va_list ap __unused) +{} + +static inline void uk_printd_once(const char *fmt, ...) __printf(1, 2); +static inline void uk_printd_once(const char *fmt __unused, ...) +{} #endif /* @@ -138,12 +167,38 @@ void _uk_printk(int lvl, const char *libname, const char *srcname, __LINE__, (fmt), ap); \ } while (0) +#define uk_vprintk_once(lvl, fmt, ap) \ + do { \ + if ((lvl) <= KLVL_MAX) { \ + static int __x; \ + if (unlikely(!__x)) { \ + _uk_vprintk((lvl), __STR_LIBNAME__, \ + __STR_BASENAME__, \ + __LINE__, (fmt), ap); \ + __x = 1; \ + } \ + } \ + } while (0) + #define uk_printk(lvl, fmt, ...) \ do { \ if ((lvl) <= KLVL_MAX) \ _uk_printk((lvl), __STR_LIBNAME__, __STR_BASENAME__, \ __LINE__, (fmt), ##__VA_ARGS__); \ } while (0) + +#define uk_printk_once(lvl, fmt, ...) \ + do { \ + if ((lvl) <= KLVL_MAX) { \ + static int __x; \ + if (unlikely(!__x)) { \ + _uk_printk((lvl), __STR_LIBNAME__, \ + __STR_BASENAME__, \ + __LINE__, (fmt), ##__VA_ARGS__); \ + __x = 1; \ + } \ + } \ + } while (0) #else static inline void uk_vprintk(int lvl __unused, const char *fmt __unused, va_list ap __unused) @@ -152,6 +207,15 @@ static inline void uk_vprintk(int lvl __unused, const char *fmt __unused, static inline void uk_printk(int lvl, const char *fmt, ...) __printf(2, 3); static inline void uk_printk(int lvl __unused, const char *fmt __unused, ...) {} + +static inline void uk_vprintk_once(int lvl __unused, const char *fmt __unused, + va_list ap __unused) +{} + +static inline void uk_printk_once(int lvl, const char *fmt, ...) __printf(2, 3); +static inline void uk_printk_once(int lvl __unused, + const char *fmt __unused, ...) +{} #endif /* CONFIG_LIBUKDEBUG_PRINTK */ /* @@ -159,23 +223,29 @@ static inline void uk_printk(int lvl __unused, const char *fmt __unused, ...) * This is similar to the pr_* variants that you find in the Linux kernel */ #define uk_pr_debug(fmt, ...) uk_printd((fmt), ##__VA_ARGS__) +#define uk_pr_debug_once(fmt, ...) uk_printd_once((fmt), ##__VA_ARGS__) #define uk_pr_info(fmt, ...) uk_printk(KLVL_INFO, (fmt), ##__VA_ARGS__) +#define uk_pr_info_once(fmt, ...) uk_printk_once(KLVL_INFO, (fmt), \ + ##__VA_ARGS__) #define uk_pr_warn(fmt, ...) uk_printk(KLVL_WARN, (fmt), ##__VA_ARGS__) +#define uk_pr_warn_once(fmt, ...) uk_printk_once(KLVL_WARN, (fmt), \ + ##__VA_ARGS__) #define uk_pr_err(fmt, ...) uk_printk(KLVL_ERR, (fmt), ##__VA_ARGS__) +#define uk_pr_err_once(fmt, ...) uk_printk_once(KLVL_ERR, (fmt), \ + ##__VA_ARGS__) #define uk_pr_crit(fmt, ...) uk_printk(KLVL_CRIT, (fmt), ##__VA_ARGS__) - -/* NOTE: borrowed from OSv */ -#define WARN_STUBBED_ONCE(thing) do { \ - static int _x; \ - if (!_x) { \ - _x = 1; \ - thing; \ - } \ -} while (0) +#define uk_pr_crit_once(fmt, ...) uk_printk_once(KLVL_CRIT, (fmt), \ + ##__VA_ARGS__) /* Warning for stubbed functions */ +#define UK_WARN_STUBBED() \ + uk_pr_warn_once("%s() stubbed\n", __func__) + +/* DEPRECATED: Please use UK_WARN_STUBBED instead */ +#ifndef WARN_STUBBED #define WARN_STUBBED() \ - WARN_STUBBED_ONCE(uk_pr_warn("%s() stubbed\n", __func__)) + UK_WARN_STUBBED() +#endif #ifdef __cplusplus }