Message ID | 1417519667-7902-2-git-send-email-taras.kondratiuk@linaro.org |
---|---|
State | New |
Headers | show |
On 2 December 2014 at 06:27, Taras Kondratiuk <taras.kondratiuk@linaro.org> wrote: > ODP application may want to override default ODP logging behaviour > and use custom logging function. Add a weak odp_override_log() function > for this purpose instead of default fprintf(). > > Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> > --- > platform/linux-generic/Makefile.am | 3 +- > platform/linux-generic/include/api/odp_debug.h | 41 > ++++++++++++++++-------- > platform/linux-generic/odp_weak.c | 23 +++++++++++++ > 3 files changed, 53 insertions(+), 14 deletions(-) > create mode 100644 platform/linux-generic/odp_weak.c > > diff --git a/platform/linux-generic/Makefile.am > b/platform/linux-generic/Makefile.am > index e709700..cc78de3 100644 > --- a/platform/linux-generic/Makefile.am > +++ b/platform/linux-generic/Makefile.am > @@ -75,4 +75,5 @@ __LIB__libodp_la_SOURCES = \ > odp_thread.c \ > odp_ticketlock.c \ > odp_time.c \ > - odp_timer.c > + odp_timer.c \ > + odp_weak.c > diff --git a/platform/linux-generic/include/api/odp_debug.h > b/platform/linux-generic/include/api/odp_debug.h > index e853be4..4b51038 100644 > --- a/platform/linux-generic/include/api/odp_debug.h > +++ b/platform/linux-generic/include/api/odp_debug.h > @@ -14,6 +14,7 @@ > > #include <stdio.h> > #include <stdlib.h> > +#include <stdarg.h> > > #ifdef __cplusplus > extern "C" { > @@ -81,61 +82,75 @@ typedef enum odp_log_level { > } odp_log_level_e; > > /** > - * ODP default LOG macro. > + * ODP log function > + * > + * Instead of direct prints to stdout/stderr all logging in ODP > implementation > + * should be done via this function or its wrappers. > + * ODP platform MUST provide a default *weak* implementation of this > function. > MUST -> must > + * Application MAY override the function if needed by providing a strong > MAY -> may > + * function. > + * > + * @param level Log level > doxygen in or out > + * @param fmt printf-style message format > doxygen in or out > + */ > need @return description or if possible @retval if there are specific cases > +extern int odp_override_log(odp_log_level_e level, const char *fmt, ...); > level does not appear to be the best name, these are output streams with different characteristics rather than a single stream with different levels > + > +/** > + * ODP LOG macro. > */ > #define ODP_LOG(level, fmt, ...) \ > do { \ > switch (level) { \ > case ODP_LOG_ERR: \ > - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ > + odp_override_log(level, "%s:%d:%s():" fmt, __FILE__, \ > __LINE__, __func__, ##__VA_ARGS__); \ > break; \ > case ODP_LOG_DBG: \ > if (ODP_DEBUG_PRINT == 1) \ > - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ > + odp_override_log(level, "%s:%d:%s():" fmt, > __FILE__, \ > __LINE__, __func__, ##__VA_ARGS__); \ > break; \ > case ODP_LOG_PRINT: \ > - fprintf(stdout, " " fmt, ##__VA_ARGS__); \ > + odp_override_log(level, " " fmt, ##__VA_ARGS__); \ > break; \ > case ODP_LOG_ABORT: \ > - fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ > + odp_override_log(level, "%s:%d:%s(): " fmt, __FILE__, \ > __LINE__, __func__, ##__VA_ARGS__); \ > abort(); \ > break; \ > case ODP_LOG_UNIMPLEMENTED: \ > - fprintf(stderr, \ > + odp_override_log(level, \ > "%s:%d:The function %s() is not implemented\n" \ > fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); > \ > break; \ > default: \ > - fprintf(stderr, "Unknown LOG level"); \ > + odp_override_log(level, "Unknown LOG level"); \ > break;\ > } \ > } while (0) > > /** > - * Printing macro, which prints output when the application > - * calls one of the ODP APIs specifically for dumping internal data. > + * Log print message when the application calls one of the ODP APIs > + * specifically for dumping internal data. > */ > #define ODP_PRINT(fmt, ...) \ > ODP_LOG(ODP_LOG_PRINT, fmt, ##__VA_ARGS__) > > /** > - * Debug printing macro, which prints output when DEBUG flag is set. > + * Log debug message if DEBUG flag is set. > The flag is ODP_DEBUG_PRINT > */ > #define ODP_DBG(fmt, ...) \ > ODP_LOG(ODP_LOG_DBG, fmt, ##__VA_ARGS__) > > /** > - * Print output to stderr (file, line and function). > + * Log error message. > We should say that this is not maskable > */ > #define ODP_ERR(fmt, ...) \ > ODP_LOG(ODP_LOG_ERR, fmt, ##__VA_ARGS__) > > /** > - * Print output to stderr (file, line and function), > - * then abort. > + * Log abort message and then stop execution (by default call abort()). > + * This function should not return. > */ > #define ODP_ABORT(fmt, ...) \ > ODP_LOG(ODP_LOG_ABORT, fmt, ##__VA_ARGS__) > diff --git a/platform/linux-generic/odp_weak.c > b/platform/linux-generic/odp_weak.c > new file mode 100644 > index 0000000..fccbc3f > --- /dev/null > +++ b/platform/linux-generic/odp_weak.c > @@ -0,0 +1,23 @@ > +/* Copyright (c) 2014, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_internal.h> > +#include <odp_debug.h> > +#include <odp_debug_internal.h> > +#include <odp_hints.h> > + > +ODP_WEAK_SYMBOL int odp_override_log(odp_log_level_e level ODP_UNUSED, > + const char *fmt, ...) > Why is this ODP_UNUSED, is it needed ? To use it a reimplementation of this function by an application would effectively have to have another switch statement. Generating that need for two switches implies we should be exporting overrides for each log type and not prematurely factorising our code. If we do that we just remove our switch statement and put the implementation under the weak function that each macro directly calls. I think Zoltan is bringing this up on the other patch as well > +{ > + va_list args; > + int r; > + > + va_start(args, fmt); > + r = vfprintf(stderr, fmt, args); > + va_end(args); > + > + return r; > +} > -- > 1.7.9.5 > > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp >
On Tue, Dec 2, 2014 at 1:35 PM, Mike Holmes <mike.holmes@linaro.org> wrote: > > > On 2 December 2014 at 06:27, Taras Kondratiuk <taras.kondratiuk@linaro.org > > wrote: > >> ODP application may want to override default ODP logging behaviour >> and use custom logging function. Add a weak odp_override_log() function >> for this purpose instead of default fprintf(). >> >> Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> >> --- >> platform/linux-generic/Makefile.am | 3 +- >> platform/linux-generic/include/api/odp_debug.h | 41 >> ++++++++++++++++-------- >> platform/linux-generic/odp_weak.c | 23 +++++++++++++ >> 3 files changed, 53 insertions(+), 14 deletions(-) >> create mode 100644 platform/linux-generic/odp_weak.c >> >> diff --git a/platform/linux-generic/Makefile.am >> b/platform/linux-generic/Makefile.am >> index e709700..cc78de3 100644 >> --- a/platform/linux-generic/Makefile.am >> +++ b/platform/linux-generic/Makefile.am >> @@ -75,4 +75,5 @@ __LIB__libodp_la_SOURCES = \ >> odp_thread.c \ >> odp_ticketlock.c \ >> odp_time.c \ >> - odp_timer.c >> + odp_timer.c \ >> + odp_weak.c >> diff --git a/platform/linux-generic/include/api/odp_debug.h >> b/platform/linux-generic/include/api/odp_debug.h >> index e853be4..4b51038 100644 >> --- a/platform/linux-generic/include/api/odp_debug.h >> +++ b/platform/linux-generic/include/api/odp_debug.h >> @@ -14,6 +14,7 @@ >> >> #include <stdio.h> >> #include <stdlib.h> >> +#include <stdarg.h> >> >> #ifdef __cplusplus >> extern "C" { >> @@ -81,61 +82,75 @@ typedef enum odp_log_level { >> } odp_log_level_e; >> >> /** >> - * ODP default LOG macro. >> + * ODP log function >> + * >> + * Instead of direct prints to stdout/stderr all logging in ODP >> implementation >> + * should be done via this function or its wrappers. >> + * ODP platform MUST provide a default *weak* implementation of this >> function. >> > > MUST -> must > > >> + * Application MAY override the function if needed by providing a strong >> > > MAY -> may > > I disagree. The use of CAPS indicates that RFC 2119 applies. It is a very standard convention and should be encouraged when applicable. > + * function. >> + * >> + * @param level Log level >> > > doxygen in or out > > >> + * @param fmt printf-style message format >> > > doxygen in or out > > >> + */ >> > > need @return description or if possible @retval if there are specific > cases > > >> +extern int odp_override_log(odp_log_level_e level, const char *fmt, ...); >> > > level does not appear to be the best name, these are output streams with > different characteristics rather than a single stream with different levels > > >> + >> +/** >> + * ODP LOG macro. >> */ >> #define ODP_LOG(level, fmt, ...) \ >> do { \ >> switch (level) { \ >> case ODP_LOG_ERR: \ >> - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ >> + odp_override_log(level, "%s:%d:%s():" fmt, __FILE__, \ >> __LINE__, __func__, ##__VA_ARGS__); \ >> break; \ >> case ODP_LOG_DBG: \ >> if (ODP_DEBUG_PRINT == 1) \ >> - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ >> + odp_override_log(level, "%s:%d:%s():" fmt, >> __FILE__, \ >> __LINE__, __func__, ##__VA_ARGS__); \ >> break; \ >> case ODP_LOG_PRINT: \ >> - fprintf(stdout, " " fmt, ##__VA_ARGS__); \ >> + odp_override_log(level, " " fmt, ##__VA_ARGS__); \ >> break; \ >> case ODP_LOG_ABORT: \ >> - fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ >> + odp_override_log(level, "%s:%d:%s(): " fmt, __FILE__, \ >> __LINE__, __func__, ##__VA_ARGS__); \ >> abort(); \ >> break; \ >> case ODP_LOG_UNIMPLEMENTED: \ >> - fprintf(stderr, \ >> + odp_override_log(level, \ >> "%s:%d:The function %s() is not implemented\n" \ >> fmt, __FILE__, __LINE__, __func__, >> ##__VA_ARGS__); \ >> break; \ >> default: \ >> - fprintf(stderr, "Unknown LOG level"); \ >> + odp_override_log(level, "Unknown LOG level"); \ >> break;\ >> } \ >> } while (0) >> >> /** >> - * Printing macro, which prints output when the application >> - * calls one of the ODP APIs specifically for dumping internal data. >> + * Log print message when the application calls one of the ODP APIs >> + * specifically for dumping internal data. >> */ >> #define ODP_PRINT(fmt, ...) \ >> ODP_LOG(ODP_LOG_PRINT, fmt, ##__VA_ARGS__) >> >> /** >> - * Debug printing macro, which prints output when DEBUG flag is set. >> + * Log debug message if DEBUG flag is set. >> > > The flag is ODP_DEBUG_PRINT > > >> */ >> #define ODP_DBG(fmt, ...) \ >> ODP_LOG(ODP_LOG_DBG, fmt, ##__VA_ARGS__) >> >> /** >> - * Print output to stderr (file, line and function). >> + * Log error message. >> > > We should say that this is not maskable > > >> */ >> #define ODP_ERR(fmt, ...) \ >> ODP_LOG(ODP_LOG_ERR, fmt, ##__VA_ARGS__) >> >> /** >> - * Print output to stderr (file, line and function), >> - * then abort. >> + * Log abort message and then stop execution (by default call abort()). >> + * This function should not return. >> */ >> #define ODP_ABORT(fmt, ...) \ >> ODP_LOG(ODP_LOG_ABORT, fmt, ##__VA_ARGS__) >> diff --git a/platform/linux-generic/odp_weak.c >> b/platform/linux-generic/odp_weak.c >> new file mode 100644 >> index 0000000..fccbc3f >> --- /dev/null >> +++ b/platform/linux-generic/odp_weak.c >> @@ -0,0 +1,23 @@ >> +/* Copyright (c) 2014, Linaro Limited >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: BSD-3-Clause >> + */ >> + >> +#include <odp_internal.h> >> +#include <odp_debug.h> >> +#include <odp_debug_internal.h> >> +#include <odp_hints.h> >> + >> +ODP_WEAK_SYMBOL int odp_override_log(odp_log_level_e level ODP_UNUSED, >> + const char *fmt, ...) >> > > Why is this ODP_UNUSED, is it needed ? > To use it a reimplementation of this function by an application would > effectively have to have another switch statement. > Generating that need for two switches implies we should be exporting > overrides for each log type and not > prematurely factorising our code. > > If we do that we just remove our switch statement and put the > implementation under the weak function that each macro directly calls. > > I think Zoltan is bringing this up on the other patch as well > > > >> +{ >> + va_list args; >> + int r; >> + >> + va_start(args, fmt); >> + r = vfprintf(stderr, fmt, args); >> + va_end(args); >> + >> + return r; >> +} >> -- >> 1.7.9.5 >> >> >> _______________________________________________ >> lng-odp mailing list >> lng-odp@lists.linaro.org >> http://lists.linaro.org/mailman/listinfo/lng-odp >> > > > > -- > *Mike Holmes* > Linaro Sr Technical Manager > LNG - ODP > > _______________________________________________ > lng-odp mailing list > lng-odp@lists.linaro.org > http://lists.linaro.org/mailman/listinfo/lng-odp > >
On 2 December 2014 at 20:03, Bill Fischofer <bill.fischofer@linaro.org> wrote: > > > On Tue, Dec 2, 2014 at 1:35 PM, Mike Holmes <mike.holmes@linaro.org> wrote: >> >> >> >> On 2 December 2014 at 06:27, Taras Kondratiuk >> <taras.kondratiuk@linaro.org> wrote: >>> >>> ODP application may want to override default ODP logging behaviour >>> and use custom logging function. Add a weak odp_override_log() function >>> for this purpose instead of default fprintf(). >>> >>> Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> >>> --- >>> platform/linux-generic/Makefile.am | 3 +- >>> platform/linux-generic/include/api/odp_debug.h | 41 >>> ++++++++++++++++-------- >>> platform/linux-generic/odp_weak.c | 23 +++++++++++++ >>> 3 files changed, 53 insertions(+), 14 deletions(-) >>> create mode 100644 platform/linux-generic/odp_weak.c >>> >>> diff --git a/platform/linux-generic/Makefile.am >>> b/platform/linux-generic/Makefile.am >>> index e709700..cc78de3 100644 >>> --- a/platform/linux-generic/Makefile.am >>> +++ b/platform/linux-generic/Makefile.am >>> @@ -75,4 +75,5 @@ __LIB__libodp_la_SOURCES = \ >>> odp_thread.c \ >>> odp_ticketlock.c \ >>> odp_time.c \ >>> - odp_timer.c >>> + odp_timer.c \ >>> + odp_weak.c >>> diff --git a/platform/linux-generic/include/api/odp_debug.h >>> b/platform/linux-generic/include/api/odp_debug.h >>> index e853be4..4b51038 100644 >>> --- a/platform/linux-generic/include/api/odp_debug.h >>> +++ b/platform/linux-generic/include/api/odp_debug.h >>> @@ -14,6 +14,7 @@ >>> >>> #include <stdio.h> >>> #include <stdlib.h> >>> +#include <stdarg.h> >>> >>> #ifdef __cplusplus >>> extern "C" { >>> @@ -81,61 +82,75 @@ typedef enum odp_log_level { >>> } odp_log_level_e; >>> >>> /** >>> - * ODP default LOG macro. >>> + * ODP log function >>> + * >>> + * Instead of direct prints to stdout/stderr all logging in ODP >>> implementation >>> + * should be done via this function or its wrappers. >>> + * ODP platform MUST provide a default *weak* implementation of this >>> function. >> >> >> MUST -> must >> >>> >>> + * Application MAY override the function if needed by providing a strong >> >> >> MAY -> may >> > > > I disagree. The use of CAPS indicates that RFC 2119 applies. It is a very > standard convention and should be encouraged when applicable. I agree that we should say that in the ODP Specification (Architecture doc), that we follow RFC 2119. We have *not* done that in the API docs at all (use git grep). If you have a couple of example API docs that uses RFC 2119 in the text then we should think about doing the same. Cheers, Anders
On 12/02/2014 08:35 PM, Mike Holmes wrote: > - * ODP default LOG macro. > + * ODP log function > + * > + * Instead of direct prints to stdout/stderr all logging in ODP > implementation > + * should be done via this function or its wrappers. > + * ODP platform MUST provide a default *weak* implementation of > this function. > > MUST -> must This follows our specification approach to use RFC 2119. > > + * Application MAY override the function if needed by providing a > strong > > > MAY -> may > > + * function. > + * > + * @param level Log level > > > doxygen in or out > > + * @param fmt printf-style message format > > > doxygen in or out > > + */ > > > need @return description or if possible @retval if there are specific > cases Will add. > > +extern int odp_override_log(odp_log_level_e level, const char *fmt, > ...); > > > level does not appear to be the best name, these are output streams with > different characteristics rather than a single stream with different levels No. This is a level. It even has type of odp_log_level_e. Mapping it to streams is an implementation/application choice. > > + > +/** > + * ODP LOG macro. > */ > #define ODP_LOG(level, fmt, ...) \ > do { \ > switch (level) { \ > case ODP_LOG_ERR: \ > - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ > + odp_override_log(level, "%s:%d:%s():" fmt, __FILE__, \ > __LINE__, __func__, ##__VA_ARGS__); \ > break; \ > case ODP_LOG_DBG: \ > if (ODP_DEBUG_PRINT == 1) \ > - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ > + odp_override_log(level, "%s:%d:%s():" fmt, > __FILE__, \ > __LINE__, __func__, ##__VA_ARGS__); \ > break; \ > case ODP_LOG_PRINT: \ > - fprintf(stdout, " " fmt, ##__VA_ARGS__); \ > + odp_override_log(level, " " fmt, ##__VA_ARGS__); \ > break; \ > case ODP_LOG_ABORT: \ > - fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ > + odp_override_log(level, "%s:%d:%s(): " fmt, __FILE__, \ > __LINE__, __func__, ##__VA_ARGS__); \ > abort(); \ > break; \ > case ODP_LOG_UNIMPLEMENTED: \ > - fprintf(stderr, \ > + odp_override_log(level, \ > "%s:%d:The function %s() is not > implemented\n" \ > fmt, __FILE__, __LINE__, __func__, > ##__VA_ARGS__); \ > break; \ > default: \ > - fprintf(stderr, "Unknown LOG level"); \ > + odp_override_log(level, "Unknown LOG level"); \ > break;\ > } \ > } while (0) > > /** > - * Printing macro, which prints output when the application > - * calls one of the ODP APIs specifically for dumping internal data. > + * Log print message when the application calls one of the ODP APIs > + * specifically for dumping internal data. > */ > #define ODP_PRINT(fmt, ...) \ > ODP_LOG(ODP_LOG_PRINT, fmt, ##__VA_ARGS__) > > /** > - * Debug printing macro, which prints output when DEBUG flag is set. > + * Log debug message if DEBUG flag is set. > > > The flag is ODP_DEBUG_PRINT I didn't change the original flag name. Will update it. > > */ > #define ODP_DBG(fmt, ...) \ > ODP_LOG(ODP_LOG_DBG, fmt, ##__VA_ARGS__) > > /** > - * Print output to stderr (file, line and function). > + * Log error message. > > > We should say that this is not maskable None of them is maskable except DEBUG level. Do you want to add an explicit note to each of them? > > */ > #define ODP_ERR(fmt, ...) \ > ODP_LOG(ODP_LOG_ERR, fmt, ##__VA_ARGS__) > > /** > - * Print output to stderr (file, line and function), > - * then abort. > + * Log abort message and then stop execution (by default call abort()). > + * This function should not return. > */ > #define ODP_ABORT(fmt, ...) \ > ODP_LOG(ODP_LOG_ABORT, fmt, ##__VA_ARGS__) > diff --git a/platform/linux-generic/odp_weak.c > b/platform/linux-generic/odp_weak.c > new file mode 100644 > index 0000000..fccbc3f > --- /dev/null > +++ b/platform/linux-generic/odp_weak.c > @@ -0,0 +1,23 @@ > +/* Copyright (c) 2014, Linaro Limited > + * All rights reserved. > + * > + * SPDX-License-Identifier: BSD-3-Clause > + */ > + > +#include <odp_internal.h> > +#include <odp_debug.h> > +#include <odp_debug_internal.h> > +#include <odp_hints.h> > + > +ODP_WEAK_SYMBOL int odp_override_log(odp_log_level_e level ODP_UNUSED, > + const char *fmt, ...) > > > Why is this ODP_UNUSED, is it needed ? Because level is unused in this default definition. > To use it a reimplementation of this function by an application would > effectively have to have another switch statement. > Generating that need for two switches implies we should be exporting > overrides for each log type and not > prematurely factorising our code. > > If we do that we just remove our switch statement and put the > implementation under the weak function that each macro directly calls. Have you looked at the next patch (#2)? I especially haven't done those changes in a first patch to keep it minimal.
On 3 December 2014 at 03:31, Taras Kondratiuk <taras.kondratiuk@linaro.org> wrote: > On 12/02/2014 08:35 PM, Mike Holmes wrote: > > - * ODP default LOG macro. >> + * ODP log function >> + * >> + * Instead of direct prints to stdout/stderr all logging in ODP >> implementation >> + * should be done via this function or its wrappers. >> + * ODP platform MUST provide a default *weak* implementation of >> this function. >> >> MUST -> must >> > > This follows our specification approach to use RFC 2119. We need to clarify this, we have not used RFC 2119 upper case in any API to date, and the api guideline doc <http://docs.opendataplane.org/arch/html/api_guide_lines.html> does not state we need to. mike@fedora1:~/git/odp/platform/linux-generic/include/api$ git grep must odp_classification.h: * @param[in] offset Number of bytes the classifier must skip. odp_classification.h: * that must match the value size requirement of the odp_classification.h: * that must match the value size requirement of the odp_init.h: * This function must be called once before calling any other ODP API odp_init.h: * @sa odp_term_local() which must have been called prior to this. odp_init.h: * All threads must call this function before calling odp_init.h: * @sa odp_init_global() which must have been called prior to this. odp_init.h: * All threads must call this function before calling mike@fedora1:~/git/odp/platform/linux-generic/include/api$ git grep may odp_classification.h: * for fields that may be used to calculate odp_classification.h: * for fields that may be used to calculate odp_classification.h: /** Inner header may repeat above values with this offset */ odp_classification.h: * for fields that may be used to identify odp_classification.h: * The underlying platform may not support all or any specific combination odp_classification.h: * @return Return value may be a positive number odp_classification.h: * may be in the range from 1 to num_terms, odp_classification.h: * may not guarantee the availability of hardware resources to create the odp_init.h: * thread before the other ODP APIs may be called. odp_init.h: * This api may have platform dependant implications. odp_packet.h: * frame, the protocol header may start 2 or 6 bytes within the buffer to odp_version.h: * Every implementation of ODP may receive bug fixes independent of the version I am OK with the change if we get a follow on patch to update all the API to match and the API guide line doc gets a patch to specify this is how things must be defined in the API headers. I have added a note to https://docs.google.com/document/d/17xVCXorgZ2KjmS7DiKwb2pp576XdUp1f1IXK_bCIUys/edit?usp=sharing > > > >> + * Application MAY override the function if needed by providing a >> strong >> >> >> MAY -> may >> >> + * function. >> + * >> + * @param level Log level >> >> >> doxygen in or out >> >> + * @param fmt printf-style message format >> >> >> doxygen in or out >> >> + */ >> >> >> need @return description or if possible @retval if there are specific >> cases >> > > Will add. > > >> +extern int odp_override_log(odp_log_level_e level, const char *fmt, >> ...); >> >> >> level does not appear to be the best name, these are output streams with >> different characteristics rather than a single stream with different >> levels >> > > No. This is a level. It even has type of odp_log_level_e. > Mapping it to streams is an implementation/application choice. > > > >> + >> +/** >> + * ODP LOG macro. >> */ >> #define ODP_LOG(level, fmt, ...) \ >> do { \ >> switch (level) { \ >> case ODP_LOG_ERR: \ >> - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ >> + odp_override_log(level, "%s:%d:%s():" fmt, __FILE__, \ >> __LINE__, __func__, ##__VA_ARGS__); \ >> break; \ >> case ODP_LOG_DBG: \ >> if (ODP_DEBUG_PRINT == 1) \ >> - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ >> + odp_override_log(level, "%s:%d:%s():" fmt, >> __FILE__, \ >> __LINE__, __func__, ##__VA_ARGS__); \ >> break; \ >> case ODP_LOG_PRINT: \ >> - fprintf(stdout, " " fmt, ##__VA_ARGS__); \ >> + odp_override_log(level, " " fmt, ##__VA_ARGS__); \ >> break; \ >> case ODP_LOG_ABORT: \ >> - fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ >> + odp_override_log(level, "%s:%d:%s(): " fmt, __FILE__, >> \ >> __LINE__, __func__, ##__VA_ARGS__); \ >> abort(); \ >> break; \ >> case ODP_LOG_UNIMPLEMENTED: \ >> - fprintf(stderr, \ >> + odp_override_log(level, \ >> "%s:%d:The function %s() is not >> implemented\n" \ >> fmt, __FILE__, __LINE__, __func__, >> ##__VA_ARGS__); \ >> break; \ >> default: \ >> - fprintf(stderr, "Unknown LOG level"); \ >> + odp_override_log(level, "Unknown LOG level"); \ >> break;\ >> } \ >> } while (0) >> >> /** >> - * Printing macro, which prints output when the application >> - * calls one of the ODP APIs specifically for dumping internal data. >> + * Log print message when the application calls one of the ODP APIs >> + * specifically for dumping internal data. >> */ >> #define ODP_PRINT(fmt, ...) \ >> ODP_LOG(ODP_LOG_PRINT, fmt, ##__VA_ARGS__) >> >> /** >> - * Debug printing macro, which prints output when DEBUG flag is set. >> + * Log debug message if DEBUG flag is set. >> >> >> The flag is ODP_DEBUG_PRINT >> > > I didn't change the original flag name. Will update it. > > >> */ >> #define ODP_DBG(fmt, ...) \ >> ODP_LOG(ODP_LOG_DBG, fmt, ##__VA_ARGS__) >> >> /** >> - * Print output to stderr (file, line and function). >> + * Log error message. >> >> >> We should say that this is not maskable >> > > None of them is maskable except DEBUG level. Do you want to add > an explicit note to each of them? > > > >> */ >> #define ODP_ERR(fmt, ...) \ >> ODP_LOG(ODP_LOG_ERR, fmt, ##__VA_ARGS__) >> >> /** >> - * Print output to stderr (file, line and function), >> - * then abort. >> + * Log abort message and then stop execution (by default call >> abort()). >> + * This function should not return. >> */ >> #define ODP_ABORT(fmt, ...) \ >> ODP_LOG(ODP_LOG_ABORT, fmt, ##__VA_ARGS__) >> diff --git a/platform/linux-generic/odp_weak.c >> b/platform/linux-generic/odp_weak.c >> new file mode 100644 >> index 0000000..fccbc3f >> --- /dev/null >> +++ b/platform/linux-generic/odp_weak.c >> @@ -0,0 +1,23 @@ >> +/* Copyright (c) 2014, Linaro Limited >> + * All rights reserved. >> + * >> + * SPDX-License-Identifier: BSD-3-Clause >> + */ >> + >> +#include <odp_internal.h> >> +#include <odp_debug.h> >> +#include <odp_debug_internal.h> >> +#include <odp_hints.h> >> + >> +ODP_WEAK_SYMBOL int odp_override_log(odp_log_level_e level >> ODP_UNUSED, >> + const char *fmt, ...) >> >> >> Why is this ODP_UNUSED, is it needed ? >> > > Because level is unused in this default definition. > > To use it a reimplementation of this function by an application would >> effectively have to have another switch statement. >> Generating that need for two switches implies we should be exporting >> overrides for each log type and not >> prematurely factorising our code. >> >> If we do that we just remove our switch statement and put the >> implementation under the weak function that each macro directly calls. >> > > Have you looked at the next patch (#2)? I especially haven't done those > changes in a first patch to keep it minimal. >
diff --git a/platform/linux-generic/Makefile.am b/platform/linux-generic/Makefile.am index e709700..cc78de3 100644 --- a/platform/linux-generic/Makefile.am +++ b/platform/linux-generic/Makefile.am @@ -75,4 +75,5 @@ __LIB__libodp_la_SOURCES = \ odp_thread.c \ odp_ticketlock.c \ odp_time.c \ - odp_timer.c + odp_timer.c \ + odp_weak.c diff --git a/platform/linux-generic/include/api/odp_debug.h b/platform/linux-generic/include/api/odp_debug.h index e853be4..4b51038 100644 --- a/platform/linux-generic/include/api/odp_debug.h +++ b/platform/linux-generic/include/api/odp_debug.h @@ -14,6 +14,7 @@ #include <stdio.h> #include <stdlib.h> +#include <stdarg.h> #ifdef __cplusplus extern "C" { @@ -81,61 +82,75 @@ typedef enum odp_log_level { } odp_log_level_e; /** - * ODP default LOG macro. + * ODP log function + * + * Instead of direct prints to stdout/stderr all logging in ODP implementation + * should be done via this function or its wrappers. + * ODP platform MUST provide a default *weak* implementation of this function. + * Application MAY override the function if needed by providing a strong + * function. + * + * @param level Log level + * @param fmt printf-style message format + */ +extern int odp_override_log(odp_log_level_e level, const char *fmt, ...); + +/** + * ODP LOG macro. */ #define ODP_LOG(level, fmt, ...) \ do { \ switch (level) { \ case ODP_LOG_ERR: \ - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ + odp_override_log(level, "%s:%d:%s():" fmt, __FILE__, \ __LINE__, __func__, ##__VA_ARGS__); \ break; \ case ODP_LOG_DBG: \ if (ODP_DEBUG_PRINT == 1) \ - fprintf(stderr, "%s:%d:%s():" fmt, __FILE__, \ + odp_override_log(level, "%s:%d:%s():" fmt, __FILE__, \ __LINE__, __func__, ##__VA_ARGS__); \ break; \ case ODP_LOG_PRINT: \ - fprintf(stdout, " " fmt, ##__VA_ARGS__); \ + odp_override_log(level, " " fmt, ##__VA_ARGS__); \ break; \ case ODP_LOG_ABORT: \ - fprintf(stderr, "%s:%d:%s(): " fmt, __FILE__, \ + odp_override_log(level, "%s:%d:%s(): " fmt, __FILE__, \ __LINE__, __func__, ##__VA_ARGS__); \ abort(); \ break; \ case ODP_LOG_UNIMPLEMENTED: \ - fprintf(stderr, \ + odp_override_log(level, \ "%s:%d:The function %s() is not implemented\n" \ fmt, __FILE__, __LINE__, __func__, ##__VA_ARGS__); \ break; \ default: \ - fprintf(stderr, "Unknown LOG level"); \ + odp_override_log(level, "Unknown LOG level"); \ break;\ } \ } while (0) /** - * Printing macro, which prints output when the application - * calls one of the ODP APIs specifically for dumping internal data. + * Log print message when the application calls one of the ODP APIs + * specifically for dumping internal data. */ #define ODP_PRINT(fmt, ...) \ ODP_LOG(ODP_LOG_PRINT, fmt, ##__VA_ARGS__) /** - * Debug printing macro, which prints output when DEBUG flag is set. + * Log debug message if DEBUG flag is set. */ #define ODP_DBG(fmt, ...) \ ODP_LOG(ODP_LOG_DBG, fmt, ##__VA_ARGS__) /** - * Print output to stderr (file, line and function). + * Log error message. */ #define ODP_ERR(fmt, ...) \ ODP_LOG(ODP_LOG_ERR, fmt, ##__VA_ARGS__) /** - * Print output to stderr (file, line and function), - * then abort. + * Log abort message and then stop execution (by default call abort()). + * This function should not return. */ #define ODP_ABORT(fmt, ...) \ ODP_LOG(ODP_LOG_ABORT, fmt, ##__VA_ARGS__) diff --git a/platform/linux-generic/odp_weak.c b/platform/linux-generic/odp_weak.c new file mode 100644 index 0000000..fccbc3f --- /dev/null +++ b/platform/linux-generic/odp_weak.c @@ -0,0 +1,23 @@ +/* Copyright (c) 2014, Linaro Limited + * All rights reserved. + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +#include <odp_internal.h> +#include <odp_debug.h> +#include <odp_debug_internal.h> +#include <odp_hints.h> + +ODP_WEAK_SYMBOL int odp_override_log(odp_log_level_e level ODP_UNUSED, + const char *fmt, ...) +{ + va_list args; + int r; + + va_start(args, fmt); + r = vfprintf(stderr, fmt, args); + va_end(args); + + return r; +}
ODP application may want to override default ODP logging behaviour and use custom logging function. Add a weak odp_override_log() function for this purpose instead of default fprintf(). Signed-off-by: Taras Kondratiuk <taras.kondratiuk@linaro.org> --- platform/linux-generic/Makefile.am | 3 +- platform/linux-generic/include/api/odp_debug.h | 41 ++++++++++++++++-------- platform/linux-generic/odp_weak.c | 23 +++++++++++++ 3 files changed, 53 insertions(+), 14 deletions(-) create mode 100644 platform/linux-generic/odp_weak.c