1: /*
2: ================================================================================
3: RPL/2 (R) version 4.1.30
4: Copyright (C) 1989-2019 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 'alarm'
29: ================================================================================
30: Entrées : pointeur sur une structure struct_processus
31: --------------------------------------------------------------------------------
32: Sorties :
33: --------------------------------------------------------------------------------
34: Effets de bord : néant
35: ================================================================================
36: */
37:
38: void
39: instruction_alarm(struct_processus *s_etat_processus)
40: {
41: double duree;
42:
43: int code_retour;
44: int erreur;
45:
46: integer8 nombre_elements;
47:
48: logical1 specification_date;
49:
50: struct_liste_chainee *l_element_courant;
51:
52: struct_objet *s_objet_argument;
53:
54: struct timeb st;
55:
56: struct timespec attente;
57:
58: struct timeval debut_interruption;
59: struct timeval duree_interruption;
60: struct timeval fin_interruption;
61:
62: struct tm *s_time_actuel;
63: struct tm s_time_alarme;
64: struct tm s_time_registre;
65:
66: time_t alarme;
67:
68: (*s_etat_processus).erreur_execution = d_ex;
69:
70: if ((*s_etat_processus).affichage_arguments == 'Y')
71: {
72: printf("\n ALARM ");
73:
74: if ((*s_etat_processus).langue == 'F')
75: {
76: printf("(suspension du processus jusqu'à un instant spécifié)\n\n");
77: }
78: else
79: {
80: printf("(wait until timestamp)\n\n");
81: }
82:
83: printf(" 1: %s\n\n", d_LST);
84:
85: if ((*s_etat_processus).langue == 'F')
86: {
87: printf(" Utilisation :\n\n");
88: }
89: else
90: {
91: printf(" Usage:\n\n");
92: }
93:
94: printf(" { hours minutes } ALARM\n");
95: printf(" { hours minutes seconds } ALARM\n");
96: printf(" { hours minutes seconds day } ALARM\n");
97: printf(" { hours minutes seconds day month } ALARM\n");
98: printf(" { hours minutes seconds day month year } ALARM\n");
99:
100: return;
101: }
102: else if ((*s_etat_processus).test_instruction == 'Y')
103: {
104: (*s_etat_processus).nombre_arguments = 1;
105: return;
106: }
107:
108: if (test_cfsf(s_etat_processus, 31) == d_vrai)
109: {
110: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
111: {
112: return;
113: }
114: }
115:
116: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
117: &s_objet_argument) == d_erreur)
118: {
119: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
120: return;
121: }
122:
123: if ((*s_objet_argument).type == LST)
124: {
125: l_element_courant = (*s_objet_argument).objet;
126: nombre_elements = 0;
127:
128: while(l_element_courant != NULL)
129: {
130: if ((*(*l_element_courant).donnee).type != INT)
131: {
132: (*s_etat_processus).erreur_execution =
133: d_ex_erreur_type_argument;
134:
135: liberation(s_etat_processus, s_objet_argument);
136: return;
137: }
138:
139: l_element_courant = (*l_element_courant).suivant;
140: nombre_elements++;
141: }
142:
143: if ((nombre_elements < 2) || (nombre_elements > 6))
144: {
145: (*s_etat_processus).erreur_execution =
146: d_ex_argument_invalide;
147:
148: liberation(s_etat_processus, s_objet_argument);
149: return;
150: }
151:
152: st.time = time(NULL);
153: s_time_actuel = localtime(&(st.time));
154:
155: l_element_courant = (*s_objet_argument).objet;
156: s_time_alarme.tm_hour = (int) (*((integer8 *) (*(*l_element_courant)
157: .donnee).objet));
158: l_element_courant = (*l_element_courant).suivant;
159: s_time_alarme.tm_min = (int) (*((integer8 *) (*(*l_element_courant)
160: .donnee).objet));
161: l_element_courant = (*l_element_courant).suivant;
162:
163: specification_date = d_faux;
164:
165: if (l_element_courant != NULL)
166: {
167: s_time_alarme.tm_sec = (int) (*((integer8 *) (*(*l_element_courant)
168: .donnee).objet));
169: l_element_courant = (*l_element_courant).suivant;
170:
171: if (l_element_courant != NULL)
172: {
173: specification_date = d_vrai;
174:
175: s_time_alarme.tm_mday = (int) (*((integer8 *)
176: (*(*l_element_courant).donnee).objet));
177: l_element_courant = (*l_element_courant).suivant;
178:
179: if (l_element_courant != NULL)
180: {
181: s_time_alarme.tm_mon = (int) ((*((integer8 *)
182: (*(*l_element_courant).donnee).objet)) - 1);
183: l_element_courant = (*l_element_courant).suivant;
184:
185: if (l_element_courant != NULL)
186: {
187: s_time_alarme.tm_year = (int) ((*((integer8 *)
188: (*(*l_element_courant).donnee).objet))
189: - 1900);
190: l_element_courant = (*l_element_courant).suivant;
191: }
192: else
193: {
194: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
195: }
196: }
197: else
198: {
199: s_time_alarme.tm_mon = (*s_time_actuel).tm_mon;
200: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
201: }
202: }
203: else
204: {
205: s_time_alarme.tm_mday = (*s_time_actuel).tm_mday;
206: s_time_alarme.tm_mon = (*s_time_actuel).tm_mon;
207: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
208: }
209: }
210: else
211: {
212: s_time_alarme.tm_sec = 0;
213: s_time_alarme.tm_mday = (*s_time_actuel).tm_mday;
214: s_time_alarme.tm_mon = (*s_time_actuel).tm_mon;
215: s_time_alarme.tm_year = (*s_time_actuel).tm_year;
216: }
217:
218: s_time_alarme.tm_isdst = -1;
219: s_time_registre = s_time_alarme;
220: alarme = mktime(&s_time_alarme);
221:
222: if ((s_time_alarme.tm_sec != s_time_registre.tm_sec) ||
223: (s_time_alarme.tm_min != s_time_registre.tm_min) ||
224: (s_time_alarme.tm_hour != s_time_registre.tm_hour) ||
225: (s_time_alarme.tm_mday != s_time_registre.tm_mday) ||
226: (s_time_alarme.tm_mon != s_time_registre.tm_mon) ||
227: (s_time_alarme.tm_year != s_time_registre.tm_year))
228: {
229: (*s_etat_processus).erreur_execution =
230: d_ex_argument_invalide;
231:
232: liberation(s_etat_processus, s_objet_argument);
233: return;
234: }
235:
236: while((duree = difftime(alarme, st.time)) < 0)
237: {
238: if (specification_date == d_vrai)
239: {
240: (*s_etat_processus).erreur_execution =
241: d_ex_argument_invalide;
242:
243: liberation(s_etat_processus, s_objet_argument);
244: return;
245: }
246:
247: s_time_alarme.tm_mday++;
248: alarme = mktime(&s_time_alarme);
249: }
250:
251: attente.tv_nsec = (long) ((duree - (double) (attente.tv_sec =
252: (time_t) floor(duree))) * 1000000000);
253:
254: if ((*s_etat_processus).profilage == d_vrai)
255: {
256: profilage(s_etat_processus, "Sleep function (ALARM)");
257:
258: if ((*s_etat_processus).erreur_systeme != d_es)
259: {
260: return;
261: }
262: }
263:
264: do
265: {
266: code_retour = nanosleep(&attente, &attente);
267: erreur = errno;
268:
269: if (code_retour == -1)
270: {
271: gettimeofday(&debut_interruption, NULL);
272:
273: scrutation_injection(s_etat_processus);
274:
275: if (pthread_mutex_lock(&((*s_etat_processus)
276: .mutex_interruptions)) != 0)
277: {
278: (*s_etat_processus).erreur_systeme = d_es_processus;
279: return;
280: }
281:
282: if ((*s_etat_processus).nombre_interruptions_non_affectees != 0)
283: {
284: affectation_interruptions_logicielles(s_etat_processus);
285: }
286:
287: if (pthread_mutex_unlock(&((*s_etat_processus)
288: .mutex_interruptions)) != 0)
289: {
290: (*s_etat_processus).erreur_systeme = d_es_processus;
291: return;
292: }
293:
294: if ((*s_etat_processus).nombre_interruptions_en_queue != 0)
295: {
296: traitement_interruptions_logicielles(s_etat_processus);
297: }
298:
299: gettimeofday(&fin_interruption, NULL);
300:
301: if (fin_interruption.tv_usec < debut_interruption.tv_usec)
302: {
303: duree_interruption.tv_usec = (1000000
304: + fin_interruption.tv_usec)
305: - debut_interruption.tv_usec;
306: duree_interruption.tv_sec = fin_interruption.tv_sec
307: - (debut_interruption.tv_sec + 1);
308: }
309: else
310: {
311: duree_interruption.tv_usec = fin_interruption.tv_usec
312: - debut_interruption.tv_usec;
313: duree_interruption.tv_sec = fin_interruption.tv_sec
314: - debut_interruption.tv_sec;
315: }
316:
317: if (attente.tv_nsec < (1000 * duree_interruption.tv_usec))
318: {
319: attente.tv_nsec = (1000000000 + attente.tv_nsec)
320: - (1000 * duree_interruption.tv_usec);
321: attente.tv_sec = attente.tv_sec
322: - (duree_interruption.tv_sec + 1);
323: }
324: else
325: {
326: attente.tv_nsec = attente.tv_nsec
327: - (1000 * duree_interruption.tv_usec);
328: attente.tv_sec = attente.tv_sec
329: - duree_interruption.tv_sec;
330: }
331:
332: if (attente.tv_sec < 0)
333: {
334: code_retour = 0;
335: }
336: }
337: } while(((code_retour == -1) && (erreur == EINTR))
338: && ((*s_etat_processus).var_volatile_requete_arret == 0));
339:
340: if ((*s_etat_processus).profilage == d_vrai)
341: {
342: profilage(s_etat_processus, NULL);
343: }
344: }
345: else
346: {
347: liberation(s_etat_processus, s_objet_argument);
348:
349: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
350: return;
351: }
352:
353: liberation(s_etat_processus, s_objet_argument);
354: return;
355: }
356:
357:
358: /*
359: ================================================================================
360: Fonction 'atexit'
361: ================================================================================
362: Entrées :
363: --------------------------------------------------------------------------------
364: Sorties :
365: --------------------------------------------------------------------------------
366: Effets de bord : néant
367: ================================================================================
368: */
369:
370: void
371: instruction_atexit(struct_processus *s_etat_processus)
372: {
373: struct_objet *s_objet_argument;
374:
375: (*s_etat_processus).erreur_execution = d_ex;
376:
377: if ((*s_etat_processus).affichage_arguments == 'Y')
378: {
379: printf("\n ATEXIT ");
380:
381: if ((*s_etat_processus).langue == 'F')
382: {
383: printf("(exécution d'une fonction à la sortie d'une tâche)\n\n");
384: }
385: else
386: {
387: printf("(register a function to be called on task exit)\n\n");
388: }
389:
390: printf(" 1: %s, %s\n", d_NOM, d_RPN);
391:
392: return;
393: }
394: else if ((*s_etat_processus).test_instruction == 'Y')
395: {
396: (*s_etat_processus).nombre_arguments = 1;
397: return;
398: }
399:
400: if (test_cfsf(s_etat_processus, 31) == d_vrai)
401: {
402: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
403: {
404: return;
405: }
406: }
407:
408: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
409: &s_objet_argument) == d_erreur)
410: {
411: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
412: return;
413: }
414:
415: if ((*s_objet_argument).type == NOM)
416: {
417: liberation(s_etat_processus, (*s_etat_processus).at_exit);
418: (*s_etat_processus).at_exit = s_objet_argument;
419: }
420: else if ((*s_objet_argument).type == RPN)
421: {
422: liberation(s_etat_processus, (*s_etat_processus).at_exit);
423: (*s_etat_processus).at_exit = s_objet_argument;
424: }
425: else
426: {
427: liberation(s_etat_processus, s_objet_argument);
428:
429: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
430: return;
431: }
432:
433: return;
434: }
435:
436:
437: /*
438: ================================================================================
439: Fonction 'atpoke'
440: ================================================================================
441: Entrées :
442: --------------------------------------------------------------------------------
443: Sorties :
444: --------------------------------------------------------------------------------
445: Effets de bord : néant
446: ================================================================================
447: */
448:
449: void
450: instruction_atpoke(struct_processus *s_etat_processus)
451: {
452: struct_objet *s_objet_argument;
453:
454: (*s_etat_processus).erreur_execution = d_ex;
455:
456: if ((*s_etat_processus).affichage_arguments == 'Y')
457: {
458: printf("\n ATPOKE ");
459:
460: if ((*s_etat_processus).langue == 'F')
461: {
462: printf("(exécution d'une fonction lors de l'injection "
463: "d'une donnée)\n\n");
464: }
465: else
466: {
467: printf("(register a function to be called on data injection)\n\n");
468: }
469:
470: printf(" 1: %s, %s\n", d_NOM, d_RPN);
471:
472: return;
473: }
474: else if ((*s_etat_processus).test_instruction == 'Y')
475: {
476: (*s_etat_processus).nombre_arguments = 1;
477: return;
478: }
479:
480: if (test_cfsf(s_etat_processus, 31) == d_vrai)
481: {
482: if (empilement_pile_last(s_etat_processus, 1) == d_erreur)
483: {
484: return;
485: }
486: }
487:
488: if (depilement(s_etat_processus, &((*s_etat_processus).l_base_pile),
489: &s_objet_argument) == d_erreur)
490: {
491: (*s_etat_processus).erreur_execution = d_ex_manque_argument;
492: return;
493: }
494:
495: if ((*s_objet_argument).type == NOM)
496: {
497: liberation(s_etat_processus, (*s_etat_processus).at_poke);
498: (*s_etat_processus).at_poke = s_objet_argument;
499: }
500: else if ((*s_objet_argument).type == RPN)
501: {
502: liberation(s_etat_processus, (*s_etat_processus).at_poke);
503: (*s_etat_processus).at_poke = s_objet_argument;
504: }
505: else
506: {
507: liberation(s_etat_processus, s_objet_argument);
508:
509: (*s_etat_processus).erreur_execution = d_ex_erreur_type_argument;
510: return;
511: }
512:
513: return;
514: }
515:
516: // vim: ts=4
CVSweb interface <joel.bertrand@systella.fr>