Monday, April 19, 2010

Learning from Linux Kernel

1. container_of: Being passed a pointer, it returns the pointer to the structure that contains this.


#define container_of(ptr, type, member) ({                      \
        const typeof( ((type *)0)->member ) *__mptr = (ptr);    \
        (type *)( (char *)__mptr - offsetof(type,member) );})
where
#define offsetof(type, member) \
    ((size_t) ( (char *)&((type *)(0))->member - (char *)0 ))

Monday, April 5, 2010

My Favourite Quotes

Pascal : "If I had more time, I would written you a shorter letter "


Einstein : "God doesn't play dice with the Universe"


Neils Bohr : "Prediction is very difficult, especially if it's about the future"

Thursday, March 11, 2010

Profiling Tools : Valgrind & co

VALGRIND
============
We will use valgrind with following tools :-

> memcheck  [default]
> callgrind
> cachegrind
> massif
> helgrind

valgrind --tool=memcheck [prog-name] [prog-argumements]
a simple example is valgrind --tool=memcheck ls -al
===================================================
nemesis@nemesis-laptop:~$ valgrind --tool=memcheck ls -al
==3497== Memcheck, a memory error detector              
==3497== Copyright (C) 2002-2009, and GNU GPL'd, by Julian Seward et al.
==3497== Using Valgrind-3.5.0-Debian and LibVEX; rerun with -h for copyright info
==3497== Command: ls -al                                                        
==3497==                                                                        
total 13300

==3497==
==3497== HEAP SUMMARY:
==3497==     in use at exit: 14,671 bytes in 95 blocks
==3497==   total heap usage: 1,902 allocs, 1,807 frees, 150,632 bytes allocated
==3497==
==3497== LEAK SUMMARY:
==3497==    definitely lost: 200 bytes in 3 blocks
==3497==    indirectly lost: 240 bytes in 20 blocks
==3497==      possibly lost: 0 bytes in 0 blocks
==3497==    still reachable: 14,231 bytes in 72 blocks
==3497==         suppressed: 0 bytes in 0 blocks
==3497== Rerun with --leak-check=full to see details of leaked memory
==3497==
==3497== For counts of detected and suppressed errors, rerun with: -v
==3497== ERROR SUMMARY: 0 errors from 0 contexts (suppressed: 33 from 10)

===================================================
[NOTE]: In the above trace "3497" which precedes every line of Valgrind output is the pid of the program being run under valgrind i.e. ls -al in this case.

PRE-REQUISITES
==============

1. Strongly recommended to run the program with -g (with debug symbols) option. It is generally true of all profiling tools.

2. Use no optimization or as a compromise -0

Wednesday, March 10, 2010

Bitfields

-- Used for saving space
-- NOT portable across platforms
-- bitfield declaration cannot use const and volatile qualifiers
-- Max bit field length is 64 bits. Using more than 32 bits is likely to be non portable

-- CANNOT take the address of a bitfield
-- CANNOT have a pointer to a bitfield
-- CANNOT define an array of bitfields

-- A bitfield of size 0 will force alignment to the nearest word boundary [depends actually on compiler behaviour -- some compilers may pad to the size of the base type...some to the word boundary]

-- A structure containing bitfields is suitably/appropriately padded.

Tuesday, March 9, 2010

Cool Compile time check

If only we could evaluate a condition at compile time instead of link or run time. Well there is a way ...
Picked up this nifty trick from the linux kernel code.

#define BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 *!!(condition)]))

Awesome piece of code ....It's a beauty...

Concept : Array of negative size is illegal. Remember array of size 0 is possible
Therefore if a condition evaluates to true we have :-
void(sizeof(NEGATIVE ARRAY) which would trigger a compile time error

If the condition is false, we have :-

void (sizeof(char[1 - 2 * !!(0))])
==> void(sizeof(char[1-2* !1])
====>void(sizeof(char[1-0])
======>void(sizeof(char[1])
========> void(const number) ====> This has no impact on C code although it is a valid expression.
you could have 1; anywhere in the code but to be "gcc warning free" it is better to have (void) 1 .


Here is a simple example, don't worry about the logic as I just needed a condition and do NOT mean to say that size of int should be smaller than that of a char :)

#define ADY_BUILD_BUG_ON(condition) ((void)sizeof(char[1 - 2 * !!(condition)]))

int main(int argc, char *argv [])
{
   /* will not compile */
   ADY_BUILD_BUG_ON(sizeof(char) <  sizeof(int));
}

and here is what we get :--

nemesis@nemesis-laptop:~/test_code$ gcc build_bug_on_example.c
build_bug_on_example.c: In function ‘main’:
build_bug_on_example.c:9: error: size of array ‘type name’ is negative