[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