This repository has been archived on 2026-03-24. You can view files and clone it. You cannot open issues or pull requests or push a commit.
Files
TP-TR/chap1/ex3.c
vandechat96 8e00fb77dd ex chap 1
2022-05-10 22:45:38 +02:00

147 lines
3.6 KiB
C

#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <unistd.h>
#define SIGRT_READY (SIGRTMIN +3)
#define SIGRT_START (SIGRTMIN +2)
#define SIGRT_CHILD (SIGRTMIN +1)
#define SIGRT_FINAL (SIGRTMIN +0)
#define __START__ 0
#define PREPARING 1
#define EXPECTING 2
#define RECIEVING 3
#define OPERATING 4
#define __FINAL__ 5
sigset_t mask ;
volatile sig_atomic_t state = __START__ ;
union sigval envelope;
struct sigaction descriptor;
volatile sig_atomic_t state_child1 = __START__ ;
volatile sig_atomic_t state_child2 = __START__ ;
volatile sig_atomic_t recieved_sigrts = 0 ;
pid_t child1,child2;
void handleStart(int signum, siginfo_t *info, void *unused) {
printf("recieved start\n");
state = OPERATING;
sigaddset(& mask , SIGRT_START );
sigprocmask(SIG_SETMASK, &mask , NULL);
}
void handleReady(int signum, siginfo_t *info, void *unused) {
printf("recieved ready\n");
if (info->si_pid == child1) state_child1 = EXPECTING;
if (info->si_pid == child2) state_child2 = EXPECTING;
}
void handleChild(int signum, siginfo_t *info, void *unused) {
printf("recieved %d\n",info->si_value.sival_int);
recieved_sigrts++;
}
void handleFinal(int signum, siginfo_t *info, void *unused) {
printf("recieved final\n");
state = __FINAL__ ;
sigaddset(& mask , SIGRT_FINAL );
sigprocmask(SIG_SETMASK, &mask, NULL);
}
void parentBehavior(){
sigdelset(&mask,SIGRT_READY);
sigprocmask(SIG_SETMASK, &mask, NULL);
printf("parent expecting\n");
while (state_child1 != EXPECTING || state_child2 != EXPECTING)
pause();
state = RECIEVING;
sigaddset(&mask,SIGRT_READY);
sigdelset(&mask,SIGRT_CHILD);
sigprocmask(SIG_SETMASK, &mask, NULL);
sigqueue(child1, SIGRT_START, envelope);
sigqueue(child2, SIGRT_START, envelope);
printf("parent recieving\n");
while (recieved_sigrts < 20)
pause();
printf("parent recieved 20 sig\n");
state = __FINAL__;
sigaddset(&mask,SIGRT_CHILD);
sigprocmask(SIG_SETMASK, &mask, NULL);
sigqueue(child1, SIGRT_FINAL, envelope);
sigqueue(child2, SIGRT_FINAL, envelope);
exit(EXIT_SUCCESS);
}
void childBehavior(pid_t parent, useconds_t delay){
srand(getpid() * time(0));
sigqueue(parent, SIGRT_READY, envelope);
state = EXPECTING;
printf("child expecting\n");
sigdelset(&mask, SIGRT_START);
sigprocmask(SIG_SETMASK, &mask, NULL);
while (state == EXPECTING)
pause();
sigdelset(&mask, SIGRT_FINAL);
sigprocmask(SIG_SETMASK, &mask, NULL);
printf("child operating\n");
while (state == OPERATING) {
envelope.sival_int = rand() % 100;
sigqueue(parent, SIGRT_CHILD, envelope);
struct timespec request = {0, delay}, remaining;
clock_nanosleep(CLOCK_MONOTONIC, 0,&request, &remaining);
}
exit(EXIT_SUCCESS);
}
int main (int argc, char *argv[]){
printf("lauching\n");
sigfillset(&mask);
sigprocmask(SIG_SETMASK , &mask, NULL);
descriptor.sa_flags = SA_SIGINFO;
descriptor.sa_sigaction = handleStart;
sigaction(SIGRT_START, &descriptor, NULL);
descriptor.sa_sigaction = handleFinal;
sigaction(SIGRT_FINAL, &descriptor, NULL);
descriptor.sa_sigaction = handleReady;
sigaction(SIGRT_READY, &descriptor, NULL);
descriptor.sa_sigaction = handleChild;
sigaction(SIGRT_CHILD, &descriptor, NULL);
child1 = fork();
if (child1 == 0)
childBehavior(getppid(), 2e5);
else {
child2 = fork();
if (child2 == 0)
childBehavior(getppid(),3e5);
else
parentBehavior();
}
}