Sophie

Sophie

distrib > Mandriva > 9.1 > i586 > by-pkgid > f1098342ec4a2b28475e34123ce17201 > files > 521

howto-html-it-9.1-0.5mdk.noarch.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
<HTML>
<HEAD>
 <META NAME="GENERATOR" CONTENT="SGML-Tools 1.0.9">
 <TITLE>KernelAnalysis-HOWTO: Utili Note</TITLE>
 <LINK HREF="KernelAnalysis-HOWTO-11.html" REL=next>
 <LINK HREF="KernelAnalysis-HOWTO-9.html" REL=previous>
 <LINK HREF="KernelAnalysis-HOWTO.html#toc10" REL=contents>
</HEAD>
<BODY>
<A HREF="KernelAnalysis-HOWTO-11.html">Avanti</A>
<A HREF="KernelAnalysis-HOWTO-9.html">Indietro</A>
<A HREF="KernelAnalysis-HOWTO.html#toc10">Indice</A>
<HR>
<H2><A NAME="s10">10. Utili Note</A></H2>

<H2><A NAME="ss10.1">10.1 Stack e Heap</A>
</H2>

<H3>Introduzione</H3>

<P>Qui vediamo come vengono allocati in memoria "stack" ed "heap".
<H3>Allocazione di memoria</H3>

<P>
<PRE>

FF..        |                 | &lt;-- inizio dello stack
       /|\  |                 |   | 
 valori |   |                 |   |   stack
piu'alti|   |                 |  \|/  crescente
di memoria  |                 |
XX..        |                 | &lt;-- attuale puntatore stack 
            |                 |
            |                 |
            |                 |
00..        |_________________| &lt;-- fine dello stack [Stack Segment]
                 
                   Stack
</PRE>
<P>Gli indirizzi di memoria partono da 00.. (che e' il dove il Segmento dello
Stack comincia) e aumentano verso il valore FF.., mentre lo stack cresce all'opposto,
cioe' dal valore FF.. al valoce 00.. verso valori bassi di memoria
<P>XX.. e' il valore attuale dello Stack Pointer.
<P>Lo Stack viene solitamente usato per:
<P>
<OL>
<LI>variabili globali</LI>
<LI>variabili locali</LI>
<LI>indirizzo di ritorno</LI>
</OL>
<P>Ad esempio una classica funzione
<P>
<PRE>

 |int funzione (parametro_1, parametro_2, ..., parametro_N) {
    |dichiarazione variabile_1;
    |dichiarazione variabile_2;
      ..
    |dichiarazione variabile_N;
   
    |// Corpo della funzione
    |dichiarazione variabile_dinamica_1;
    |dichiarazione variabile_dinamica_2;
     ..
    |dichiarazione variabile_dinamica_N;

    |// Il Codice e' all'interno del Segmento di Codice, non nel Segmento Dati/Stack! 
    
    |return (ret-type) valore; // Spesso finisce in qualche registro, per 386+: registro ''eax''
 |}
</PRE>
<P>
<BLOCKQUOTE>
utilizza uno stack del tipo
</BLOCKQUOTE>
<P>
<PRE>

          |                       |
          | 1. parametro_1 pushato| \
    S     | 2. parameter_2 pushato|  | Prima della
    T     | ...................   |  | chiamata
    A     | N. parameter_N pushato| /
    C     | *Indirizzo di Ritorno*| -- Chiamata
    K     | 1. variabile_1 locale | \ 
          | 2. variabile_2 locale |  | Dopo la
          | .................     |  | chiamata
          | N. variabile_N locale | /
          |                       | 
         ...                     ...   Stack
         ...                     ...   Libero
          |                       |
    H     | N.variabile_N dinamica| \
    E     | ...................   |  | Allocato dalle
    A     | 2.variabile_2 dinamica|  | malloc &amp; kmalloc
    P     | 1.variabile_1 dinamica| /
          |_______________________|
        
            Utilizzo tipico dello Stack
 
</PRE>
<P>Nota: L'ordine delle variabile puo' essere differente a seconda dell'architettura
hardware (come sempre qui si ipotizza l'utilizzo del 386+).
<P>
<PRE>
</PRE>
<H2><A NAME="ss10.2">10.2 Applicazione vs Task</A>
</H2>

<H3>Definizioni di Base</H3>

<P>Distinguiamo 2 2 concetti:
<P>
<UL>
<LI>Applicazione: che e' il codice che vogliamo eseguire</LI>
<LI>Processo: che rappresenta l'Immagine in memoria dell'applicazione (dipende
dalla strategia di memoria utilizzata, Segmentazione e/o Paginazione).</LI>
</UL>
<P>Spesso i Processi vengono chiamati Task o Thread.
<H2><A NAME="ss10.3">10.3 Locks</A>
</H2>

<H3>Introduzione</H3>

<P>2 tipi di locks:
<P>
<OL>
<LI>intraCPU</LI>
<LI>interCPU</LI>
</OL>
<H2><A NAME="ss10.4">10.4 Copy_on_write</A>
</H2>

<P>Il meccanismo della Copy_on_write consente di ridurre l'utilizzo di memoria,
postponendo l'allocazione per un nuovo Thread fino a quando non e' strettamente
necessario.
<P>Ad esempio, quando un Task esegue la "fork()" per creare un nuovo Processo,
le pagine del vecchio processo non vengono copiate, ma vengono soltanto "referenziate"
in modalita' READ ONLY in modo che, quando il nuovo Task andra' a scrivervi
sopra, l'eccezione generata si occupera' di creare una nuova copia della pagina
marcandola, questa volta READ + WRITE.
<P>Ecco uno schema riassuntivo: 
<P>
<PRE>

1-) La Pagina X e' condivisa tra Il Task Padre e quello figlio
 Task Padre
 |         | Accesso RW ________
 |         |----------&gt;|Pagina X|    
 |_________|           |________|
                          /|\
                           |
 Task Figlio               | 
 |         | Accesso RO    |  
 |         |----------------                
 |_________| 
 
 
2-) Richiesta di Scrittura da parte del Task Figlio
 Task Figlio
 |         | Accesso RW ________
 |         |----------&gt;|Pagina X|    
 |_________|           |________|
                          /|\
                           |
 Task Figlio               | 
 |         | Accesso W     |  
 |         |----------------                
 |_________| 
 
 
3-) Configurazione Finale: il Task Padre e quello Figlio hanno ognuno una copia indipendente della Pagina, X e Y
 Task Padre
 |         | Accesso RW ________
 |         |----------&gt;|Pagina X|    
 |_________|           |________|
              
              
 Task Figlio
 |         | Accesso RW ________
 |         |----------&gt;|Pagina Y|    
 |_________|           |________|
</PRE>
<HR>
<A HREF="KernelAnalysis-HOWTO-11.html">Avanti</A>
<A HREF="KernelAnalysis-HOWTO-9.html">Indietro</A>
<A HREF="KernelAnalysis-HOWTO.html#toc10">Indice</A>
</BODY>
</HTML>