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: (*s_buffer).classe = classe;
240: (*s_buffer).longueur_requise = longueur;
241:
242: return(NULL);
243: }
244:
245:
246: void
247: liberation_buffer(struct_processus *s_etat_processus, struct_buffer *s_buffer)
248: {
249: if ((*s_buffer).classe < 0)
250: {
251: free((*s_buffer).buffer);
252: }
253: else
254: {
255: if ((*s_etat_processus).pointeur_cache_buffer[(*s_buffer).classe]
256: < TAILLE_CACHE)
257: {
258: (*s_etat_processus).cache_buffer[(*s_buffer).classe]
259: [(*s_etat_processus).pointeur_cache_buffer
260: [(*s_buffer).classe]++] = (*s_buffer).buffer;
261: }
262: else
263: {
264: free((*s_buffer).buffer);
265: }
266: }
267:
268: liberation_enveloppe_buffer(s_etat_processus, s_buffer);
269: return;
270: }
271:
272: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>