TA043

Sistemas Operativos (TA043)
Index Commits Files Refs
pract/process_pingpong.c (3116B)
   1 /*
   2  * Process Ping Pong
   3  * Martin Klöckner - mklockner@fi.uba.ar
   4  *
   5  * Based on examples given in wait(2) man page
   6  */
   7 
   8 #include <stdio.h>
   9 #include <stdlib.h>
  10 #include <string.h>
  11 #include <sys/wait.h>
  12 #include <stdint.h>
  13 #include <time.h>
  14 #include <unistd.h>
  15 
  16 #define LOG_ENABLE     true
  17 #define PIPE_READ_END  0
  18 #define PIPE_WRITE_END 1
  19 #define DELAY_MS       100
  20 
  21 #if true == LOG_ENABLE
  22 #define LOG(fmt, ...) do {                  \
  23         printf("[LOG] "fmt"\n", ##__VA_ARGS__); \
  24     } while (0)
  25 #define LOG_ID(fmt, ...) do {                                \
  26         printf("[LOG][%ld] "fmt"\n", proc_count, ##__VA_ARGS__); \
  27     } while (0)
  28 #else
  29 #define LOG(fmt, ...)
  30 #define PROC_LOG(fmt, ...)
  31 #endif
  32 
  33 void sleep_ms(long ms)
  34 {
  35     struct timespec ts = {
  36         .tv_sec = ms / 1000,
  37         .tv_nsec = (ms % 1000) * 1000000L
  38     };
  39 
  40     nanosleep(&ts, NULL);
  41 }
  42 
  43 /*
  44  * Parent ===pipefd_1===> Child
  45  * Parent <==pipefd_2==== Child
  46  */
  47 
  48 int main (void)
  49 {
  50     int wstatus, cpid, proc_count;
  51     int pipefd_1[2], pipefd_2[2];
  52     uint32_t ball;
  53 
  54     proc_count = 0;
  55     ball = 0;
  56 
  57     if ((pipe(pipefd_1) == -1) || (pipe(pipefd_2) == -1))
  58     {
  59         perror("pipe");
  60         exit(EXIT_FAILURE);
  61     }
  62 
  63     cpid = fork();
  64 
  65     if (cpid == -1)
  66     {
  67         perror("fork");
  68         exit(EXIT_FAILURE);
  69     }
  70 
  71     if (cpid == 0)
  72     {
  73         // Child
  74         proc_count++;
  75         LOG_ID("PID is %jd", (intmax_t) getpid());
  76         sleep_ms(DELAY_MS);
  77 
  78         if (close(pipefd_1[PIPE_WRITE_END]) == -1)
  79         {
  80             // Close unused pipefd_1 write end
  81             perror("close");
  82             exit(EXIT_FAILURE);
  83         }
  84 
  85         if (close(pipefd_2[PIPE_READ_END]) == -1)
  86         {
  87             // Close unused pipefd_2 read end
  88             perror("close");
  89             exit(EXIT_FAILURE);
  90         }
  91 
  92         while (true)
  93         {
  94             // Wait for response from the other end
  95             while (read(pipefd_1[PIPE_READ_END], &ball, sizeof(ball)) <= 0)
  96             {
  97                 ;
  98             }
  99             sleep_ms(DELAY_MS);
 100 
 101             ball++;
 102             LOG_ID("%d", ball);
 103             write(pipefd_2[PIPE_WRITE_END], &ball, sizeof(ball));
 104         }
 105 
 106         exit(EXIT_SUCCESS);
 107     }
 108     else
 109     {
 110         // Parent
 111         LOG_ID("PID is %jd", (intmax_t) getpid());
 112         sleep_ms(DELAY_MS);
 113 
 114         if (close(pipefd_1[PIPE_READ_END]) == -1)
 115         {
 116             // Close unused pipefd_1 read end
 117             perror("close");
 118             exit(EXIT_FAILURE);
 119         }
 120 
 121         if (close(pipefd_2[PIPE_WRITE_END]) == -1)
 122         {
 123             // Close unused pipefd_2 write end
 124             perror("close");
 125             exit(EXIT_FAILURE);
 126         }
 127 
 128         while (true)
 129         {
 130             ball++;
 131             LOG_ID("%d", ball);
 132             write(pipefd_1[PIPE_WRITE_END], &ball, sizeof(ball));
 133 
 134             // Wait for response from the other end
 135             while (read(pipefd_2[PIPE_READ_END], &ball, sizeof(ball)) <= 0)
 136             {
 137                 ;
 138             }
 139 
 140             sleep_ms(DELAY_MS);
 141         }
 142 
 143         exit(EXIT_SUCCESS);
 144     }
 145 
 146     exit(EXIT_SUCCESS);
 147 }