Linux Kernel Architecture

(Jacob Rumans) #1
Mauerer app03.tex V1 - 09/04/2008 6:11pm Page 1198

Appendix C: Notes on C


The pre-processor constantLOCK_PREFIXis used to make the operation atomic. On single-processor
systems, this constant is empty because a single assembly statement that cannot be interrupted is used to
set the bit. On SMP systems, the constant expands tolock. This is a separate assembler statement, known
as alock prefix, which prevents all other processors of the system from interfering with the following
statement, and thus makes it atomic.

Naturally, not only individual assembler statements are used in inline code. For example, atomic incre-
menting of an integer variable is a complex operation on Alpha CPUs as shown here:

include/asm-alpha/atomic.h
static __inline__ void atomic_add(int i, atomic_t * v)
{
unsigned long temp;
__asm__ __volatile__(
"1: ldl_l %0,%1\n"
" addl %0,%2,%0\n"
" stl_c %0,%1\n"
" beq %0,2f\n"
".subsection 2\n"
"2: br 1b\n"
".previous"
:"=&r" (temp), "=m" (v->counter)
:"Ir" (i), "m" (v->counter));
}

This appendix does not discuss why so much code is needed because that would necessitate an excursion
into the characteristics of Alpha processors. The sole aim of the example is to demonstrate that compar-
atively complicated operations that do not just use single assembler statements can be implemented in
inline assembler.

C.1.8 __builtinFunctions


__builtinfunctions provide the compiler with additional options to perform more manipulations on
programs than would normally be possible in C without having to resort to the inline assembler.

Each architecture defines its own set of__builtinfunctions, which are described in detail in the GCC
documentation. A number of__builtinvariants are common to all architectures and two of these are
used by the kernel.

❑ __builtin_return_address(0)yields the return address to which code flow is positioned at the
end of a function. As described previously, this information can also be extracted from the acti-
vation record. This is actually an architecture-specific task but the preceding__builtinfunction
makes a universal front-end available for it.
The argument specifies how many levels the function should work upward in the activation
records. 0 delivers the return address to whichthe function currently running will return, 1
yields the address to which the function that called the current function will return, and so on.

On some architectures (IA-64, for instance), there are basic difficulties in
determining activation records. For thisreason, the function always returns the
value 0 for arguments larger than 0.
Free download pdf