Changes between Version 53 and Version 54 of AS6-TME-B6


Ignore:
Timestamp:
Mar 30, 2022, 9:32:46 AM (3 years ago)
Author:
franck
Comment:

--

Legend:

Unmodified
Added
Removed
Modified
  • AS6-TME-B6

    v53 v54  
    216216 * La politique de rendre un slab dès qu'il est plein (qu'il ne contient que des objets libres) n'est pas forcément efficace.
    217217 * En effet, si on alloue un objet d'une taille T, alors on ouvre un slab (on l'alloue) et si on le libère, alors on ferme le slab (on le libère). Si on fait ça en boucle, l'ouverture/fermeture (allocation/libération) des slabs est une perte de temps.
    218  * Il est sans doute préférable d'avoir toujours des listes d'objets libres non vides. On peut donc définir un seuil d'objets libres en dessous duquel ne pas descendre. C'est le sujet d'un exercice possible.
     218 * Il est sans doute préférable d'avoir toujours des listes d'objets libres non vides. On peut donc définir un seuil d'objets libres en dessous duquel ne pas descendre.
    219219'''
    220220}}}
     
    309309== B.1. Transformer l'allocateur first-fit et allocateur next-fit
    310310
     311
    311312L'allocateur first-fit parcourt la liste des blocs depuis le tout premier jusqu'à la fin à la recherche du premier bloc non plein assez grand pour l'objet à allouer. Pour transformer ce comportement en next-fit, il suffit de se souvenir du dernier bloc alloué.
    312313
     
    420421}}}
    421422
     423
    422424== B.4. Faire en sorte que les listes d'objets libres du noyau ne retombent à 0
    423425
    424 Dans le fichier , on peut voir qu'il existe un tableau `Objects[]` contenant de cases qu'il existe de taille d'objets possibles (mesurée en nombre de lignes) et dont chaque case contient le nombre d'objet libre
    425 de listes d'objets libres, indexé par les identifiants de slab (l'identifiant de slab est la taille des objets qu'il contient en nombre de lignes). Le tableau `Objects` contiens le nombre d'objets alloués. Il faudrait un autre tableau semblable contenant le nombre d'objets libres disponible.
     426
     427Si on alloue un objet d'une taille T et que la liste des objets libres de taille T est vide alors on ouvre un slab (on l'alloue).  Si on libère l'objet de taille T, alors le slab est entièrement libre et on ferme le slab (on le libère). Si on fait ça en boucle, l'ouverture/fermeture (allocation/libération) des slabs est une perte de temps. Il est sans doute préférable d'avoir toujours des listes d'objets libres non vides. On peut donc définir un seuil d'objets libres en dessous duquel ne pas descendre.
     428
     429Dans le fichier `kernel/kmemory.c`, on peut voir qu'il existe un tableau `Objects[]` contenant autant de cases qu'il existe de taille d'objets possibles (mesurée en nombre de lignes) et dont chaque case contient le nombre d'objets alloués de cette taille. Ce tableau a 256 cases au maximum (si la ligne de cache fait 16 octets), la case 0 contient le nombre de pages allouées, la case 1 contient le nombre d'objets alloués d'1 ligne, la case 2 pour les objets de 2 lignes, etc.
     430
     431Il n'y a pas de tableau pour compter le nombre d'objets libres dans les listes d'objets. L'idée c'est d'en ajouter un, et ne pas demander la suppression de slab si le nombre d'objet est inférieur à un seuil choisi (qui pourrait être 1).
     432
     433**kernel/kfree**
     434
     435{{{#!c
     436void kfree (void * obj, size_t size)
     437{
     438    size_t nbline= NBLINE(size) % MaxLinePage;              // which slab to use
     439    size_t npage = (size_t)(obj - (void *)kmb)>>12;         // relative page number from kmb
     440
     441    PANIC_IF ((nbline>255)||(npage >= NbPages),             // too big or outside of the region
     442        "\ncan't free object not allocated by kmalloc()");  // write a message then panic
     443
     444    list_addfirst (&Slab[nbline], (list_t *)obj);           // add it to the right free list
     445    Objects[nbline]--;                                      // decr the number of obj of size nbline
     446    if (size == PAGE_SIZE) return;
     447    if (--Page[npage].alloc==0) {                           // splitted page and no more object left
     448        list_t *page = (list_t *)((size_t)obj & ~0xFFF);    // address of the page containing obj
     449        list_foreach (&Slab[nbline], item) {                // browse all item in free list
     450            size_t np_item = (size_t)((char*)item-kmb)>>12; // page number Page[] table
     451            if (np_item == npage) {                         // if current item is in the page
     452                list_unlink (item);                         // unlink it
     453            }
     454        }
     455        Page[npage].slab = 0;                               // since the page is empty, thus slab 0
     456        list_addfirst (&Slab[0], (list_t *)page);           // add the free page in slab[O]
     457        Objects[0]--;                                       // decr the number of pages used
     458    }
     459}
     460}}}
     461
     462 **Explication de l'usage du tableau `Page`** :\\Le tableau `Page[]` est un tableau de structures dont chaque case contient l'usage de la page : pour quel slab la page est utilisée et combien d'objets y sont alloués. Lors de la libération d'un objet du noyau par `kfree()`, l'allocateur remet l'objet dans la liste des objets libres de sa taille (le tableau de listes `Slab[]`) et il décrémente le compteur d'objets présents dans la page `--Page[npage].alloc` (`npage` identifie la page). Si la page ne contient plus d'objet alloué alors `kfree()` recherche les objets libres de même taille qui sont dans la page `npage` alors il les retire. Ensuite la page est libérée.\\Vous n'avez pas à changer ce fonctionnement, ce qu'il faut c'est ne pas l'invoquer si le nombre d'objet libre est en dessous d'un seuil.
     463
     464