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