[fpc-devel] ConsoleIO and flushing buffered output

Michael Van Canneyt michael at freepascal.org
Mon Jun 8 15:27:42 CEST 2020



On Mon, 8 Jun 2020, Christo Crause via fpc-devel wrote:

> On Mon, Jun 8, 2020 at 12:15 PM Tomas Hajny <XHajT03 at hajny.biz> wrote:
>
>> On 2020-06-08 11:39, Michael Van Canneyt wrote:
>>> On Mon, 8 Jun 2020, Christo Crause via fpc-devel wrote:
>>   .
>>   .
>>>> Thanks for your response Michael.  Using InOutFunc to also flush the
>>>> output
>>>> buffer will work, but that seems inefficient, since the flush needs to
>>>> wait
>>>> until the transmit buffer is empty (at slow UART speeds this could
>>>> potentially take several ms to complete).   Is there a specific reason
>>>> why
>>>> the RTL Flush procedure does not call the FlushFunc method?
>>>
>>> I checked; That code is so old, no idea.
>>>
>>> From what I can see the flush code could be changed to
>>>
>>> if Assigned((TextRec(t).FlushFunc) then
>>>   FileFunc(TextRec(t).FlushFunc)(TextRec(t))
>>> else
>>>   FileFunc(TextRec(t).InOutFunc)(TextRec(t));
>>>
>>> But keep in mind that the InoutFunc() is only called when actually
>>> writing
>>> data, meaning: when the internal text buffer is full or on a terminal
>>> with
>>> every writeln(), so I don't think it is inefficient. Writeln() will do
>>> a
>>> flush. Whether this happens in .InOutFunc or .FlushFunc is largely
>>> irrelevant.
>>
>> The question is whether the potential change would make any difference.
>> IMHO, the important points are:
>>
>> 1) The point of flushing is making sure the I/O is really performed (the
>> data are sent to the operating system _and_ flushed from internal
>> buffers of the underlying operating system / platform). Doing the latter
>> without the former makes no sense.
>>
>> 2) From semantic point of view, all data should be sent to the final
>> place (block device / console / ...) before the call to Flush is
>> finished (otherwise the following actions may have incorrect results -
>> the program might finish before all data are transmitted, other I/O may
>> be invoked, etc.).
>>
>>  From this point of view, the proposed change would only lead to code
>> duplication between FlushFunc and InOutFunc and / or to increased code -
>> e.g. checking FlushFunc being nil before calling InOutFunc just to call
>> InOutFunc (or to perform functionality currently included in InOutFunc)
>> from within FlushFunc anyway.
>> <https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel>
>
>
> Tomas and Michael, thank you for this discussion.  I'm starting to think
> the use case I'm considering is perhaps not covered by the current design.

I don't understand why you don't do the flush in the InOutFunc ?

That's what it is for: the text filetype already does the buffering for you.
So any performance impact is IMO unavoidable: when InOutFunc is called, the
RTL really needs it to clear the buffer.

Michael.


More information about the fpc-devel mailing list