File:  [local] / rpl / src / allocateur.c
Revision 1.2: download - view: text, annotated - select for diffs - revision graph
Thu Jan 8 16:05:31 2015 UTC (9 years, 3 months ago) by bertrand
Branches: MAIN
CVS tags: HEAD
Ajout d'un garde-fou.

    1: /*
    2: ================================================================================
    3:   RPL/2 (R) version 4.1.20
    4:   Copyright (C) 1989-2015 Dr. BERTRAND Joël
    5: 
    6:   This file is part of RPL/2.
    7: 
    8:   RPL/2 is free software; you can redistribute it and/or modify it
    9:   under the terms of the CeCILL V2 License as published by the french
   10:   CEA, CNRS and INRIA.
   11:  
   12:   RPL/2 is distributed in the hope that it will be useful, but WITHOUT
   13:   ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
   14:   FITNESS FOR A PARTICULAR PURPOSE.  See the CeCILL V2 License
   15:   for more details.
   16:  
   17:   You should have received a copy of the CeCILL License
   18:   along with RPL/2. If not, write to info@cecill.info.
   19: ================================================================================
   20: */
   21: 
   22: 
   23: #include "rpl-conv.h"
   24: 
   25: 
   26: static size_t                   tailles[] =
   27:         { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10,
   28:         11, 12, 13, 14, 15, 16, 24, 32, 48, 64,
   29:         96, 128, 192, 256, 384, 512, 768, 1024, 1536, 2048,
   30:         3072, 4096, 6144, 8192, 12288, 16384, 24576, 32768, 49152, 65536,
   31:         0 };
   32: static int                      longueur_tailles = 0;
   33: 
   34: 
   35: /*
   36: ================================================================================
   37:   Recherche de la longueur optimale du buffer
   38: ================================================================================
   39:   Entrée : longueur du buffer à allouer
   40: --------------------------------------------------------------------------------
   41:   Sortie : indice de la liste candidate, -1 si aucune liste
   42: --------------------------------------------------------------------------------
   43:   Effets de bord : néant
   44: ================================================================================
   45: */
   46: 
   47: static int
   48: recherche_longueur_buffer_optimale(integer8 longueur)
   49: {
   50:     int         a;
   51:     int         b;
   52:     int         m;
   53: 
   54:     a = 0;
   55:     b = longueur_tailles - 1;
   56: 
   57:     if (longueur > ((integer8) tailles[b]))
   58:     {
   59:         return(-1);
   60:     }
   61: 
   62:     while((b - a) > 1)
   63:     {
   64:         m = (a + b) / 2;
   65: 
   66:         if (longueur <= ((integer8) tailles[m]))
   67:         {
   68:             b = m;
   69:         }
   70:         else
   71:         {
   72:             a = m;
   73:         }
   74:     }
   75: 
   76:     return(b);
   77: }
   78: 
   79: 
   80: /*
   81: ================================================================================
   82:   Allocateur de mémoire fonctionnant avec un cache
   83: ================================================================================
   84:   Entrée : longueur du buffer à allouer
   85: --------------------------------------------------------------------------------
   86:   Sortie : pointeur sur une structure struct_buffer (ou NULL)
   87: --------------------------------------------------------------------------------
   88:   Effets de bord : néant
   89: ================================================================================
   90: */
   91: 
   92: void
   93: initialisation_allocateur_buffer(struct_processus *s_etat_processus)
   94: {
   95:     int         i;
   96: 
   97:     if (longueur_tailles == 0)
   98:     {
   99:         while(tailles[longueur_tailles] != 0)
  100:         {
  101:             longueur_tailles++;
  102:         }
  103: 
  104:         if (((*s_etat_processus).cache_buffer = malloc(((size_t)
  105:                 longueur_tailles) * sizeof(unsigned char **))) == NULL)
  106:         {
  107:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  108:             return;
  109:         }
  110: 
  111:         if (((*s_etat_processus).pointeur_cache_buffer = malloc(((size_t)
  112:                 longueur_tailles) * sizeof(int))) == NULL)
  113:         {
  114:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  115:             return;
  116:         }
  117: 
  118:         for(i = 0; i < longueur_tailles; i++)
  119:         {
  120:             if (((*s_etat_processus).cache_buffer[i] =
  121:                     malloc(TAILLE_CACHE * sizeof(unsigned char *))) == NULL)
  122:             {
  123:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  124:                 return;
  125:             }
  126: 
  127:             (*s_etat_processus).pointeur_cache_buffer[i] = 0;
  128:         }
  129:     }
  130: 
  131:     return;
  132: }
  133: 
  134: 
  135: void
  136: liberation_allocateur_buffer(struct_processus *s_etat_processus)
  137: {
  138:     int                         i;
  139:     int                         j;
  140: 
  141:     for(i = 0; i < longueur_tailles; i++)
  142:     {
  143:         for(j = 0; j < (*s_etat_processus).pointeur_cache_buffer[i]; j++)
  144:         {
  145:             free((*s_etat_processus).cache_buffer[i][j]);
  146:         }
  147: 
  148:         free((*s_etat_processus).cache_buffer[i]);
  149:     }
  150: 
  151:     free((*s_etat_processus).cache_buffer);
  152:     return;
  153: }
  154: 
  155: 
  156: static inline struct_buffer *
  157: allocation_enveloppe_buffer(struct_processus *s_etat_processus)
  158: {
  159:     struct_buffer           *s_buffer;
  160: 
  161:     if ((*s_etat_processus).pointeur_enveloppes_buffers > 0)
  162:     {
  163:         s_buffer = (*s_etat_processus).enveloppes_buffers
  164:                 [--(*s_etat_processus).pointeur_enveloppes_buffers];
  165:     }
  166:     else
  167:     {
  168:         if ((s_buffer = malloc(sizeof(struct_buffer))) == NULL)
  169:         {
  170:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  171:             return(NULL);
  172:         }
  173:     }
  174: 
  175:     return(NULL);
  176: }
  177: 
  178: 
  179: static inline void
  180: liberation_enveloppe_buffer(struct_processus *s_etat_processus,
  181:         struct_buffer *s_buffer)
  182: {
  183:     if ((*s_etat_processus).pointeur_enveloppes_buffers < TAILLE_CACHE)
  184:     {
  185:         (*s_etat_processus).enveloppes_buffers
  186:                 [(*s_etat_processus).pointeur_enveloppes_buffers++] = s_buffer;
  187:     }
  188:     else
  189:     {
  190:         free(s_buffer);
  191:     }
  192: 
  193:     return;
  194: }
  195: 
  196: 
  197: struct_buffer *
  198: allocation_buffer(struct_processus *s_etat_processus, integer8 longueur)
  199: {
  200:     int                     classe;
  201: 
  202:     struct_buffer           *s_buffer;
  203: 
  204:     if (allocation_enveloppe_buffer(s_etat_processus) == NULL)
  205:     {
  206:         (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  207:         return(NULL);
  208:     }
  209: 
  210:     classe = recherche_longueur_buffer_optimale(longueur);
  211: 
  212:     if (classe >= 0)
  213:     {
  214:         if ((*s_etat_processus).pointeur_cache_buffer[classe] > 0)
  215:         {
  216:             (*s_buffer).buffer = (*s_etat_processus).cache_buffer[classe]
  217:                     [--(*s_etat_processus).pointeur_cache_buffer[classe]];
  218:         }
  219:         else
  220:         {
  221:             if (((*s_buffer).buffer = malloc(tailles[classe] *
  222:                     sizeof(unsigned char))) == NULL)
  223:             {
  224:                 (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  225:                 return(NULL);
  226:             }
  227:         }
  228:     }
  229:     else
  230:     {
  231:         if (((*s_buffer).buffer = malloc(((size_t) longueur) *
  232:                 sizeof(unsigned char))) == NULL)
  233:         {
  234:             (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
  235:             return(NULL);
  236:         }
  237:     }
  238: 
  239:     BUG((longueur > ((integer8) tailles[classe])),
  240:             uprintf("Bad buffer class !\n"));
  241: 
  242:     (*s_buffer).classe = classe;
  243:     (*s_buffer).longueur_requise = longueur;
  244: 
  245:     return(NULL);
  246: }
  247: 
  248: 
  249: void
  250: liberation_buffer(struct_processus *s_etat_processus, struct_buffer *s_buffer)
  251: {
  252:     if ((*s_buffer).classe < 0)
  253:     {
  254:         free((*s_buffer).buffer);
  255:     }
  256:     else
  257:     {
  258:         if ((*s_etat_processus).pointeur_cache_buffer[(*s_buffer).classe]
  259:                 < TAILLE_CACHE)
  260:         {
  261:             (*s_etat_processus).cache_buffer[(*s_buffer).classe]
  262:                     [(*s_etat_processus).pointeur_cache_buffer
  263:                     [(*s_buffer).classe]++] = (*s_buffer).buffer;
  264:         }
  265:         else
  266:         {
  267:             free((*s_buffer).buffer);
  268:         }
  269:     }
  270: 
  271:     liberation_enveloppe_buffer(s_etat_processus, s_buffer);
  272:     return;
  273: }
  274: 
  275: // vim: ts=4

CVSweb interface <joel.bertrand@systella.fr>