LinuxQuestions.org

LinuxQuestions.org (/questions/)
-   Linux - Kernel (https://www.linuxquestions.org/questions/linux-kernel-70/)
-   -   Linux Kernel source code: What does static void __##func mean? (https://www.linuxquestions.org/questions/linux-kernel-70/linux-kernel-source-code-what-does-static-void-__-func-mean-4175682300/)

GreyGnome 09-17-2020 02:40 PM

Linux Kernel source code: What does static void __##func mean?
 
Hello,
I am trying to find out what the CAL interrupt in /proc/interrupts is all about. I understand it's "Function Call interrupts" but there seems to be a dearth of information about what a Function Call interrupt really is. I can presume it means "an interrupt generated whenever you call a system call", but I'm not so sure about that. "Prove it," I says to myself.

So I did some digging and uncovered https://elixir.bootlin.com/linux/v5....nel/smp.c#L234 (assume we're staying in x86-land for now), which says
Code:

DEFINE_IDTENTRY_SYSVEC(sysvec_call_function)
{
        ack_APIC_irq();
        trace_call_function_entry(CALL_FUNCTION_VECTOR);
        inc_irq_stat(irq_call_count);
        generic_smp_call_function_interrupt();
        trace_call_function_exit(CALL_FUNCTION_VECTOR);
}

. This is where the CAL counter gets incremented (it's irq_call_count). Perfect!

But I can't figure out how DEFINE_IDTENTRY_SYSVEC(sysvec_call_function) is called. What is a "sysvec_call_function"? That's not defined anywhere. And DEFINE_IDTENTRY_SYSVEC has a definition that I don't understand:

Code:

#define DEFINE_IDTENTRY_SYSVEC(func)                                        \
static void __##func(struct pt_regs *regs);

...

(at https://elixir.bootlin.com/linux/v5....dtentry.h#L239)

I think I might understand better if I could figure out what
Code:

__##func
means.

Can you help? Thanks.

powerboat9 09-17-2020 09:49 PM

While I'm not sure about the details of what you're working on, it looks like that's a token concatenation. Macros in c are based on tokens, not pieces of text like it may at first appear.

Ex:

#define FOO(x, y) x##y
FOO(abc, def)

would be processed roughly as follows:


[FOO] ( [abc] , [def] )
[abc]##[def]
[abcdef]

The "##" acts to concatenate the two identifier tokens into a single identifier token. Essentially, the macro would turn something like:

DEFINE_IDTENTRY_SYSVEC(my_cool_function)

into:

static void [__my_cool_function] ( struct [pt_regs] * [regs] ) ;

instead of:

static void [__] [my_cool_function] ( struct [pt_regs] * [regs] ) ;

which would produce a compiler error.

GreyGnome 09-18-2020 05:35 PM

Thanks. I understand, from your example, that the square brackets are not inserted by the macro preprocessor? In other words, technically it would be

static void __my_cool_function ( struct pt_regs *regs ) ;

and not

static void [__my_cool_function] ( struct [pt_regs] * [regs] ) ;

...Or do I misunderstand?

powerboat9 09-19-2020 09:17 AM

Yeah, sorry. I was using square brackets to show identifier tokens ([abc] was an identifier token named "abc").


All times are GMT -5. The time now is 05:03 AM.