>>>>> "Borislav" == Borislav Petkov <petkov@uni-muenster.de> writes: Borislav> Hi there people, Borislav> I'm trying to figure out for several days now how the following functions: Borislav> <from include/asm-i386/thread_info.h> Borislav> 86 /* how to get the thread information struct from C */ Borislav> 87 static inline struct thread_info *current_thread_info(void) Borislav> 88 { Borislav> 89 struct thread_info *ti; Borislav> 90 __asm__("andl %%esp,%0; ":"=r" (ti) : "" (~(THREAD_SIZE - 1))); Borislav> 91 return ti; Borislav> 92 } Borislav> I've read several tutorials on inline asm but what is peculiar here is, that Borislav> the input operand's constraint is "" (nothing) What version of the kernel is that? There's no such thing in 2.6.6 and both gcc 3.3 and gcc 3.5 report an error compiling your example. The constraint must be "0", so initially the constant is loaded into a register and the result is obtained in the same register ("0" means "the same constraint as the one of operand 0"). Borislav> I also have another question: Borislav> <from include/linux/kernel.h> Borislav> 203 /** Borislav> 204 * container_of - cast a member of a structure out to the containing Borislav> structure Borislav> 205 * Borislav> 206 * @ptr: the pointer to the member. Borislav> 207 * @type: the type of the container struct this is embedded in. Borislav> 208 * @member: the name of the member within the struct. Borislav> 209 * Borislav> 210 */ Borislav> 211 #define container_of(ptr, type, member) ({ \ Borislav> 212 const typeof( ((type *)0)->member ) *__mptr = (ptr); \ Borislav> 213 (type *)( (char *)__mptr - offsetof(type,member) );}) Borislav> I can't understand the ((type *)0) part - type is passed as an argument and it Borislav> is some struct pointer but the trailing 0 ... what does it actually do? No type is passed as an argument as this is a macro. The syntactic construct "typeof (expr)" is parsed as a type, the type of the expression (surprise). For example: "int a; typeof (a) b;" - "a" and "b" have the same type, "int" "struct S { int x, y; } a; typeof (a.x) b;" - "b" has type "int" "((struct S *)0)" is an expression of type "pointer to S", thus "((struct S *)0)->x" is an expression of type "int", thus "typeof (((struct S *)0)->x) b" declares an interer variable "b" Borislav> offsetof is similar: Borislav> <from include/linux/stddef.h> Borislav> 12 #define offsetof(TYPE, MEMBER) ((size_t) &((TYPE *)0)->MEMBER) "(type *)0" is simply an idiom for obtaining a fictitious object out of the thin air. Compare to "struct S *a; ptrdiff_t off = (char *)&a->y - (char *)a" Obviously the value of "off" is the same no matter the value of "a", so we can just as well use "0", thus obtaining "(char *) &((struct S *)0)->a - (char *)0". Next we remove the gratuitous subtraction of zero, not having subtraction we don't need any more the cast to "char *", hence "&((struct S *)0)->a" and to make it reusable for any member of any structured type we make it into a macro #define offsetoff (S,a) (&((S *) 0)->a) QED :) ~velco -- Kernelnewbies: Help each other learn about the Linux kernel. Archive: http://mail.nl.linux.org/kernelnewbies/ FAQ: http://kernelnewbies.org/faq/