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