File:
[local] /
rpl /
src /
gestion_variables_partagees.c
Revision
1.21:
download - view:
text,
annotated -
select for diffs -
revision graph
Tue Jun 21 15:26:29 2011 UTC (13 years, 3 months ago) by
bertrand
Branches:
MAIN
CVS tags:
HEAD
Correction d'une réinitialisation sauvage de la pile des variables par niveau
dans la copie de la structure de description du processus. Cela corrige
la fonction SPAWN qui échouait sur un segmentation fault car la pile des
variables par niveau était vide alors même que l'arbre des variables contenait
bien les variables. Passage à la prerelease 2.
1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.0.prerelease.2
4: Copyright (C) 1989-2011 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: /*
27: ================================================================================
28: Routine de création d'une nouvelle variable partagee
29: ================================================================================
30: Entrée :
31: --------------------------------------------------------------------------------
32: Sortie :
33: --------------------------------------------------------------------------------
34: Effets de bords : néant
35: ================================================================================
36: */
37:
38: logical1
39: creation_variable_partagee(struct_processus *s_etat_processus,
40: struct_variable_partagee *s_variable)
41: {
42: struct_variable_partagee *s_nouvelle_base;
43:
44: long i;
45:
46: (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables++;
47:
48: if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables >
49: (*(*s_etat_processus).s_liste_variables_partagees)
50: .nombre_variables_allouees)
51: {
52: // La nouvelle variable partagée ne tient pas dans la table existante.
53: // Il convient donc d'en augmenter la taille.
54:
55: if ((*(*s_etat_processus).s_liste_variables_partagees)
56: .nombre_variables_allouees == 0)
57: {
58: (*(*s_etat_processus).s_liste_variables_partagees)
59: .nombre_variables_allouees = (*(*s_etat_processus)
60: .s_liste_variables_partagees).nombre_variables;
61: }
62: else
63: {
64: while((*(*s_etat_processus).s_liste_variables_partagees)
65: .nombre_variables > (*(*s_etat_processus)
66: .s_liste_variables_partagees).nombre_variables_allouees)
67: {
68: (*(*s_etat_processus).s_liste_variables_partagees)
69: .nombre_variables_allouees *= 2;
70: }
71: }
72:
73: if ((s_nouvelle_base = realloc((struct_variable_partagee *)
74: (*(*s_etat_processus).s_liste_variables_partagees).table,
75: (*(*s_etat_processus).s_liste_variables_partagees)
76: .nombre_variables_allouees *
77: sizeof(struct_variable_partagee))) == NULL)
78: {
79: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
80: (*(*s_etat_processus).s_liste_variables_partagees)
81: .nombre_variables--;
82: return(d_erreur);
83: }
84:
85: (*(*s_etat_processus).s_liste_variables_partagees).table =
86: s_nouvelle_base;
87: }
88:
89: /*
90: * Positionnement de la variable partagée au bon endroit
91: */
92:
93: if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables
94: == 1)
95: {
96: (*(*s_etat_processus).s_liste_variables_partagees).table[0]
97: = (*s_variable);
98: }
99: else
100: {
101: for(i = (*(*s_etat_processus).s_liste_variables_partagees)
102: .nombre_variables - 2; i >= 0; i--)
103: {
104: if (strcmp((*s_variable).nom, (*(*s_etat_processus)
105: .s_liste_variables_partagees).table[i].nom) < 0)
106: {
107: (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1]
108: = (*(*s_etat_processus).s_liste_variables_partagees)
109: .table[i];
110: }
111: else
112: {
113: break;
114: }
115: }
116:
117: (*(*s_etat_processus).s_liste_variables_partagees).table[i + 1]
118: = (*s_variable);
119: }
120:
121: return d_absence_erreur;
122: }
123:
124:
125: /*
126: ================================================================================
127: Procédure de retrait d'une variable partagee de la base
128: ================================================================================
129: Entrée :
130: --------------------------------------------------------------------------------
131: Sortie :
132: --------------------------------------------------------------------------------
133: Effets de bord : néant
134: ================================================================================
135: */
136:
137: logical1
138: retrait_variable_partagee(struct_processus *s_etat_processus,
139: unsigned char *nom_variable, union_position_variable position)
140: {
141: struct_variable_partagee *s_nouvelle_base;
142:
143: logical1 erreur;
144:
145: unsigned long position_courante;
146: unsigned long position_supprimee;
147:
148: if (recherche_variable_partagee(s_etat_processus, nom_variable,
149: position, ((*s_etat_processus).mode_execution_programme == 'Y')
150: ? 'P' : 'E') == d_vrai)
151: {
152: if ((*(*s_etat_processus).s_liste_variables_partagees).nombre_variables
153: < ((*(*s_etat_processus).s_liste_variables_partagees)
154: .nombre_variables_allouees / 2))
155: {
156: (*(*s_etat_processus).s_liste_variables_partagees)
157: .nombre_variables_allouees /= 2;
158:
159: if ((s_nouvelle_base = realloc((struct_variable_partagee *)
160: (*(*s_etat_processus).s_liste_variables_partagees).table,
161: (*(*s_etat_processus).s_liste_variables_partagees)
162: .nombre_variables_allouees *
163: sizeof(struct_variable_partagee))) == NULL)
164: {
165: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
166: return(d_erreur);
167: }
168:
169: (*(*s_etat_processus).s_liste_variables_partagees).table =
170: s_nouvelle_base;
171: }
172:
173: position_supprimee = (*(*s_etat_processus)
174: .s_liste_variables_partagees).position_variable;
175:
176: liberation(s_etat_processus, (*(*s_etat_processus)
177: .s_liste_variables_partagees).table[position_supprimee].objet);
178: free((*(*s_etat_processus).s_liste_variables_partagees)
179: .table[position_supprimee].nom);
180:
181: (*(*s_etat_processus).s_liste_variables_partagees).nombre_variables--;
182:
183: for(position_courante = position_supprimee; position_courante <
184: (*(*s_etat_processus).s_liste_variables_partagees)
185: .nombre_variables; position_courante++)
186: {
187: (*(*s_etat_processus).s_liste_variables_partagees).table
188: [position_courante] = (*(*s_etat_processus)
189: .s_liste_variables_partagees).table[position_courante + 1];
190: }
191:
192: erreur = d_absence_erreur;
193: }
194: else
195: {
196: erreur = d_erreur;
197: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
198: }
199:
200: return erreur;
201: }
202:
203:
204: /*
205: ================================================================================
206: Procédure de recherche d'une variable partagee par son nom dans la base
207: ================================================================================
208: Entrée :
209: --------------------------------------------------------------------------------
210: Sortie :
211: --------------------------------------------------------------------------------
212: Effets de bord : néant
213: ================================================================================
214: */
215:
216: logical1
217: recherche_variable_partagee(struct_processus *s_etat_processus,
218: unsigned char *nom_variable, union_position_variable position,
219: unsigned char origine)
220: {
221: logical1 existence_variable;
222:
223: long difference;
224: long difference_inferieure;
225: long difference_superieure;
226:
227: unsigned long borne_inferieure;
228: unsigned long borne_superieure;
229: unsigned long moyenne;
230: unsigned long nombre_iterations_maximal;
231: unsigned long ordre_iteration;
232:
233: if ((*(*s_etat_processus).s_liste_variables_partagees)
234: .nombre_variables == 0)
235: {
236: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
237: return d_faux;
238: }
239:
240: ordre_iteration = 0;
241: nombre_iterations_maximal = ((unsigned long)
242: (log((*(*s_etat_processus).s_liste_variables_partagees)
243: .nombre_variables) / log(2))) + 2;
244:
245: borne_inferieure = 0;
246: borne_superieure = (*(*s_etat_processus).s_liste_variables_partagees)
247: .nombre_variables - 1;
248:
249: do
250: {
251: moyenne = (borne_inferieure + borne_superieure) / 2;
252: ordre_iteration++;
253:
254: if ((2 * ((unsigned long) ((borne_inferieure + borne_superieure) / 2)))
255: == (borne_inferieure + borne_superieure))
256: {
257: difference = strcmp(nom_variable,
258: (*(*s_etat_processus).s_liste_variables_partagees)
259: .table[moyenne].nom);
260:
261: if (difference != 0)
262: {
263: if (difference > 0)
264: {
265: borne_inferieure = moyenne;
266: }
267: else
268: {
269: borne_superieure = moyenne;
270: }
271: }
272: }
273: else
274: {
275: difference_inferieure = strcmp(nom_variable,
276: (*(*s_etat_processus).s_liste_variables_partagees).table
277: [moyenne].nom);
278: difference_superieure = strcmp(nom_variable,
279: (*(*s_etat_processus).s_liste_variables_partagees).table
280: [moyenne + 1].nom);
281:
282: if (difference_inferieure == 0)
283: {
284: difference = 0;
285: }
286: else if (difference_superieure == 0)
287: {
288: difference = 0;
289: moyenne++;
290: }
291: else
292: {
293: difference = difference_inferieure;
294:
295: if (difference > 0)
296: {
297: borne_inferieure = moyenne;
298: }
299: else
300: {
301: borne_superieure = moyenne;
302: }
303: }
304: }
305: } while((difference != 0) &&
306: (ordre_iteration <= nombre_iterations_maximal));
307:
308: if (ordre_iteration > nombre_iterations_maximal)
309: {
310: existence_variable = d_faux;
311: (*s_etat_processus).erreur_systeme = d_es_variable_introuvable;
312: }
313: else
314: {
315: // Reste à rechercher la variable déclarée à la position 'position'...
316:
317: if ((*(*s_etat_processus).s_liste_variables_partagees).table[moyenne]
318: .origine == 'P')
319: {
320: if (((*(*s_etat_processus).s_liste_variables_partagees)
321: .table[moyenne].variable_partagee.adresse ==
322: position.adresse) && ((*(*s_etat_processus)
323: .s_liste_variables_partagees).table[moyenne]
324: .origine == origine))
325: {
326: existence_variable = d_vrai;
327: }
328: else
329: {
330: existence_variable = d_faux;
331: }
332: }
333: else
334: {
335: if (((*(*s_etat_processus).s_liste_variables_partagees)
336: .table[moyenne].variable_partagee.pointeur ==
337: position.pointeur) && ((*(*s_etat_processus)
338: .s_liste_variables_partagees).table[moyenne]
339: .origine == origine))
340: {
341: existence_variable = d_vrai;
342: }
343: else
344: {
345: existence_variable = d_faux;
346: }
347: }
348:
349: if (existence_variable == d_faux)
350: {
351: // On rembobine.
352:
353: if (moyenne > 0)
354: {
355: while(strcmp(nom_variable, (*(*s_etat_processus)
356: .s_liste_variables_partagees).table[moyenne - 1].nom)
357: == 0)
358: {
359: moyenne--;
360:
361: if (moyenne == 0)
362: {
363: break;
364: }
365: }
366: }
367:
368: // Un petit test pour voir si le premier élément du tableau
369: // peut correspondre au critère de recherche.
370:
371: existence_variable = d_faux;
372:
373: if (strcmp((*(*s_etat_processus).s_liste_variables_partagees).table
374: [moyenne].nom, nom_variable) == 0)
375: {
376: if ((*(*s_etat_processus).s_liste_variables_partagees).table
377: [moyenne].origine == 'P')
378: {
379: if (((*(*s_etat_processus).s_liste_variables_partagees)
380: .table[moyenne].variable_partagee.adresse
381: == position.adresse) &&
382: ((*(*s_etat_processus).s_liste_variables_partagees)
383: .table[moyenne].origine == origine))
384: {
385: existence_variable = d_vrai;
386: }
387: }
388: else
389: {
390: if (((*(*s_etat_processus).s_liste_variables_partagees)
391: .table[moyenne].variable_partagee.pointeur
392: == position.pointeur) &&
393: ((*(*s_etat_processus).s_liste_variables_partagees)
394: .table[moyenne].origine == origine))
395: {
396: existence_variable = d_vrai;
397: }
398: }
399: }
400:
401: // Puis on balaye dans le sens croissant.
402:
403: if (((moyenne + 1) < (*(*s_etat_processus)
404: .s_liste_variables_partagees).nombre_variables)
405: && (existence_variable == d_faux))
406: {
407: while(strcmp((*(*s_etat_processus)
408: .s_liste_variables_partagees).table[moyenne + 1].nom,
409: nom_variable) == 0)
410: {
411: moyenne++;
412:
413: if ((*(*s_etat_processus).s_liste_variables_partagees)
414: .table[moyenne].origine == 'P')
415: {
416: if (((*(*s_etat_processus).s_liste_variables_partagees)
417: .table[moyenne].variable_partagee.adresse ==
418: position.adresse) && ((*(*s_etat_processus)
419: .s_liste_variables_partagees)
420: .table[moyenne].origine == origine))
421: {
422: existence_variable = d_vrai;
423: break;
424: }
425: }
426: else
427: {
428: if (((*(*s_etat_processus).s_liste_variables_partagees)
429: .table[moyenne].variable_partagee.pointeur ==
430: position.pointeur) && ((*(*s_etat_processus)
431: .s_liste_variables_partagees)
432: .table[moyenne].origine == origine))
433: {
434: existence_variable = d_vrai;
435: break;
436: }
437: }
438:
439: if ((moyenne + 1) >= (*(*s_etat_processus)
440: .s_liste_variables_partagees).nombre_variables)
441: {
442: break;
443: }
444: }
445: }
446: }
447:
448: (*(*s_etat_processus).s_liste_variables_partagees).position_variable
449: = moyenne;
450: }
451:
452: /*
453: * Si la variable partagée n'existe pas, elle a été rendue privée par un
454: * thread concurrent. Il faut donc l'enlever de la table des variables
455: * du thread courant.
456: */
457:
458: if (existence_variable == d_faux)
459: {
460: if (retrait_variable(s_etat_processus, nom_variable, 'L') == d_faux)
461: {
462: return d_faux;
463: }
464: }
465:
466: return existence_variable;
467: }
468:
469: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>