TA043

Sistemas Operativos (TA043)
Index Commits Files Refs
commit 3bf497ca1d55d7fea7cb032de44561cf0fac14f9
parent 65edaf3b3b0ea2d26bed884549b29b9e6b01a768
Author: Martin Kloeckner <mjkloeckner@gmail.com>
Date:   Fri, 21 Aug 2026 21:56:51 -0300

Add `process_pingpong`

Diffstat:
Aejs/process_pingpong.c | 146+++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 146 insertions(+), 0 deletions(-)
diff --git a/ejs/process_pingpong.c b/ejs/process_pingpong.c
@@ -0,0 +1,146 @@
+/*
+ * Process Ping Pong
+ * Martin Klöckner - mklockner@fi.uba.ar
+ *
+ * Based on examples given in wait(2) man page
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/wait.h>
+#include <stdint.h>
+#include <time.h>
+#include <unistd.h>
+
+#define LOG_ENABLE     true
+#define PIPE_READ_END  0
+#define PIPE_WRITE_END 1
+
+#if true == LOG_ENABLE
+#define LOG(fmt, ...) do {                  \
+        printf("[LOG] "fmt"\n", ##__VA_ARGS__); \
+    } while (0)
+#define LOG_ID(fmt, ...) do {                                \
+        printf("[LOG][%ld] "fmt"\n", proc_count, ##__VA_ARGS__); \
+    } while (0)
+#else
+#define LOG(fmt, ...)
+#define PROC_LOG(fmt, ...)
+#endif
+
+void sleep_ms(long ms)
+{
+    struct timespec ts = {
+        .tv_sec = ms / 1000,
+        .tv_nsec = (ms % 1000) * 1000000L
+    };
+
+    nanosleep(&ts, NULL);
+}
+
+/*
+ * Parent ===pipefd_1===> Child
+ * Parent <==pipefd_2==== Child
+ */
+
+int main (void)
+{
+    int wstatus, cpid, proc_count;
+    int pipefd_1[2], pipefd_2[2];
+    uint32_t ball;
+
+    proc_count = 0;
+    ball = 0;
+
+    if ((pipe(pipefd_1) == -1) || (pipe(pipefd_2) == -1))
+    {
+        perror("pipe");
+        exit(EXIT_FAILURE);
+    }
+
+    cpid = fork();
+
+    if (cpid == -1)
+    {
+        perror("fork");
+        exit(EXIT_FAILURE);
+    }
+
+    if (cpid == 0)
+    {
+        // Child
+        proc_count++;
+        LOG_ID("PID is %jd", (intmax_t) getpid());
+        sleep_ms(1000);
+
+        if (close(pipefd_1[PIPE_WRITE_END]) == -1)
+        {
+            // Close unused pipefd_1 write end
+            perror("close");
+            exit(EXIT_FAILURE);
+        }
+
+        if (close(pipefd_2[PIPE_READ_END]) == -1)
+        {
+            // Close unused pipefd_2 read end
+            perror("close");
+            exit(EXIT_FAILURE);
+        }
+
+        while (true)
+        {
+            // Wait for response from the other end
+            while (read(pipefd_1[PIPE_READ_END], &ball, 1) <= 0)
+            {
+                ;
+            }
+            sleep_ms(1000);
+
+            ball++;
+            LOG_ID("%d", ball);
+            write(pipefd_2[PIPE_WRITE_END], &ball, 1);
+        }
+
+        exit(EXIT_SUCCESS);
+    }
+    else
+    {
+        // Parent
+        LOG_ID("PID is %jd", (intmax_t) getpid());
+        sleep_ms(1000);
+
+        if (close(pipefd_1[PIPE_READ_END]) == -1)
+        {
+            // Close unused pipefd_1 read end
+            perror("close");
+            exit(EXIT_FAILURE);
+        }
+
+        if (close(pipefd_2[PIPE_WRITE_END]) == -1)
+        {
+            // Close unused pipefd_2 write end
+            perror("close");
+            exit(EXIT_FAILURE);
+        }
+
+        while (true)
+        {
+            ball++;
+            LOG_ID("%d", ball);
+            write(pipefd_1[PIPE_WRITE_END], &ball, 1);
+
+            // Wait for response from the other end
+            while (read(pipefd_2[PIPE_READ_END], &ball, 1) <= 0)
+            {
+                ;
+            }
+
+            sleep_ms(1000);
+        }
+
+        exit(EXIT_SUCCESS);
+    }
+
+    exit(EXIT_SUCCESS);
+}