~ubuntu-branches/ubuntu/hoary/scilab/hoary

« back to all changes in this revision

Viewing changes to routines/libcomm/buf_dynam.c

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2005-01-09 22:58:21 UTC
  • mfrom: (1.1.1 upstream)
  • Revision ID: james.westby@ubuntu.com-20050109225821-473xr8vhgugxxx5j
Tags: 3.0-12
changed configure.in to build scilab's own malloc.o, closes: #255869

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/************************************************/
2
 
/* Module de gestion de buffers dynamiques v1.0 */
3
 
/************************************************/
4
 
 
5
 
#include <stdio.h>
6
 
#include <stdlib.h>
7
 
/** #include "IG.h"**/
8
 
#include "gestion_memoire.h"
9
 
#include "listes_chainees.h"
10
 
#include "buffer_dynamiques.h"
11
 
 
12
 
/* Cette structure code un buffer dynamique.                         
13
 
   Il faut laisser cette structure et Premier_buffer_dynamique dans  
14
 
   gestion_memoire.c : c'est une structure privee.                   */
15
 
typedef struct gbd_Buffer_dynamique
16
 
{
17
 
    long taille_elements;
18
 
    long nbre_elements_initial;
19
 
    long nbre_elements_total;
20
 
    long nbre_elements_occupes;
21
 
    void *pointeur_buffer;
22
 
    void *(*allouer)();
23
 
    void *(*reallouer)();
24
 
    void (*liberer)();
25
 
    void (*desallouer)();
26
 
} gbd_buffer_dynamique;
27
 
 
28
 
static void gbd_desallouer_buffer();
29
 
static int gbd_chercher_buffer_dynamique();
30
 
static void *gbd_modifier_buffer_dynamique();
31
 
static long puissance_2_sup();
32
 
 
33
 
/* Pointeur sur le premier buffer dynamique de la liste chainee. */
34
 
/* Ce pointeur est egal a NULL au debut, car la liste est vide.  */
35
 
 
36
 
static ldc_liste_chainee liste_buffer_dynamiques=NULL;
37
 
 
38
 
/* Cette procedure ajoute un buffer dynamique dans la liste chainee.                */
39
 
/* Cette procedure peut etre appelee par la macro creer_buffer_dynamique            */
40
 
/* (cf gestion_memoire.h)                                                           */
41
 
void *gbd_creer_buffer_dynamique(taille,nbre_initial,allouer,reallouer,liberer,desallouer)
42
 
long taille;
43
 
long nbre_initial;
44
 
void *(*allouer)();
45
 
void *(*reallouer)();
46
 
void (*liberer)();
47
 
void (*desallouer)();
48
 
{
49
 
    gbd_buffer_dynamique *nouvelle_structure;
50
 
    long nbre_initial_p2 = puissance_2_sup(nbre_initial);
51
 
 
52
 
    if (liste_buffer_dynamiques == NULL)
53
 
        liste_buffer_dynamiques=ldc_creer(gbd_chercher_buffer_dynamique,gbd_desallouer_buffer,liberer,allouer);
54
 
        
55
 
    nouvelle_structure = (*allouer)(sizeof(gbd_buffer_dynamique));
56
 
    nouvelle_structure -> pointeur_buffer = allouer(taille*nbre_initial_p2);
57
 
    nouvelle_structure -> taille_elements = taille;
58
 
    nouvelle_structure -> nbre_elements_initial = nbre_initial_p2;
59
 
    nouvelle_structure -> nbre_elements_total = nbre_initial_p2;
60
 
    nouvelle_structure -> nbre_elements_occupes = 0;
61
 
    nouvelle_structure -> liberer = liberer;
62
 
    nouvelle_structure -> allouer = allouer;
63
 
    nouvelle_structure -> reallouer = reallouer;
64
 
    nouvelle_structure -> desallouer = desallouer;
65
 
 
66
 
    ldc_ajouter_objet(liste_buffer_dynamiques,nouvelle_structure);
67
 
 
68
 
    return nouvelle_structure -> pointeur_buffer;
69
 
}
70
 
 
71
 
/* Cette procedure detruit un buffer dynamique dans la liste chainee. */
72
 
int gbd_detruire_buffer_dynamique(pointeur_buffer)
73
 
void *pointeur_buffer;
74
 
{
75
 
    return ldc_supprimer_objet(liste_buffer_dynamiques,pointeur_buffer);
76
 
}
77
 
 
78
 
static void gbd_desallouer_buffer(pointeur_struct_buffer_nc)
79
 
ldc_objet_liste pointeur_struct_buffer_nc;
80
 
{
81
 
    long compteur;
82
 
    char *buffer;
83
 
    gbd_buffer_dynamique *pointeur_struct_buffer = (gbd_buffer_dynamique *) pointeur_struct_buffer_nc;
84
 
 
85
 
    if (pointeur_struct_buffer -> desallouer != NULL)
86
 
    {
87
 
        buffer = (char *)(pointeur_struct_buffer -> pointeur_buffer);
88
 
        for(compteur = 0; compteur < pointeur_struct_buffer -> nbre_elements_occupes; compteur++)
89
 
            (pointeur_struct_buffer -> desallouer)(buffer + (pointeur_struct_buffer -> nbre_elements_occupes) * (pointeur_struct_buffer -> taille_elements));
90
 
    }
91
 
    (pointeur_struct_buffer -> liberer)(pointeur_struct_buffer -> pointeur_buffer);
92
 
    (pointeur_struct_buffer -> liberer)(pointeur_struct_buffer);
93
 
}
94
 
 
95
 
/* Cette procedure permet d'augmenter la taille virtuelle d'un buffer dynamique. */
96
 
/* Si la taille virtuelle depasse la taille reelle du buffer, une reallocation   */
97
 
/* est effectuee. Le nombre d'elements apres la reallocation sera toujours egal  */
98
 
/* au nombre d'elements initial multiplie par une puissance de deux.             */
99
 
void *gbd_augmenter_buffer_dynamique(pointeur_buffer,nombre_elements)
100
 
void *pointeur_buffer;
101
 
long nombre_elements;
102
 
{
103
 
    return gbd_modifier_buffer_dynamique(pointeur_buffer,nombre_elements,1);
104
 
}
105
 
 
106
 
/* La taille virtuelle d'un buffer dynamique est diminuee. */
107
 
/* Aucune reallocation n'est effectuee.                    */
108
 
/** supprimer la duplication de code **/
109
 
void *gbd_diminuer_buffer_dynamique(pointeur_buffer,nombre_elements)
110
 
void *pointeur_buffer;
111
 
long nombre_elements;
112
 
{
113
 
    return gbd_modifier_buffer_dynamique(pointeur_buffer,nombre_elements,-1);
114
 
}
115
 
 
116
 
static void *gbd_modifier_buffer_dynamique(pointeur_buffer,nombre_elements,operation)
117
 
void *pointeur_buffer;
118
 
long nombre_elements;
119
 
int operation;
120
 
{
121
 
    long nombre_elements_a_reallouer,nombre_elements_a_reallouer_p2;
122
 
    gbd_buffer_dynamique *buffer_a_modifier;
123
 
    void *nouvelle_adresse;
124
 
 
125
 
    if ((buffer_a_modifier = ldc_rechercher_objet(liste_buffer_dynamiques,pointeur_buffer)) != NULL)
126
 
    {
127
 
        nombre_elements_a_reallouer = (buffer_a_modifier -> nbre_elements_occupes) + operation * nombre_elements;
128
 
        if ((operation == 1 && (nombre_elements_a_reallouer <= (buffer_a_modifier -> nbre_elements_total))) ||
129
 
            ((operation == -1) && (nombre_elements_a_reallouer >= ((buffer_a_modifier -> nbre_elements_total) >> 1)) &&
130
 
             (nombre_elements_a_reallouer > (buffer_a_modifier -> nbre_elements_initial))))
131
 
             
132
 
        {
133
 
            buffer_a_modifier -> nbre_elements_occupes += nombre_elements * operation;
134
 
            return buffer_a_modifier -> pointeur_buffer;
135
 
        }
136
 
        else
137
 
        {
138
 
            nombre_elements_a_reallouer_p2 = puissance_2_sup(nombre_elements_a_reallouer);
139
 
 
140
 
            nouvelle_adresse = (buffer_a_modifier -> reallouer)(buffer_a_modifier -> pointeur_buffer,nombre_elements_a_reallouer_p2 * buffer_a_modifier -> taille_elements);
141
 
            buffer_a_modifier -> nbre_elements_total = nombre_elements_a_reallouer_p2;
142
 
            buffer_a_modifier -> pointeur_buffer = nouvelle_adresse;
143
 
            buffer_a_modifier -> nbre_elements_occupes = nombre_elements_a_reallouer;
144
 
 
145
 
            return nouvelle_adresse;
146
 
        }
147
 
    }
148
 
    return NULL;
149
 
}
150
 
 
151
 
/* Demande de la taille virtuelle d'un tableau dynamique */
152
 
long gbd_taille_buffer_dynamique(pointeur_buffer)
153
 
void *pointeur_buffer;
154
 
{
155
 
    gbd_buffer_dynamique *buffer_recherche;
156
 
 
157
 
    if ((buffer_recherche = ldc_rechercher_objet(liste_buffer_dynamiques,pointeur_buffer)) != NULL)
158
 
        return buffer_recherche -> nbre_elements_total;
159
 
 
160
 
    /** Erreur a gerer peut etre **/
161
 
    return 0;
162
 
}
163
 
 
164
 
/* Recherche de la structure d'un buffer dynamique, connaissant le pointeur    */
165
 
/* sur le buffer dynamique. Si la recherche echoue, la fonction retourne NULL. */
166
 
static int gbd_chercher_buffer_dynamique(pointeur_struct_buffer_nc,pointeur_buffer_nc)
167
 
ldc_objet_liste pointeur_struct_buffer_nc;
168
 
ldc_element_correspondance pointeur_buffer_nc;
169
 
{
170
 
    gbd_buffer_dynamique *pointeur_struct_buffer = (gbd_buffer_dynamique *) pointeur_struct_buffer_nc;
171
 
    void *pointeur_buffer = (void *) pointeur_buffer_nc;
172
 
 
173
 
    return (pointeur_struct_buffer -> pointeur_buffer == pointeur_buffer);
174
 
}
175
 
 
176
 
static long puissance_2_sup(nombre)
177
 
long nombre;
178
 
{
179
 
    long puissance = 1;
180
 
 
181
 
    while(puissance < nombre)
182
 
        puissance <<= 1;
183
 
 
184
 
    return puissance;
185
 
}
186
 
 
187
 
/* Liberation mixte : libere un buffer dynamique ou un buffer ordinaire */
188
 
void gbd_liberer_mixte(buffer)
189
 
void *buffer;
190
 
{
191
 
    if (!gbd_detruire_buffer_dynamique(buffer))
192
 
        liberer(buffer);
193
 
}