Implémentation du concept de Recovery block en C
Pour expérimenter votre implémentation vous utiliserez les deux implémentations fact1 et fact2 de la fonction factorielle (l’une est défaillante, l’autre non (cas de défaillance par dépassement de capacité de représentation).
Vous trouverez le fichier objet facotrielle.o dans cette archive
https://trobert.wp.imt.fr/files/2019/12/factoriellev2.zip
A) Rappels
Pour la restauration d’état, nous vous demandons d’utiliser sigsetjmp et setlongjmp.
Vous pouvez positionnez le point de reprise en utilisant sigsetjmp plutôt que setjmp (cf. man sigsetjmp). Lors de l’appel à la fonction sigsetjmp on mettra le second paramètre à 1.
Vous pouvez déclencher la restauration d’état à partir de en utilisant la fonction siglongjmp.
En cas de problème cf https://inf104.wp.imt.fr/tp-signaux/
B) Implémentation du recovery block
1) Implémentez une fonction main ou vous appelez simplement fact1(4), puis affichez le résultat puis fact(30) et au final fact(-1).
fact2 retourne -1 pour les nombres négatifs et la valeur attendu jusqu’à n=21.
2) Utilisez la restauration d’état pour exécuter fact2 en cas de défaillance
3) Utilisez la déclaration de la structure rb_t pour implémenter le recovery block à partir de la restauration d’état en supposant alternative1= fact1 et alternative2=fact2.
Et le code de lancement suivant:
#include <stdio.h>
#include « RB.h »
int main(int argc, char* argv[]){
long long aux=0;
printf(« Initialisation du recovery block »);
rb_t myRB;
init(&myRB);
run(&myRB, 4, &aux);
printf(« la valeur de 4! est %lld », aux);
aux=0;
run(&myRB, 17, &aux);
printf(« la valeur de 17! est %lld »,aux);
if (run(&myRB, -1, &aux)==-1) /// cas d’erreur -1 =>failed
{
printf(« la valeur de ! est %lld »,aux);
}
}
Il est possible de déclarer une variable de type pointeur de fonction de la manière suivante. Si vous souhaitez définir une fonction de type int f (int) vous devez déclarer int (* pfrf) (int); pour que prtf soit un pointeur de f. Dans ce cas il est possible d’écrire ptff=f;
Créez un fichier RB.h avec le contenu suivant :
typedef struct {
long long (*alternative1)(long);
long long (*alternative2)(long);;
int (*acceptanceTest)(long long,long);
} rb_t ;
void init(rb_t*);
void run (rb_t *, long , long long*);
Créez un fichier RB.c qui contiendra le code permettant de créer votre recovery block. Ce code devra contenir l’implémentation des fonctions
void run (rb_t *, long , long long*);
et void init(rb_t*);
Utilisez la structure suivante pour implémenter le principe du recovery block de manière générique en supposant que vous n’avez que des défaillances en valeur.
typedef struct {
long long (*alternative1)(long);
long long (*alternative2)(long);
int (*acceptanceTest)(long long,long);
} rb_t ;
Il y a défaillance en valeur si la fonction acceptanceTest retourne 0
Dans notre cas le test d’acceptation sera passé si le résultat est positif.
Autre mise en œuvre : http://people.cs.aau.dk/~apr/ITV-MD3/Seminar2/RecoveryBlocks/sorting.html