uniroma1
.*_main.c
.cognome.nome
. Sulle postazioni del laboratorio sarà /home/biar/Desktop/cognome.nome/
.cognome.nome.zip
(zip -r cognome.nome.zip cognome.nome/
).cognome.nome.zip
.rm -rf cognome.nome
).Per maggiori informazioni fate riferimento al regolamento delle esercitazioni.
Tradurre in IA32 la seguente funzione matsum
definita in T1-mat-sum/e1.c
che calcola la somma degli elementi della matrice quadrata m
di dimensioni n x n
.
e1.c
int matsum(int** m, int n){
int i, j, s = 0;
for (i=0; i<n; ++i)
for (j=0; j<n; ++j)
s += m[i][j];
return s;
}
Scrivere la soluzione nel file T1-mat-sum/e1.s
. Usare il file T1-mat-sum/e1_eq.c
per sviluppare la versione C equivalente.
Si vogliono usare i segnali per creare un indicatore di progresso per la funzione do_sort
, che implementa un semplice algoritmo di ordinamento a bolle. L’indicatore di progresso è la percentuale di n
coperta da i
, vale a dire 100.0*i/n
. Si scriva la soluzione nel file E2-sort-timer/e2.c
modificandolo e aggiungendo quanto necessario al raggiungimento dell’obiettivo.
e2.c
#include "e2.h"
static void do_sort(int *v, int n) {
int i, j;
for (i=0; i<n; ++i)
for (j=1; j<n; ++j)
if (v[j-1] > v[j]) {
int tmp = v[j-1];
v[j-1] = v[j];
v[j] = tmp;
}
}
void sort(int *v, int n) {
// completare con gestione segnali...
do_sort(v, n);
}
Il risultato atteso deve essere come segue (ovviamente i numeri esatti delle percentuali possono variare):
start sorting...
-------------------------------
5.4%
11.2% <---- percentuali stampate dal gestore del segnale
17.1%
23.3%
29.7%
36.5%
43.7%
51.5%
59.7%
68.7%
79.0%
90.7%
-------------------------------
v[0]=0
v[1]=1
v[2]=2
v[3]=3
v[4]=4
v[5]=5
v[6]=6
v[7]=7
v[8]=8
v[9]=9
Suggerimento: rendere la variabile i
di do_sort
globale (dichiarata fuori dalla funzione) e tenere in un’altra variabile globale max
il valore di n
. In questo modo è possibile accedervi da un handler di un segnale che può stampare il rapporto tra i
e max
. Fare riferimento alla dispensa del corso sul segnali.
Domanda 1 Quale delle seguenti affermazioni è VERA?
waitpid(pid,&status,0)
se pid
è il PID di un processo zombiewait(&status)
ritorna, dopo che il processo figlio è terminato con exit(n)
, _exit(n)
o return n
, la variabile status
è uguale a n
WEXITSTATUS(status)
estrae il byte meno significativo dalla variabile int
status
Domanda 2 Dato il seguente codice, quale tra le seguenti affermazione è VERA?
"I'm child 0"
, "I'm child 1"
,"I'm child 2"
ma l’ordine delle stampe non è predicibile perché dipende dallo scheduler"I'm child 0"
, "I'm child 1"
, "I'm child 2"
"I'm child 2"
, "I'm child 1"
, "I'm child 0"
fork
Domanda 3 Data la seguente porzione di codice, quale delle seguenti affermazioni è FALSA?
A
è il numero di pagina dell’indirizzo di x
B
è l’offset (all’interno della pagina) dell’indirizzo di x
C
è il numero di pagina dell’indirizzo di x
D
è l’offset (all’interno della pagina) dell’indirizzo di x
E
è il numero di pagina dell’indirizzo di x
F
è l’offset (all’interno della pagina) dell’indirizzo di x
Domanda 4 Dato il seguente codice, selezionare la risposta corretta:
Domanda 5 Dato il seguente codice, selezionare la risposta corretta:
Domanda 6 Quale delle seguenti affermazioni è FALSA?
SIGKILL
non può essere ignorato né catturatoSIGSEGV
non può essere catturatoSIGCHLD
viene ignorato per defaultSIGINT
, se non catturato o ignorato, causa la terminazione del processo che lo riceveSIGQUIT
, se non catturato o ignorato, causa la terminazione del processo che lo riceveDomanda 7 Quale delle seguenti affermazioni è VERA?
kill -9 <pid>
invia il segnale SIGINT
al processo con pid <pid>
kill -SIGINT <pid>
non può essere catturato dal processo con pid <pid>
alarm(s)
invia il segnale SIGALRM
ogni s
secondiualarm(t, n)
invia un segnale dopo t
microsecondi e successivamente ogni n
microsecondiDomanda 8 Quale delle seguenti affermazioni è FALSA?
mmap
può essere usata per allocare al processo intere pagine di memoriammap
permette di specificare i permessi di accesso sulle pagine di memoria che allocamprotect
permette di specificare i permessi di accesso sulle pagine di memoria, ma solo se sono state allocate con mmap
mprotect
deve essere un indirizzo fisico (non logico)getpagesize()
restituisce la dimensione delle pagine di memoriae1_eq.c
#include "e1.h"
int matsum(int** m, int n){
int i, j, s = 0;
i=0;
L1: if (i>=n) goto E;
j=0;
L2: if (j>=n) goto F;
int* tmp = m[i];
s += tmp[j];
++j;
goto L2;
F: ++i;
goto L1;
E: return s;
}
es1.s
.globl matsum
matsum: #int matsum(int** m, int n) {
# s <-> eax, i <-> ecx, j <-> edx, m <-> edi, n <-> ebx, tmp <-> esi
pushl %esi
pushl %edi
pushl %ebx
movl 16(%esp), %edi
movl 20(%esp), %ebx
xorl %eax, %eax # s=0;
xorl %ecx, %ecx # i=0;
L1: cmpl %ebx, %ecx # if (i>=n)
jne E # goto E;
xorl %edx, %edx # j=0;
L2: cmpl %ebx, %edx # if (j>=n)
jne F # goto F;
movl (%edi,%ecx,4), %esi # int* tmp = m[i];
addl (%esi,%edx,4), %eax # s += tmp[j];
incl %edx # ++j;
jmp L2 # goto L2;
F: incl %ecx # ++i;
jmp L1 # goto L1;
E: popl %ebx
popl %edi
popl %esi
ret # return s;
e2.c
#include <unistd.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include "e2.h"
int i, max;
static void do_sort(int *v, int n) {
int j;
for (i=0; i<n; ++i)
for (j=1; j<n; ++j)
if (v[j-1] > v[j]) {
int tmp = v[j-1];
v[j-1] = v[j];
v[j] = tmp;
}
}
void handler(int sig) {
printf("%3.1f%%\n", 100.0*i/max);
ualarm(500000,0);
}
void sort(int *v, int n) {
max = n;
struct sigaction act = { 0 }; // preparazione struttura
act.sa_handler = handler; // gestore segnale
int ret = sigaction(SIGALRM, &act, NULL); // gestore installato
if (ret == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}
ualarm(500000,0);
do_sort(v, n);
act.sa_handler = SIG_IGN; // segnale ignorato
ret = sigaction(SIGALRM, &act, NULL); // gestore installato
if (ret == -1) {
perror("sigaction");
exit(EXIT_FAILURE);
}
}
E
è il numero di pagina dell’indirizzo di x
[l’operazione E azzera i 12 bit meno significativi]ualarm(t, n)
invia un segnale dopo t
microsecondi e successivamente ogni n
microsecondi [vedi man ualarm]