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: Routines de gestion du nombre d'occurrences comme grandeur atomique
29: ================================================================================
30: entrées : structure sur l'état du processus et objet à afficher
31: --------------------------------------------------------------------------------
32: sorties : chaine de caractères
33: --------------------------------------------------------------------------------
34: effets de bord : néant
35: ================================================================================
36: */
37:
38: static inline void
39: incrementation_atomique(struct_objet *s_objet)
40: {
41: // Le mutex est sur l'objet.
42:
43: (*s_objet).nombre_occurrences++;
44:
45: BUG((*s_objet).nombre_occurrences <= 0,
46: uprintf("Capacity exceeded %ld\n", (*s_objet).nombre_occurrences));
47:
48: return;
49: }
50:
51: static inline long
52: decrementation_atomique(struct_objet *s_objet)
53: {
54: // Le mutex est sur l'objet.
55:
56: (*s_objet).nombre_occurrences--;
57: return((*s_objet).nombre_occurrences);
58: }
59:
60: void
61: initialisation_objet(struct_objet *s_objet)
62: {
63: pthread_mutexattr_t attributs_mutex;
64:
65: pthread_mutexattr_init(&attributs_mutex);
66: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
67: pthread_mutex_init(&((*s_objet).mutex), &attributs_mutex);
68: pthread_mutexattr_destroy(&attributs_mutex);
69:
70: (*s_objet).nombre_occurrences = 1;
71:
72: return;
73: }
74:
75:
76: /*
77: ================================================================================
78: Routines d'initialisation et de purge de l'allocateur
79: ================================================================================
80: Entrées : structure sur l'état du processus et objet à afficher
81: --------------------------------------------------------------------------------
82: Sorties : chaine de caractères
83: --------------------------------------------------------------------------------
84: Effets de bord : néant
85: ================================================================================
86: */
87:
88: void
89: initialisation_allocateur(struct_processus *s_etat_processus)
90: {
91: (*s_etat_processus).estimation_taille_pile_tampon = 0;
92: (*s_etat_processus).taille_pile_tampon = 0;
93: (*s_etat_processus).pile_tampon = NULL;
94:
95: (*s_etat_processus).estimation_taille_pile_systeme_tampon = 0;
96: (*s_etat_processus).taille_pile_systeme_tampon = 0;
97: (*s_etat_processus).pile_systeme_tampon = NULL;
98:
99: (*s_etat_processus).taille_pile_objets = 0;
100: (*s_etat_processus).pile_objets = NULL;
101:
102: (*s_etat_processus).pointeur_adr = 0;
103: (*s_etat_processus).pointeur_bin = 0;
104: (*s_etat_processus).pointeur_cpl = 0;
105: (*s_etat_processus).pointeur_fct = 0;
106: (*s_etat_processus).pointeur_int = 0;
107: (*s_etat_processus).pointeur_mat = 0;
108: (*s_etat_processus).pointeur_nom = 0;
109: (*s_etat_processus).pointeur_rel = 0;
110: (*s_etat_processus).pointeur_tab = 0;
111: (*s_etat_processus).pointeur_vec = 0;
112: (*s_etat_processus).pointeur_maillons = 0;
113:
114: (*s_etat_processus).pointeur_variables_noeud = 0;
115: (*s_etat_processus).pointeur_variables_partagees_noeud = 0;
116: (*s_etat_processus).pointeur_variables_feuille = 0;
117: (*s_etat_processus).pointeur_variables_variable = 0;
118: (*s_etat_processus).pointeur_variables_tableau_noeuds = 0;
119: (*s_etat_processus).pointeur_variables_tableau_noeuds_partages = 0;
120:
121: return;
122: }
123:
124:
125: void
126: liberation_allocateur(struct_processus *s_etat_processus)
127: {
128: int i;
129:
130: for(i = 0; i < (*s_etat_processus).pointeur_adr;
131: free((*s_etat_processus).objets_adr[i++]));
132: for(i = 0; i < (*s_etat_processus).pointeur_bin;
133: free((*s_etat_processus).objets_bin[i++]));
134: for(i = 0; i < (*s_etat_processus).pointeur_cpl;
135: free((*s_etat_processus).objets_cpl[i++]));
136: for(i = 0; i < (*s_etat_processus).pointeur_fct;
137: free((*s_etat_processus).objets_fct[i++]));
138: for(i = 0; i < (*s_etat_processus).pointeur_int;
139: free((*s_etat_processus).objets_int[i++]));
140: for(i = 0; i < (*s_etat_processus).pointeur_mat;
141: free((*s_etat_processus).objets_mat[i++]));
142: for(i = 0; i < (*s_etat_processus).pointeur_nom;
143: free((*s_etat_processus).objets_nom[i++]));
144: for(i = 0; i < (*s_etat_processus).pointeur_rel;
145: free((*s_etat_processus).objets_rel[i++]));
146: for(i = 0; i < (*s_etat_processus).pointeur_tab;
147: free((*s_etat_processus).objets_tab[i++]));
148: for(i = 0; i < (*s_etat_processus).pointeur_vec;
149: free((*s_etat_processus).objets_vec[i++]));
150: for(i = 0; i < (*s_etat_processus).pointeur_maillons;
151: free((*s_etat_processus).maillons[i++]));
152:
153: for(i = 0; i < (*s_etat_processus).pointeur_variables_noeud;
154: free((*s_etat_processus).variables_noeud[i++]));
155: for(i = 0; i < (*s_etat_processus).pointeur_variables_feuille;
156: free((*s_etat_processus).variables_feuille[i++]));
157: for(i = 0; i < (*s_etat_processus).pointeur_variables_variable;
158: free((*s_etat_processus).variables_variable[i++]));
159: for(i = 0; i < (*s_etat_processus).pointeur_variables_tableau_noeuds;
160: free((*s_etat_processus).variables_tableau_noeuds[i++]));
161:
162: {
163: struct_liste_chainee *l_element_courant;
164: struct_liste_chainee *l_element_suivant;
165:
166: l_element_courant = (*s_etat_processus).pile_tampon;
167:
168: while(l_element_courant != NULL)
169: {
170: l_element_suivant = (*l_element_courant).suivant;
171: liberation(s_etat_processus, (*l_element_courant).donnee);
172: free(l_element_courant);
173: l_element_courant = l_element_suivant;
174: }
175: }
176:
177: {
178: struct_liste_pile_systeme *l_element_courant;
179: struct_liste_pile_systeme *l_element_suivant;
180:
181: l_element_courant = (*s_etat_processus).pile_systeme_tampon;
182:
183: while(l_element_courant != NULL)
184: {
185: l_element_suivant = (*l_element_courant).suivant;
186: free(l_element_courant);
187: l_element_courant = l_element_suivant;
188: }
189: }
190:
191: {
192: struct_objet *l_element_courant;
193: struct_objet *l_element_suivant;
194:
195: l_element_courant = (*s_etat_processus).pile_objets;
196:
197: while(l_element_courant != NULL)
198: {
199: l_element_suivant = (*l_element_courant).objet;
200:
201: if (pthread_mutex_destroy(&((*l_element_courant).mutex)) != 0)
202: {
203: (*s_etat_processus).erreur_systeme = d_es_processus;
204: BUG(1, printf("Mutex error\n"));
205: return;
206: }
207:
208: free(l_element_courant);
209: l_element_courant = l_element_suivant;
210: }
211: }
212:
213: return;
214: }
215:
216:
217: /*
218: ================================================================================
219: Routine d'allocation d'un maillon d'un objet (liste, expression...)
220: ================================================================================
221: Entrées : structure sur l'état du processus et objet à afficher
222: --------------------------------------------------------------------------------
223: Sorties : chaine de caractères
224: --------------------------------------------------------------------------------
225: Effets de bord : néant
226: ================================================================================
227: */
228:
229: void *
230: allocation_maillon(struct_processus *s_etat_processus)
231: {
232: struct_liste_chainee *s_maillon;
233:
234: if ((*s_etat_processus).pointeur_maillons > 0)
235: {
236: s_maillon = (*s_etat_processus).maillons
237: [--(*s_etat_processus).pointeur_maillons];
238: }
239: else
240: {
241: if ((s_maillon = malloc(sizeof(struct_liste_chainee))) == NULL)
242: {
243: return(NULL);
244: }
245: }
246:
247: return(s_maillon);
248: }
249:
250:
251: /*
252: ================================================================================
253: Routine de libération d'un maillon d'un objet (liste, expression...)
254: ================================================================================
255: Entrées : structure sur l'état du processus et objet à afficher
256: --------------------------------------------------------------------------------
257: Sorties : chaine de caractères
258: --------------------------------------------------------------------------------
259: Effets de bord : néant
260: ================================================================================
261: */
262:
263: void
264: liberation_maillon(struct_processus *s_etat_processus,
265: struct_liste_chainee *maillon)
266: {
267: if ((*s_etat_processus).pointeur_maillons < TAILLE_CACHE)
268: {
269: (*s_etat_processus).maillons
270: [(*s_etat_processus).pointeur_maillons++] = maillon;
271: }
272: else
273: {
274: free(maillon);
275: }
276:
277: return;
278: }
279:
280:
281: /*
282: ================================================================================
283: Routine d'allocation d'une structure *s_objet
284: ================================================================================
285: Entrées : structure sur l'état du processus et objet à allouer
286: --------------------------------------------------------------------------------
287: Sorties : chaine de caractères
288: --------------------------------------------------------------------------------
289: Effets de bord : néant
290: ================================================================================
291: */
292:
293: struct_objet *
294: allocation(struct_processus *s_etat_processus, enum t_type type)
295: {
296: struct_objet *s_objet;
297:
298: if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation)) != 0)
299: {
300: (*s_etat_processus).erreur_systeme = d_es_processus;
301: return(NULL);
302: }
303:
304: if ((*s_etat_processus).pile_objets == NULL)
305: {
306: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0)
307: {
308: (*s_etat_processus).erreur_systeme = d_es_processus;
309: return(NULL);
310: }
311:
312: // Il n'existe aucune structure struct_objet disponible dans le cache.
313:
314: if ((s_objet = malloc(sizeof(struct_objet))) == NULL)
315: {
316: return(NULL);
317: }
318:
319: initialisation_objet(s_objet);
320: }
321: else
322: {
323: // Récupération d'une structure dans le cache.
324:
325: s_objet = (*s_etat_processus).pile_objets;
326: (*s_etat_processus).pile_objets = (*s_objet).objet;
327: (*s_etat_processus).taille_pile_objets--;
328:
329: (*s_objet).nombre_occurrences = 1;
330:
331: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0)
332: {
333: (*s_etat_processus).erreur_systeme = d_es_processus;
334: return(NULL);
335: }
336: }
337:
338: (*s_objet).type = type;
339:
340: switch(type)
341: {
342: case ADR :
343: {
344: if ((*s_etat_processus).pointeur_adr > 0)
345: {
346: (*s_objet).objet = (*s_etat_processus).objets_adr
347: [--(*s_etat_processus).pointeur_adr];
348: }
349: else
350: {
351: if (((*s_objet).objet = malloc(sizeof(unsigned long))) == NULL)
352: {
353: free(s_objet);
354: return(NULL);
355: }
356: }
357:
358: break;
359: }
360:
361: case ALG :
362: {
363: (*s_objet).objet = NULL;
364: break;
365: }
366:
367: case BIN :
368: {
369: if ((*s_etat_processus).pointeur_bin > 0)
370: {
371: (*s_objet).objet = (*s_etat_processus).objets_bin
372: [--(*s_etat_processus).pointeur_bin];
373: }
374: else
375: {
376: if (((*s_objet).objet = malloc(sizeof(logical8))) == NULL)
377: {
378: free(s_objet);
379: return(NULL);
380: }
381: }
382:
383: break;
384: }
385:
386: case CHN :
387: {
388: (*s_objet).objet = NULL;
389: break;
390: }
391:
392: case CPL :
393: {
394: if ((*s_etat_processus).pointeur_cpl > 0)
395: {
396: (*s_objet).objet = (*s_etat_processus).objets_cpl
397: [--(*s_etat_processus).pointeur_cpl];
398: }
399: else
400: {
401: if (((*s_objet).objet = malloc(sizeof(struct_complexe16)))
402: == NULL)
403: {
404: free(s_objet);
405: return(NULL);
406: }
407: }
408:
409: break;
410: }
411:
412: case FCH :
413: {
414: if (((*s_objet).objet = malloc(sizeof(struct_fichier))) == NULL)
415: {
416: free(s_objet);
417: return(NULL);
418: }
419:
420: break;
421: }
422:
423: case FCT :
424: {
425: if ((*s_etat_processus).pointeur_fct > 0)
426: {
427: (*s_objet).objet = (*s_etat_processus).objets_fct
428: [--(*s_etat_processus).pointeur_fct];
429: }
430: else
431: {
432: if (((*s_objet).objet = malloc(sizeof(struct_fonction)))
433: == NULL)
434: {
435: free(s_objet);
436: return(NULL);
437: }
438: }
439:
440: (*((struct_fonction *) (*s_objet).objet)).fonction = NULL;
441: (*((struct_fonction *) (*s_objet).objet)).prediction_saut = NULL;
442: (*((struct_fonction *) (*s_objet).objet)).prediction_execution
443: = d_faux;
444: break;
445: }
446:
447: case INT :
448: {
449: if ((*s_etat_processus).pointeur_int > 0)
450: {
451: (*s_objet).objet = (*s_etat_processus).objets_int
452: [--(*s_etat_processus).pointeur_int];
453: }
454: else
455: {
456: if (((*s_objet).objet = malloc(sizeof(integer8))) == NULL)
457: {
458: free(s_objet);
459: return(NULL);
460: }
461: }
462:
463: break;
464: }
465:
466: case LST :
467: {
468: (*s_objet).objet = NULL;
469: break;
470: }
471:
472: case MCX :
473: {
474: if ((*s_etat_processus).pointeur_mat > 0)
475: {
476: (*s_objet).objet = (*s_etat_processus).objets_mat
477: [--(*s_etat_processus).pointeur_mat];
478: }
479: else
480: {
481: if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL)
482: {
483: free(s_objet);
484: return(NULL);
485: }
486: }
487:
488: (*((struct_matrice *) (*s_objet).objet)).type = 'C';
489: (*((struct_matrice *) (*s_objet).objet)).nombre_lignes = 0;
490: (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes = 0;
491: (*((struct_matrice *) (*s_objet).objet)).tableau = NULL;
492: break;
493: }
494:
495: case MIN :
496: {
497: if ((*s_etat_processus).pointeur_mat > 0)
498: {
499: (*s_objet).objet = (*s_etat_processus).objets_mat
500: [--(*s_etat_processus).pointeur_mat];
501: }
502: else
503: {
504: if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL)
505: {
506: free(s_objet);
507: return(NULL);
508: }
509: }
510:
511: (*((struct_matrice *) (*s_objet).objet)).type = 'I';
512: (*((struct_matrice *) (*s_objet).objet)).nombre_lignes = 0;
513: (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes = 0;
514: (*((struct_matrice *) (*s_objet).objet)).tableau = NULL;
515: break;
516: }
517:
518: case MRL :
519: {
520: if ((*s_etat_processus).pointeur_mat > 0)
521: {
522: (*s_objet).objet = (*s_etat_processus).objets_mat
523: [--(*s_etat_processus).pointeur_mat];
524: }
525: else
526: {
527: if (((*s_objet).objet = malloc(sizeof(struct_matrice))) == NULL)
528: {
529: free(s_objet);
530: return(NULL);
531: }
532: }
533:
534: (*((struct_matrice *) (*s_objet).objet)).type = 'R';
535: (*((struct_matrice *) (*s_objet).objet)).nombre_lignes = 0;
536: (*((struct_matrice *) (*s_objet).objet)).nombre_colonnes = 0;
537: (*((struct_matrice *) (*s_objet).objet)).tableau = NULL;
538: break;
539: }
540:
541: case MTX :
542: {
543: if (((*s_objet).objet = malloc(sizeof(struct_mutex))) == NULL)
544: {
545: free(s_objet);
546: return(NULL);
547: }
548:
549: (*((struct_mutex *) (*s_objet).objet)).tid = pthread_self();
550: break;
551: }
552:
553: case NOM :
554: {
555: if ((*s_etat_processus).pointeur_nom > 0)
556: {
557: (*s_objet).objet = (*s_etat_processus).objets_nom
558: [--(*s_etat_processus).pointeur_nom];
559: }
560: else
561: {
562: if (((*s_objet).objet = malloc(sizeof(struct_nom))) == NULL)
563: {
564: free(s_objet);
565: return(NULL);
566: }
567: }
568:
569: break;
570: }
571:
572: case NON :
573: {
574: (*s_objet).objet = NULL;
575: break;
576: }
577:
578: case PRC :
579: {
580: if (((*s_objet).objet = malloc(sizeof(struct_processus_fils)))
581: == NULL)
582: {
583: free(s_objet);
584: return(NULL);
585: }
586:
587: break;
588: }
589:
590: case REL :
591: {
592: if ((*s_etat_processus).pointeur_rel > 0)
593: {
594: (*s_objet).objet = (*s_etat_processus).objets_rel
595: [--(*s_etat_processus).pointeur_rel];
596: }
597: else
598: {
599: if (((*s_objet).objet = malloc(sizeof(real8))) == NULL)
600: {
601: free(s_objet);
602: return(NULL);
603: }
604: }
605:
606: break;
607: }
608:
609: case RPN :
610: {
611: (*s_objet).objet = NULL;
612: break;
613: }
614:
615: case SCK :
616: {
617: if (((*s_objet).objet = malloc(sizeof(struct_socket))) == NULL)
618: {
619: free(s_objet);
620: return(NULL);
621: }
622:
623: break;
624: }
625:
626: case SLB :
627: {
628: if (((*s_objet).objet = malloc(sizeof(struct_bibliotheque)))
629: == NULL)
630: {
631: free(s_objet);
632: return(NULL);
633: }
634:
635: break;
636: }
637:
638: case SPH :
639: {
640: if (((*s_objet).objet = malloc(sizeof(struct_semaphore))) == NULL)
641: {
642: free(s_objet);
643: return(NULL);
644: }
645:
646: break;
647: }
648:
649: case SQL :
650: {
651: if (((*s_objet).objet = malloc(sizeof(struct_connecteur_sql)))
652: == NULL)
653: {
654: free(s_objet);
655: return(NULL);
656: }
657:
658: break;
659: }
660:
661: case TBL :
662: {
663: if ((*s_etat_processus).pointeur_tab > 0)
664: {
665: (*s_objet).objet = (*s_etat_processus).objets_tab
666: [--(*s_etat_processus).pointeur_tab];
667: }
668: else
669: {
670: if (((*s_objet).objet = malloc(sizeof(struct_tableau))) == NULL)
671: {
672: free(s_objet);
673: return(NULL);
674: }
675: }
676:
677: (*((struct_tableau *) (*s_objet).objet)).nombre_elements = 0;
678: (*((struct_tableau *) (*s_objet).objet)).elements = NULL;
679: break;
680: }
681:
682: case VCX :
683: {
684: if ((*s_etat_processus).pointeur_vec > 0)
685: {
686: (*s_objet).objet = (*s_etat_processus).objets_vec
687: [--(*s_etat_processus).pointeur_vec];
688: }
689: else
690: {
691: if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL)
692: {
693: free(s_objet);
694: return(NULL);
695: }
696: }
697:
698: (*((struct_vecteur *) (*s_objet).objet)).type = 'C';
699: (*((struct_vecteur *) (*s_objet).objet)).taille = 0;
700: (*((struct_vecteur *) (*s_objet).objet)).tableau = NULL;
701: break;
702: }
703:
704: case VIN :
705: {
706: if ((*s_etat_processus).pointeur_vec > 0)
707: {
708: (*s_objet).objet = (*s_etat_processus).objets_vec
709: [--(*s_etat_processus).pointeur_vec];
710: }
711: else
712: {
713: if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL)
714: {
715: free(s_objet);
716: return(NULL);
717: }
718: }
719:
720: (*((struct_vecteur *) (*s_objet).objet)).type = 'I';
721: (*((struct_vecteur *) (*s_objet).objet)).taille = 0;
722: (*((struct_vecteur *) (*s_objet).objet)).tableau = NULL;
723: break;
724: }
725:
726: case VRL :
727: {
728: if ((*s_etat_processus).pointeur_vec > 0)
729: {
730: (*s_objet).objet = (*s_etat_processus).objets_vec
731: [--(*s_etat_processus).pointeur_vec];
732: }
733: else
734: {
735: if (((*s_objet).objet = malloc(sizeof(struct_vecteur))) == NULL)
736: {
737: free(s_objet);
738: return(NULL);
739: }
740: }
741:
742: (*((struct_vecteur *) (*s_objet).objet)).type = 'R';
743: (*((struct_vecteur *) (*s_objet).objet)).taille = 0;
744: (*((struct_vecteur *) (*s_objet).objet)).tableau = NULL;
745: break;
746: }
747:
748: default :
749: {
750: free(s_objet);
751: BUG(1, printf("Allocation failure (type %d)\n", type));
752:
753: return(NULL);
754: }
755: }
756:
757: return(s_objet);
758: }
759:
760:
761: /*
762: ================================================================================
763: Routine de libération d'une structure *s_objet
764: ================================================================================
765: Entrées : structure sur l'état du processus et objet à afficher
766: --------------------------------------------------------------------------------
767: Sorties : chaine de caractères
768: --------------------------------------------------------------------------------
769: Effets de bord : néant
770: ================================================================================
771: */
772:
773: void
774: liberation(struct_processus *s_etat_processus, struct_objet *s_objet)
775: {
776: logical1 drapeau;
777:
778: struct_liste_chainee *l_element_courant;
779: struct_liste_chainee *l_element_suivant;
780:
781: unsigned long i;
782:
783: if (s_objet == NULL)
784: {
785: return;
786: }
787:
788: if (pthread_mutex_lock(&((*s_objet).mutex)) != 0)
789: {
790: (*s_etat_processus).erreur_systeme = d_es_processus;
791: return;
792: }
793:
794: #define return \
795: if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0) \
796: { (*s_etat_processus).erreur_systeme = d_es_processus; return; } \
797: return
798:
799: BUG((*s_objet).nombre_occurrences <= 0,
800: pthread_mutex_unlock(&((*s_objet).mutex)),
801: printf("(*s_objet).nombre_occurrences=%ld\n",
802: (*s_objet).nombre_occurrences));
803:
804: switch((*s_objet).type)
805: {
806: case ADR :
807: {
808: if (decrementation_atomique(s_objet) > 0)
809: {
810: return;
811: }
812:
813: if ((*s_etat_processus).pointeur_adr < TAILLE_CACHE)
814: {
815: (*s_etat_processus).objets_adr
816: [(*s_etat_processus).pointeur_adr++] = (*s_objet).objet;
817: }
818: else
819: {
820: free((unsigned long *) ((*s_objet).objet));
821: }
822:
823: break;
824: }
825:
826: case ALG :
827: {
828: l_element_courant = (struct_liste_chainee *) ((*s_objet).objet);
829:
830: if (decrementation_atomique(s_objet) > 0)
831: { // Il reste un pointeur sur l'objet.
832: while(l_element_courant != NULL)
833: {
834: BUG((*(*l_element_courant).donnee).nombre_occurrences <= 1,
835: pthread_mutex_unlock(&((*s_objet).mutex)),
836: printf("(*(*l_element_courant).donnee)"
837: ".nombre_occurrences=%ld\n",
838: (*(*l_element_courant).donnee).nombre_occurrences));
839:
840: liberation(s_etat_processus, (*l_element_courant).donnee);
841: l_element_courant = (*l_element_courant).suivant;
842: }
843:
844: return;
845: }
846: else
847: { // Il ne reste plus aucun pointeur sur l'objet.
848: while(l_element_courant != NULL)
849: {
850: l_element_suivant = (*l_element_courant).suivant;
851: liberation(s_etat_processus, (*l_element_courant).donnee);
852: liberation_maillon(s_etat_processus, l_element_courant);
853: l_element_courant = l_element_suivant;
854: }
855: }
856:
857: break;
858: }
859:
860: case BIN :
861: {
862: if (decrementation_atomique(s_objet) > 0)
863: {
864: return;
865: }
866:
867: if ((*s_etat_processus).pointeur_bin < TAILLE_CACHE)
868: {
869: (*s_etat_processus).objets_bin
870: [(*s_etat_processus).pointeur_bin++] = (*s_objet).objet;
871: }
872: else
873: {
874: free((logical8 *) ((*s_objet).objet));
875: }
876:
877: break;
878: }
879:
880: case CHN :
881: {
882: if (decrementation_atomique(s_objet) > 0)
883: {
884: return;
885: }
886:
887: free((unsigned char *) ((*s_objet).objet));
888: break;
889: }
890:
891: case CPL :
892: {
893: if (decrementation_atomique(s_objet) > 0)
894: {
895: return;
896: }
897:
898: if ((*s_etat_processus).pointeur_cpl < TAILLE_CACHE)
899: {
900: (*s_etat_processus).objets_cpl
901: [(*s_etat_processus).pointeur_cpl++] = (*s_objet).objet;
902: }
903: else
904: {
905: free((struct_complexe16 *) ((*s_objet).objet));
906: }
907:
908: break;
909: }
910:
911: case FCH :
912: {
913: if (decrementation_atomique(s_objet) > 0)
914: {
915: BUG((*(*((struct_fichier *) (*s_objet).objet)).format)
916: .nombre_occurrences <= 1,
917: pthread_mutex_unlock(&((*s_objet).mutex)),
918: printf("(*(*((struct_fichier *) (*s_objet).objet))"
919: ".format).nombre_occurrences=%ld\n",
920: (*(*((struct_fichier *) (*s_objet).objet)).format)
921: .nombre_occurrences));
922:
923: liberation(s_etat_processus,
924: (*((struct_fichier *) (*s_objet).objet)).format);
925: return;
926: }
927:
928: liberation(s_etat_processus,
929: (*((struct_fichier *) (*s_objet).objet)).format);
930: free((unsigned char *) (*((struct_fichier *)
931: (*s_objet).objet)).nom);
932: free((struct_fichier *) ((*s_objet).objet));
933: break;
934: }
935:
936: case FCT :
937: {
938: if (decrementation_atomique(s_objet) > 0)
939: {
940: return;
941: }
942:
943: free((unsigned char *) (*((struct_fonction *)
944: (*s_objet).objet)).nom_fonction);
945:
946: if ((*s_etat_processus).pointeur_fct < TAILLE_CACHE)
947: {
948: (*s_etat_processus).objets_fct
949: [(*s_etat_processus).pointeur_fct++] = (*s_objet).objet;
950: }
951: else
952: {
953: free((struct_fonction *) (*s_objet).objet);
954: }
955:
956: break;
957: }
958:
959: case INT :
960: {
961: if (decrementation_atomique(s_objet) > 0)
962: {
963: return;
964: }
965:
966: if ((*s_etat_processus).pointeur_int < TAILLE_CACHE)
967: {
968: (*s_etat_processus).objets_int
969: [(*s_etat_processus).pointeur_int++] = (*s_objet).objet;
970: }
971: else
972: {
973: free((integer8 *) ((*s_objet).objet));
974: }
975:
976: break;
977: }
978:
979: case LST :
980: {
981: l_element_courant = (struct_liste_chainee *) ((*s_objet).objet);
982:
983: if (decrementation_atomique(s_objet) > 0)
984: { // Il reste un pointeur sur l'objet.
985: while(l_element_courant != NULL)
986: {
987: BUG((*(*l_element_courant).donnee).nombre_occurrences <= 1,
988: pthread_mutex_unlock(&((*s_objet).mutex)),
989: printf("(*(*l_element_courant).donnee)"
990: ".nombre_occurrences=%ld\n",
991: (*(*l_element_courant).donnee).nombre_occurrences));
992:
993: liberation(s_etat_processus, (*l_element_courant).donnee);
994: l_element_courant = (*l_element_courant).suivant;
995: }
996:
997: return;
998: }
999: else
1000: { // Il ne reste plus aucun pointeur sur l'objet.
1001: while(l_element_courant != NULL)
1002: {
1003: l_element_suivant = (*l_element_courant).suivant;
1004: liberation(s_etat_processus, (*l_element_courant).donnee);
1005: liberation_maillon(s_etat_processus, l_element_courant);
1006: l_element_courant = l_element_suivant;
1007: }
1008: }
1009:
1010: break;
1011: }
1012:
1013: case MIN :
1014: {
1015: if (decrementation_atomique(s_objet) > 0)
1016: {
1017: return;
1018: }
1019:
1020: for(i = 0; i < (*((struct_matrice *)
1021: ((*s_objet).objet))).nombre_lignes; i++)
1022: {
1023: free(((integer8 **) (*((struct_matrice *)
1024: (*s_objet).objet)).tableau)[i]);
1025: }
1026:
1027: free((integer8 **) (*((struct_matrice *)
1028: (*s_objet).objet)).tableau);
1029:
1030: if ((*s_etat_processus).pointeur_mat < TAILLE_CACHE)
1031: {
1032: (*s_etat_processus).objets_mat
1033: [(*s_etat_processus).pointeur_mat++] = (*s_objet).objet;
1034: }
1035: else
1036: {
1037: free((struct_matrice *) (*s_objet).objet);
1038: }
1039:
1040: break;
1041: }
1042:
1043: case MCX :
1044: {
1045: if (decrementation_atomique(s_objet) > 0)
1046: {
1047: return;
1048: }
1049:
1050: for(i = 0; i < (*((struct_matrice *)
1051: ((*s_objet).objet))).nombre_lignes; i++)
1052: {
1053: free(((struct_complexe16 **) (*((struct_matrice *)
1054: (*s_objet).objet)).tableau)[i]);
1055: }
1056:
1057: free((struct_complexe16 **) (*((struct_matrice *)
1058: (*s_objet).objet)).tableau);
1059:
1060: if ((*s_etat_processus).pointeur_mat < TAILLE_CACHE)
1061: {
1062: (*s_etat_processus).objets_mat
1063: [(*s_etat_processus).pointeur_mat++] = (*s_objet).objet;
1064: }
1065: else
1066: {
1067: free((struct_matrice *) (*s_objet).objet);
1068: }
1069:
1070: break;
1071: }
1072:
1073: case MRL :
1074: {
1075: if (decrementation_atomique(s_objet) > 0)
1076: {
1077: return;
1078: }
1079:
1080: for(i = 0; i < (*((struct_matrice *)
1081: ((*s_objet).objet))).nombre_lignes; i++)
1082: {
1083: free(((real8 **) (*((struct_matrice *)
1084: (*s_objet).objet)).tableau)[i]);
1085: }
1086:
1087: free((real8 **) (*((struct_matrice *) (*s_objet).objet)).tableau);
1088:
1089: if ((*s_etat_processus).pointeur_mat < TAILLE_CACHE)
1090: {
1091: (*s_etat_processus).objets_mat
1092: [(*s_etat_processus).pointeur_mat++] = (*s_objet).objet;
1093: }
1094: else
1095: {
1096: free((struct_matrice *) (*s_objet).objet);
1097: }
1098:
1099: break;
1100: }
1101:
1102: case MTX :
1103: {
1104: if (decrementation_atomique(s_objet) > 0)
1105: {
1106: return;
1107: }
1108:
1109: if (pthread_mutex_trylock(&((*((struct_mutex *)
1110: (*s_objet).objet)).mutex)) == 0)
1111: {
1112: // On a pu verrouiller le mutex. Il faut donc spécifier le tid.
1113: (*((struct_mutex *) (*s_objet).objet)).tid = pthread_self();
1114: }
1115:
1116: if (pthread_equal(pthread_self(),
1117: (*((struct_mutex *) (*s_objet).objet)).tid) != 0)
1118: {
1119: pthread_mutex_unlock(&((*((struct_mutex *)
1120: (*s_objet).objet)).mutex));
1121: }
1122: else
1123: {
1124: (*s_etat_processus).erreur_systeme =
1125: d_es_mutex_acquis_autre_thread;
1126: return;
1127: }
1128:
1129: pthread_mutex_destroy(&((*((struct_mutex *)
1130: (*s_objet).objet)).mutex));
1131: free((struct_mutex *) (*s_objet).objet);
1132: break;
1133: }
1134:
1135: case NOM :
1136: {
1137: if (decrementation_atomique(s_objet) > 0)
1138: {
1139: return;
1140: }
1141:
1142: free((*((struct_nom *) (*s_objet).objet)).nom);
1143:
1144: if ((*s_etat_processus).pointeur_nom < TAILLE_CACHE)
1145: {
1146: (*s_etat_processus).objets_nom
1147: [(*s_etat_processus).pointeur_nom++] = (*s_objet).objet;
1148: }
1149: else
1150: {
1151: free((struct_nom *) (*s_objet).objet);
1152: }
1153:
1154: break;
1155: }
1156:
1157: case NON :
1158: {
1159: if (decrementation_atomique(s_objet) > 0)
1160: {
1161: return;
1162: }
1163:
1164: break;
1165: }
1166:
1167: case PRC :
1168: {
1169: if (pthread_mutex_lock(&((*(*((struct_processus_fils *)
1170: (*s_objet).objet)).thread).mutex_nombre_references)) != 0)
1171: {
1172: (*s_etat_processus).erreur_systeme = d_es_processus;
1173: return;
1174: }
1175:
1176: (*(*((struct_processus_fils *) (*s_objet).objet)).thread)
1177: .nombre_references--;
1178:
1179: BUG((*(*((struct_processus_fils *) (*s_objet).objet)).thread)
1180: .nombre_references < 0, uprintf(
1181: "(*(*((struct_processus_fils"
1182: " *) (*s_objet).objet)).thread).nombre_references = %d\n",
1183: (int) (*(*((struct_processus_fils *) (*s_objet).objet))
1184: .thread).nombre_references));
1185:
1186: if ((*(*((struct_processus_fils *) (*s_objet).objet)).thread)
1187: .nombre_references == 0)
1188: {
1189: drapeau = d_vrai;
1190: }
1191: else
1192: {
1193: drapeau = d_faux;
1194: }
1195:
1196: if (pthread_mutex_unlock(&((*(*((struct_processus_fils *)
1197: (*s_objet).objet)).thread).mutex_nombre_references)) != 0)
1198: {
1199: (*s_etat_processus).erreur_systeme = d_es_processus;
1200: return;
1201: }
1202:
1203: if (drapeau == d_vrai)
1204: {
1205: pthread_mutex_destroy(&((*(*((struct_processus_fils *)
1206: (*s_objet).objet)).thread).mutex));
1207: pthread_mutex_destroy(&((*(*((struct_processus_fils *)
1208: (*s_objet).objet)).thread).mutex_nombre_references));
1209: free((*((struct_processus_fils *) (*s_objet).objet)).thread);
1210: }
1211:
1212: if (decrementation_atomique(s_objet) > 0)
1213: {
1214: BUG(drapeau == d_vrai, uprintf("(*(*((struct_processus_fils"
1215: " *) (*s_objet).objet)).thread).nombre_references "
1216: "= 0 with nombre_occurrences > 0\n"));
1217: return;
1218: }
1219:
1220: free((struct_processus_fils *) ((*s_objet).objet));
1221: break;
1222: }
1223:
1224: case REL :
1225: {
1226: if (decrementation_atomique(s_objet) > 0)
1227: {
1228: return;
1229: }
1230:
1231: if ((*s_etat_processus).pointeur_rel < TAILLE_CACHE)
1232: {
1233: (*s_etat_processus).objets_rel
1234: [(*s_etat_processus).pointeur_rel++] = (*s_objet).objet;
1235: }
1236: else
1237: {
1238: free((real8 *) ((*s_objet).objet));
1239: }
1240:
1241: break;
1242: }
1243:
1244: case RPN :
1245: {
1246: l_element_courant = (struct_liste_chainee *) ((*s_objet).objet);
1247:
1248: if (decrementation_atomique(s_objet) > 0)
1249: { // Il reste un pointeur sur l'objet.
1250: while(l_element_courant != NULL)
1251: {
1252: BUG((*(*l_element_courant).donnee).nombre_occurrences <= 1,
1253: pthread_mutex_unlock(&((*s_objet).mutex)),
1254: printf("(*(*l_element_courant).donnee)"
1255: ".nombre_occurrences=%ld\n",
1256: (*(*l_element_courant).donnee).nombre_occurrences));
1257:
1258: liberation(s_etat_processus, (*l_element_courant).donnee);
1259: l_element_courant = (*l_element_courant).suivant;
1260: }
1261:
1262: return;
1263: }
1264: else
1265: { // Il ne reste plus aucun pointeur sur l'objet.
1266: while(l_element_courant != NULL)
1267: {
1268: l_element_suivant = (*l_element_courant).suivant;
1269: liberation(s_etat_processus, (*l_element_courant).donnee);
1270: liberation_maillon(s_etat_processus, l_element_courant);
1271: l_element_courant = l_element_suivant;
1272: }
1273: }
1274:
1275: break;
1276: }
1277:
1278: case SCK :
1279: {
1280: if (decrementation_atomique(s_objet) > 0)
1281: {
1282: BUG((*(*((struct_socket *) (*s_objet).objet)).format)
1283: .nombre_occurrences <= 1,
1284: pthread_mutex_unlock(&((*s_objet).mutex)),
1285: printf("(*(*((struct_socket *) (*s_objet).objet))"
1286: ".format).nombre_occurrences=%ld\n",
1287: (*(*((struct_socket *) (*s_objet).objet)).format)
1288: .nombre_occurrences));
1289:
1290: liberation(s_etat_processus, (*((struct_socket *)
1291: (*s_objet).objet)).format);
1292: return;
1293: }
1294:
1295: liberation(s_etat_processus, (*((struct_socket *)
1296: (*s_objet).objet)).format);
1297:
1298: free((unsigned char *) (*((struct_socket *) (*s_objet).objet))
1299: .adresse);
1300: free((unsigned char *) (*((struct_socket *) (*s_objet).objet))
1301: .adresse_distante);
1302: free((struct_socket *) ((*s_objet).objet));
1303: break;
1304: }
1305:
1306: case SLB :
1307: {
1308: if (decrementation_atomique(s_objet) > 0)
1309: {
1310: return;
1311: }
1312:
1313: free((*((struct_bibliotheque *) (*s_objet).objet)).nom);
1314: free((struct_bibliotheque *) (*s_objet).objet);
1315: break;
1316: }
1317:
1318: case SPH :
1319: {
1320: if (decrementation_atomique(s_objet) > 0)
1321: {
1322: return;
1323: }
1324:
1325: free((*((struct_semaphore *) (*s_objet).objet)).nom);
1326: free((struct_bibliotheque *) (*s_objet).objet);
1327: break;
1328: }
1329:
1330: case SQL :
1331: {
1332: if (decrementation_atomique(s_objet) > 0)
1333: {
1334: return;
1335: }
1336:
1337: free((*((struct_connecteur_sql *) (*s_objet).objet)).type);
1338: free((*((struct_connecteur_sql *) (*s_objet).objet)).locale);
1339: free((struct_connecteur_sql *) (*s_objet).objet);
1340: break;
1341: }
1342:
1343: case TBL :
1344: {
1345: if (decrementation_atomique(s_objet) > 0)
1346: {
1347: for(i = 0; i < (*((struct_tableau *) (*s_objet).objet))
1348: .nombre_elements; i++)
1349: {
1350: BUG((*((*((struct_tableau *)
1351: (*s_objet).objet)).elements[i]))
1352: .nombre_occurrences <= 1,
1353: pthread_mutex_unlock(&((*s_objet).mutex)),
1354: printf("(*((*((struct_tableau *) (*s_objet).objet))"
1355: ".element[%lu])).nombre_occurrences=%ld\n", i,
1356: (*((*((struct_tableau *) (*s_objet).objet))
1357: .elements[i])).nombre_occurrences));
1358: liberation(s_etat_processus, (*((struct_tableau *)
1359: (*s_objet).objet)).elements[i]);
1360: }
1361:
1362: return;
1363: }
1364:
1365: for(i = 0; i < (*((struct_tableau *) (*s_objet).objet))
1366: .nombre_elements; i++)
1367: {
1368: liberation(s_etat_processus, (*((struct_tableau *)
1369: (*s_objet).objet)).elements[i]);
1370: }
1371:
1372: free((*((struct_tableau *) (*s_objet).objet)).elements);
1373:
1374: if ((*s_etat_processus).pointeur_tab < TAILLE_CACHE)
1375: {
1376: (*s_etat_processus).objets_tab
1377: [(*s_etat_processus).pointeur_tab++] = (*s_objet).objet;
1378: }
1379: else
1380: {
1381: free((struct_tableau *) (*s_objet).objet);
1382: }
1383:
1384: break;
1385: }
1386:
1387: case VIN :
1388: {
1389: if (decrementation_atomique(s_objet) > 0)
1390: {
1391: return;
1392: }
1393:
1394: free((integer8 *) (*((struct_vecteur *) (*s_objet).objet)).tableau);
1395:
1396: if ((*s_etat_processus).pointeur_vec < TAILLE_CACHE)
1397: {
1398: (*s_etat_processus).objets_vec
1399: [(*s_etat_processus).pointeur_vec++] = (*s_objet).objet;
1400: }
1401: else
1402: {
1403: free((struct_vecteur *) (*s_objet).objet);
1404: }
1405:
1406: break;
1407: }
1408:
1409: case VCX :
1410: {
1411: if (decrementation_atomique(s_objet) > 0)
1412: {
1413: return;
1414: }
1415:
1416: free((struct_complexe16 *) (*((struct_vecteur *)
1417: (*s_objet).objet)).tableau);
1418:
1419: if ((*s_etat_processus).pointeur_vec < TAILLE_CACHE)
1420: {
1421: (*s_etat_processus).objets_vec
1422: [(*s_etat_processus).pointeur_vec++] = (*s_objet).objet;
1423: }
1424: else
1425: {
1426: free((struct_vecteur *) (*s_objet).objet);
1427: }
1428:
1429: break;
1430: }
1431:
1432: case VRL :
1433: {
1434: if (decrementation_atomique(s_objet) > 0)
1435: {
1436: return;
1437: }
1438:
1439: free((real8 *) (*((struct_vecteur *) (*s_objet).objet)).tableau);
1440:
1441: if ((*s_etat_processus).pointeur_vec < TAILLE_CACHE)
1442: {
1443: (*s_etat_processus).objets_vec
1444: [(*s_etat_processus).pointeur_vec++] = (*s_objet).objet;
1445: }
1446: else
1447: {
1448: free((struct_vecteur *) (*s_objet).objet);
1449: }
1450:
1451: break;
1452: }
1453:
1454: default :
1455: {
1456: if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0)
1457: {
1458: (*s_etat_processus).erreur_systeme = d_es_processus;
1459: return;
1460: }
1461:
1462: if (pthread_mutex_destroy(&((*s_objet).mutex)) != 0)
1463: {
1464: (*s_etat_processus).erreur_systeme = d_es_processus;
1465: return;
1466: }
1467:
1468: BUG(1, printf("Free failure (type %d)\n", (*s_objet).type));
1469: return;
1470: }
1471: }
1472:
1473: #undef return
1474:
1475: if (pthread_mutex_unlock(&((*s_objet).mutex)) != 0)
1476: {
1477: (*s_etat_processus).erreur_systeme = d_es_processus;
1478: return;
1479: }
1480:
1481: if (pthread_mutex_lock(&((*s_etat_processus).mutex_allocation)) != 0)
1482: {
1483: (*s_etat_processus).erreur_systeme = d_es_processus;
1484: return;
1485: }
1486:
1487: if ((*s_etat_processus).taille_pile_objets < TAILLE_CACHE)
1488: {
1489: (*s_objet).objet = (*s_etat_processus).pile_objets;
1490: (*s_etat_processus).pile_objets = s_objet;
1491: (*s_etat_processus).taille_pile_objets++;
1492: }
1493: else
1494: {
1495: if (pthread_mutex_destroy(&((*s_objet).mutex)) != 0)
1496: {
1497: pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation));
1498: (*s_etat_processus).erreur_systeme = d_es_processus;
1499: return;
1500: }
1501:
1502: free(s_objet);
1503: }
1504:
1505: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_allocation)) != 0)
1506: {
1507: (*s_etat_processus).erreur_systeme = d_es_processus;
1508: return;
1509: }
1510:
1511: return;
1512: }
1513:
1514:
1515: /*
1516: ================================================================================
1517: Routine de copie d'une structure *s_objet
1518: ================================================================================
1519: Entrées : structure *s_objet à copier
1520: type :
1521: 'P' : renvoie le même objet en incrémentant le nombre
1522: d'occurrence de chaque objet élémentaire ;
1523: 'O' : crée un nouvel objet en copiant chaque objet élémentaire ;
1524: 'N' : crée un nouvel objet mais les objets élémentaires
1525: sont réutilisés (voir 'P'). Dans le cas d'un objet
1526: élémentaire, 'N' et 'P' sont identiques.
1527: 'Q' : 'P' si nombre_occurrences vaut 1, 'O' sinon.
1528: 'R' : 'P' si nombre_occurrences vaut 1, 'N' sinon.
1529: --------------------------------------------------------------------------------
1530: Sorties : structure identique (tous les objets sont copiés)
1531: --------------------------------------------------------------------------------
1532: Effets de bord : néant
1533: ================================================================================
1534: */
1535:
1536: struct_objet *
1537: copie_objet(struct_processus *s_etat_processus,
1538: struct_objet *s_objet, unsigned char type)
1539: {
1540: struct_liste_chainee *l_element_base;
1541: struct_liste_chainee *l_element_courant;
1542: struct_liste_chainee *l_element_courant_ecriture;
1543: struct_liste_chainee *l_element_courant_lecture;
1544: struct_liste_chainee *l_element_suivant_ecriture;
1545: struct_liste_chainee *l_element_suivant_lecture;
1546:
1547: struct_objet *s_nouvel_objet;
1548: struct_objet *s_objet_tampon;
1549:
1550: unsigned long i;
1551: unsigned long j;
1552:
1553: if (pthread_mutex_lock(&((*s_objet).mutex)) != 0)
1554: {
1555: (*s_etat_processus).erreur_systeme = d_es_processus;
1556: return(NULL);
1557: }
1558:
1559: if (type == 'Q')
1560: {
1561: if ((*s_objet).nombre_occurrences == 1)
1562: {
1563: type = 'P';
1564: }
1565: else
1566: {
1567: type = 'O';
1568: }
1569: }
1570: else if (type == 'R')
1571: {
1572: if ((*s_objet).nombre_occurrences == 1)
1573: {
1574: type = 'P';
1575: }
1576: else
1577: {
1578: type = 'N';
1579: }
1580: }
1581:
1582: #define return(pointeur) \
1583: if (pthread_mutex_unlock(&((*s_objet).mutex))) \
1584: { (*s_etat_processus).erreur_systeme = d_es_processus; return(NULL); } \
1585: return(pointeur)
1586:
1587: switch((*s_objet).type)
1588: {
1589: case ADR :
1590: {
1591: if (type != 'O')
1592: {
1593: incrementation_atomique(s_objet);
1594: return(s_objet);
1595: }
1596:
1597: if ((s_nouvel_objet = allocation(s_etat_processus, ADR)) == NULL)
1598: {
1599: return(NULL);
1600: }
1601:
1602: (*((unsigned long *) ((*s_nouvel_objet).objet))) =
1603: (*((unsigned long *) ((*s_objet).objet)));
1604: break;
1605: }
1606:
1607: case ALG :
1608: {
1609: if (type != 'P')
1610: {
1611: if ((s_nouvel_objet = allocation(s_etat_processus, ALG))
1612: == NULL)
1613: {
1614: return(NULL);
1615: }
1616:
1617: l_element_courant_lecture = (struct_liste_chainee *)
1618: ((*s_objet).objet);
1619:
1620: l_element_base = NULL;
1621: l_element_courant_ecriture = l_element_base;
1622:
1623: while(l_element_courant_lecture != NULL)
1624: {
1625: s_objet_tampon = copie_objet(s_etat_processus,
1626: (*l_element_courant_lecture).donnee, type);
1627: l_element_suivant_ecriture = (struct_liste_chainee *)
1628: malloc(sizeof(struct_liste_chainee));
1629:
1630: if ((s_objet_tampon == NULL) ||
1631: (l_element_suivant_ecriture == NULL))
1632: {
1633: l_element_courant_lecture = (struct_liste_chainee *)
1634: ((*s_nouvel_objet).objet);
1635:
1636: while(l_element_courant_lecture != NULL)
1637: {
1638: l_element_suivant_lecture =
1639: (*l_element_courant_lecture).suivant;
1640: liberation(s_etat_processus,
1641: (*l_element_courant_lecture).donnee);
1642: free(l_element_courant_lecture);
1643: l_element_courant_lecture =
1644: l_element_suivant_lecture;
1645: }
1646:
1647: return(NULL);
1648: }
1649:
1650: if (l_element_courant_ecriture == NULL)
1651: {
1652: l_element_base = l_element_suivant_ecriture;
1653: }
1654: else
1655: {
1656: (*l_element_courant_ecriture).suivant =
1657: l_element_suivant_ecriture;
1658: }
1659:
1660: l_element_courant_ecriture = l_element_suivant_ecriture;
1661:
1662: (*l_element_courant_ecriture).donnee = s_objet_tampon;
1663: (*l_element_courant_ecriture).suivant = NULL;
1664: l_element_courant_lecture =
1665: (*l_element_courant_lecture).suivant;
1666: }
1667:
1668: (*s_nouvel_objet).objet = (void *) ((struct_liste_chainee *)
1669: l_element_base);
1670: }
1671: else // type == 'P'
1672: {
1673: incrementation_atomique(s_objet);
1674: l_element_courant = (*s_objet).objet;
1675:
1676: while(l_element_courant != NULL)
1677: {
1678: (*l_element_courant).donnee = copie_objet(s_etat_processus,
1679: (*l_element_courant).donnee, 'P');
1680: l_element_courant = (*l_element_courant).suivant;
1681: }
1682:
1683: return(s_objet);
1684: }
1685:
1686: break;
1687: }
1688:
1689: case BIN :
1690: {
1691: if (type != 'O')
1692: {
1693: incrementation_atomique(s_objet);
1694: return(s_objet);
1695: }
1696:
1697: if ((s_nouvel_objet = allocation(s_etat_processus, BIN)) == NULL)
1698: {
1699: return(NULL);
1700: }
1701:
1702: (*((logical8 *) ((*s_nouvel_objet).objet))) =
1703: (*((logical8 *) ((*s_objet).objet)));
1704: break;
1705: }
1706:
1707: case CHN :
1708: {
1709: if (type != 'O')
1710: {
1711: incrementation_atomique(s_objet);
1712: return(s_objet);
1713: }
1714:
1715: if ((s_nouvel_objet = allocation(s_etat_processus, CHN)) == NULL)
1716: {
1717: return(NULL);
1718: }
1719:
1720: (*s_nouvel_objet).objet = (void *) ((unsigned char *)
1721: malloc((strlen((unsigned char *) ((*s_objet).objet)) + 1)
1722: * sizeof(unsigned char)));
1723:
1724: if ((*s_nouvel_objet).objet == NULL)
1725: {
1726: free(s_nouvel_objet);
1727: return(NULL);
1728: }
1729:
1730: strcpy((unsigned char *) ((*s_nouvel_objet).objet),
1731: (unsigned char *) ((*s_objet).objet));
1732: break;
1733: }
1734:
1735: case CPL :
1736: {
1737: if (type != 'O')
1738: {
1739: incrementation_atomique(s_objet);
1740: return(s_objet);
1741: }
1742:
1743: if ((s_nouvel_objet = allocation(s_etat_processus, CPL)) == NULL)
1744: {
1745: return(NULL);
1746: }
1747:
1748: (*((struct_complexe16 *) ((*s_nouvel_objet).objet))) =
1749: (*((struct_complexe16 *) ((*s_objet).objet)));
1750: break;
1751: }
1752:
1753: case RPN :
1754: {
1755: if (type != 'P')
1756: {
1757: if ((s_nouvel_objet = allocation(s_etat_processus, RPN))
1758: == NULL)
1759: {
1760: return(NULL);
1761: }
1762:
1763: l_element_courant_lecture = (struct_liste_chainee *)
1764: ((*s_objet).objet);
1765:
1766: l_element_base = NULL;
1767: l_element_courant_ecriture = l_element_base;
1768:
1769: while(l_element_courant_lecture != NULL)
1770: {
1771: s_objet_tampon = copie_objet(s_etat_processus,
1772: (*l_element_courant_lecture).donnee, type);
1773: l_element_suivant_ecriture = (struct_liste_chainee *)
1774: malloc(sizeof(struct_liste_chainee));
1775:
1776: if ((s_objet_tampon == NULL) ||
1777: (l_element_suivant_ecriture == NULL))
1778: {
1779: l_element_courant_lecture = (struct_liste_chainee *)
1780: ((*s_nouvel_objet).objet);
1781:
1782: while(l_element_courant_lecture != NULL)
1783: {
1784: l_element_suivant_lecture =
1785: (*l_element_courant_lecture).suivant;
1786: liberation(s_etat_processus,
1787: (*l_element_courant_lecture).donnee);
1788: free(l_element_courant_lecture);
1789: l_element_courant_lecture =
1790: l_element_suivant_lecture;
1791: }
1792:
1793: return(NULL);
1794: }
1795:
1796: if (l_element_courant_ecriture == NULL)
1797: {
1798: l_element_base = l_element_suivant_ecriture;
1799: }
1800: else
1801: {
1802: (*l_element_courant_ecriture).suivant =
1803: l_element_suivant_ecriture;
1804: }
1805:
1806: l_element_courant_ecriture = l_element_suivant_ecriture;
1807:
1808: (*l_element_courant_ecriture).donnee = s_objet_tampon;
1809: (*l_element_courant_ecriture).suivant = NULL;
1810: l_element_courant_lecture =
1811: (*l_element_courant_lecture).suivant;
1812: }
1813:
1814: (*s_nouvel_objet).objet = (void *) ((struct_liste_chainee *)
1815: l_element_base);
1816: }
1817: else // type == 'P'
1818: {
1819: incrementation_atomique(s_objet);
1820: l_element_courant = (*s_objet).objet;
1821:
1822: while(l_element_courant != NULL)
1823: {
1824: (*l_element_courant).donnee = copie_objet(s_etat_processus,
1825: (*l_element_courant).donnee, 'P');
1826: l_element_courant = (*l_element_courant).suivant;
1827: }
1828:
1829: return(s_objet);
1830: }
1831:
1832: break;
1833: }
1834:
1835: case FCH :
1836: {
1837: if (type == 'P')
1838: {
1839: incrementation_atomique(s_objet);
1840:
1841: if (((*((struct_fichier *) ((*s_objet).objet))).format =
1842: copie_objet(s_etat_processus, (*((struct_fichier *)
1843: ((*s_objet).objet))).format, 'P')) == NULL)
1844: {
1845: return(NULL);
1846: }
1847:
1848: return(s_objet);
1849: }
1850:
1851: if ((s_nouvel_objet = allocation(s_etat_processus, FCH)) == NULL)
1852: {
1853: return(NULL);
1854: }
1855:
1856: (*((struct_fichier *) ((*s_nouvel_objet).objet))).descripteur =
1857: (*((struct_fichier *) ((*s_objet).objet))).descripteur;
1858: (*((struct_fichier *) ((*s_nouvel_objet).objet))).acces =
1859: (*((struct_fichier *) ((*s_objet).objet))).acces;
1860: (*((struct_fichier *) ((*s_nouvel_objet).objet))).binaire =
1861: (*((struct_fichier *) ((*s_objet).objet))).binaire;
1862: (*((struct_fichier *) ((*s_nouvel_objet).objet))).ouverture =
1863: (*((struct_fichier *) ((*s_objet).objet))).ouverture;
1864: (*((struct_fichier *) ((*s_nouvel_objet).objet))).protection =
1865: (*((struct_fichier *) ((*s_objet).objet))).protection;
1866: (*((struct_fichier *) ((*s_nouvel_objet).objet)))
1867: .position_clef = (*((struct_fichier *)
1868: ((*s_objet).objet))).position_clef;
1869: (*((struct_fichier *) ((*s_nouvel_objet).objet))).pid =
1870: (*((struct_fichier *) ((*s_objet).objet))).pid;
1871: (*((struct_fichier *) ((*s_nouvel_objet).objet))).tid =
1872: (*((struct_fichier *) ((*s_objet).objet))).tid;
1873:
1874: if (((*((struct_fichier *) ((*s_nouvel_objet).objet))).format =
1875: copie_objet(s_etat_processus, (*((struct_fichier *)
1876: ((*s_objet).objet))).format, type)) == NULL)
1877: {
1878: free((*s_nouvel_objet).objet);
1879: free(s_nouvel_objet);
1880: return(NULL);
1881: }
1882:
1883: if (((*((struct_fichier *) ((*s_nouvel_objet).objet))).nom =
1884: (unsigned char *) malloc((strlen((*((struct_fichier *)
1885: ((*s_objet).objet))).nom) + 1) * sizeof(unsigned char)))
1886: == NULL)
1887: {
1888: liberation(s_etat_processus, (*((struct_fichier *)
1889: (*s_nouvel_objet).objet)).format);
1890: free((*s_nouvel_objet).objet);
1891: free(s_nouvel_objet);
1892: return(NULL);
1893: }
1894:
1895: strcpy((*((struct_fichier *) ((*s_nouvel_objet).objet))).nom,
1896: (*((struct_fichier *) ((*s_objet).objet))).nom);
1897: break;
1898: }
1899:
1900: case FCT :
1901: {
1902: if (type != 'O')
1903: {
1904: /*
1905: * Remise à zéro de la prédiction pour respecter la cohérence
1906: * du saut dans les cas EXSUB et OBSUB.
1907: */
1908:
1909: (*((struct_fonction *) ((*s_objet).objet)))
1910: .prediction_saut = NULL;
1911: incrementation_atomique(s_objet);
1912: return(s_objet);
1913: }
1914:
1915: if ((s_nouvel_objet = allocation(s_etat_processus, FCT)) == NULL)
1916: {
1917: return(NULL);
1918: }
1919:
1920: if (((*((struct_fonction *) ((*s_nouvel_objet).objet)))
1921: .nom_fonction = (unsigned char *)
1922: malloc((strlen((*((struct_fonction *)
1923: ((*s_objet).objet))).nom_fonction) + 1) *
1924: sizeof(unsigned char))) == NULL)
1925: {
1926: free(s_nouvel_objet);
1927: return(NULL);
1928: }
1929:
1930: strcpy((unsigned char *) (*((struct_fonction *)
1931: ((*s_nouvel_objet).objet))).nom_fonction,
1932: (unsigned char *) (*((struct_fonction *)
1933: ((*s_objet).objet))).nom_fonction);
1934: (*((struct_fonction *) ((*s_nouvel_objet).objet)))
1935: .nombre_arguments = (*((struct_fonction *)
1936: ((*s_objet).objet))).nombre_arguments;
1937: (*((struct_fonction *) ((*s_nouvel_objet).objet))).fonction =
1938: (*((struct_fonction *) ((*s_objet).objet))).fonction;
1939: break;
1940: }
1941:
1942: case INT :
1943: {
1944: if (type != 'O')
1945: {
1946: incrementation_atomique(s_objet);
1947: return(s_objet);
1948: }
1949:
1950: if ((s_nouvel_objet = allocation(s_etat_processus, INT)) == NULL)
1951: {
1952: return(NULL);
1953: }
1954:
1955: (*((integer8 *) ((*s_nouvel_objet).objet))) =
1956: (*((integer8 *) ((*s_objet).objet)));
1957: break;
1958: }
1959:
1960: case LST :
1961: {
1962: if (type != 'P')
1963: {
1964: if ((s_nouvel_objet = allocation(s_etat_processus, LST))
1965: == NULL)
1966: {
1967: return(NULL);
1968: }
1969:
1970: l_element_courant_lecture = (struct_liste_chainee *)
1971: ((*s_objet).objet);
1972:
1973: l_element_base = NULL;
1974: l_element_courant_ecriture = l_element_base;
1975:
1976: while(l_element_courant_lecture != NULL)
1977: {
1978: s_objet_tampon = copie_objet(s_etat_processus,
1979: (*l_element_courant_lecture).donnee, type);
1980: l_element_suivant_ecriture = (struct_liste_chainee *)
1981: malloc(sizeof(struct_liste_chainee));
1982:
1983: if ((s_objet_tampon == NULL) ||
1984: (l_element_suivant_ecriture == NULL))
1985: {
1986: l_element_courant_lecture = (struct_liste_chainee *)
1987: ((*s_nouvel_objet).objet);
1988:
1989: while(l_element_courant_lecture != NULL)
1990: {
1991: l_element_suivant_lecture =
1992: (*l_element_courant_lecture).suivant;
1993: liberation(s_etat_processus,
1994: (*l_element_courant_lecture).donnee);
1995: free(l_element_courant_lecture);
1996: l_element_courant_lecture =
1997: l_element_suivant_lecture;
1998: }
1999:
2000: return(NULL);
2001: }
2002:
2003: if (l_element_courant_ecriture == NULL)
2004: {
2005: l_element_base = l_element_suivant_ecriture;
2006: }
2007: else
2008: {
2009: (*l_element_courant_ecriture).suivant =
2010: l_element_suivant_ecriture;
2011: }
2012:
2013: l_element_courant_ecriture = l_element_suivant_ecriture;
2014:
2015: (*l_element_courant_ecriture).donnee = s_objet_tampon;
2016: (*l_element_courant_ecriture).suivant = NULL;
2017: l_element_courant_lecture =
2018: (*l_element_courant_lecture).suivant;
2019: }
2020:
2021: (*s_nouvel_objet).objet = (void *) ((struct_liste_chainee *)
2022: l_element_base);
2023: }
2024: else
2025: {
2026: incrementation_atomique(s_objet);
2027: l_element_courant = (*s_objet).objet;
2028:
2029: while(l_element_courant != NULL)
2030: {
2031: (*l_element_courant).donnee = copie_objet(s_etat_processus,
2032: (*l_element_courant).donnee, 'P');
2033: l_element_courant = (*l_element_courant).suivant;
2034: }
2035:
2036: return(s_objet);
2037: }
2038:
2039: break;
2040: }
2041:
2042: case MIN :
2043: {
2044: if (type != 'O')
2045: {
2046: incrementation_atomique(s_objet);
2047: return(s_objet);
2048: }
2049:
2050: if ((s_nouvel_objet = allocation(s_etat_processus, MIN)) == NULL)
2051: {
2052: return(NULL);
2053: }
2054:
2055: (*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau =
2056: (void **) ((integer8 **) malloc(
2057: ((*((struct_matrice *) ((*s_objet).objet))).nombre_lignes)
2058: * sizeof(integer8 *)));
2059:
2060: if ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau
2061: == NULL)
2062: {
2063: free((*s_nouvel_objet).objet);
2064: free(s_nouvel_objet);
2065: return(NULL);
2066: }
2067:
2068: (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_colonnes =
2069: (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes;
2070: (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_lignes =
2071: (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes;
2072: (*((struct_matrice *) ((*s_nouvel_objet).objet))).type =
2073: (*((struct_matrice *) ((*s_objet).objet))).type;
2074:
2075: for(i = 0; i < (*((struct_matrice *)
2076: ((*s_objet).objet))).nombre_lignes; i++)
2077: {
2078: if ((((integer8 **) ((*((struct_matrice *)
2079: ((*s_nouvel_objet).objet))).tableau))[i] =
2080: (void *) ((integer8 *) malloc(
2081: ((*((struct_matrice *) ((*s_objet).objet)))
2082: .nombre_colonnes) * sizeof(integer8)))) == NULL)
2083: {
2084: for(j = 0; j < i; j++)
2085: {
2086: free(((integer8 **) ((*((struct_matrice *)
2087: ((*s_nouvel_objet).objet))).tableau))[j]);
2088: }
2089:
2090: free((*s_nouvel_objet).objet);
2091: free(s_nouvel_objet);
2092: return(NULL);
2093: }
2094:
2095: for(j = 0; j < (*((struct_matrice *)
2096: ((*s_objet).objet))).nombre_colonnes; j++)
2097: {
2098: ((integer8 **) ((*((struct_matrice *)
2099: ((*s_nouvel_objet).objet))).tableau))[i][j] =
2100: ((integer8 **) ((*((struct_matrice *)
2101: ((*s_objet).objet))).tableau))[i][j];
2102: }
2103: }
2104:
2105: break;
2106: }
2107:
2108: case MCX :
2109: {
2110: if (type != 'O')
2111: {
2112: incrementation_atomique(s_objet);
2113: return(s_objet);
2114: }
2115:
2116: if ((s_nouvel_objet = allocation(s_etat_processus, MCX))
2117: == NULL)
2118: {
2119: return(NULL);
2120: }
2121:
2122: (*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau =
2123: (void **) ((struct_complexe16 **) malloc(
2124: ((*((struct_matrice *) ((*s_objet).objet))).nombre_lignes)
2125: * sizeof(struct_complexe16 *)));
2126:
2127: if ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau
2128: == NULL)
2129: {
2130: free((*s_nouvel_objet).objet);
2131: free(s_nouvel_objet);
2132: return(NULL);
2133: }
2134:
2135: (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_colonnes =
2136: (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes;
2137: (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_lignes =
2138: (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes;
2139: (*((struct_matrice *) ((*s_nouvel_objet).objet))).type =
2140: (*((struct_matrice *) ((*s_objet).objet))).type;
2141:
2142: for(i = 0; i < (*((struct_matrice *)
2143: ((*s_objet).objet))).nombre_lignes; i++)
2144: {
2145: if ((((struct_complexe16 **) ((*((struct_matrice *)
2146: ((*s_nouvel_objet).objet))).tableau))[i] =
2147: (void *) ((struct_complexe16 *) malloc(
2148: ((*((struct_matrice *) ((*s_objet).objet)))
2149: .nombre_colonnes) * sizeof(struct_complexe16))))
2150: == NULL)
2151: {
2152: for(j = 0; j < i; j++)
2153: {
2154: free(((struct_complexe16 **) ((*((struct_matrice *)
2155: ((*s_nouvel_objet).objet))).tableau))[j]);
2156: }
2157:
2158: free((*s_nouvel_objet).objet);
2159: free(s_nouvel_objet);
2160: return(NULL);
2161: }
2162:
2163: for(j = 0; j < (*((struct_matrice *)
2164: ((*s_objet).objet))).nombre_colonnes; j++)
2165: {
2166: ((struct_complexe16 **) ((*((struct_matrice *)
2167: ((*s_nouvel_objet).objet))).tableau))[i][j] =
2168: ((struct_complexe16 **) ((*((struct_matrice *)
2169: ((*s_objet).objet))).tableau))[i][j];
2170: }
2171: }
2172:
2173: break;
2174: }
2175:
2176: case MRL :
2177: {
2178: if (type != 'O')
2179: {
2180: incrementation_atomique(s_objet);
2181: return(s_objet);
2182: }
2183:
2184: if ((s_nouvel_objet = allocation(s_etat_processus, MRL)) == NULL)
2185: {
2186: return(NULL);
2187: }
2188:
2189: (*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau =
2190: (void **) ((real8 **) malloc(
2191: ((*((struct_matrice *) ((*s_objet).objet))).nombre_lignes)
2192: * sizeof(real8 *)));
2193:
2194: if ((*((struct_matrice *) ((*s_nouvel_objet).objet))).tableau
2195: == NULL)
2196: {
2197: free((*s_nouvel_objet).objet);
2198: free(s_nouvel_objet);
2199: return(NULL);
2200: }
2201:
2202: (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_colonnes =
2203: (*((struct_matrice *) ((*s_objet).objet))).nombre_colonnes;
2204: (*((struct_matrice *) ((*s_nouvel_objet).objet))).nombre_lignes =
2205: (*((struct_matrice *) ((*s_objet).objet))).nombre_lignes;
2206: (*((struct_matrice *) ((*s_nouvel_objet).objet))).type =
2207: (*((struct_matrice *) ((*s_objet).objet))).type;
2208:
2209: for(i = 0; i < (*((struct_matrice *)
2210: ((*s_objet).objet))).nombre_lignes; i++)
2211: {
2212: if ((((real8 **) ((*((struct_matrice *)
2213: ((*s_nouvel_objet).objet))).tableau))[i] =
2214: (void *) ((real8 *) malloc(
2215: ((*((struct_matrice *) ((*s_objet).objet)))
2216: .nombre_colonnes) * sizeof(real8)))) == NULL)
2217: {
2218: for(j = 0; j < i; j++)
2219: {
2220: free(((real8 **) ((*((struct_matrice *)
2221: ((*s_nouvel_objet).objet))).tableau))[j]);
2222: }
2223:
2224: free((*s_nouvel_objet).objet);
2225: free(s_nouvel_objet);
2226: return(NULL);
2227: }
2228:
2229: for(j = 0; j < (*((struct_matrice *)
2230: ((*s_objet).objet))).nombre_colonnes; j++)
2231: {
2232: ((real8 **) ((*((struct_matrice *)
2233: ((*s_nouvel_objet).objet))).tableau))[i][j] =
2234: ((real8 **) ((*((struct_matrice *)
2235: ((*s_objet).objet))).tableau))[i][j];
2236: }
2237: }
2238:
2239: break;
2240: }
2241:
2242: case MTX :
2243: {
2244: // La duplication d'un mutex renvoie le même objet.
2245: incrementation_atomique(s_objet);
2246: return(s_objet);
2247: }
2248:
2249: case NOM :
2250: {
2251: if (type != 'O')
2252: {
2253: incrementation_atomique(s_objet);
2254: return(s_objet);
2255: }
2256:
2257: if ((s_nouvel_objet = allocation(s_etat_processus, NOM)) == NULL)
2258: {
2259: return(NULL);
2260: }
2261:
2262: (*((struct_nom *) (*s_nouvel_objet).objet)).nom = malloc((
2263: strlen((*((struct_nom *) (*s_objet).objet)).nom) + 1) *
2264: sizeof(unsigned char));
2265:
2266: if ((*((struct_nom *) (*s_nouvel_objet).objet)).nom == NULL)
2267: {
2268: free((*s_nouvel_objet).objet);
2269: free(s_nouvel_objet);
2270: return(NULL);
2271: }
2272:
2273: strcpy((*((struct_nom *) (*s_nouvel_objet).objet)).nom,
2274: (*((struct_nom *) (*s_objet).objet)).nom);
2275: (*((struct_nom *) (*s_nouvel_objet).objet)).symbole =
2276: (*((struct_nom *) (*s_objet).objet)).symbole;
2277: break;
2278: }
2279:
2280: case NON :
2281: {
2282: if (type != 'O')
2283: {
2284: incrementation_atomique(s_objet);
2285: return(s_objet);
2286: }
2287:
2288: // Un objet de type NON est un objet encapsulé dans une
2289: // structure de type struct_objet. Elle peut très bien contenir
2290: // une donnée, mais c'est à l'utilisateur de la libérer
2291: // explicitement avec un free().
2292:
2293: if ((s_nouvel_objet = allocation(s_etat_processus, NON)) == NULL)
2294: {
2295: return(NULL);
2296: }
2297:
2298: (*s_nouvel_objet).objet = (*s_objet).objet;
2299: break;
2300: }
2301:
2302: case PRC :
2303: {
2304: if (pthread_mutex_lock(&((*(*((struct_processus_fils *)
2305: (*s_objet).objet)).thread).mutex_nombre_references)) != 0)
2306: {
2307: return(NULL);
2308: }
2309:
2310: (*(*((struct_processus_fils *) (*s_objet).objet)).thread)
2311: .nombre_references++;
2312:
2313: if (pthread_mutex_unlock(&((*(*((struct_processus_fils *)
2314: (*s_objet).objet)).thread).mutex_nombre_references)) != 0)
2315: {
2316: return(NULL);
2317: }
2318:
2319: if (type != 'O')
2320: {
2321: incrementation_atomique(s_objet);
2322: return(s_objet);
2323: }
2324:
2325: if ((s_nouvel_objet = allocation(s_etat_processus, PRC)) == NULL)
2326: {
2327: return(NULL);
2328: }
2329:
2330: (*((struct_processus_fils *) (*s_nouvel_objet).objet)) =
2331: (*((struct_processus_fils *) (*s_objet).objet));
2332: break;
2333: }
2334:
2335: case REL :
2336: {
2337: if (type != 'O')
2338: {
2339: incrementation_atomique(s_objet);
2340: return(s_objet);
2341: }
2342:
2343: if ((s_nouvel_objet = allocation(s_etat_processus, REL)) == NULL)
2344: {
2345: return(NULL);
2346: }
2347:
2348: (*((real8 *) ((*s_nouvel_objet).objet))) =
2349: (*((real8 *) ((*s_objet).objet)));
2350: break;
2351: }
2352:
2353: case SCK :
2354: {
2355: if (type == 'P')
2356: {
2357: incrementation_atomique(s_objet);
2358:
2359: if (((*((struct_socket *) ((*s_objet).objet)))
2360: .format = copie_objet(s_etat_processus,
2361: (*((struct_socket *) ((*s_objet).objet))).format, 'P'))
2362: == NULL)
2363: {
2364: return(NULL);
2365: }
2366:
2367: return(s_objet);
2368: }
2369:
2370: if ((s_nouvel_objet = allocation(s_etat_processus, SCK)) == NULL)
2371: {
2372: return(NULL);
2373: }
2374:
2375: (*((struct_socket *) ((*s_nouvel_objet).objet))).socket =
2376: (*((struct_socket *) ((*s_objet).objet))).socket;
2377: (*((struct_socket *) ((*s_nouvel_objet).objet))).domaine =
2378: (*((struct_socket *) ((*s_objet).objet))).domaine;
2379: (*((struct_socket *) ((*s_nouvel_objet).objet))).socket_en_ecoute =
2380: (*((struct_socket *) ((*s_objet).objet))).socket_en_ecoute;
2381: (*((struct_socket *) ((*s_nouvel_objet).objet))).socket_connectee =
2382: (*((struct_socket *) ((*s_objet).objet))).socket_connectee;
2383: (*((struct_socket *) ((*s_nouvel_objet).objet))).pid =
2384: (*((struct_socket *) ((*s_objet).objet))).pid;
2385: (*((struct_socket *) ((*s_nouvel_objet).objet))).binaire =
2386: (*((struct_socket *) ((*s_objet).objet))).binaire;
2387: (*((struct_socket *) ((*s_nouvel_objet).objet))).effacement =
2388: (*((struct_socket *) ((*s_objet).objet))).effacement;
2389: (*((struct_socket *) ((*s_nouvel_objet).objet))).protection =
2390: (*((struct_socket *) ((*s_objet).objet))).protection;
2391: (*((struct_socket *) ((*s_nouvel_objet).objet))).localisation =
2392: (*((struct_socket *) ((*s_objet).objet))).localisation;
2393: (*((struct_socket *) ((*s_nouvel_objet).objet))).pid =
2394: (*((struct_socket *) ((*s_objet).objet))).pid;
2395: (*((struct_socket *) ((*s_nouvel_objet).objet))).tid =
2396: (*((struct_socket *) ((*s_objet).objet))).tid;
2397:
2398: if (((*((struct_socket *) ((*s_nouvel_objet).objet))).format =
2399: copie_objet(s_etat_processus, (*((struct_socket *)
2400: ((*s_objet).objet))).format, type)) == NULL)
2401: {
2402: free((*s_nouvel_objet).objet);
2403: free(s_nouvel_objet);
2404: return(NULL);
2405: }
2406:
2407: if (((*((struct_socket *) ((*s_nouvel_objet).objet))).adresse =
2408: (unsigned char *) malloc((strlen((*((struct_socket *)
2409: ((*s_objet).objet))).adresse) + 1) * sizeof(unsigned char)))
2410: == NULL)
2411: {
2412: liberation(s_etat_processus, (*((struct_fichier *)
2413: (*s_nouvel_objet).objet)).format);
2414: free((*s_nouvel_objet).objet);
2415: free(s_nouvel_objet);
2416: return(NULL);
2417: }
2418:
2419: strcpy((*((struct_socket *) ((*s_nouvel_objet).objet)))
2420: .adresse, (*((struct_socket *) ((*s_objet).objet)))
2421: .adresse);
2422:
2423: if (((*((struct_socket *) ((*s_nouvel_objet).objet)))
2424: .adresse_distante = malloc((strlen((*((struct_socket *)
2425: ((*s_objet).objet))).adresse_distante) + 1) *
2426: sizeof(unsigned char))) == NULL)
2427: {
2428: liberation(s_etat_processus, (*((struct_fichier *)
2429: (*s_nouvel_objet).objet)).format);
2430: free((*s_nouvel_objet).objet);
2431: free(s_nouvel_objet);
2432: return(NULL);
2433: }
2434:
2435: strcpy((*((struct_socket *) ((*s_nouvel_objet).objet)))
2436: .adresse_distante, (*((struct_socket *) ((*s_objet).objet)))
2437: .adresse_distante);
2438:
2439: strcpy((*((struct_socket *) ((*s_nouvel_objet).objet))).type,
2440: (*((struct_socket *) ((*s_objet).objet))).type);
2441: break;
2442: }
2443:
2444: case SLB :
2445: {
2446: if (type != 'O')
2447: {
2448: incrementation_atomique(s_objet);
2449: return(s_objet);
2450: }
2451:
2452: if ((s_nouvel_objet = allocation(s_etat_processus, SLB)) == NULL)
2453: {
2454: return(NULL);
2455: }
2456:
2457: if (((*((struct_bibliotheque *) ((*s_nouvel_objet).objet))).nom =
2458: (unsigned char *) malloc((strlen((*((struct_bibliotheque *)
2459: ((*s_objet).objet))).nom) + 1) * sizeof(unsigned char)))
2460: == NULL)
2461: {
2462: free((*s_nouvel_objet).objet);
2463: free(s_nouvel_objet);
2464: return(NULL);
2465: }
2466:
2467: strcpy((*((struct_bibliotheque *) ((*s_nouvel_objet).objet))).nom,
2468: (*((struct_bibliotheque *) ((*s_objet).objet))).nom);
2469:
2470: /*
2471: * C'est objet est non modifiable et est un pointeur
2472: * sur un objet système. Seul la référence est copiée.
2473: */
2474:
2475: (*((struct_bibliotheque *) (*s_nouvel_objet).objet)).descripteur =
2476: (*((struct_bibliotheque *) (*s_objet).objet)).descripteur;
2477: (*((struct_bibliotheque *) (*s_nouvel_objet).objet)).pid =
2478: (*((struct_bibliotheque *) (*s_objet).objet)).pid;
2479: (*((struct_bibliotheque *) (*s_nouvel_objet).objet)).tid =
2480: (*((struct_bibliotheque *) (*s_objet).objet)).tid;
2481: break;
2482: }
2483:
2484: case SPH :
2485: {
2486: if (type != 'O')
2487: {
2488: incrementation_atomique(s_objet);
2489: return(s_objet);
2490: }
2491:
2492: if ((s_nouvel_objet = allocation(s_etat_processus, SPH)) == NULL)
2493: {
2494: return(NULL);
2495: }
2496:
2497: if (((*((struct_semaphore *) (*s_nouvel_objet).objet)).nom =
2498: malloc((strlen((*((struct_semaphore *) (*s_objet).objet))
2499: .nom) + 1) * sizeof(unsigned char))) == NULL)
2500: {
2501: free((*s_nouvel_objet).objet);
2502: free(s_nouvel_objet);
2503: return(NULL);
2504: }
2505:
2506: (*((struct_semaphore *) (*s_nouvel_objet).objet)).semaphore =
2507: (*((struct_semaphore *) (*s_objet).objet)).semaphore;
2508: strcpy((*((struct_semaphore *) (*s_nouvel_objet).objet)).nom,
2509: (*((struct_semaphore *) (*s_objet).objet)).nom);
2510: break;
2511: }
2512:
2513: case SQL :
2514: {
2515: if (type != 'O')
2516: {
2517: incrementation_atomique(s_objet);
2518: return(s_objet);
2519: }
2520:
2521: if ((s_nouvel_objet = allocation(s_etat_processus, SQL)) == NULL)
2522: {
2523: return(NULL);
2524: }
2525:
2526: (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).pid =
2527: (*((struct_connecteur_sql *) (*s_objet).objet)).pid;
2528: (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).tid =
2529: (*((struct_connecteur_sql *) (*s_objet).objet)).tid;
2530: (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).descripteur =
2531: (*((struct_connecteur_sql *) (*s_objet).objet)).descripteur;
2532:
2533: if (((*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).type =
2534: malloc((strlen((*((struct_connecteur_sql *)
2535: (*s_objet).objet)).type) + 1) * sizeof(unsigned char)))
2536: == NULL)
2537: {
2538: free(s_nouvel_objet);
2539: return(NULL);
2540: }
2541:
2542: strcpy((*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).type,
2543: (*((struct_connecteur_sql *) (*s_objet).objet)).type);
2544:
2545: if ((*((struct_connecteur_sql *) (*s_objet).objet)).locale != NULL)
2546: {
2547: if (((*((struct_connecteur_sql *) (*s_nouvel_objet).objet))
2548: .locale = malloc((strlen((*((struct_connecteur_sql *)
2549: (*s_objet).objet)).locale) + 1) *
2550: sizeof(unsigned char))) == NULL)
2551: {
2552: free((*((struct_connecteur_sql *) (*s_nouvel_objet).objet))
2553: .locale);
2554: free(s_nouvel_objet);
2555: return(NULL);
2556: }
2557:
2558: strcpy((*((struct_connecteur_sql *) (*s_nouvel_objet).objet))
2559: .locale, (*((struct_connecteur_sql *)
2560: (*s_objet).objet)).locale);
2561: }
2562: else
2563: {
2564: (*((struct_connecteur_sql *) (*s_nouvel_objet).objet)).locale
2565: = NULL;
2566: }
2567:
2568: break;
2569: }
2570:
2571: case TBL :
2572: {
2573: if (type != 'P')
2574: {
2575: if ((s_nouvel_objet = allocation(s_etat_processus, TBL))
2576: == NULL)
2577: {
2578: return(NULL);
2579: }
2580:
2581: (*((struct_tableau *) (*s_nouvel_objet).objet))
2582: .nombre_elements = (*((struct_tableau *)
2583: (*s_objet).objet)).nombre_elements;
2584:
2585: if (((*((struct_tableau *) (*s_nouvel_objet).objet)).elements =
2586: malloc((*((struct_tableau *) (*s_objet).objet))
2587: .nombre_elements * sizeof(struct_objet *))) == NULL)
2588: {
2589: return(NULL);
2590: }
2591:
2592: for(i = 0; i < (*((struct_tableau *) (*s_objet).objet))
2593: .nombre_elements; i++)
2594: {
2595: if (((*((struct_tableau *) (*s_nouvel_objet).objet))
2596: .elements[i] = copie_objet(s_etat_processus,
2597: (*((struct_tableau *) (*s_objet).objet))
2598: .elements[i], type)) == NULL)
2599: {
2600: for(j = 0; j < i; j++)
2601: {
2602: liberation(s_etat_processus, (*((struct_tableau *)
2603: (*s_nouvel_objet).objet)).elements[j]);
2604: }
2605:
2606: free((*((struct_tableau *) (*s_nouvel_objet).objet))
2607: .elements);
2608: free((*s_nouvel_objet).objet);
2609: free(s_nouvel_objet);
2610:
2611: return(NULL);
2612: }
2613: }
2614: }
2615: else
2616: {
2617: incrementation_atomique(s_objet);
2618:
2619: for(i = 0; i < (*((struct_tableau *) (*s_objet).objet))
2620: .nombre_elements; i++)
2621: {
2622: (*((struct_tableau *) (*s_objet).objet)).elements[i] =
2623: copie_objet(s_etat_processus, (*((struct_tableau *)
2624: (*s_objet).objet)).elements[i], 'P');
2625: }
2626:
2627: return(s_objet);
2628: }
2629:
2630: break;
2631: }
2632:
2633: case VIN :
2634: {
2635: if (type != 'O')
2636: {
2637: incrementation_atomique(s_objet);
2638: return(s_objet);
2639: }
2640:
2641: if ((s_nouvel_objet = allocation(s_etat_processus, VIN)) == NULL)
2642: {
2643: return(NULL);
2644: }
2645:
2646: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau =
2647: (void *) ((integer8 *) malloc(
2648: ((*((struct_vecteur *) ((*s_objet).objet))).taille)
2649: * sizeof(integer8)));
2650:
2651: if ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau
2652: == NULL)
2653: {
2654: free((*s_nouvel_objet).objet);
2655: free(s_nouvel_objet);
2656: return(NULL);
2657: }
2658:
2659: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).taille =
2660: (*((struct_vecteur *) ((*s_objet).objet))).taille;
2661: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).type =
2662: (*((struct_vecteur *) ((*s_objet).objet))).type;
2663:
2664: for(i = 0; i < (*((struct_vecteur *) ((*s_objet).objet))).taille;
2665: i++)
2666: {
2667: ((integer8 *) ((*((struct_vecteur *)
2668: ((*s_nouvel_objet).objet))).tableau))[i] =
2669: ((integer8 *) ((*((struct_vecteur *)
2670: ((*s_objet).objet))).tableau))[i];
2671: }
2672:
2673: break;
2674: }
2675:
2676: case VCX :
2677: {
2678: if (type != 'O')
2679: {
2680: incrementation_atomique(s_objet);
2681: return(s_objet);
2682: }
2683:
2684: if ((s_nouvel_objet = allocation(s_etat_processus, VCX)) == NULL)
2685: {
2686: return(NULL);
2687: }
2688:
2689: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau =
2690: (void *) ((struct_complexe16 *) malloc(
2691: ((*((struct_vecteur *) ((*s_objet).objet))).taille)
2692: * sizeof(struct_complexe16)));
2693:
2694: if ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau
2695: == NULL)
2696: {
2697: free((*s_nouvel_objet).objet);
2698: free(s_nouvel_objet);
2699: return(NULL);
2700: }
2701:
2702: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).taille =
2703: (*((struct_vecteur *) ((*s_objet).objet))).taille;
2704: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).type =
2705: (*((struct_vecteur *) ((*s_objet).objet))).type;
2706:
2707: for(i = 0; i < (*((struct_vecteur *) ((*s_objet).objet))).taille;
2708: i++)
2709: {
2710: ((struct_complexe16 *) ((*((struct_vecteur *)
2711: ((*s_nouvel_objet).objet))).tableau))[i] =
2712: ((struct_complexe16 *) ((*((struct_vecteur *)
2713: ((*s_objet).objet))).tableau))[i];
2714: }
2715:
2716: break;
2717: }
2718:
2719: case VRL :
2720: {
2721: if (type != 'O')
2722: {
2723: incrementation_atomique(s_objet);
2724: return(s_objet);
2725: }
2726:
2727: if ((s_nouvel_objet = allocation(s_etat_processus, VRL)) == NULL)
2728: {
2729: return(NULL);
2730: }
2731:
2732: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau =
2733: (void *) ((real8 *) malloc(
2734: ((*((struct_vecteur *) ((*s_objet).objet))).taille)
2735: * sizeof(real8)));
2736:
2737: if ((*((struct_vecteur *) ((*s_nouvel_objet).objet))).tableau
2738: == NULL)
2739: {
2740: free((*s_nouvel_objet).objet);
2741: free(s_nouvel_objet);
2742: return(NULL);
2743: }
2744:
2745: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).taille =
2746: (*((struct_vecteur *) ((*s_objet).objet))).taille;
2747: (*((struct_vecteur *) ((*s_nouvel_objet).objet))).type =
2748: (*((struct_vecteur *) ((*s_objet).objet))).type;
2749:
2750: for(i = 0; i < (*((struct_vecteur *) ((*s_objet).objet))).taille;
2751: i++)
2752: {
2753: ((real8 *) ((*((struct_vecteur *)
2754: ((*s_nouvel_objet).objet))).tableau))[i] =
2755: ((real8 *) ((*((struct_vecteur *)
2756: ((*s_objet).objet))).tableau))[i];
2757: }
2758:
2759: break;
2760: }
2761:
2762: default :
2763: {
2764: return(NULL);
2765: }
2766: }
2767:
2768: return(s_nouvel_objet);
2769:
2770: #undef return
2771: }
2772:
2773:
2774: /*
2775: ================================================================================
2776: Routine de copie d'une structure de description d'un processus
2777: ================================================================================
2778: Entrées : pointeur sur la structure de description d'un processus
2779: --------------------------------------------------------------------------------
2780: Sorties : structure identique (tous les objets sont copiés)
2781: --------------------------------------------------------------------------------
2782: Effets de bord : néant
2783: ================================================================================
2784: */
2785:
2786: struct_processus *
2787: copie_etat_processus(struct_processus *s_etat_processus)
2788: {
2789: pthread_mutexattr_t attributs_mutex;
2790:
2791: struct_liste_chainee *l_element_lecture;
2792: struct_liste_chainee *l_element_precedent;
2793: struct_liste_chainee *l_element_suivant;
2794:
2795: struct_processus *s_nouvel_etat_processus;
2796:
2797: unsigned long i;
2798:
2799: if (pthread_mutex_lock(&((*s_etat_processus).mutex)) != 0)
2800: {
2801: (*s_etat_processus).erreur_systeme = d_es_processus;
2802: return(NULL);
2803: }
2804:
2805: if ((s_nouvel_etat_processus = malloc(sizeof(struct_processus))) == NULL)
2806: {
2807: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2808: return(NULL);
2809: }
2810:
2811: (*s_nouvel_etat_processus) = (*s_etat_processus);
2812:
2813: // On réinitialise l'allocateur.
2814:
2815: initialisation_allocateur(s_nouvel_etat_processus);
2816:
2817: /*
2818: * (*s_etat_processus).definition_chainee,
2819: * (*s_etat_processus).nom_fichier_source,
2820: * (*s_etat_processus).nom_fichier_historique et
2821: * (*s_etat_processus).chemin_fichier_temporaires
2822: * n'ont aucune raison de changer.
2823: */
2824:
2825: pthread_mutexattr_init(&attributs_mutex);
2826: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
2827: (*s_nouvel_etat_processus).sections_critiques = 0;
2828:
2829: // Les sémaphores sont initialisés dans le nouveau thread. Il
2830: // s'agit d'une limitation de l'implantation de l'émulation
2831: // de sem_init().
2832:
2833: initialisation_contexte_cas(s_etat_processus);
2834:
2835: (*s_nouvel_etat_processus).var_volatile_processus_pere = 0;
2836: (*s_nouvel_etat_processus).var_volatile_processus_racine = 0;
2837: (*s_nouvel_etat_processus).fichiers_graphiques = NULL;
2838: (*s_nouvel_etat_processus).entree_standard = NULL;
2839: (*s_nouvel_etat_processus).s_marques = NULL;
2840: (*s_nouvel_etat_processus).requete_nouveau_plan = d_vrai;
2841: (*s_nouvel_etat_processus).mise_a_jour_trace_requise = d_faux;
2842: (*s_nouvel_etat_processus).nom_fichier_impression = NULL;
2843: (*s_nouvel_etat_processus).expression_courante = NULL;
2844: (*s_nouvel_etat_processus).objet_courant = NULL;
2845: (*s_nouvel_etat_processus).processus_detache = d_faux;
2846: (*s_nouvel_etat_processus).evaluation_forcee = 'N';
2847:
2848: (*s_nouvel_etat_processus).nombre_objets_envoyes_non_lus = 0;
2849: (*s_nouvel_etat_processus).nombre_objets_injectes = 0;
2850: (*s_nouvel_etat_processus).presence_fusible = d_faux;
2851: (*s_nouvel_etat_processus).thread_fusible = 0;
2852: (*s_nouvel_etat_processus).niveau_initial =
2853: (*s_etat_processus).niveau_courant;
2854: (*s_nouvel_etat_processus).presence_pipes = d_faux;
2855: (*s_nouvel_etat_processus).debug_programme = d_faux;
2856: (*s_nouvel_etat_processus).s_fichiers = NULL;
2857: (*s_nouvel_etat_processus).s_connecteurs_sql = NULL;
2858:
2859: // On réinitialise toutes les interruptions.
2860:
2861: (*s_nouvel_etat_processus).traitement_interruption = 'N';
2862: (*s_nouvel_etat_processus).traitement_interruptible = 'Y';
2863: (*s_nouvel_etat_processus).nombre_interruptions_en_queue = 0;
2864: (*s_nouvel_etat_processus).nombre_interruptions_non_affectees = 0;
2865:
2866: (*s_nouvel_etat_processus).at_exit = NULL;
2867: (*s_nouvel_etat_processus).at_poke = NULL;
2868: (*s_nouvel_etat_processus).traitement_at_poke = 'N';
2869:
2870: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
2871: {
2872: (*s_nouvel_etat_processus).corps_interruptions[i] = NULL;
2873: (*s_nouvel_etat_processus).masque_interruptions[i] = 'N';
2874: (*s_nouvel_etat_processus).queue_interruptions[i] = 0;
2875: (*s_nouvel_etat_processus).pile_origine_interruptions[i] = NULL;
2876: }
2877:
2878: if ((*s_nouvel_etat_processus).generateur_aleatoire != NULL)
2879: {
2880: if (((*s_nouvel_etat_processus).generateur_aleatoire =
2881: gsl_rng_clone((*s_etat_processus).generateur_aleatoire))
2882: == NULL)
2883: {
2884: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2885: return(NULL);
2886: }
2887:
2888: gsl_rng_set((*s_nouvel_etat_processus).generateur_aleatoire,
2889: gsl_rng_get((*s_etat_processus).generateur_aleatoire));
2890: }
2891:
2892: // Copie de la localisation
2893:
2894: if (((*s_nouvel_etat_processus).localisation = malloc((strlen(
2895: (*s_etat_processus).localisation) + 1) * sizeof(unsigned char)))
2896: == NULL)
2897: {
2898: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2899: return(NULL);
2900: }
2901:
2902: strcpy((*s_nouvel_etat_processus).localisation,
2903: (*s_etat_processus).localisation);
2904:
2905: if ((*s_etat_processus).indep != NULL)
2906: {
2907: if (((*s_nouvel_etat_processus).indep = copie_objet(s_etat_processus,
2908: (*s_etat_processus).indep, 'P')) == NULL)
2909: {
2910: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
2911: {
2912: (*s_etat_processus).erreur_systeme = d_es_processus;
2913: return(NULL);
2914: }
2915:
2916: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2917: return(NULL);
2918: }
2919: }
2920: else
2921: {
2922: (*s_nouvel_etat_processus).indep = NULL;
2923: }
2924:
2925: if ((*s_etat_processus).depend != NULL)
2926: {
2927: if (((*s_nouvel_etat_processus).depend = copie_objet(s_etat_processus,
2928: (*s_etat_processus).depend, 'P')) == NULL)
2929: {
2930: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
2931: {
2932: (*s_etat_processus).erreur_systeme = d_es_processus;
2933: return(NULL);
2934: }
2935:
2936: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2937: return(NULL);
2938: }
2939: }
2940: else
2941: {
2942: (*s_nouvel_etat_processus).depend = NULL;
2943: }
2944:
2945: if ((*s_etat_processus).parametres_courbes_de_niveau != NULL)
2946: {
2947: if (((*s_nouvel_etat_processus).parametres_courbes_de_niveau =
2948: copie_objet(s_etat_processus, (*s_etat_processus)
2949: .parametres_courbes_de_niveau, 'P')) == NULL)
2950: {
2951: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
2952: {
2953: (*s_etat_processus).erreur_systeme = d_es_processus;
2954: return(NULL);
2955: }
2956:
2957: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2958: return(NULL);
2959: }
2960: }
2961: else
2962: {
2963: (*s_nouvel_etat_processus).parametres_courbes_de_niveau = NULL;
2964: }
2965:
2966: (*s_nouvel_etat_processus).instruction_derniere_erreur = NULL;
2967:
2968: if (((*s_etat_processus).instruction_courante != NULL) &&
2969: (*s_etat_processus).evaluation_expression_compilee == 'N')
2970: {
2971: if (((*s_nouvel_etat_processus).instruction_courante = malloc((strlen(
2972: (*s_etat_processus).instruction_courante) + 1) *
2973: sizeof(unsigned char))) == NULL)
2974: {
2975: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
2976: {
2977: (*s_etat_processus).erreur_systeme = d_es_processus;
2978: return(NULL);
2979: }
2980:
2981: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
2982: return(NULL);
2983: }
2984:
2985: strcpy((*s_nouvel_etat_processus).instruction_courante,
2986: (*s_etat_processus).instruction_courante);
2987: }
2988: else
2989: {
2990: (*s_nouvel_etat_processus).instruction_courante = NULL;
2991: }
2992:
2993: if ((*s_etat_processus).label_x != NULL)
2994: {
2995: if (((*s_nouvel_etat_processus).label_x = malloc((strlen(
2996: (*s_etat_processus).label_x) + 1) *
2997: sizeof(unsigned char))) == NULL)
2998: {
2999: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3000: {
3001: (*s_etat_processus).erreur_systeme = d_es_processus;
3002: return(NULL);
3003: }
3004:
3005: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3006: return(NULL);
3007: }
3008:
3009: strcpy((*s_nouvel_etat_processus).label_x,
3010: (*s_etat_processus).label_x);
3011: }
3012: else
3013: {
3014: (*s_nouvel_etat_processus).label_x = NULL;
3015: }
3016:
3017: if ((*s_etat_processus).label_y != NULL)
3018: {
3019: if (((*s_nouvel_etat_processus).label_y = malloc((strlen(
3020: (*s_etat_processus).label_y) + 1) *
3021: sizeof(unsigned char))) == NULL)
3022: {
3023: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3024: {
3025: (*s_etat_processus).erreur_systeme = d_es_processus;
3026: return(NULL);
3027: }
3028:
3029: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3030: return(NULL);
3031: }
3032:
3033: strcpy((*s_nouvel_etat_processus).label_y,
3034: (*s_etat_processus).label_y);
3035: }
3036: else
3037: {
3038: (*s_nouvel_etat_processus).label_y = NULL;
3039: }
3040:
3041: if ((*s_etat_processus).label_z != NULL)
3042: {
3043: if (((*s_nouvel_etat_processus).label_z = malloc((strlen(
3044: (*s_etat_processus).label_z) + 1) *
3045: sizeof(unsigned char))) == NULL)
3046: {
3047: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3048: {
3049: (*s_etat_processus).erreur_systeme = d_es_processus;
3050: return(NULL);
3051: }
3052:
3053: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3054: return(NULL);
3055: }
3056:
3057: strcpy((*s_nouvel_etat_processus).label_z,
3058: (*s_etat_processus).label_z);
3059: }
3060: else
3061: {
3062: (*s_nouvel_etat_processus).label_z = NULL;
3063: }
3064:
3065: if ((*s_etat_processus).titre != NULL)
3066: {
3067: if (((*s_nouvel_etat_processus).titre = malloc((strlen(
3068: (*s_etat_processus).titre) + 1) *
3069: sizeof(unsigned char))) == NULL)
3070: {
3071: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3072: {
3073: (*s_etat_processus).erreur_systeme = d_es_processus;
3074: return(NULL);
3075: }
3076:
3077: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3078: return(NULL);
3079: }
3080:
3081: strcpy((*s_nouvel_etat_processus).titre,
3082: (*s_etat_processus).titre);
3083: }
3084: else
3085: {
3086: (*s_nouvel_etat_processus).titre = NULL;
3087: }
3088:
3089: if ((*s_etat_processus).legende != NULL)
3090: {
3091: if (((*s_nouvel_etat_processus).legende = malloc((strlen(
3092: (*s_etat_processus).legende) + 1) *
3093: sizeof(unsigned char))) == NULL)
3094: {
3095: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3096: {
3097: (*s_etat_processus).erreur_systeme = d_es_processus;
3098: return(NULL);
3099: }
3100:
3101: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3102: return(NULL);
3103: }
3104:
3105: strcpy((*s_nouvel_etat_processus).legende,
3106: (*s_etat_processus).legende);
3107: }
3108: else
3109: {
3110: (*s_nouvel_etat_processus).legende = NULL;
3111: }
3112:
3113: /*
3114: * Copie de la table des variables
3115: */
3116:
3117: (*s_nouvel_etat_processus).l_liste_variables_statiques = NULL;
3118: copie_arbre_variables(s_etat_processus, s_nouvel_etat_processus);
3119:
3120: if ((*s_nouvel_etat_processus).erreur_systeme != d_es)
3121: {
3122: return(NULL);
3123: }
3124:
3125: (*(*s_nouvel_etat_processus).l_liste_variables_partagees) =
3126: (*(*s_etat_processus).l_liste_variables_partagees);
3127: (*(*s_nouvel_etat_processus).s_arbre_variables_partagees) =
3128: (*(*s_etat_processus).s_arbre_variables_partagees);
3129:
3130: /*
3131: * Copie de la pile opérationnelle
3132: */
3133:
3134: (*s_nouvel_etat_processus).l_base_pile = NULL;
3135: l_element_lecture = (*s_etat_processus).l_base_pile;
3136: l_element_precedent = NULL;
3137:
3138: while(l_element_lecture != NULL)
3139: {
3140: if ((l_element_suivant = malloc(sizeof(struct_liste_chainee))) == NULL)
3141: {
3142: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3143: {
3144: (*s_etat_processus).erreur_systeme = d_es_processus;
3145: return(NULL);
3146: }
3147:
3148: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3149: return(NULL);
3150: }
3151:
3152: if (((*l_element_suivant).donnee = copie_objet(s_etat_processus,
3153: (*l_element_lecture).donnee, 'P')) == NULL)
3154: {
3155: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3156: {
3157: (*s_etat_processus).erreur_systeme = d_es_processus;
3158: return(NULL);
3159: }
3160:
3161: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3162: return(NULL);
3163: }
3164:
3165: (*l_element_suivant).suivant = NULL;
3166:
3167: if ((*s_nouvel_etat_processus).l_base_pile == NULL)
3168: {
3169: (*s_nouvel_etat_processus).l_base_pile = l_element_suivant;
3170: }
3171: else
3172: {
3173: (*l_element_precedent).suivant = l_element_suivant;
3174: }
3175:
3176: l_element_precedent = l_element_suivant;
3177: l_element_lecture = (*l_element_lecture).suivant;
3178: }
3179:
3180: /*
3181: * Copie de la pile système
3182: */
3183:
3184: (*s_nouvel_etat_processus).l_base_pile_systeme = NULL;
3185: (*s_nouvel_etat_processus).hauteur_pile_systeme = 0;
3186:
3187: empilement_pile_systeme(s_nouvel_etat_processus);
3188:
3189: if ((*s_nouvel_etat_processus).erreur_systeme != d_es)
3190: {
3191: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3192: {
3193: (*s_etat_processus).erreur_systeme = d_es_processus;
3194: return(NULL);
3195: }
3196:
3197: (*s_etat_processus).erreur_systeme =
3198: (*s_nouvel_etat_processus).erreur_systeme;
3199: return(NULL);
3200: }
3201:
3202: (*(*s_nouvel_etat_processus).l_base_pile_systeme).retour_definition = 'Y';
3203:
3204: /*
3205: * On empile deux valeurs retour_definition pour pouvoir récupérer
3206: * les variables dans le cas d'un programme compilé.
3207: */
3208:
3209: empilement_pile_systeme(s_nouvel_etat_processus);
3210:
3211: if ((*s_nouvel_etat_processus).erreur_systeme != d_es)
3212: {
3213: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3214: {
3215: (*s_etat_processus).erreur_systeme = d_es_processus;
3216: return(NULL);
3217: }
3218:
3219: (*s_etat_processus).erreur_systeme =
3220: (*s_nouvel_etat_processus).erreur_systeme;
3221: return(NULL);
3222: }
3223:
3224: (*(*s_nouvel_etat_processus).l_base_pile_systeme).retour_definition = 'Y';
3225:
3226: /*
3227: * Destruction de la pile last pour le thread en cours.
3228: */
3229:
3230: (*s_nouvel_etat_processus).l_base_pile_last = NULL;
3231: (*s_nouvel_etat_processus).l_base_pile_processus = NULL;
3232:
3233: /*
3234: * Copie des différents contextes
3235: */
3236:
3237: (*s_nouvel_etat_processus).pointeur_signal_lecture = d_faux;
3238: (*s_nouvel_etat_processus).pointeur_signal_ecriture = d_faux;
3239:
3240: (*s_nouvel_etat_processus).l_base_pile_contextes = NULL;
3241: l_element_lecture = (*s_etat_processus).l_base_pile_contextes;
3242:
3243: while(l_element_lecture != NULL)
3244: {
3245: if ((l_element_suivant = malloc(sizeof(struct_liste_chainee))) == NULL)
3246: {
3247: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3248: {
3249: (*s_etat_processus).erreur_systeme = d_es_processus;
3250: return(NULL);
3251: }
3252:
3253: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3254: return(NULL);
3255: }
3256:
3257: if (((*l_element_suivant).donnee = copie_objet(s_etat_processus,
3258: (*l_element_lecture).donnee, 'P')) == NULL)
3259: {
3260: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3261: {
3262: (*s_etat_processus).erreur_systeme = d_es_processus;
3263: return(NULL);
3264: }
3265:
3266: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3267: return(NULL);
3268: }
3269:
3270: (*l_element_suivant).suivant = NULL;
3271:
3272: if ((*s_nouvel_etat_processus).l_base_pile_contextes == NULL)
3273: {
3274: (*s_nouvel_etat_processus).l_base_pile_contextes =
3275: l_element_suivant;
3276: }
3277: else
3278: {
3279: (*l_element_precedent).suivant = l_element_suivant;
3280: }
3281:
3282: l_element_precedent = l_element_suivant;
3283: l_element_lecture = (*l_element_lecture).suivant;
3284: }
3285:
3286: (*s_nouvel_etat_processus).l_base_pile_taille_contextes = NULL;
3287: l_element_lecture = (*s_etat_processus).l_base_pile_taille_contextes;
3288:
3289: while(l_element_lecture != NULL)
3290: {
3291: if ((l_element_suivant = malloc(sizeof(struct_liste_chainee))) == NULL)
3292: {
3293: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3294: {
3295: (*s_etat_processus).erreur_systeme = d_es_processus;
3296: return(NULL);
3297: }
3298:
3299: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3300: return(NULL);
3301: }
3302:
3303: if (((*l_element_suivant).donnee = copie_objet(s_etat_processus,
3304: (*l_element_lecture).donnee, 'P')) == NULL)
3305: {
3306: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3307: {
3308: (*s_etat_processus).erreur_systeme = d_es_processus;
3309: return(NULL);
3310: }
3311:
3312: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3313: return(NULL);
3314: }
3315:
3316: (*l_element_suivant).suivant = NULL;
3317:
3318: if ((*s_nouvel_etat_processus).l_base_pile_taille_contextes == NULL)
3319: {
3320: (*s_nouvel_etat_processus).l_base_pile_taille_contextes =
3321: l_element_suivant;
3322: }
3323: else
3324: {
3325: (*l_element_precedent).suivant = l_element_suivant;
3326: }
3327:
3328: l_element_precedent = l_element_suivant;
3329: l_element_lecture = (*l_element_lecture).suivant;
3330: }
3331:
3332: /*
3333: * Copies des piles s_sockets, s_bibliotheques et
3334: * s_instructions_externes.
3335: */
3336:
3337: (*s_nouvel_etat_processus).s_sockets = NULL;
3338: l_element_lecture = (*s_etat_processus).s_sockets;
3339:
3340: while(l_element_lecture != NULL)
3341: {
3342: if ((l_element_suivant = malloc(sizeof(struct_liste_chainee))) == NULL)
3343: {
3344: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3345: {
3346: (*s_etat_processus).erreur_systeme = d_es_processus;
3347: return(NULL);
3348: }
3349:
3350: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3351: return(NULL);
3352: }
3353:
3354: if (((*l_element_suivant).donnee = copie_objet(s_etat_processus,
3355: (*l_element_lecture).donnee, 'P')) == NULL)
3356: {
3357: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3358: {
3359: (*s_etat_processus).erreur_systeme = d_es_processus;
3360: return(NULL);
3361: }
3362:
3363: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3364: return(NULL);
3365: }
3366:
3367: (*l_element_suivant).suivant = NULL;
3368:
3369: if ((*s_nouvel_etat_processus).s_sockets == NULL)
3370: {
3371: (*s_nouvel_etat_processus).s_sockets = l_element_suivant;
3372: }
3373: else
3374: {
3375: (*l_element_precedent).suivant = l_element_suivant;
3376: }
3377:
3378: l_element_precedent = l_element_suivant;
3379: l_element_lecture = (*l_element_lecture).suivant;
3380: }
3381:
3382: (*s_nouvel_etat_processus).s_bibliotheques = NULL;
3383: l_element_precedent = NULL;
3384: l_element_lecture = (*s_etat_processus).s_bibliotheques;
3385:
3386: while(l_element_lecture != NULL)
3387: {
3388: if ((l_element_suivant = malloc(sizeof(struct_liste_chainee))) == NULL)
3389: {
3390: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3391: {
3392: (*s_etat_processus).erreur_systeme = d_es_processus;
3393: return(NULL);
3394: }
3395:
3396: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3397: return(NULL);
3398: }
3399:
3400: if (((*l_element_suivant).donnee = malloc(sizeof(struct_bibliotheque)))
3401: == NULL)
3402: {
3403: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3404: return(NULL);
3405: }
3406:
3407: (*((struct_bibliotheque *) (*l_element_suivant).donnee)).descripteur
3408: = (*((struct_bibliotheque *) (*l_element_lecture).donnee))
3409: .descripteur;
3410: (*((struct_bibliotheque *) (*l_element_suivant).donnee)).pid
3411: = (*((struct_bibliotheque *) (*l_element_lecture).donnee)).pid;
3412: (*((struct_bibliotheque *) (*l_element_suivant).donnee)).tid
3413: = (*((struct_bibliotheque *) (*l_element_lecture).donnee)).tid;
3414:
3415: if (((*((struct_bibliotheque *) (*l_element_suivant).donnee)).nom =
3416: malloc((strlen((*((struct_bibliotheque *) (*l_element_lecture)
3417: .donnee)).nom) + 1) * sizeof(unsigned char))) == NULL)
3418: {
3419: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3420: {
3421: (*s_etat_processus).erreur_systeme = d_es_processus;
3422: return(NULL);
3423: }
3424:
3425: (*s_etat_processus).erreur_systeme = d_es_allocation_memoire;
3426: return(NULL);
3427: }
3428:
3429: strcpy((*((struct_bibliotheque *) (*l_element_suivant).donnee)).nom,
3430: (*((struct_bibliotheque *) (*l_element_lecture).donnee)).nom);
3431:
3432: (*l_element_suivant).suivant = NULL;
3433:
3434: if ((*s_nouvel_etat_processus).s_bibliotheques == NULL)
3435: {
3436: (*s_nouvel_etat_processus).s_bibliotheques = l_element_suivant;
3437: }
3438: else
3439: {
3440: (*l_element_precedent).suivant = l_element_suivant;
3441: }
3442:
3443: l_element_precedent = l_element_suivant;
3444: l_element_lecture = (*l_element_lecture).suivant;
3445: }
3446:
3447: if ((*s_etat_processus).nombre_instructions_externes != 0)
3448: {
3449: if (((*s_nouvel_etat_processus).s_instructions_externes =
3450: malloc((*s_etat_processus).nombre_instructions_externes *
3451: sizeof(struct_instruction_externe))) == NULL)
3452: {
3453: (*s_etat_processus).erreur_systeme = d_es_processus;
3454: return(NULL);
3455: }
3456:
3457: for(i = 0; i < (*s_etat_processus).nombre_instructions_externes; i++)
3458: {
3459: if (((*s_nouvel_etat_processus).s_instructions_externes[i].nom =
3460: malloc((strlen((*s_etat_processus).s_instructions_externes
3461: [i].nom) + 1) * sizeof(unsigned char))) == NULL)
3462: {
3463: (*s_etat_processus).erreur_systeme = d_es_processus;
3464: return(NULL);
3465: }
3466:
3467: strcpy((*s_nouvel_etat_processus).s_instructions_externes[i].nom,
3468: (*s_etat_processus).s_instructions_externes[i].nom);
3469:
3470: if (((*s_nouvel_etat_processus).s_instructions_externes[i]
3471: .nom_bibliotheque = malloc((strlen((*s_etat_processus)
3472: .s_instructions_externes[i].nom_bibliotheque) + 1) *
3473: sizeof(unsigned char))) == NULL)
3474: {
3475: (*s_etat_processus).erreur_systeme = d_es_processus;
3476: return(NULL);
3477: }
3478:
3479: strcpy((*s_nouvel_etat_processus).s_instructions_externes[i]
3480: .nom_bibliotheque, (*s_etat_processus)
3481: .s_instructions_externes[i].nom_bibliotheque);
3482:
3483: (*s_nouvel_etat_processus).s_instructions_externes[i]
3484: .descripteur_bibliotheque = (*s_etat_processus)
3485: .s_instructions_externes[i].descripteur_bibliotheque;
3486: }
3487: }
3488: else
3489: {
3490: (*s_nouvel_etat_processus).s_instructions_externes = NULL;
3491: }
3492:
3493: pthread_mutexattr_init(&attributs_mutex);
3494: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
3495: pthread_mutex_init(&((*s_nouvel_etat_processus).mutex), &attributs_mutex);
3496: pthread_mutexattr_destroy(&attributs_mutex);
3497:
3498: pthread_mutexattr_init(&attributs_mutex);
3499: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_NORMAL);
3500: pthread_mutex_init(&((*s_nouvel_etat_processus).mutex_allocation),
3501: &attributs_mutex);
3502: pthread_mutexattr_destroy(&attributs_mutex);
3503:
3504: if (pthread_mutex_unlock(&((*s_etat_processus).mutex)) != 0)
3505: {
3506: (*s_etat_processus).erreur_systeme = d_es_processus;
3507: return(NULL);
3508: }
3509:
3510: return(s_nouvel_etat_processus);
3511:
3512: #undef return
3513: }
3514:
3515:
3516: /*
3517: ================================================================================
3518: Routines de debug
3519: ================================================================================
3520: entrées :
3521: --------------------------------------------------------------------------------
3522: sorties :
3523: --------------------------------------------------------------------------------
3524: effets de bord : néant
3525: ================================================================================
3526: */
3527:
3528: #ifdef DEBUG_MEMOIRE
3529:
3530: #undef malloc
3531: #undef realloc
3532: #undef free
3533: #undef fork
3534:
3535: #ifdef return
3536: # undef return
3537: #endif
3538:
3539: #ifdef __BACKTRACE
3540: #define PROFONDEUR_PILE 64
3541: #define return(a) { if (a == NULL) \
3542: { BACKTRACE(PROFONDEUR_PILE); \
3543: fprintf(stderr, ">>> MEDITATION %d\n", __LINE__); } \
3544: return(a); } while(0)
3545: #endif
3546:
3547: #undef fprintf
3548: #define check(a, b) ((strcmp(#a, fonction) == 0) && (ligne == b))
3549: #undef CORE_DUMP
3550:
3551: typedef struct memoire
3552: {
3553: void *pointeur;
3554: unsigned char *fonction;
3555: unsigned char *argument;
3556: unsigned long ligne;
3557: size_t taille;
3558: unsigned long long ordre;
3559: # ifdef __BACKTRACE
3560: void *pile[PROFONDEUR_PILE];
3561: int profondeur;
3562: # endif
3563: struct memoire *suivant;
3564: } struct_memoire;
3565:
3566: static struct_memoire *debug = NULL;
3567: static unsigned long long ordre = 0;
3568: static pthread_mutex_t mutex_allocation;
3569:
3570: void
3571: debug_memoire_initialisation()
3572: {
3573: pthread_mutexattr_t attributs_mutex;
3574:
3575: pthread_mutexattr_init(&attributs_mutex);
3576: pthread_mutexattr_settype(&attributs_mutex, PTHREAD_MUTEX_RECURSIVE);
3577: pthread_mutex_init(&mutex_allocation, &attributs_mutex);
3578: pthread_mutexattr_destroy(&attributs_mutex);
3579:
3580: return;
3581: }
3582:
3583: void *
3584: debug_memoire_ajout(size_t taille, const unsigned char *fonction,
3585: unsigned long ligne, const unsigned char *argument)
3586: {
3587: struct_memoire *ancienne_base;
3588:
3589: void *pointeur;
3590:
3591: pthread_mutex_lock(&mutex_allocation);
3592:
3593: ancienne_base = debug;
3594:
3595: if ((debug = malloc(sizeof(struct_memoire))) == NULL)
3596: {
3597: pthread_mutex_unlock(&mutex_allocation);
3598: return(NULL);
3599: }
3600:
3601: if (((*debug).pointeur = malloc(taille)) == NULL)
3602: {
3603: pthread_mutex_unlock(&mutex_allocation);
3604: return(NULL);
3605: }
3606:
3607: (*debug).suivant = ancienne_base;
3608: (*debug).ligne = ligne;
3609: (*debug).taille = taille;
3610: (*debug).ordre = ordre;
3611:
3612: pointeur = (*debug).pointeur;
3613:
3614: # ifdef __BACKTRACE
3615: (*debug).profondeur = backtrace((*debug).pile, PROFONDEUR_PILE);
3616: # endif
3617:
3618: if (((*debug).fonction = malloc((strlen(fonction) + 1) *
3619: sizeof(unsigned char))) == NULL)
3620: {
3621: pthread_mutex_unlock(&mutex_allocation);
3622: return(NULL);
3623: }
3624:
3625: if (((*debug).argument = malloc((strlen(argument) + 1) *
3626: sizeof(unsigned char))) == NULL)
3627: {
3628: pthread_mutex_unlock(&mutex_allocation);
3629: return(NULL);
3630: }
3631:
3632: strcpy((*debug).fonction, fonction);
3633: strcpy((*debug).argument, argument);
3634:
3635: memset((*debug).pointeur, 0, (*debug).taille);
3636:
3637: pthread_mutex_unlock(&mutex_allocation);
3638: ordre++;
3639:
3640: return(pointeur);
3641: }
3642:
3643: void *
3644: debug_memoire_modification(void *pointeur, size_t taille,
3645: const unsigned char *fonction, unsigned long ligne,
3646: const unsigned char *argument)
3647: {
3648: struct_memoire *element_courant;
3649:
3650: if (pointeur != NULL)
3651: {
3652: if (taille == 0)
3653: {
3654: // Revient à free(). Il n'y a pas de parenthèses car on ne veut
3655: // pas utiliser la macro return().
3656:
3657: debug_memoire_retrait(pointeur);
3658: return NULL ;
3659: }
3660: else
3661: {
3662: // Réallocation réelle
3663:
3664: pthread_mutex_lock(&mutex_allocation);
3665:
3666: element_courant = debug;
3667:
3668: while(element_courant != NULL)
3669: {
3670: if ((*element_courant).pointeur == pointeur)
3671: {
3672: break;
3673: }
3674:
3675: element_courant = (*element_courant).suivant;
3676: }
3677:
3678: if (element_courant == NULL)
3679: {
3680: pthread_mutex_unlock(&mutex_allocation);
3681:
3682: uprintf("[%d-%llu] ILLEGAL POINTER (realloc)\n",
3683: getpid(), (unsigned long long) pthread_self());
3684: # ifdef __BACKTRACE
3685: BACKTRACE(PROFONDEUR_PILE);
3686: # endif
3687:
3688: return(realloc(pointeur, taille));
3689: }
3690: else
3691: {
3692: if (((*element_courant).pointeur = realloc(pointeur, taille))
3693: == NULL)
3694: {
3695: pthread_mutex_unlock(&mutex_allocation);
3696: return(NULL);
3697: }
3698:
3699: (*element_courant).ligne = ligne;
3700: (*element_courant).taille = taille;
3701: free((*element_courant).fonction);
3702: free((*element_courant).argument);
3703:
3704: if (((*element_courant).fonction = malloc((strlen(fonction)
3705: + 1) * sizeof(unsigned char))) == NULL)
3706: {
3707: pthread_mutex_unlock(&mutex_allocation);
3708: return(NULL);
3709: }
3710:
3711: if (((*element_courant).argument = malloc((strlen(argument)
3712: + 1) * sizeof(unsigned char))) == NULL)
3713: {
3714: pthread_mutex_unlock(&mutex_allocation);
3715: return(NULL);
3716: }
3717:
3718: strcpy((*element_courant).fonction, fonction);
3719: strcpy((*element_courant).argument, argument);
3720:
3721: pthread_mutex_unlock(&mutex_allocation);
3722:
3723: return((*element_courant).pointeur);
3724: }
3725: }
3726: }
3727: else
3728: {
3729: // Revient à malloc()
3730: pointeur = debug_memoire_ajout(taille, fonction, ligne, argument);
3731: return(pointeur);
3732: }
3733: }
3734:
3735: void
3736: debug_memoire_retrait(void *pointeur)
3737: {
3738: struct_memoire *element_courant;
3739: struct_memoire *element_precedent;
3740:
3741: pthread_mutex_lock(&mutex_allocation);
3742:
3743: element_courant = debug;
3744: element_precedent = NULL;
3745:
3746: while(element_courant != NULL)
3747: {
3748: if ((*element_courant).pointeur == pointeur)
3749: {
3750: if (element_precedent == NULL)
3751: {
3752: debug = (*debug).suivant;
3753: }
3754: else
3755: {
3756: (*element_precedent).suivant = (*element_courant).suivant;
3757: }
3758:
3759: if (pointeur != NULL)
3760: {
3761: memset(pointeur, 0, (*element_courant).taille);
3762: }
3763:
3764: free((*element_courant).fonction);
3765: free((*element_courant).argument);
3766: free(element_courant);
3767:
3768: break;
3769: }
3770:
3771: element_precedent = element_courant;
3772: element_courant = (*element_courant).suivant;
3773: }
3774:
3775: pthread_mutex_unlock(&mutex_allocation);
3776:
3777: if (element_courant == NULL)
3778: {
3779: uprintf("[%d-%llu] ILLEGAL POINTER (free)\n",
3780: getpid(), (unsigned long long) pthread_self());
3781: # ifdef __BACKTRACE
3782: BACKTRACE(PROFONDEUR_PILE);
3783: # endif
3784: }
3785:
3786: free(pointeur);
3787: return;
3788: }
3789:
3790: void
3791: debug_memoire_verification()
3792: {
3793: # ifdef __BACKTRACE
3794: char **appels;
3795:
3796: int j;
3797: # endif
3798:
3799: integer8 i;
3800:
3801: struct_memoire *element_courant;
3802: struct_memoire *element_suivant;
3803:
3804: fprintf(stderr, "[%d-%llu] LIST OF MEMORY LEAKS\n",
3805: getpid(), (unsigned long long) pthread_self());
3806:
3807: pthread_mutex_lock(&mutex_allocation);
3808:
3809: element_courant = debug;
3810: i = 1;
3811:
3812: while(element_courant != NULL)
3813: {
3814: fprintf(stderr, "[%d-%llu] MEDITATION %lld (%llu)\n", getpid(),
3815: (unsigned long long) pthread_self(), i,
3816: (*element_courant).ordre);
3817: fprintf(stderr, "[%d-%llu] P: %p, F: %s(), L: %lu, S: %d\n",
3818: getpid(), (unsigned long long) pthread_self(),
3819: (*element_courant).pointeur,
3820: (*element_courant).fonction, (*element_courant).ligne,
3821: (int) (*element_courant).taille);
3822: fprintf(stderr, "[%d-%llu] A: %s\n", getpid(),
3823: (unsigned long long) pthread_self(),
3824: (*element_courant).argument);
3825:
3826: if (strstr((*element_courant).argument, "sizeof(unsigned char)")
3827: != NULL)
3828: {
3829: fprintf(stderr, "[%d-%llu] ", getpid(),
3830: (unsigned long long) pthread_self());
3831: fprintf(stderr, "O: %s\n", (unsigned char *)
3832: (*element_courant).pointeur);
3833: }
3834: else if (strcmp((*element_courant).argument, "sizeof(struct_objet)")
3835: == 0)
3836: {
3837: fprintf(stderr, "[%d-%llu] ", getpid(),
3838: (unsigned long long) pthread_self());
3839: fprintf(stderr, "O: %d\n", (*((struct_objet *)
3840: (*element_courant).pointeur)).type);
3841: }
3842: else if (strcmp((*element_courant).argument,
3843: "sizeof(struct_liste_chainee)") == 0)
3844: {
3845: fprintf(stderr, "[%d-%llu] ", getpid(),
3846: (unsigned long long) pthread_self());
3847: fprintf(stderr, "O: data=%p next=%p\n", (*((struct_liste_chainee *)
3848: (*element_courant).pointeur)).donnee,
3849: (*((struct_liste_chainee *) (*element_courant).pointeur))
3850: .suivant);
3851: }
3852:
3853: # ifdef __BACKTRACE
3854: appels = backtrace_symbols((*element_courant).pile,
3855: (*element_courant).profondeur);
3856:
3857: fprintf(stderr, "[%d-%llu] BACKTRACE\n",
3858: getpid(), (unsigned long long) pthread_self());
3859:
3860: if (appels != NULL)
3861: {
3862: for(j = 0; j < (*element_courant).profondeur; j++)
3863: {
3864: fprintf(stderr, "[%d-%llu] %s\n", getpid(),
3865: (unsigned long long) pthread_self(), appels[j]);
3866: }
3867:
3868: free(appels);
3869: }
3870: # endif
3871:
3872: fprintf(stderr, "\n");
3873:
3874: i++;
3875:
3876: element_suivant = (*element_courant).suivant;
3877:
3878: # ifndef CORE_DUMP
3879: free((*element_courant).fonction);
3880: free((*element_courant).argument);
3881: free(element_courant);
3882: # endif
3883:
3884: element_courant = element_suivant;
3885: }
3886:
3887: pthread_mutex_unlock(&mutex_allocation);
3888: pthread_mutex_destroy(&mutex_allocation);
3889:
3890: fprintf(stderr, "[%d-%llu] END OF LIST\n", getpid(),
3891: (unsigned long long) pthread_self());
3892:
3893: return;
3894: }
3895:
3896: pid_t
3897: debug_fork()
3898: {
3899: pid_t pid;
3900:
3901: pthread_mutex_lock(&mutex_allocation);
3902: pid = fork();
3903:
3904: if (pid == 0)
3905: {
3906: liberation_queue_signaux(s_etat_processus);
3907: creation_queue_signaux(s_etat_processus);
3908:
3909: pthread_mutex_destroy(&mutex_allocation);
3910: debug_memoire_initialisation();
3911: }
3912: else
3913: {
3914: pthread_mutex_unlock(&mutex_allocation);
3915: }
3916:
3917: // Pas de parenthèses pour ne pas remplacer return par sa macro.
3918: return pid;
3919: }
3920:
3921: void
3922: analyse_post_mortem()
3923: {
3924: # ifdef CORE_DUMP
3925: BUG(debug != NULL, uprintf("[%d-%llu] CREATE CORE DUMP FILE FOR "
3926: "POST MORTEM ANALYZE\n", getpid(),
3927: (unsigned long long) pthread_self()));
3928: # endif
3929:
3930: return;
3931: }
3932:
3933: #endif
3934:
3935: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>