1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.36
4: Copyright (C) 1989-2025 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: Fonction d'affectation des interruptions aux différentes queues
29: ================================================================================
30: Entrées : s_etat_processus
31: --------------------------------------------------------------------------------
32: Sorties :
33: --------------------------------------------------------------------------------
34: Effets de bord : néant
35: ================================================================================
36: */
37:
38: void
39: affectation_interruptions_logicielles(struct_processus *s_etat_processus)
40: {
41: int interruption;
42: int ios;
43:
44: sig_atomic_t registre;
45:
46: volatile struct_liste_chainee *l_element_courant;
47: struct_liste_chainee *l_element;
48:
49: struct_objet *s_objet_processus;
50:
51: if ((*s_etat_processus).var_volatile_requete_arret == -1)
52: {
53: // Si une requête d'arrêt est reçue par le processus durant la
54: // phase de verrouillage, on n'empile rien car la structure
55: // processus peut déjà être libérée par le thread de surveillance.
56:
57: (*s_etat_processus).nombre_interruptions_non_affectees = 0;
58: return;
59: }
60:
61: if ((ios = pthread_mutex_trylock(&((*s_etat_processus)
62: .mutex_pile_processus))) != 0)
63: {
64: if (ios != EBUSY)
65: {
66: (*s_etat_processus).erreur_systeme = d_es_processus;
67: }
68:
69: return;
70: }
71:
72: l_element_courant = (*s_etat_processus).l_base_pile_processus;
73:
74: while(l_element_courant != NULL)
75: {
76: /*
77: * On regarde s'il y a quelque chose dans le pipe d'interruptions
78: * du processus fils.
79: *
80: * Cette routine est interruptible par l'arrivée d'une interruption
81: * de type SWI.
82: */
83:
84: if ((*(*l_element_courant).donnee).type != PRC)
85: {
86: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
87:
88: (*s_etat_processus).erreur_systeme = d_es_processus;
89: return;
90: }
91:
92: if (pthread_mutex_lock(&((*(*((struct_processus_fils *)
93: (*(*l_element_courant).donnee).objet)).thread).mutex)) != 0)
94: {
95: pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus));
96:
97: (*s_etat_processus).erreur_systeme = d_es_processus;
98: return;
99: }
100:
101: if ((*(*((struct_processus_fils *) (*(*l_element_courant).donnee)
102: .objet)).thread).nombre_interruptions_dans_pipe > 0)
103: {
104: registre = (*s_etat_processus).var_volatile_traitement_retarde_stop;
105: (*s_etat_processus).var_volatile_traitement_retarde_stop = 1;
106:
107: if (read_atomic(s_etat_processus, (*(*((struct_processus_fils *)
108: (*(*l_element_courant).donnee)
109: .objet)).thread).pipe_interruptions[0], &interruption,
110: sizeof(interruption)) == sizeof(interruption))
111: {
112: if (registre == 0)
113: {
114: if ((*s_etat_processus).var_volatile_traitement_retarde_stop
115: == -1)
116: {
117: (*s_etat_processus).var_volatile_requete_arret = -1;
118: }
119:
120: (*s_etat_processus).var_volatile_traitement_retarde_stop
121: = registre;
122: }
123:
124: if ((interruption < 1) || (interruption >
125: d_NOMBRE_INTERRUPTIONS))
126: {
127: pthread_mutex_unlock(&((*(*((struct_processus_fils *)
128: (*(*l_element_courant).donnee).objet)).thread)
129: .mutex));
130: pthread_mutex_unlock(&((*s_etat_processus)
131: .mutex_pile_processus));
132:
133: (*s_etat_processus).erreur_systeme =
134: d_es_interruption_invalide;
135: return;
136: }
137:
138: /*
139: * On ne pousse dans les queues des interruptions que les
140: * interruptions qui ne sont pas masquées.
141: */
142:
143: if ((*s_etat_processus).masque_interruptions[interruption - 1]
144: != 'I')
145: {
146: if ((s_objet_processus = copie_objet(s_etat_processus,
147: (*l_element_courant).donnee, 'P')) == NULL)
148: {
149: pthread_mutex_unlock(&((*(*((struct_processus_fils *)
150: (*(*l_element_courant).donnee).objet)).thread)
151: .mutex));
152: pthread_mutex_unlock(&((*s_etat_processus)
153: .mutex_pile_processus));
154:
155: (*s_etat_processus).erreur_systeme =
156: d_es_allocation_memoire;
157: return;
158: }
159:
160: // Pile LIFO
161:
162: if (empilement(s_etat_processus, &((*s_etat_processus)
163: .pile_origine_interruptions[interruption - 1]),
164: s_objet_processus) == d_erreur)
165: {
166: pthread_mutex_unlock(&((*(*((struct_processus_fils *)
167: (*(*l_element_courant).donnee).objet)).thread)
168: .mutex));
169:
170: if (pthread_mutex_unlock(&((*s_etat_processus)
171: .mutex_pile_processus)) != 0)
172: {
173: (*s_etat_processus).erreur_systeme = d_es_processus;
174: return;
175: }
176:
177: return;
178: }
179:
180: (*s_etat_processus).queue_interruptions[interruption - 1]++;
181: (*s_etat_processus).nombre_interruptions_en_queue++;
182:
183: // Transformation en FIFO
184:
185: if ((*s_etat_processus).queue_interruptions
186: [interruption - 1] > 1)
187: {
188: l_element = (*s_etat_processus)
189: .pile_origine_interruptions[interruption - 1];
190:
191: while((*l_element).suivant != NULL)
192: {
193: l_element = (*l_element).suivant;
194: }
195:
196: (*l_element).suivant = (*s_etat_processus)
197: .pile_origine_interruptions[interruption - 1];
198: (*s_etat_processus).pile_origine_interruptions
199: [interruption - 1] =
200: (*(*l_element).suivant).suivant;
201: (*(*l_element).suivant).suivant = NULL;
202: }
203:
204: if ((*s_etat_processus).debug == d_vrai)
205: if (((*s_etat_processus).type_debug &
206: d_traitement_interruption) != 0)
207: {
208: if ((*(*((struct_processus_fils *) (*s_objet_processus)
209: .objet)).thread).processus_detache == d_vrai)
210: {
211: if ((*s_etat_processus).langue == 'F')
212: {
213: printf("[%d] Interruption logicielle "
214: "%d empilée en "
215: "provenance du processus %d\n",
216: (int) getpid(), interruption,
217: (int) (*(*((struct_processus_fils *)
218: (*s_objet_processus).objet)).thread)
219: .pid);
220: }
221: else
222: {
223: printf("[%d] Software interrupt %d stacked from"
224: " process %d\n", interruption,
225: (int) getpid(),
226: (int) (*(*((struct_processus_fils *)
227: (*s_objet_processus).objet)).thread)
228: .pid);
229: }
230: }
231: else
232: {
233: if ((*s_etat_processus).langue == 'F')
234: {
235: printf("[%d] Interruption logicielle "
236: "%d empilée en "
237: "provenance du thread %lld\n",
238: (int) getpid(), interruption, (integer8)
239: (*(*((struct_processus_fils *)
240: (*s_objet_processus).objet)).thread)
241: .tid);
242: }
243: else
244: {
245: printf("[%d] Software interrupt %d stacked from"
246: " process %lld\n", interruption,
247: (int) getpid(), (integer8)
248: (*(*((struct_processus_fils *)
249: (*s_objet_processus).objet)).thread)
250: .tid);
251: }
252: }
253:
254: fflush(stdout);
255: }
256: }
257:
258: (*(*((struct_processus_fils *) (*(*l_element_courant).donnee)
259: .objet)).thread).nombre_interruptions_dans_pipe--;
260: (*s_etat_processus).nombre_interruptions_non_affectees--;
261: }
262: else
263: {
264: pthread_mutex_unlock(&((*(*((struct_processus_fils *)
265: (*(*l_element_courant).donnee).objet)).thread).mutex));
266: pthread_mutex_unlock(&((*s_etat_processus)
267: .mutex_pile_processus));
268:
269: if (registre == 0)
270: {
271: if ((*s_etat_processus).var_volatile_traitement_retarde_stop
272: == -1)
273: {
274: (*s_etat_processus).var_volatile_requete_arret = -1;
275: }
276:
277: (*s_etat_processus).var_volatile_traitement_retarde_stop
278: = registre;
279: }
280:
281: (*s_etat_processus).erreur_systeme = d_es_interruption_invalide;
282: return;
283: }
284: }
285:
286: if (pthread_mutex_unlock(&((*(*((struct_processus_fils *)
287: (*(*l_element_courant).donnee).objet)).thread).mutex)) != 0)
288: {
289: (*s_etat_processus).erreur_systeme = d_es_processus;
290: return;
291: }
292:
293: l_element_courant = (*l_element_courant).suivant;
294: }
295:
296: if (pthread_mutex_unlock(&((*s_etat_processus).mutex_pile_processus)) != 0)
297: {
298: (*s_etat_processus).erreur_systeme = d_es_processus;
299: return;
300: }
301:
302: return;
303: }
304:
305:
306: /*
307: ================================================================================
308: Fonction de traitement des différentes interruptions
309: ================================================================================
310: Entrées : s_etat_processus
311: --------------------------------------------------------------------------------
312: Sorties :
313: --------------------------------------------------------------------------------
314: Effets de bord : néant
315: ================================================================================
316: */
317:
318: void
319: traitement_interruptions_logicielles(struct_processus *s_etat_processus)
320: {
321: int i;
322:
323: logical1 drapeau_erreur;
324: logical1 processus;
325: logical1 registre_arret_si_exception;
326:
327: pid_t pid;
328: pthread_t tid;
329:
330: struct_objet *s_objet_processus;
331:
332: unsigned char registre;
333: unsigned char tampon[22];
334:
335: /*
336: * Les interruptions sont non interruptibles.
337: */
338:
339: if (((*s_etat_processus).traitement_interruption == 'Y') ||
340: ((*s_etat_processus).traitement_interruptible == 'N'))
341: {
342: return;
343: }
344:
345: registre = (*s_etat_processus).traitement_interruption;
346: (*s_etat_processus).traitement_interruption = 'Y';
347:
348: /*
349: * Lancement d'une interruption. Les interruptions sont d'autant plus
350: * prioritaires que leur numéro est faible.
351: */
352:
353: for(i = 0; i < d_NOMBRE_INTERRUPTIONS; i++)
354: {
355: pid = 0;
356: tid = 0;
357: processus = d_faux;
358:
359: if ((*s_etat_processus).queue_interruptions[i] > 0)
360: {
361: if ((*s_etat_processus).masque_interruptions[i] == 'N')
362: {
363: /*
364: * Exécution de la i-ème interruption si celle-ci existe. Dans
365: * le cas contraire, une erreur d'exécution est renvoyée.
366: */
367:
368: if (((*s_etat_processus).corps_interruptions[i] != NULL) &&
369: ((*s_etat_processus).pile_origine_interruptions[i]
370: != NULL))
371: {
372: if (depilement(s_etat_processus, &((*s_etat_processus)
373: .pile_origine_interruptions[i]),
374: &s_objet_processus) == d_erreur)
375: {
376: (*s_etat_processus).traitement_interruption =
377: registre;
378: (*s_etat_processus).erreur_execution =
379: d_ex_interruption_invalide;
380: return;
381: }
382:
383: if (empilement(s_etat_processus, &((*s_etat_processus)
384: .l_base_pile), s_objet_processus) == d_erreur)
385: {
386: (*s_etat_processus).traitement_interruption =
387: registre;
388: return;
389: }
390:
391: if ((*s_etat_processus).debug == d_vrai)
392: if (((*s_etat_processus).type_debug &
393: d_traitement_interruption) != 0)
394: {
395: if ((*s_etat_processus).langue == 'F')
396: {
397: if ((processus = (*(*((struct_processus_fils *)
398: (*s_objet_processus).objet)).thread)
399: .processus_detache) == d_faux)
400: {
401: printf("[%d] Traitement de l'interruption "
402: "logicielle %d en provenance du thread "
403: "%llu\n", (int) getpid(), i + 1,
404: (unsigned long long)
405: (tid = (*(*((struct_processus_fils *)
406: (*s_objet_processus).objet)).thread)
407: .tid));
408: }
409: else
410: {
411: printf("[%d] Traitement de l'interruption "
412: "logicielle %d en provenance du "
413: "processus "
414: "%d\n", (int) getpid(), i + 1, (int)
415: (pid = (*(*((struct_processus_fils *)
416: (*s_objet_processus).objet)).thread)
417: .pid));
418: }
419: }
420: else
421: {
422: if ((processus = (*(*((struct_processus_fils *)
423: (*s_objet_processus).objet)).thread)
424: .processus_detache) == d_faux)
425: {
426: printf("[%d] Start software interrupt "
427: "%d from thread "
428: "%llu\n", (int) getpid(), i + 1,
429: (unsigned long long)
430: (tid = (*(*((struct_processus_fils *)
431: (*s_objet_processus).objet)).thread)
432: .tid));
433: }
434: else
435: {
436: printf("[%d] Start software interrupt "
437: "%d from process "
438: "%d\n", (int) getpid(), i + 1, (int)
439: (pid = (*(*((struct_processus_fils *)
440: (*s_objet_processus).objet)).thread)
441: .pid));
442: }
443: }
444:
445: fflush(stdout);
446: }
447:
448: (*s_etat_processus).nombre_interruptions_en_queue--;
449: (*s_etat_processus).queue_interruptions[i]--;
450:
451: registre_arret_si_exception =
452: (*s_etat_processus).arret_si_exception;
453: (*s_etat_processus).arret_si_exception = d_vrai;
454:
455: if ((*s_etat_processus).profilage == d_vrai)
456: {
457: sprintf(tampon, "Software interrupt %-2d", i + 1);
458: profilage(s_etat_processus, tampon);
459:
460: if ((*s_etat_processus).erreur_systeme != d_es)
461: {
462: return;
463: }
464: }
465:
466: drapeau_erreur = evaluation(s_etat_processus,
467: (*s_etat_processus).corps_interruptions[i], 'E');
468:
469: if ((*s_etat_processus).profilage == d_vrai)
470: {
471: profilage(s_etat_processus, NULL);
472: }
473:
474: if (drapeau_erreur == d_absence_erreur)
475: {
476: (*s_etat_processus).arret_si_exception =
477: registre_arret_si_exception;
478: }
479: else
480: {
481: if ((((*s_etat_processus).erreur_execution != d_ex) ||
482: ((*s_etat_processus).exception != d_ep) ||
483: ((*s_etat_processus).erreur_systeme != d_es)) &&
484: ((*s_etat_processus).core == d_vrai) &&
485: ((*s_etat_processus)
486: .var_volatile_traitement_sigint == 0))
487: {
488: printf("\n");
489:
490: if ((*s_etat_processus).langue == 'F')
491: {
492: printf("+++Information : "
493: "Génération du fichier rpl-core "
494: "[%d]\n", (int) getpid());
495: }
496: else
497: {
498: printf("+++Information : "
499: "Writing rpl-core file [%d]\n",
500: (int) getpid());
501: }
502:
503: rplcore(s_etat_processus);
504:
505: if ((*s_etat_processus).langue == 'F')
506: {
507: printf("+++Information : "
508: "Processus tracé [%d]\n",
509: (int) getpid());
510: }
511: else
512: {
513: printf("+++Information : Done [%d]\n",
514: (int) getpid());
515: }
516:
517: printf("\n");
518: fflush(stdout);
519: }
520:
521: }
522:
523: if ((*s_etat_processus).debug == d_vrai)
524: if (((*s_etat_processus).type_debug &
525: d_traitement_interruption) != 0)
526: {
527: if ((*s_etat_processus).langue == 'F')
528: {
529: if (processus == d_faux)
530: {
531: printf("[%d] Fin de l'interruption logicielle"
532: " %d en provenance du thread %llu\n",
533: (int) getpid(), i + 1,
534: (unsigned long long) tid);
535: }
536: else
537: {
538: printf("[%d] Fin de l'interruption logicielle"
539: " %d en provenance du processus %d\n",
540: (int) getpid(), i + 1, (int) pid);
541: }
542: }
543: else
544: {
545: if (processus == d_faux)
546: {
547: printf("[%d] Stop software interrupt "
548: "%d from thread "
549: "%llu\n", (int) getpid(), i + 1,
550: (unsigned long long) pid);
551: }
552: else
553: {
554: printf("[%d] Stop software interrupt "
555: "%d from process "
556: "%d\n", (int) getpid(), i + 1,
557: (int) pid);
558: }
559: }
560:
561: fflush(stdout);
562: }
563:
564: if ((drapeau_erreur == d_erreur) &&
565: ((*s_etat_processus).erreur_execution == d_ex))
566: {
567: if (((*s_etat_processus).erreur_execution == d_ex) &&
568: ((*s_etat_processus).erreur_systeme == d_es))
569: {
570: (*s_etat_processus).erreur_execution =
571: d_ex_erreur_evaluation;
572: }
573: }
574: }
575: else
576: {
577: (*s_etat_processus).erreur_execution =
578: d_ex_interruption_invalide;
579: }
580: }
581: }
582: }
583:
584: (*s_etat_processus).traitement_interruption = registre;
585:
586: return;
587: }
588:
589: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>