Show Menu
Cheatography

Calcolatori Elettronici Cheat Sheet by

Cheatsheet per l'insegnamento di Calcolatori Elettronici relativo al nucleo v6.x, università di Pisa

Semafori

sem_wait(sem);
Esegue
counter--
e nel caso aggiunge a waiting il processo.
sem_signal(sem);
Rilascia un gettone. Esegue
counter++
ed estrae dalla lista dei waiting.
sem_ini($gettoni);
Restit­uisce il primo semaforo libero insere­ndovi $gettoni gettoni. 0xFFFFFFFF se qualcosa è andato storto.
sem_valid(id);
Verifica la validità di un semaforo.
Mutex: $gettone = 1
Sync: $gettone = 0
Nota: tutti gli errori sono 0xFFFFFFFF
Attenz­ione: Tutti gli id sono
natl

Processi

des_p(id);
Restit­uisce un des_proc* a partire dall'id.
c_abort_p();
Porta all'in­ter­ruzione del processo. Non effettua return ed è utile nei casi di errore.
p->­con­testo[I_RAX] = $value;
Ritorno della funzione di value.
rimozione_lista($lista);
Rimuove la testa dalla lista (max prio)
inspronti();
Inserisce esecuzione in testa a pronti
Tutti gli
id
sono
natl

Preemption

des_proc* work = rimozione_lista($lista);
inspronti();
inserimento_lista(pronti, work);
schedulatore();
Alla fine ci sarà sicura­mente uno tra il processo in esecuzione e work attivo

Utilità

flog(MODE, "­msg­");
Mostra a schermo il messaggio msg
LOG_DEBUG: costante per debug
LOG_INFO: costante per inform­azioni
LOG_WARN: costante per avviso

Tab iter

tab_iter it(tab, begin, dim);
Utile per scorrere le entrate dell'a­lbero degli indirizzi
it.down();
Per scorrere in profon­dità, vedi vm.h
it.is_leaf();
restit­uisce
true
se è una foglia
tab_entry& e = it.get_e();
Restit­uisce un riferi­mento al descri­ttore corrente
vaddr v = it.get_v();
Restit­uisce l'indi­rizzo virtuale asdsociato alla entry in it
paddr p = extr_I­ND_­FIS­ICO­($e);
Restit­uisce l'indi­rizzo fisico associato alla entry
set_IN­D_F­ISI­CO($e, $paddr);
Setta l'indi­rizzo fisico corris­pon­dente alla entry $e
alloca­_tab();
Alloca un frame libero destinato a contenere una tabella di traduzione restit­uendo l'indi­rizzo del frame
copy_d­es(­paddr src, paddr dst, natl i, natl n);
Copia 'n' descri­ttori da src in dst a partire dall'i­ndice i
set_de­s(paddr dst, natl i, natl n, tab_entry e);
Setta il valore 'e' su 'n' descri­ttori a partire dall'i­ndice 'i'

Utilizzo tab_iter

for (tab_iter it(p->cr3, ini_utn_p, dim); it; it.next()) {
    if (!it.is_leaf())
      continue;
 
    tab_entry& e = it.get_e();
    vaddr v = it.get_v();
    paddr p = extr_IND_FISICO(e); // or set
    /* e &= ~BIT_RW;
       abbiamo modificato RW: invalidamo 
       le entrate nel TLB
       invalida_entrata_TLB(v);*/
}

Memoria Virtuale

trasforma(vaddr);
Restit­uisce il paddr relativo a un vaddr
tipo_livello_accesso
Vedere le note
alloca_frame();
restit­uisce l'indi­rizzo del frame caricato
rilascia_frame($paddr);
Libera il frame in cui è contenuto $paddr
paddr base = p & ~0xFFF;
base di un frame
natl indice = p / DIM_PAGINA;
Indice di frame
invali­da_­ent­rat­a_T­LB(­$va­ddr);
Invalida l'entrata del TLB del processo in esecuzione
cr0
Abilita la pagina­zione
cr1
Non implem­entato
cr2
Indirizzo che ha causato page fault
cr3
paddr albero di traduzione del processo
vdf[];
array dei descri­ttori di frame
memcpy( (void) dst, (void) src, int nbytes);
copia da dst a src nbytes
map(p-­>cr3, vaddr begin, vaddr end, FLAGS, putpaddr);
Mappa gli indirizzi fisici passati da putpaddr nell'i­nte­rvallo [begin, end) restit­uendo il primo che non è riuscito a tradurre
unmap(­p->cr3, vaddr begin, vaddr end, getpaddr);
Rimuove le traduzioni nell'i­nte­rvallo [begin, end) da p->cr3
- tipo: ini, fin
- livello: utn, sis
- accesso: p, c
Livello tabelle: 4, 3, 2, 1
FLAGS: bit_RW, bit_US
 

Funtore

class Funtore{
    public:
        paddr pa[DIM_PAGINA];
        natl i;

        // init di i a 0
        Funtore() : i(0) {}

        // per la map
        paddr operator()(vaddr v){
            return pa[i++];
        }

       // per la unmap
        void operator()(vaddr, paddr p, int){
            pa[i++] = p;
            // oppure trasforma(v);
        }
}; // attento a ; !!!

Elimina da lista

des_proc elimina_da_lista(des_proc& testa, des_proc* p){
  des_proc *prec = &testa, scorri = testa;
  while (scorri && scorri != p) {
    prec = &scorri->puntatore;
    scorri = scorri->puntatore;
  }
  if (scorri)
    *prec = scorri->puntatore;

  return scorri;
}
Rimuove dalla lista puntata da
$testa
il
des_proc* p
.

I/O

access­(vaddr b, natq dim, bool w, bool s);
Controlla il cavallo di Troia per w(ritable) e s(hared)
z = inputx(reg);
Inserisce il valore al registro reg in z
outputx(value, reg);
Inserisce nel registro reg il valore value
des_x y = new(align_­val­_t{dim}) des_x;
Allinea il nuovo valore in memoria
natl spostabili = DIM_PAGINA - (paddr & 0xFFF);
Calcola il numero di byte spostabili per esaurire il frame
x: b(yte), l(ong), q(uad)

Approccio I/O

- Quando viene chiamata l'inte­rru­zione?
- Chi prepara il descri­ttore?
- Cosa deve fare l'inte­rru­zione?
- Come rispon­diamo all'in­ter­ruz­ione?
- Come ci prepariamo alla prossima interr­uzione?

Nota: nei casi, perlomeno di lettura, potrebbe essere sensato impostare i valori passati come parametri dalla primitiva all'in­terno del descri­ttore. Sarà poi l'inte­rru­zione (se chiamata ogni tot) a sistemare questi valori già inizia­lizzati con i valori aggior­nati. Se invece dovesse essere richiamata solo alla fine del processo, sarà compito della read fare tutto il processo e abilitare le interr­uzioni alla fine facendo riattivare la estern_ce

Nota2: quando in una read viene passato un buffer, questo dovrà essere copiato nel descri­ttore in quanto è il buffer in cui la periferica dovrà scrivere i valori che dovremo leggere.

Nota3: se il passaggio di byte tra utente e periferica viene effettuato tramite un buffer di appoggio interm­edio, dobbiamo necess­ari­amente usare la memcpy, in quanto questi dati devono essere copiati in una zona di memoria.

Estern CE

// chiamata dalla periferica con un'interruzione
extern "C" void estern_ce(natl id){
    
    // recuperare periferica
    for(;;){

        // sem_wait(mutex);
        // libera il sync occupato nella primitiva
        // sem_signal(sync); 
        // sem_signal(mutex);

        wfi();
    }
}

Metodi di scorri­mento tab_iter

it.post(); it; it.nex­t_p­ost()
Effettua un accesso postic­ipato. Viene solita­mente utilizzato quando devo cancellare un albero.
tab_iter it(ese­cuz­ion­e->cr3, v, n); it; it.next()
Effettua un accesso anticipato. Viene solita­mente utilizzato quando si deve sempli­cemente scorrere l'albero per farci operazioni di qualsiasi tipo.

inspronti e inseri­men­to_­lis­ta(­pronti, esecuz­ione)

La primitiva
 ­ ­ ­ 
inspro­nti();

inserisce il processo in esecuzione in testa alla coda pronti.
La primitiva
 ­ ­ ­ 
inseri­men­to_­lis­ta(­pronti, esecuz­ione);

inserisce il processo in esecuzione nella coda pronti in maniera ordinata. Quindi, se nella coda pronti c'è un processo P1 con priorità uguale a quella del processo in esecuz­ione, quest'­ultimo verrà inserito nella lista dopo il processo P1.
inspro­nti();
: esecuzione -> P1
inseri­men­to_­lis­ta(­pronti, esecuz­ione);
: P1 -> esecuzione

Primitive con tipo di ritorno

Se abbiamo una primitiva del tipo
bool primit­iva­(pa­ram­etri)

dovremo implem­entarla in due modi diversi nel modulo sistema e nel modulo I/O.
SISTEMA: non possiamo farle restituire un tipo (deve essere void), quindi il valore di ritorno dovremo inserirlo nel contesto del processo in esecuz­ione.
extern "­C" void primit­iva­(pa­ram­etri) {

//oper­azioni

esecuz­ion­e->­con­tes­to[­I_RAX] = valore­_ri­torno;

}

I/O: possiamo utilizzare i tipi di ritorno delle primitive nel seguente modo:
extern "­C" bool primit­iva­(pa­ram­etri) {

//oper­azioni

return valore­_ri­torno;

}
 

Comments

No comments yet. Add yours below!

Add a Comment

Your Comment

Please enter your name.

    Please enter your email address

      Please enter your Comment.

          Related Cheat Sheets

          C Reference Cheat Sheet
          C program Cheat Sheet

          More Cheat Sheets by Gray00

          C++ introduttivo Cheat Sheet