![]() ![]() | ![]() |
Passage de la branche 4.1 en branche stable.
1: /* 2: ================================================================================ 3: RPL/2 (R) version 4.1.0 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