1: /*
2: ================================================================================
3: RPL/2 (R) version 4.0.14
4: Copyright (C) 1989-2010 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>