Advertisement
Guest User

Untitled

a guest
Jan 16th, 2019
59
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 7.00 KB | None | 0 0
  1. #include <stdio.h>
  2. #include <stdlib.h>
  3. #include <unistd.h>
  4. #include <errno.h>
  5. #include <time.h>
  6. #include <string.h>
  7. #include <signal.h>
  8. #include <sys/types.h>
  9. #include <sys/wait.h>
  10. #include <sys/sem.h>
  11. #include <sys/ipc.h>
  12. #include <sys/msg.h>
  13. #include <sys/shm.h>
  14.  
  15. #define POP_SIZE 4
  16. #define TEXT_LEN 32
  17. #define TEST_ERROR if (errno) {dprintf(STDERR_FILENO, \
  18. "%s:%d: PID=%5d: Error %d (%s)\n", \
  19. __FILE__, \
  20. __LINE__, \
  21. getpid(), \
  22. errno, \
  23. strerror(errno));}
  24.  
  25. typedef int bool;
  26. #define true 1
  27. #define false 0
  28.  
  29. typedef struct student {
  30. int matricola;
  31. int voto_AdE;
  32. int nof_elems;
  33. bool member;
  34. } student;
  35.  
  36. struct shared_data {
  37. unsigned int idx;
  38. student students[];
  39. };
  40.  
  41. struct msgbuf {
  42. long mtype;
  43. char mtext[TEXT_LEN];
  44. };
  45.  
  46. int msg_send(int queue, const struct msgbuf*, size_t msg_length);
  47.  
  48. void make_student();
  49.  
  50. void make_groups();
  51.  
  52. void handle_signal(int signal);
  53.  
  54. void start_timer(int sim_time);
  55.  
  56. int s_id, m_id, turn1, turn2;
  57. struct shared_data * my_data;
  58. struct sembuf sops;
  59. struct msgbuf my_msg;
  60. struct sigaction sa;
  61. sigset_t my_mask;
  62.  
  63.  
  64. int main() {
  65. sa.sa_handler = handle_signal;
  66. sa.sa_flags = 0;
  67. sigemptyset(&my_mask);
  68. sa.sa_mask = my_mask;
  69. sigaction(SIGTERM, &sa, NULL);
  70.  
  71. s_id = semget(IPC_PRIVATE, 2, 0600);
  72. TEST_ERROR;
  73. semctl(s_id, 0, SETVAL, 0);
  74. sops.sem_num = 0;
  75.  
  76. m_id = shmget(IPC_PRIVATE, sizeof(*my_data), 0600);
  77. TEST_ERROR;
  78. my_data = shmat(m_id, NULL, 0);
  79. TEST_ERROR
  80.  
  81. turn1 = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | 0600);
  82. turn2 = msgget(IPC_PRIVATE, IPC_CREAT | IPC_EXCL | 0600);
  83. TEST_ERROR;
  84.  
  85. my_data->idx = 0;
  86.  
  87. for(int i = 0; i < POP_SIZE; i++){
  88. make_student();
  89. }
  90.  
  91. sops.sem_num = 1;
  92. sops.sem_op = -POP_SIZE;
  93. semop(s_id, &sops, 1);
  94. start_timer(1);
  95. sleep(2);
  96.  
  97. semctl(s_id, 0, IPC_RMID);
  98. shmdt(my_data);
  99. shmctl(m_id, IPC_RMID, NULL);
  100. msgctl(turn1, IPC_RMID, NULL);
  101. msgctl(turn2, IPC_RMID, NULL);
  102. raise(SIGKILL);
  103. return 0;
  104. }
  105.  
  106. void make_student() {
  107. student new_student;
  108. int i;
  109.  
  110. new_student.voto_AdE = rand() % 13 + 18;
  111. switch (fork()) {
  112. case -1:
  113. TEST_ERROR;
  114. break;
  115.  
  116. case 0:
  117. i = my_data->idx;
  118. new_student.matricola = getpid();
  119. new_student.nof_elems = rand() % 3 + 2;
  120. my_data->students[i].matricola = new_student.matricola;
  121. my_data->students[i].voto_AdE = new_student.voto_AdE;
  122. my_data->students[i].nof_elems = new_student.nof_elems;
  123. my_data->students[i].member = false;
  124. my_data->idx++;
  125. printf("Studente: Matricola = %d, Voto = %d, Numero elementi = %d, PID Padre = %d\n",
  126. my_data->students[i].matricola, my_data->students[i].voto_AdE, my_data->students[i].nof_elems, getppid());
  127. sops.sem_num = 0;
  128. if(i == POP_SIZE-1) {
  129. sops.sem_op = POP_SIZE;
  130. semop(s_id, &sops, 1);
  131. } else {
  132. sops.sem_op = -1;
  133. semop(s_id, &sops, 1);
  134. }
  135. // printf("%d - Sem value: %d\n", i, semctl(s_id, i, GETVAL));
  136. make_groups(i);
  137. sops.sem_num = 1;
  138. sops.sem_op = 1;
  139. semop(s_id, &sops, 1);
  140. exit(0);
  141.  
  142. default:
  143. break;
  144. }
  145.  
  146. }
  147.  
  148. void make_groups(int k) {
  149.  
  150. int nof_invites, rem_invites, max_reject, queue, vote;
  151. nof_invites = 1;
  152. rem_invites = nof_invites;
  153. printf("Indice: %d\n", k);
  154. for(int i = 0; i < POP_SIZE; i++)
  155. printf("%d\n", my_data->students[i].matricola);
  156. while(rem_invites > 0 && my_data->students[k].member == false) {
  157. vote = my_data->students[k].voto_AdE;
  158. int i = 0;
  159. int j = 0;
  160. while(i < POP_SIZE){
  161. if(my_data->students[i].member == false && my_data->students[i].matricola != getpid()) {
  162. if(rem_invites < nof_invites / 2) {
  163. if(my_data->students[k].nof_elems == my_data->students[i].nof_elems) {
  164. if(vote <= my_data->students[i].voto_AdE) {
  165. vote = my_data->students[i].voto_AdE;
  166. j = i;
  167. i++;
  168. } else
  169. i++;
  170. } else
  171. i++;
  172. } else {
  173. if(vote <= my_data->students[i].voto_AdE) {
  174. vote = my_data->students[i].voto_AdE;
  175. j = i;
  176. i++;
  177. } else
  178. i++;
  179. }
  180. } else
  181. i++;
  182. }
  183. my_msg.mtype = my_data->students[j].matricola;
  184. sprintf(my_msg.mtext, "invite");
  185. printf("%d, %s - %li\n", getpid(), my_msg.mtext, my_msg.mtype);
  186. /*if(getpid() % 2 == 0)
  187. /msg_send(turn1, &my_msg, sizeof(my_msg)-sizeof(long));
  188. else
  189. msg_send(turn2, &my_msg, sizeof(my_msg)-sizeof(long));
  190. */
  191. rem_invites--;
  192. }
  193.  
  194. }
  195.  
  196. void start_timer(int sim_time) {
  197. sigaction(SIGALRM, &sa, NULL);
  198. alarm(sim_time);
  199. }
  200.  
  201. void handle_signal(int signal) {
  202. if(signal == SIGALRM) {
  203. printf("Tempo scaduto\n");
  204. } else if(signal == SIGKILL) {
  205. printf("Terminato");
  206. semctl(s_id, 0, IPC_RMID);
  207. shmdt(my_data);
  208. shmctl(m_id, IPC_RMID, NULL);
  209. msgctl(turn1, IPC_RMID, NULL);
  210. msgctl(turn2, IPC_RMID, NULL);
  211. raise(SIGKILL);
  212. }
  213. }
  214.  
  215. int msg_send(int queue, const struct msgbuf* my_msg, size_t msg_length) {
  216.  
  217. msgsnd(queue, my_msg, msg_length, 0);
  218. switch (errno) {
  219. case EAGAIN:
  220. dprintf(STDERR_FILENO,
  221. "Queue is full and IPC_NOWAIT was set to have a non-blocking msgsnd()\n\
  222. Fix it by:\n \
  223. (1) making sure that some process read messages, or\n \
  224. (2) changing the queue size by msgctl()\n");
  225. return(-1);
  226. case EACCES:
  227. dprintf(STDERR_FILENO,
  228. "No write permission to the queue.\n\
  229. Fix it by adding permissions properly\n");
  230. return(-1);
  231. case EFAULT:
  232. dprintf(STDERR_FILENO,
  233. "The address of the message isn't accessible\n");
  234. return(-1);
  235. case EIDRM:
  236. dprintf(STDERR_FILENO,
  237. "The queue was removed\n");
  238. return(-1);
  239. case EINTR:
  240. dprintf(STDERR_FILENO,
  241. "The process got unblocked by a signal, while waiting on a full queue\n");
  242. return(-1);
  243. case EINVAL:
  244. TEST_ERROR;
  245. return(-1);
  246. case ENOMEM:
  247. TEST_ERROR;
  248. return(-1);
  249. default:
  250. TEST_ERROR;
  251. }
  252. return(0);
  253. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement