Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <stdio.h>
- #include <stdlib.h>
- #include <unistd.h>
- #include <errno.h>
- #include <time.h>
- #include <string.h>
- #include <signal.h>
- #include <sys/types.h>
- #include <sys/wait.h>
- #include <sys/sem.h>
- #include <sys/ipc.h>
- #include <sys/msg.h>
- #include <sys/shm.h>
- #define POP_SIZE 4
- #define TEXT_LEN 32
- #define TEST_ERROR if (errno) {dprintf(STDERR_FILENO, \
- "%s:%d: PID=%5d: Error %d (%s)\n", \
- __FILE__, \
- __LINE__, \
- getpid(), \
- errno, \
- strerror(errno));}
- typedef int bool;
- #define true 1
- #define false 0
- typedef struct student {
- int matricola;
- int voto_AdE;
- int nof_elems;
- bool member;
- } student;
- struct shared_data {
- unsigned int idx;
- student students[];
- };
- struct msgbuf {
- long mtype;
- char mtext[TEXT_LEN];
- };
- int msg_send(int queue, const struct msgbuf*, size_t msg_length);
- void make_student();
- void make_groups();
- void handle_signal(int signal);
- void start_timer(int sim_time);
- int s_id, m_id, turn1, turn2;
- struct shared_data * my_data;
- struct sembuf sops;
- struct msgbuf my_msg;
- struct sigaction sa;
- sigset_t my_mask;
- int main() {
- sa.sa_handler = handle_signal;
- sa.sa_flags = 0;
- sigemptyset(&my_mask);
- sa.sa_mask = my_mask;
- sigaction(SIGTERM, &sa, NULL);
- s_id = semget(IPC_PRIVATE, 2, 0600);
- TEST_ERROR;
- semctl(s_id, 0, SETVAL, 0);
- sops.sem_num = 0;
- m_id = shmget(IPC_PRIVATE, sizeof(*my_data), 0600);
- TEST_ERROR;
- my_data = shmat(m_id, NULL, 0);
- TEST_ERROR
- turn1 = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | 0600);
- turn2 = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | 0600);
- TEST_ERROR;
- my_data->idx = 0;
- for(int i = 0; i < POP_SIZE; i++){
- make_student();
- }
- sops.sem_num = 1;
- sops.sem_op = -POP_SIZE;
- semop(s_id, &sops, 1);
- start_timer(1);
- sleep(2);
- semctl(s_id, 0, IPC_RMID);
- shmdt(my_data);
- shmctl(m_id, IPC_RMID, NULL);
- msgctl(turn1, IPC_RMID, NULL);
- msgctl(turn2, IPC_RMID, NULL);
- raise(SIGKILL);
- return 0;
- }
- void make_student() {
- student new_student;
- int i;
- new_student.voto_AdE = rand() % 13 + 18;
- switch (fork()) {
- case -1:
- TEST_ERROR;
- break;
- case 0:
- i = my_data->idx;
- new_student.matricola = getpid();
- new_student.nof_elems = rand() % 3 + 2;
- my_data->students[i].matricola = new_student.matricola;
- my_data->students[i].voto_AdE = new_student.voto_AdE;
- my_data->students[i].nof_elems = new_student.nof_elems;
- my_data->students[i].member = false;
- my_data->idx++;
- printf("Studente: Matricola = %d, Voto = %d, Numero elementi = %d, PID Padre = %d\n",
- my_data->students[i].matricola, my_data->students[i].voto_AdE, my_data->students[i].nof_elems, getppid());
- sops.sem_num = 0;
- if(i == POP_SIZE-1) {
- sops.sem_op = POP_SIZE;
- semop(s_id, &sops, 1);
- } else {
- sops.sem_op = -1;
- semop(s_id, &sops, 1);
- }
- // printf("%d - Sem value: %d\n", i, semctl(s_id, i, GETVAL));
- make_groups(i);
- sops.sem_num = 1;
- sops.sem_op = 1;
- semop(s_id, &sops, 1);
- exit(0);
- default:
- break;
- }
- }
- void make_groups(int k) {
- int nof_invites, rem_invites, max_reject, queue, vote;
- nof_invites = 1;
- rem_invites = nof_invites;
- printf("Indice: %d\n", k);
- for(int i = 0; i < POP_SIZE; i++)
- printf("%d\n", my_data->students[i].matricola);
- while(rem_invites > 0 && my_data->students[k].member == false) {
- vote = my_data->students[k].voto_AdE;
- int i = 0;
- int j = 0;
- while(i < POP_SIZE){
- if(my_data->students[i].member == false && my_data->students[i].matricola != getpid()) {
- if(rem_invites < nof_invites / 2) {
- if(my_data->students[k].nof_elems == my_data->students[i].nof_elems) {
- if(vote <= my_data->students[i].voto_AdE) {
- vote = my_data->students[i].voto_AdE;
- j = i;
- i++;
- } else
- i++;
- } else
- i++;
- } else {
- if(vote <= my_data->students[i].voto_AdE) {
- vote = my_data->students[i].voto_AdE;
- j = i;
- i++;
- } else
- i++;
- }
- } else
- i++;
- }
- my_msg.mtype = my_data->students[j].matricola;
- sprintf(my_msg.mtext, "invite");
- printf("%d, %s - %li\n", getpid(), my_msg.mtext, my_msg.mtype);
- /*if(getpid() % 2 == 0)
- /msg_send(turn1, &my_msg, sizeof(my_msg)-sizeof(long));
- else
- msg_send(turn2, &my_msg, sizeof(my_msg)-sizeof(long));
- */
- rem_invites--;
- }
- }
- void start_timer(int sim_time) {
- sigaction(SIGALRM, &sa, NULL);
- alarm(sim_time);
- }
- void handle_signal(int signal) {
- if(signal == SIGALRM) {
- printf("Tempo scaduto\n");
- } else if(signal == SIGKILL) {
- printf("Terminato");
- semctl(s_id, 0, IPC_RMID);
- shmdt(my_data);
- shmctl(m_id, IPC_RMID, NULL);
- msgctl(turn1, IPC_RMID, NULL);
- msgctl(turn2, IPC_RMID, NULL);
- raise(SIGKILL);
- }
- }
- int msg_send(int queue, const struct msgbuf* my_msg, size_t msg_length) {
- msgsnd(queue, my_msg, msg_length, 0);
- switch (errno) {
- case EAGAIN:
- dprintf(STDERR_FILENO,
- "Queue is full and IPC_NOWAIT was set to have a non-blocking msgsnd()\n\
- Fix it by:\n \
- (1) making sure that some process read messages, or\n \
- (2) changing the queue size by msgctl()\n");
- return(-1);
- case EACCES:
- dprintf(STDERR_FILENO,
- "No write permission to the queue.\n\
- Fix it by adding permissions properly\n");
- return(-1);
- case EFAULT:
- dprintf(STDERR_FILENO,
- "The address of the message isn't accessible\n");
- return(-1);
- case EIDRM:
- dprintf(STDERR_FILENO,
- "The queue was removed\n");
- return(-1);
- case EINTR:
- dprintf(STDERR_FILENO,
- "The process got unblocked by a signal, while waiting on a full queue\n");
- return(-1);
- case EINVAL:
- TEST_ERROR;
- return(-1);
- case ENOMEM:
- TEST_ERROR;
- return(-1);
- default:
- TEST_ERROR;
- }
- return(0);
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement