Qroc A23 - Architecture des systèmes à microprocesseur

Durée 2H00 - tous documents autorisés

5 rubriques indépendantes à 4 points

Performances du matériel (4 points)

Enoncé : un modem est configuré avec les paramètres suivants 19200 bps, 8 bits de données, 1 bit d'arrêt, pas de parité. Le processeur est un Risc 32 bits qui par hypothèse exécute 1 instruction par cycle d'horloge. La fréquence d'horloge est 250 MHz. La longueur moyenne d'une instruction est de 4 octets.

Un programme exécute l'instruction suivante :

	// point A
	writeComm( hModem, "Salut la compagnie" );
	// point B

L'appel à writeComm envoie la chaine "Salut la compagnie" au modem. C'est un appel bloquant : l'exécution ne se poursuit au point B que lorsque la sérialisation de la chaine à émettre est terminée. On admet que le programme dispose de 100% de la puissance CPU.

Question : estimer le temps passé pour passer du point A au point B du programme. Calculer le nombre moyen d'instructions exécutées pendant ce temps.

Complément d'énoncé : Il s'agit toujours du même processeur. Un algorithme de compression d'images animées doit traiter 24 images CIF (288x352) true color (24 bits par pixel) en 1 seconde. Le système d'exploitation consomme en pointe un maximum de 20% de la puissance CPU disponible.

Question : Calculer le nombre moyen d'instructions par pixel que l'algorithme ne doit pas dépasser.

Pointeurs (4 points)

int tab[10];

int raz( int *tab1 ) {
	int i=0;
	while(i<10) {
		// point A
		*tab1=0;
		tab1++;
		i++;
	}
}

int main() {
	raz( tab );
}

On considère un instant de l'exécution telle que i=5 au point A (*tab1=0 va être exécuté)

Dessinez avec des schémas d'occupation de la mémoire, les variables mises en jeu, leurs éventuelles relations, leur contenu : on mettra un "?" pour un contenu indéterminé ou inconnu)

struct enr {
	char nom[25];
	char prenom[25];
	int age;
};

void inputString( char invite[50], char string[25] ) {
	printf( "%s", invite );
	scanf( "%s", string );
}

int main() {
	struct enr e;
	inputString( "Entrez votre prénom : ", xxxxxx );
	...
}

Dans le code ci-dessus, par quoi doit-on remplacer xxxxxx pour saisir le prénom dans la structure e ?

Dessinez les schémas d'occupation mémoire représentant les objets e, "Entrez votre prénom : ", invite, et string., leurs éventuelles relation, leur contenu : on mettra un "?" pour un contenu indéterminé.

Paramètres, variables locales et globales (4 points)

int tab[50];
int dichoSearch( int left, int right, float value ) {
	ind middle;
	// point A
	middle=(left+right)/2;
	...
	return dichoSearch( left, middle, value );
	...
}

int main() {
	int toSearch, ind;
	...
	printf( "Entrez la valeur à rechercher : " );
	scanf( &toSearch );
	ind = dichoSearch( 0, 49, toSearch );
	...
}

Dessinez le schéma de pile au point A quand l'exécution de dichoSearch a lieu pour la 1ère fois.

Donnez le code assembleur correspondant à return dichoSearch( left, middle, value );

Compilation (4 points)

Implanter en langage d'assemblage la procédure initResources.

#define TRUE (1)
#define FALSE (0)
#define MAX_SECT 8000

struct resource {
	int busy, chain;
};

struct resource resources[MAX_SECT];
int freeChain;
void initResources() {
	int i;
	for (i=1; i<MAX_SECT-1; i++) {
		resources[i].busy = FALSE;		// not busy
		resources[i].chain = i+1;			// next is following in the tab
	}
	resources[MAX_SECT-1].busy = FALSE;	// not busy
	resources[MAX_SECT-1].chain = 0;		// end of chain
	freeChain=1;
}

Système d'exploitation (4 points)

Sur une carte à microprocesseur sans système d'exploitation, on souhaite pouvoir exécuter plusieurs processus en parallèle.

Tous les processus utilisent le même espace adressable.

Question : en quoi les fonctions setjmp et longjmp sont-elles intéressantes ? Répondre en deux lignes.

Pour simplifier, on suppose que les processus n'ont jamais besoin de s'attendre. Ils sont disciplinés : un processus travaille puis donne la main au processus suivant selon un ordre "tour de table" préétabli et fixe. On se limite ci-dessous à 2 processus mais on peut généraliser à un nombre quelconque de processus en changeant la valeur de MAX_PROC.

Questions :

A quoi peut servir setjmp ?

A quoi peut servir longjmp ?

Implanter en C les macros J_EXISTE(procSuivant), DERNIER_J_EXISTE() et PROCESSUS_SUIVANT()

#define MAX_PROC 2
jmp_buf tabProc[MAX_PROC];
int currentProc;

#define J_EXISTE(procSuivant) { \
	// à compléter
}

#define DERNIER_J_EXISTE() { \
	// à compléter
}

#define PROCESSUS_SUIVANT() { \
	// à compléter
}

void proc1() {
	J_EXISTE( proc2 );// je signale que j'existe et le processus suivant est proc2
	// initialisations
	...
	while (1) {
		// corps du processus
		...
		PROCESSUS_SUIVANT();// passer au processus suivant
	}
}

void proc2() {
	DENIER_J_EXISTE();// j'existe et l'ordonnancement peut commencer
	// initialisations
	...
	while (1) {// boucle infinie
		// corps du processus
		...
		PROCESSUS_SUIVANT();// passer au processus suivant
	}
}

int main() {
	currentProc=0;
	p1();
}

Annexe

Extrait du manuel unix en ligne des fonctions setjmp et longjmp.

NAME

setjmp, longjmp - non-local goto

SYNOPSIS

#include <setjmp.h>
int setjmp( jmp_buf env );
void longjmp( jmp_buf env, int val );

DESCRIPTION

These functions are useful for dealing with errors and interrupts encountered in a low-level subroutine of a program.

setjmp() saves its stack environment in env for later use by longjmp().

longjmp() restores the environment saved by the last call of setjmp() with the corresponding env argument. After longjmp() is completed, program execution continues as if the corresponding call of setjmp() had just returned the value val. The caller of setjmp() must not have returned in the interim. longjmp() cannot cause setjmp() to return the value 0. If longjmp() is invoked with a second argument of 0, setjmp() will return 1. At the time of the second return from setjmp(), all external and static variables have values as of the time longjmp() is called (see example).

EXAMPLES

#include <stdio.h>
#include <stdlib.h>
#include <setjmp.h>

jmp_buf env;
int i = 0;

int main() {
	if (setjmp(env) != 0) {
		printf( "value of i on 2nd return from setjmp: %d\n", i );
		exit(0);
	}
	printf( "value of i on 1st return from setjmp: %d\n", i );
	i = 1;
	restore_env();
	/* NOTREACHED */
}

void restore_env() {
	longjmp(env, 1);
	/* NOTREACHED */
}

If this code is run, the output will be:

RETURN VALUES

If longjmp() is invoked with a second argument of 0, setjmp() returns 1. Otherwise, setjmp() returns 0.

WARNINGS

If longjmp() is called even though env was never primed by a call to setjmp(), or when the last such call was in a function that has since returned, absolute chaos is guaranteed.