Friday, 01 December 2017
|
Écrit par
Grégory Soutadé

Tux, the Linux mascot

For some projects I have to work inside Linux kernel code and, as a developer, I have my own preferences for coding rules (not stable for variable/function naming in facts...) . Especially, I prefer 4 spaces for indentation, curly brackets at a newline. But, the kernel is full of narcissists dictatorscoders and a strict set of coding rules has been determined some years ago. It can be found in Documentation/CodingStyle. Linux is a big project with thousands of people working on it, so I agree that it requires some code normalization for all contribution. Even if you don't plan to verse your patches into upstream, it's good to follow these rules. Here is some tips to comply with it.

First, as an emacs user I have my own rules in my ~/.emacs configuration file. But, when I work on Linux kernel, I want "linux" rules to be applied. A tip from emacswiki allows to automatically switch when a file with "linux" in its path name is found :

(defun maybe-linux-style ()
  (when (and buffer-file-name
         (string-match "linux" buffer-file-name))
    (c-set-style "Linux")
    (c-set-indentation-style "linux")
    (indent-tabs-mode t)
    ))
(add-hook 'c-mode-hook 'maybe-linux-style)
(add-hook 'before-save-hook 'delete-trailing-whitespace)

Another tip I use is a modified pre-commit hook that will checks my modifications before validate the commit. Edit you .git/hooks/pre-commit with the following lines :

#!/bin/sh
#
# An example hook script to verify what is about to be committed.
# Called by "git commit" with no arguments.  The hook should
# exit with non-zero status after issuing an appropriate message if
# it wants to stop the commit.
#
# To enable this hook, rename this file to "pre-commit".

temp_file=`mktemp`
files=`git diff --name-only`
to_diff=""
for file in ${files} ; do
    # Filter .c and .h files
    echo ${file} | grep ".h$" > /dev/null 2>&1
    if [ $? -ne 0 ] ; then
    echo ${file} | grep ".c$" > /dev/null 2>&1
    if [ $? -ne 0 ] ; then
        continue
    fi
    fi
    # Add not deleted file
    if [ -f ${file} ] ; then
    to_diff="${to_diff} ${file}"
    fi
done
git diff --no-color -u --summary ${to_diff} > ${temp_file}
./scripts/checkpatch.pl --no-signoff --min-conf-desc-length=0 --no-summary --mailback ${temp_file}
ret=$?
rm -f ${temp_file}
exit $ret

Don't forget chmod +x .git/hooks/pre-commit

Unfortunately, this hook can't be stored into the central repository and have to be copied each time you clone it (or install a server hook). If you want to bypass it (for some reasons), just commit with "--no-verify" option.

Finally, when you already have a custom codebase ready and commited, you can use some scripts provided by the kernel team to check for coding rules. The first is scripts/Lindent that will indent your file following the kernel coding rules via indent util (needs to be installed). The second is scripts/cleanfile which remove unnecessary whitespaces. The third is scripts/checkpatch.pl -f that will checks the whole file (and not just a patch).

Tuesday, 28 November 2017
|
Écrit par
Grégory Soutadé

Logo Cross Amnesty International

L'édition 2017 du cross Amnesty International se déroulera le dimanche 10 décembre place Bermond. Comme l'année dernière, une collecte de vos anciennes chaussures de sport sera réalisée au profit des réfugiés. Le site a fait peau neuve, pas le principe : 4 parcours de 1km, 4km et 11km (compte pour le challenge 06) dans la forêt Valbonnaise. Les départs seront donnés à 10h, 10h30 et 11h15. Le tout pour la modique somme de 10€ (12€ sur place), excepté pour le 1km qui est gratuit.

PS : N'oubliez pas le certificat médical !

Monday, 23 October 2017
|
Écrit par
Grégory Soutadé

Départ course des paroisses

Cette fois on y croit ! Un nouveau site web est mis en ligne pour cette 21e (bis) édition. La date, les horaires, le parcours restent quant à eux inchangés. Le samedi 11 novembre 2017 à 11h30 et pour 5€, les trois courses (1km, 1.7km et 4km) débuterons, tandis qu'à 13h, le 6km (8€) et le 12km (12€) s'élanceront depuis le col de Belle-Barbe (commune d'Agay, parc de l'Estérel). Prévoir 1€ supplémentaire via l'inscription en ligne et 3€ sur place. Les dons supplémentaires pour la Paroisse sont appréciés (des sous, des sous pour la Paroisse).

Pour les jeunes (mais pas trop quand même), une page Facebook est ouverte afin de suivre l'actualité de la course.

Retour : Enfin ! Après trois années de disette, j'ai pu participer à cette course dans le massif de l’Estérel ! Le cadre est idéal. Malheureusement, on n'en profite pas à 100% : il s'agit d'un trail plus que d'une course, donc il ne faut pas lâcher des yeux le sol trop longtemps sous peine de buter sur une pierre. Le temps était parfait : ciel voilé, température agréable (~17°C). Les bénévoles présents en masse (un grand merci à eux !). L'ambiance familiale, cachant pourtant le niveau relevé des participants (375 dont la moitié sur le 6km et 12km). Pour toute inscription, on a même droit à une bière gratuite en fin de course. Bon, on pourra l'échanger contre une crêpe, gaufre, part de tarte ou autre si l'envie nous en dit.

Pour être tout à fait exact, le parcours 2017 ne fait que 11,55km (et pas 12km). Ceci dit, il fallait bien regarder le profil de la course avant de s'élancer. En effet, si on commence tranquillement sur des pistes relativements larges, mais caillouteuses, vers les 3,5km commence l'ascension : 1km à 7% de dénivelé, puis 1km plus tranquille et encore 1km à 7%... La gestion est primordiale. Garder le rythme, ne rien lâcher dans la tête. On s'accroche aux baskets de nos prédécesseurs. Au "sommet" se trouve le ravitaillement, pas le temps de s'arrêter ! Le parcours bascule sur des sentiers plus étroits dont la pente est non négligeable et toujours aussi caillouteuse, on regrette la côte. Ce dernier se resserre encore durant une montée sur une cornière (magnifique) (on regrette d'avoir regretté), avant de basculer de nouveau dans une descente ardue pour finalement rejoindre une piste large. C'est le second point de ravitaillement, aux 8km, ne pas se laisser tenter par un verre d'eau ! Les 2km suivants sont traîtres puisqu'il s'agit d'une pente à presque 5%. Les jambes ne forcent pas malgré la vitesse, mais le cœur est au plafond. La dernière partie est également rapide, avec de nouveau des sentiers étroits, parsemés d'embûches, pour finalement retomber sur la route goudronnée synonyme de fin de course. Dans cette dernière relance, il ne faudra pas oublier de sourire à l'appareil photo disposé sur la ligne d'arrivée.

Il n'y avait hélas pas de curée sur cette course, que le lapin courant en croks aurait pu poursuivre (1h30, bravo à lui) ! Dans tout ce joyeux bordel, je termine en 59'16 (87/184), satisfait de ma gestion de l'épreuve.

Wednesday, 04 October 2017
|
Écrit par
Grégory Soutadé

Logo Odyssea

Après une année blanche, Odyssea revient à Cannes ! C'est l'année du changement : nouvelle date et nouveau parcours, plus accessible. C'est donc le dimanche 29 octobre 2017 que se déroulera cette édition, sur le front de mer entre Cannes et Cannes La Bocca (départ square Mistral). Les 3 formules sont toujours disponibles :

  • 10km course
  • 5km marche/course
  • 1km enfant

Attention cependant, l'ordre des départs est inversé ! On commence désormais par le 10km pour finir par le 5km. Concernant les tarifs, ils sont de 4€ pour le 1km, 12€ pour le 5km et 15€ pour le 10km (avec un certificat médical obligatoire pour les non licenciés). En hausse donc par rapport aux éditions précédentes, probablement pour pallier (entre autres) aux surcoûts liés à la sécurité. Ce qui ne change pas est la destination des fonds collectés : à savoir les associations locales Toujours Femme pays de Grasse, SOS CANCER DU SEIN PACA et DEFI DE FEMMES.

Parcours Odyssea Cannes 2017

Retour : Une bien belle journée pour cette édition 2017 (bon, ça fait 6 mois qu'il ne pleut plus dans la région...). Le changement de formule a porté ses fruits : en plein octobre rose, c'est 2200 participants qui sont venus relever le défi (1500 et 1600 les années précédentes) et 16 000€ récoltés. L'objectif des organisateurs était de 3000 participants, on s'en rapproche doucement, surtout que le circuit étant plus accessible, il ne peut que gagner en popularité. Personnellement je termine la course en 47'24 à la 149e position (sur 643), ce qui est honorable. Inflation oblige, il faudra faire mieux l'année prochaine !!

Wednesday, 27 September 2017
|
Écrit par
Grégory Soutadé

For a human, it's pretty simple to divide a number by ten because we used to calculate in ten base everyday. But ... a computer handle numbers in base 2. It doesn't means that it can't compute a division with a number that is not a power of 2, but operations are really faster in this base. Especially if you don't have floating point unit.

At work, I had to re implement the function "printf". To display decimal integers, I use an algorithm like :

while (value)
{
    *cur_ptr = '0' + (value%10);
    value = value/10;
    ...
}

This works fine, but two GCC builtin functions udivdi3 and umoddi3 are called which represent an amount of 3.5kB of code. So, I was looking for a code size optimized implementation on the Internet and didn't found my way.

Finally, I wrote my own. It's a basic one inspired from child learning method :

01. void div10(unsigned value, unsigned* _res, unsigned* _mod)
02. {
03.    unsigned res = value / 8;
04.    unsigned mod = value - (res*10);
05.
06.    while (mod > 10)
07.    {
08.        res -= 1;
09.        mod += 10;
10.    }
11.
12.    *_res = res;
13.    *_mod = mod;
14. }

This algorithm is a basic approach to division. It tries all numbers until it find the good one.

First thing : why I use variables instead of directly write values to pointers ? It's to indicate to GCC that they are temporary values which can be kept into registers and not written every loop into the memory (save instructions and memory accesses).

Line 3 is the begining. We will start at value / 8 which can be easily done by the computer because it is equivalent to a right shift of 3 bits (only one instruction). Note that 8 is the closest power of two to 10 and x/8 is greater than x/10 .

Line 4 is the computation of difference (distance) between my result multiplied by 10 and the current value. For the final result, this difference must be less than 10 (which correspond to the modulo).

Line 6 : while its not the case, we decrement result and increment modulo. Why incrementing modulo ? It's an optimization of the re computation of :

mod = value - (res*10);

If res is decremented, modulo is incremented as value is fixed. So, a simple addition is sufficient here.

There is another big trick in this code : the substract line 4 is done with UNSIGNED values and the result of line 4 is most of the time negative ! Which corresponds to big unsigned value (> 2147483648) that also implies > 10. We have to wait an integer overflow for mod to become positive and when it's done, we get the current modulo value (at least MAXLONGINT+10 = 9) !

If we does opposite operation ((res*10) - value), we have to decrement mod until it becomes less or equals to 0. But, in this case, all operations must be done in signed mode and the final modulo must be inverted at the end (more instructions) :

void div10(unsigned long value, unsigned long* _res, unsigned long* _mod)
{
    unsigned long res = value / 8;
    unsigned long mod = (res*10) - value;

    while (((signed long)mod) > 0)
    {
        res -= 1;
        mod -= 10;
    }

    *_res = res;
    *_mod = (unsigned long)-(signed long)mod;
}

Facts : the unsigned version of my algorithm is 15 instructions while udivdi3 + umoddi3 is 881 instructions. Wonderful !

Beware : this algorithm is slow. For small numbers it's not import because x/8 =~ x/10, but when x becomes bigger, the difference can be huge and requires one decrement, one increment and one test multiplied (x/8 - x/10)/10 times. For 32 bits numbers, it's 10 737 418 loops...

This algorithm can be extended to any divisor by replacing hardcoded divisor with a parameter and a function that finds the nearest and inferior power of 2.

void div(unsigned long value, unsigned long divisor, unsigned long* _res, unsigned long* _mod)
{
    unsigned long res, mod, tmp = divisor, power2 = 0;

    /* Nearest inferior power of 2 */
    while (tmp > 1)
    {
        tmp >>=1;
        power2++;
    }

    res = value >> power2;
    mod = value - (res*divisor);

    while (mod > divisor)
    {
        res -= 1;
        mod += divisor;
    }

    *_res = res;
    *_mod = mod;
}
Dernier gif les joies du code Quand mon environnement de développement n'est pas adapté