Annotation of rpl/src/gestion_variables_partagees.c, revision 1.1
1.1 ! bertrand 1: /*
! 2: ================================================================================
! 3: RPL/2 (R) version 4.0.9
! 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>