[libc-commits] [PATCH] D126829: [libc] add buffering to FILE writes

Michael Jones via Phabricator via libc-commits libc-commits at lists.llvm.org
Fri Jun 3 14:53:00 PDT 2022


michaelrj added inline comments.


================
Comment at: libc/src/__support/File/file.cpp:34
+    return written;
+  }
   cpp::ArrayRef<uint8_t> dataref(data, len);
----------------
sivachandra wrote:
> These additional conditionals are making the code even more complicated. Instead, we should do this: rename the current `write_unlocked` method to `write_unlocked_fully_buffered` and make it private. Next, add two new methods like this:
> 
> ```
> public:
> size_t write_unlocked(const void *data, size_t len) {
>   if (bufmode == _IOLBF) {
>     return write_unlocked_line_buffered(data, len);
>   } else if (bufmode == _IOFBF) {
>     return write_unlocked_fully_buffered(data, len);
>   } else {
>     size_t written_size =platform_write(this, data, len);
>     // Error handling if platform_write fails.
> 
>     platform_flush(this);
> 
>     // Error handling if platform_flush fails
> 
>     return len;
>   }
> }
> 
> private:
> size_t write_unlocked_line_buffered(const void *data, size_t len) {
>   // Instead of looking for the first new line char, look for the last new line char.
>   char *last = last_newline(data, len);
>   if (last == nullptr) {
>    // If no new line char is found, just do normal buffering.
>     return write_unlocked_fully_buffered(data, len);
>   }
> 
>   size_t written_size;
>   if (pos == 0) {
>     // If there is no content in the buffer, write out the new data.
>     written_size = platform_write(data, last - data /* size including the new line char */);
>     // Perform error handling
>   } else {
>     // First write out the existing content, and then write out the new data.
>     platform_write(buf, pos);
>     // Perform error handling
>     pos = 0;
> 
>     written_size = platform_write(data, last - data);
>     // Perform error handling.
>   }
> 
> 
>   platform_flush();
> 
>   // Perform error handling
> 
>   if (written_size == len)
>     return len;
> 
>   // Remaining data should be buffered.
>   written_size = write_unlocked_fully_buffered(data + written_size, len - written_size);
> 
>   // Perform error handling
> 
>   return len;
> }
> ```
I don't think splitting line buffered and fully buffered writes is the correct design. The reason being that their logic is almost identical, only varying in the spot where they flush the buffer. With this idea in mind, I've rewritten the original function to support both types of buffering in a manner closer to your original design. I've also kept unbuffered writes in this function, since it seems odd to split just that  function off on its own if all the other write modes are together.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D126829/new/

https://reviews.llvm.org/D126829



More information about the libc-commits mailing list