Re: what is static inline void tvec_base

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Fri, Aug 27, 2010 at 10:53 PM, James Bond <jamesbond.2k.g@xxxxxxxxx> wrote:
>
>
>
> Hi,
> I am new to kernel development.
> So after being able to have some basic understand of some things I just went
> through source code.
> I was going through a file known as
> linux-2.6.34/kernel/timer.c and found following code.
> I want to understand what is it doing.
> What should I be reading to be able to understand it?
>
> static inline void
> timer_set_base(struct timer_list *timer, struct tvec_base *new_base)
> {
>         timer->base = (struct tvec_base *)((unsigned long)(new_base) |
>                                       tbase_get_deferrable(timer->base));
> }
>


What static does is to create a label for a certain global memory
chunk and give that a value at compile time, plus not making it
available to the linker.

Look at these examples

static int mystatic = 6;

int main(void)
{
    return 0;
}

Generated ASM is as follows:
Code:

	.file	"static2.c"
	.data
	.align 4
	.type	mystatic, @object
	.size	mystatic, 4
mystatic:
	.long	6
	.text
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, %eax
	popl	%ebp
	ret
	.size	main, .-main
	.ident	"GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
	.section	.note.GNU-stack,"",@progbits

Compare that with declaring the global variable as non-static:
Code:

int mynonstatic = 6;

int main(void)
{
    return 0;
}


Code:

	.file	"nonstatic2.c"
.globl mynonstatic
	.data
	.align 4
	.type	mynonstatic, @object
	.size	mynonstatic, 4
mynonstatic:
	.long	6
	.text
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, %eax
	popl	%ebp
	ret
	.size	main, .-main
	.ident	"GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
	.section	.note.GNU-stack,"",@progbits

The only difference is that in the non-static case, there's the .globl
mynonstatic that makes that symbol available to the linker.
Now, careful observation will make you notice that both global
variables are declared as labels, exactly the same way as main is. ASM
doesn't really distinguish between functions and variables (the
@function and @object thing is just an optimization gcc does): all
there is memory addresses that you conveniently can refer to with a
label. So, when you declare a function static, what will happen is
exactly the same: the function is given a value (its code) and make it
unavailable to the linker... exactly what was done to the variable.

Here you have the C and ASM for a static function:
Code:

	.file	"stat_func.c"
	.text
	.type	something, @function
something:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, %eax
	popl	%ebp
	ret
	.size	something, .-something
	.ident	"GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
	.section	.note.GNU-stack,"",@progbits

Again, the value for something is its code, it's a global value but
not available to the linker because there's no .globl something.

What about local static variables? Actually, the idea of local
variables is lost when compiling C to ASM. What you have is a global
stack that each function is in charge to clean up when returning...
therefore making its local values no longer available outside the
function... but place a jmp and the value will be available. What
happens with static variables is that the static again sets up a value
at compile time and makes the symbol unavailable for the linker... as
you'll see here:

Code:

int main(void)
{
    static int mystatic = 6;

    return 0;
}

Code:

	.file	"static.c"
	.text
.globl main
	.type	main, @function
main:
	pushl	%ebp
	movl	%esp, %ebp
	movl	$0, %eax
	popl	%ebp
	ret
	.size	main, .-main
	.data
	.align 4
	.type	mystatic.1248, @object
	.size	mystatic.1248, 4
mystatic.1248:
	.long	6
	.ident	"GCC: (Debian 4.4.4-8) 4.4.5 20100728 (prerelease)"
	.section	.note.GNU-stack,"",@progbits

The only difference here is that the .data section has been placed
*after* the main "rets" (a kind of return you have in ASM...)... ASM
indentation is awful here, but actually main ends at the ret, not at
the mystatic.1248 label. Ok, I'm not sure why the name is "mangled"
but it's clear that the variable is declared as global even when we
declared it as local in C. What will happen is that the C compiler
will restrict the usage of that symbol to the main function, but you
clearly see that it's just a way to create the illusion of locality...
It's actually a global and that's why its value is persistent across
the program's execution.

So, in summary, it seems that the real effective meaning (I don't care
what the standard says) of static is "Make a global memory address not
be available to the linker"... therefore we can explain why is it used
both for functions and variables.

Of course, tutorials are doing fine to explain this the way they do...
As you see, you have to step down to ASM in order to make some sense
of this. Also, this is another great reason of why C is such a pain to
use: in the end you still have to understand the basics of ASM...
while to use bash, Perl, Python you don't need to know C (or the
language the implementation is written in).

--
To unsubscribe from this list: send an email with
"unsubscribe kernelnewbies" to ecartis@xxxxxxxxxxxx
Please read the FAQ at http://kernelnewbies.org/FAQ




[Index of Archives]     [Newbies FAQ]     [Linux Kernel Mentors]     [Linux Kernel Development]     [IETF Annouce]     [Git]     [Networking]     [Security]     [Bugtraq]     [Yosemite]     [MIPS Linux]     [ARM Linux]     [Linux RAID]     [Linux SCSI]     [Linux ACPI]
  Powered by Linux