[fpc-devel] ConsoleIO and flushing buffered output
Tomas Hajny
XHajT03 at hajny.biz
Tue Jun 9 10:55:41 CEST 2020
On 2020-06-09 08:55, Christo Crause via fpc-devel wrote:
> On Tue, Jun 9, 2020 at 12:03 AM Michael Van Canneyt
> <michael at freepascal.org>
> wrote:
>
>> Could you please submit a patch with this modification to the
>> bugtracker ?
>>
>> We don't as a rule follow up on such things in github.
>>
>
> I will of course submit a patch once I'm satisfied it is good enough.
> My
> concern with the current patch is that a low level flush is called
> after
> every write statement, so a simple loop like the following:
>
> for c := 'A' to 'Z" do write(c);
>
> will incur the burden of a low level flush after each iteration. In
> normal
> use the low level flush call is not needed and causes unnecessary
> blocks.
> This is what Tomas mentioned, so I'm looking for a different
> implementation
> that can fit in with the rest of the use cases in the RTL.
>
> It would make more sense to me if there was a distinct difference in
> use
> case between InOutFunc and FlushFunc (for fmoutput case), to my naive
> view
> it seems as if they are mostly used interchangeably and in many cases
> even
> share the same implementation function. This makes sense for the
> traditional targets (Windows, Linux etc.), but for lower level targets
> a
> distinction between the internal RTL buffer and the external
> OS/hardware
> buffer is useful. For a low level target I would think an InOutfunc
> that
> flushes the internal buffer to the OS/hardware and a FlushFunc that
> ensures
> the internal buffer is empty and then blocks until the OS/hardware has
> completed transmission would make sense.
Note that there is an (intended) difference between output to console
and output to files (Do_IsDevice provides this differentiation in
standard RTL). Output to console is supposed to be flushed after every
Write(Ln) statement, because it should provide immediate feedback to the
user. Output to files should not be flushed immediately. Obviously, it's
up to the target maintainer to decide what's the proper behaviour in
case of output devices connected to your target, but the semantics
should be preferably kept, IMHO. Also note the difference between
outputting a series of individual characters using individual Write
calls (your loop above calling flush after every character) compared to
outputting a whole string (flush called after outputting all the
characters in the string).
Finally, note that TP-compatible part of the standard RTL does _not_
call the ("low-level") flush call of the underlying operating system.
Such calls exist in API for most platforms (DOS: int 21h, AH=68h; OS/2:
DosResetBuffer; Unix: (fp)fsync; WinXX: FlushFileBuffers), but they are
not used within our RTL implementation as far as I know (flushing is
always performed automatically when closing a file, but the operating
systems take care of that).
Tomas
More information about the fpc-devel
mailing list