Scope Guard in C - c

I would like to use scope guard in C in order to do profiling.
I would like to know how much time I spend in a function. Here is what I do:
int function() {
tic();
... do stuff ...
if (something)
{
toc();
return 0;
}
toc();
return 1;
}
I need to place a toc statement each time I exit the function. I would like to do that without having to copy paste toc everywhere. Is there a generic way to do that, using a macro or something ?
Also I don't want to change the way the function is called, as there are many functions I have to profile.
Thanks

This doesn't change the way the function is called. Probably not much use if you want to be able to profile every single function, though.
static inline int real_function() {
// previous contents of function(), with no tic or toc
}
int function() {
tic();
int r = real_function();
toc();
return r;
}
As everyone else says: use a profiler, it will save you a lot of effort in the long run. As they don't say: if your platform has one.
If it doesn't, then the easiest might be to say (as a coding rule) that functions must have only one exit point, and that exit point must be via your macro. Then you can manually instrument all your functions with code at entry and exit. Legacy functions with multiple returns can be wrapped up as above.
Also, bear in mind when you're doing anything like this that your compiler can mess you up. You might write this:
tic();
do_something();
int i = something_else();
toc();
return i;
If the compiler determines that something_else has no side-effects, then even though something_else takes significant time, it might turn the code into this:
tic();
do_something();
toc();
return something_else();
And your profile data will under-estimate the time spent in your function. Another reason it's so good to have a real profiler - it can co-operate with the compiler.

You could define a macro like:
#define TOC_RETURN(x) \
do { \
toc(); \
return x; \
} while(0)
which should work anywhere you put it. Then you can automate replacing return *; with TOC_RETURN(*).

Why not use an actual profiling tool, like gprof?

You could just "redefine" return via a macro: (please see Disclaimer)
#include <stdio.h>
void tic() { printf("tic\n"); }
void toc() { printf("toc\n"; }
#define return toc(); return
int foo() {
tic();
return 0;
}
#undef return
int main() {
foo();
return 0;
}
Disclaimer: This can be considered ugly and hacky because:
It won't work for void functions unless you use return;-statements.
It might not be portable/standard, even though it works on MSVC8.
One shouldn't define keywords.

I am very late to the party, but there is another way to do scope guarding in C using the GCC extension cleanup attribute. The cleanup attribute attaches a function to a variable declaration that is run when the variable goes out of scope. Originally intended to perform memory deallocation for dynamically allocated types, it can also be abused as a scope guard.
void cleanup_toc(int *ignored __attribute__((__unused__))) { toc(); }
int function(void) {
tic();
int atexit __attribute__((__cleanup__(cleanup_toc))) = 0;
//... do stuff ...
if (something) {
return 0;
}
return 1;
}
This solution does not use macros, but you can of course wrap this into a macro. For example:
#define CONCATENATE_IMPL(x, y) x ## y
#define CONCATENATE(x, y) CONCATENATE_IMPL(x, y)
#define ATEXIT(f) int CONCATENATE(atexit, __LINE__) __attribute__((__cleanup__(f))) = 0
int function(void) {
ATEXIT(cleanup1); // These are executed in reverse order, i.e.
ATEXIT(cleanup2); // cleanup2 will run before cleanup1.
}

I wouldn't recommend a macro for this. You profile the code just once in a while, and replacing 'return' with some special macro just for that purpose makes code less readable.
Isn't it better to do as follows?
tic();
call_function();
toc();
This automatically handles "all exit points" from the function.
P.S. Why don't you use a profiler?

A real profiler doesn't need you to modify the code, just to compile it with profiling enabled.

Hmm, maybe wrap the function call in a macro (family of macros, really)? Here is one which takes no arguments and returns Retval:
// define the wrapper for name
#define DEFTIMECALL0(Retval,name) \
Retval timed##name() \
{ \
Retval ret;
tic(); \
ret = name(); \
toc(); \
return ret; \
}
You'll need macros for every arity of function calls you make, with a Retval and void returning version.
Edit Maybe there isn't even a point in defining the wrapper function, and better to just have a family of macros (again, for each arity and return type/void versions) which wrap a function call in a tic/toc directly at the callsites
Don't be afraid of instrumenting profilers, which essentially do this for you.

Related

Use of spinlock_check() function

I have a question about the function spinlock_check() used in spin_lock_init() macro.
The code of spinlock_check is written below and it returns address of rlock
static __always_inline raw_spinlock_t *spinlock_check(spinlock_t *lock)
{
return &lock->rlock;
}
It is used in the macro spin_lock_init. The code of this macro:
#define spin_lock_init(_lock) \
do { \
spinlock_check(_lock); \
raw_spin_lock_init(&(_lock)->rlock); \
} while (0)
I saw a question about this topic in here.
But i did not quite understand and I want to express doubts in my way.
The spin_lock_init() is a macro but spinlock_check() isnt a macro. Its an inline function. So I think there is no way for some compilation magic to happen here but I expect some magic during execution of those instructions.
What effect does spinlock_check() has?
Because nothing is using the return value of spinlock_check() function.
Even though spinlock_check() return something the next step is going to get executed anyways.
Because I saw its usage in one of the file and I thought that its different from min(x, y) macro.
Here is the usage which I found
#ifdef CONFIG_NUMA
static void do_numa_crng_init(struct work_struct *work)
{
int i;
struct crng_state *crng;
struct crng_state **pool;
pool = kcalloc(nr_node_ids, sizeof(*pool), GFP_KERNEL|__GFP_NOFAIL);
for_each_online_node(i) {
crng = kmalloc_node(sizeof(struct crng_state),
GFP_KERNEL | __GFP_NOFAIL, i);
spin_lock_init(&crng->lock);
crng_initialize(crng);
pool[i] = crng;
}
mb();
if (cmpxchg(&crng_node_pool, NULL, pool)) {
for_each_node(i)
kfree(pool[i]);
kfree(pool);
}
}
So here crng is dynamically allocated one. say I have missed the kmalloc code meaning I haven't allocated memory for crng but still I used the macro spin_lock_init(crng).
Now what good the spinlock_check() function does ?
Isn't it that after spinlock_check() function raw_spin_lock_init automatically executes ?
If it is going to execute then whats the use of spinlock_check() function?
There should be some meaning but I can't figure it out.
What you are missing is that spinlock_check() does not perform any check at run time. That's why its returned value is ignored. This instruction is expected to be removed during compilation by the optimizer.
Is it of any use, then? Yes! It's purpose is to ensure at compile time that the type of its parameter is spinlock_t *. If you don't give a pointer to spinlock_t as a parameter to spin_lock_init(), you will trigger a compilation error.

Is it OK to use a code block as an argument for a C macro?

I have a pattern that is basically some boilerplate code with a part that varies in the middle
if(condition){
struct Foo m = start_stuff();
{ m.foo = bar(1,2); m.baz = 17; } //this part varies
end_stuff();
}
Is it OK to make a macro taht takes that intermediate code block as an argument? The rules for macro expansion in C seem awfully complicated so I am not sure if there aren't any corner cases that could come and bite me in the future (in particular, I don't understand how the macro arguments are separated if my code has commas in it).
#define MY_MACRO(typ, do_stuff) do { \
if(condition){ \
struct typ m = start_stuff(); \
do_stuff; \
end_stuff(); \
} \
}while(0)
//usage
MY_MACRO(Foo, {
m.foo = bar(1,2);
m.baz = 17;
});
So far the only thing that I managed to think of is break and continue getting captured if I use looping statements in my macro and that would be an acceptable tradeoff for my particular use case.
edit: Of course, I would have used a functions if I could. The example I used in this question is simplified and doesn't showcase the bits that can only work with macro magic.
You can put a code block into a macro argument provided that it has no unguarded comma. In your example, the only comma in the argument is guarded because it is surrounded by parentheses.
Note that only parentheses guard commas. Brackets ([]) and braces ({}) do not. (And neither do angle brackets (<>) as noted in a comment.)
However, if the code block argument is the macro's last argument, you can use a variadic macro to increase flexibility. But beware: the increased flexibility also means that errors might go unnoticed. If you do this, you'll only have to make sure that the parentheses are balanced. (Again, only parentheses matter to the macro processor.)
As an alternative, you could consider using a macro that precedes your compound statement, as illustrated below. One of the pros of this is that all debuggers would still be able to step inside your compound statement, which is not the case with the compound-statement-as-macro-argument method.
//usage
MY_MACRO(Foo, condition) {
m.foo = bar(1,2);
m.baz = 17;
}
Using some goto magic (yes, 'goto' may be evil in some cases, but we have few alternatives in C), the macro can be implemented as:
#define CAT(prefix, suffix) prefix ## suffix
#define _UNIQUE_LABEL(prefix, suffix) CAT(prefix, suffix)
#define UNIQUE_LABEL(prefix) _UNIQUE_LABEL(prefix, __LINE__)
#define MY_MACRO(typ, condition) if (condition) { \
struct typ m = start_stuff(); goto UNIQUE_LABEL(enter);} \
if (condition) while(1) if (1) {end_stuff(); break;} \
else UNIQUE_LABEL(enter):
Note that this has a small performance and footprint impact when compiler optimization is disabled. Also, a debugger will seem jump back to the MY_MACRO line when running calling the end_stuff() function, which is not really desirable.
Also, you might want to use the macro inside a new block scope to avoid pollution your scope with the 'm' variable:
{MY_MACRO(Foo, condition) {
m.foo = bar(1,2);
m.baz = 17;
}}
Of course, using 'break' not inside a nested loop in the compound statement would skip the 'end_stuff()'. To allow for those to break the surrounding loop and still call 'end_stuff()', I think you'd have to enclose the compound statement with a start token and an end token as in:
#define MY_MACRO_START(typ, condition) if (condition) { \
struct typ m = start_stuff(); do {
#define MY_MACRO_EXIT goto UNIQUE_LABEL(done);} while (0); \
end_stuff(); break; \
UNIQUE_LABEL(done): end_stuff();}
MY_MACRO_START(foo, condition) {
m.foo = bar(1,2);
m.baz = 17;
} MY_MACRO_END
Note that because of the 'break' in that approach, the MY_MACRO_EXIT macro would only be usable inside a loop or switch. You could use a simpler implementation when not inside a loop:
#define MY_MACRO_EXIT_NOLOOP } while (0); end_stuff();}
I used 'condition' as a macro argument, but you may also embed it directly in the macro if desired.
You can put code block into a macro but you must be warned that it makes debugging a lot harder using a debugger. IMHO is better just to either write a function or cut'n'paste the lines of code.
How about function pointers instead (and optionally inline functions)?
void do_stuff_inner_alpha(struct Foo *m)
{
m->foo = bar(1,2); m->baz = 17;
}
void do_stuff_inner_beta(struct Foo *m)
{
m->foo = bar(9, 13); m->baz = 445;
}
typedef void(*specific_modifier_t)(struct Foo *);
void do_stuff(specific_modifier_t func)
{
if (condition){
struct Foo m = start_stuff();
func(&m); //this part varies
end_stuff();
}
}
int main(int argc, const char *argv[])
{
do_stuff(do_stuff_inner_beta);
return EXIT_SUCCESS;
}
"Is it OK?" may mean two things:
Will it work? Here the answer is generally yes, but there are pitfalls. One, as rici mentioned, is an unguarded comma. Basically, remember that macro expansion is a copy&paste operation, and the preprocessor doesn't understand the code it copies and pastes.
Is it a good idea? I'd say the answer is generally no. It makes your code unreadable and hard to maintain. In some rare cases, this may be better than alternatives, if implemented well, but that's the exception.
Note that in C++ you could use a lambda the following way:
#include <iostream>
#define MY_MACRO(body) \
setup();\
body();\
teardown();\
int main() {
int a = 1;
MY_MACRO(([&]() mutable {
std::cout << "Look, no setup" << std::endl;
a++;
}));
std::cout << "a is now " << a << std::endl;
}
If you do this, you should first consider if there should instead be a function that plainly takes the lambda:
void withSetup(std::function<void ()> callback) {
setup();
callback();
teardown();
}
int main() {
withSetup([&]() {
doStuff();
});
}
Before answering your question "is it OK to use macro" I'd like to know why you want to convert that block of code to macro. What's that you're trying to gain and at what cost?
If same block of code you're using repeatedly, it's better to convert that in a function, maybe an inline function and leave it to compiler to make it inline or not.
Should you run into crash\issue, debugging a macro is a tedious task.

How to prevent function from printing?

Is it possible to silence a function?
For example:
#include <stdio.h>
int function(){
printf("BLAH!");
return 10;
}
int main(){
printf("%d", silence( function()) );
return 0;
}
And instead of:
BLAH!
10
I would get:
10
Is it possible? If positive how to do it?
An awfully complicated way to do almost what you want is to use the dup2() system call. This requires executing fflush(stdout); dup2(silentfd, stdout); before function() is called, and copying back afterwards: fflush(stdout); dup2(savedstdoutfd, stdout);. So it is not possible to do as just silence(function()), since this construct only allows to execute code after function() has already been executed.
The file descriptors silentfd and savedstdoutfd have to be prepared in advance (untested code):
int silentfd = open("/dev/null",O_WRONLY);
int savedstdoutfd = dup(stdout);
This is almost certainly not what you really want, but inasmuch as your question is phrased as “is it possible?”, the answer is “almost”.
use macro function and null device.
E.g. for windows
#include <stdio.h>
#define silence(x) (_stream = freopen("NUL:", "w", stdout), _ret_value = x,_stream = freopen("CON:", "w", stdout),_ret_value)
int _ret_value;
FILE *_stream;
int function(){
printf("BLAH!");
return 10;
}
int main(void){
printf("%d", silence( function()) );
return 0;
}
No its not possible. You could however try to temporarily redirect the stdout to something else. That may come close to what you want.
You can use this macro instead of printf to be able to prevent printing:
int flag=0;
#define PRINT(...) if(flag){printf(...)}
then use PRINT macro by considering the variable flag. If flag==1, the function will print and if flag==0, the function will not print.
With GCC extensions, you might consider having macros like
bool silent;
#define silence(X) ({int _x; quiet(); _x = (X); verbose(); _x; })
#define printf(Fmt,...) \
do{if (!silent) printf(Fmt,##__VA_ARGS__);}while(0)
that silence macro would work only if its argument X is a int expression (or use typeof) I also assume that the result of printf is never used. Recall that "recursive" macros are specially pre-processed, the inside occurrence of printf (in that printf macro) is left verbatim without macro-expansion.
Notice that silence cannot be a function (otherwise, its argument would have been evaluated before calling it). And you need GCC statement expressions extension to "remember" the result of the argument in some variable _x (you could generate that name using __COUNTER__ and preprocessor concatenation), to give it back as the value of silence macro invocation.
Then you need to define your functions quiet() and verbose(), perhaps something like
void quiet()
{
silent = true;
}
void verbose()
{
silent = false,
}
if you don't want to define printf as your macro, you could use freopen(3) on stdout (perhaps with "/dev/null" etc...) or do dup2(2) tricks (like suggested by Pascal Cuoq).
If your code base is huge, and you want something more serious and are willing to spend days or weeks of work, consider customizing your GCC compiler with a plugin or a MELT extension (or ask someone to do it). Notice that printf is known to GCC.
In reality, you should define your own macro like
#define myprintf(Fmt, ...) do{if (!silent) \
printf(Fmt,__VA_ARGS__);}while(0)
and just use myprintf instead of printf everywhere, this is a portable trick. Of course, I assume you are not passing printf as a function pointer.
For debugging, I actually recommend
#define dbgprintf(Fmt,...) do{if (wantdebug) \
printf("%s:%d:" Fmt "\n", __FILE__, __LINE__, \
##__VA_ARGS__);}while(0)
and then I use dbgprintf("i=%d",i) or simply dbgprintf("foo here") in my code.
I'm using ##__VA_ARGS__ which is a GCC extension to accept no variable arguments to a variadic macro. If you want strict C99, you will just say __VA_ARGS__ and every dbgprintf would need one argument after the format.
You could also re-implement your own printf function, but I don't advise doing that.
(Notice that things could be more complex, you can print using fputs not printf ....)
If you're designing the function do the following:
int function(void (*printer)(char *)){
if (!printer)
printer = printf;
printer("BLAH!");
return 10;
}
void silence(char *s){
return;
}
int main(int argc, char **argv){
printf("%d\n", function(silence));
return 0;
}
That should do what you're looking for. Unfortunately, I didn't test it and my C is probably a little bit rusty.
Of course if function isn't something you have control over, the answers already posted are all correct solutions.
Actually, if you're designing the function yourself, just do:
int function(int print){
if (print)
printf("BLAH!");
return 10;
}
function(0); /* Won't print anything */
function(!0); /* Will print "BLAH!" */
because 0 is false and any non-zero (or !0) value is true. My above suggestion is error prone since you'll have to be able to mimic the printf signature for silence or for any other function you wish to use.
Unfortunately if you have the function explicitly printing and call it like this then it will always print. if you want to silence the function completely you could simply comment out that line.You could even use a control statement so that it only prints IF and when a condition is met otherwise it stays blank and only returns the number.

Portable instrumentation

GCC has a nice feature about instrumentation which let you call a routine every time a function is called, or every time a function returns.
Now, I want to create my own system to make it portable to other compilers, and also to allow to instrumentalize the functions I want (which can vary in number of parameters), so I was thinking in two macro for both situations. I am thinking in making some kind of profile that it is activated only with a define clause.
#define FUNCT(t,function_name,...) \
(t) function_name(...) { \
(void) *func_pointer = &(function_name); \
start_data(func_pointer, myclock());
#define RETURN(x) {stop_data(func_pointer, myclock()); return (x);}
FUNCT(BOOL, LMP, const int prof, const int nmo))
if (nmo <= 5 ||
prof > (prof_l / 3)) {
.... do long operations....
RETURN(FALSE);
}
... do more....
RETURN(TRUE);
}
but I can’t get it to work. Can someone help me with this? or is this a difficult task to accomplish?
Other alternative that comes to my mind is let the function declare without a macro, and if it is anyway to know the function pointer without knowing its name, something like in VB when you call a Form with Me, with it is a generic alias. is it possible?
Use gcc -E to debug your macros. Using the code you posted:
$ gcc -E t.c
# ... skip stuff ....
(BOOL) LMP(...) { (void) *func_pointer = &(LMP);
start_data(func_pointer, myclock());)
if (nmo <= 5 ||
prof > (prof_l / 3)) {
.... do long operations....
{stop_data(func_pointer, myclock()); return (FALSE);};
}
... do more....
{stop_data(func_pointer, myclock()); return (TRUE);};
}
(I added some whitespace to make it readable.)
You can see two problems immediately: function arguments didn't get expanded as you thought they would, and there's an extra ) from somewhere.
To get the expanded variadic arguments, use __VA_ARGS__, not .... The stray ) is at the call site.
So:
#define FUNCT(t,function_name,...) \
(t) function_name(__VA_ARGS__) { \
(void) *func_pointer = &(function_name); \
start_data(func_pointer, myclock());
#define RETURN(x) {stop_data(func_pointer, myclock()); return (x);}
FUNCT(BOOL, LMP, const int prof, const int nmo)
if (nmo <= 5 ||
prof > (prof_l / 3)) {
.... do long operations....
RETURN(FALSE);
}
... do more....
RETURN(TRUE);
}
As to whether this is worth trying (variadic macros came with C99, not all compilers implement that standard, and support might vary from compiler to compiler), I'm not certain. You are probably better off using each compiler's native profiling tools - you'll get better results with hopefully less overhead.
It is much easier to instrument your functions at the calling side instead of the function side. A macro can have the same name as a function. Declare your replacement function somewhere
double myfunc_wrapper(int someArg) {
double ret = 0;
// do something before
...
// now call it
ret = (myfunc)(someArg);
// Then do something after
....
return ret;
}
Just to be sure put the () arround the call itself to be sure that always a function is called and not a macro.
And then "overload" your function with a macro
#define myfunc(...) mfunc_wrapper(__VA_ARGS__)
with that idea you can replace your function on the fly in the compilation units that interes you.
in addition to Mat, there is a ergonimical problem with using #define RETURN(x) {...}:
if (test)
RETURN (TRUE);
else
RETURN (FALSE);
will evaluate to
if (test)
{...}
; // <syntactical error
else
{...}
;

Evaluate macro parameter once only

In the following code, whatever is passed as retval is evaluated as given for every use of that token.
#define _CPFS_RETURN(commit, retval) do { \
util_cpfs_exit(commit); \
return retval; \
} while (false)
#define CPFS_RETURN_BOOL(retval) do { \
_CPFS_RETURN(retval, retval); \
} while (false)
For example given the use CPFS_RETURN_BOOL(inode && file_truncate(inode, len));, this is generated:
do {
do {
util_cpfs_exit(inode && file_truncate(inode, len));
return inode && file_truncate(inode, len);
} while (0);
} while (0);
Evidently I don't want to execute the statement inode && file_truncate(inode, len); more than once.
How can I ensure that the given tokens are evaluated before being pasted helter-skelter?
Update
I believe I have good reason to use macros here. Where possible, code is put into real functions (such as util_cpfs_exit) which are invoked from a set of macros I'm using. The macros vary based on the return type: in C++ I'd have explicit templates to handle this.
As your macro vary on the return type, you can evaluate the retval expression and store it in a variable of the right type inside the first level of macro then use this variable. ie:
#define CPFS_RETURN_BOOL(retval) do { \
bool _tmp_ = retval;
_CPFS_RETURN(_tmp_, _tmp_); \
} while (false);
If I understand well, that should be enough for your use case, and for other use cases you can use functions.
In your exemple you'll get:
do {
bool _tmp_ = inode && file_truncate(inode, len);
do {
util_cpfs_exit(_tmp_);
return _tmp_;
} while (0);
} while (0);
Looks fine.
PS: as a sidenote if you always use _CPFS_RETURN indirectly through another macro following the above model, there is no need to protect it by a do { } while (false);. Also, putting a semi-colon after the while(false) removes most of the interest of using it... that may be a good example of why C macros are dangerous and hides easy pitfalls. Not that I dislike macros, quite the contrary. I'm from the (probably rare) kind of people that would prefer C macros to be enhanced to bypass their current limitations to become really cool (and no, C++ templates are not enhanced macros, they are something completely different).
I would recommend that you evaluate the condition first.
i.e.
bool val = inode && file_truncate(inode, len);
Other than that may advice would be to steer well clear of macros, they seem unnecessary in this instance, use functions instead.
Write a function instead of using a macro. In this case, where you want to build a return statement in, you might be better off just writing the code explicitly instead of relying on a macro to hide what you're doing.
Change the macro to a "static inline" function. In gcc, it's as fast as a macro.
http://gcc.gnu.org/onlinedocs/gcc/Inline.html

Resources