Annotation of rpl/src/allocateur.c, revision 1.2

1.1       bertrand    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: 
1.2     ! bertrand  239:    BUG((longueur > ((integer8) tailles[classe])),
        !           240:            uprintf("Bad buffer class !\n"));
        !           241: 
1.1       bertrand  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>