Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement pipe(2) #58

Open
fischerling opened this issue Mar 9, 2024 · 1 comment
Open

Implement pipe(2) #58

fischerling opened this issue Mar 9, 2024 · 1 comment

Comments

@fischerling
Copy link
Contributor

No description provided.

@Galfurian
Copy link
Member

I've implemented the pipes; you can find them in the official develop branch.

Now, they work both in block and non-blocking mode. I've added fcntl to set the non-blocking feature.

The blocking pipe uses wait queues, so there is no mechanical polling. However, even with the blocking pipe, on the user side, we need to write something like this:

    do {
          bytes_read = read(fds[0], read_msg, sizeof(read_msg));
          if (bytes_read > 0) {
              printf("Child read message: '%s' (%ld bytes)\n", read_msg, bytes_read);
          } else if ((bytes_read == -1) && (errno != EAGAIN)) {
              fprintf(stderr, "Error occurred during read in child process\n");
              error_code = 1;
              break;
          }
      } while (bytes_read != 0);

That's because, even with the blocking behavior, once there is something to read, it will first return that there is nothing to read, and then at the second call, it will give you the data.

The reason is explained in the following. I'll try my best to make it clear.

Here is the blocking behavior:

  • [User] Call read on reading end fd[0].
  • [Kernel] Through sys_read and then vfs_read, it enters pipe_read.
  • [Kernel] Inside pipe_read checks if there is stuff to read inside the pipe.
  • [Kernel] There is none, so it puts the process inside a wait queue. However, we are storing the status of the process, waiting for an answer from the read function.
  • Some time passes...
  • [Kernel] Someone writes inside the pipe, so the process is correctly woken up.
  • [User] The process resumes from after the call to the read, and the read returns that there was nothing to read inside the pipe. That was the return value when the read was initially called.

So, it's like, I cannot interrupt the kernel execution midway through the pipe_read and then resume the execution precisely from the exact location in the kernel code when the process is woken up.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants