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