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