<div dir="ltr"><div>Michael, it is entirely possible that I am misunderstanding your suggestion, I probably don't grasp the complexities of the RTL texmode IO system and also not explaining my intention clearly, for this I apologise. Take for example the esp32 unit provided by Florian, here the link between the underlying OS output and the RTL is configured by calling OpenIO and providing readchar and writechar functions which in turn calls getchar and putchar (<a href="https://github.com/ccrause/freepascal/blob/76911c528251b48e18c348de1758c098ee9fb763/rtl/freertos/xtensa/esp32.pp#L106" target="_blank">https://github.com/ccrause/freepascal/blob/76911c528251b48e18c348de1758c098ee9fb763/rtl/freertos/xtensa/esp32.pp#L106</a>). In this unit Florian uses a custom printpchar procedure which pushes characters to the OS and at the end directly calls the OS fflush function. This ensures that the haltproc message gets transmitted before the cpu goes to sleep.</div><div><br></div><div>I'm trying to change the controller unit to use standard RTL write functionality, since this gets configured during unit initialization anyway. My attempt at "Pascalizing" Florian's version (<a href="https://github.com/ccrause/freepascal/blob/76911c528251b48e18c348de1758c098ee9fb763/rtl/freertos/xtensa/esp8266.pp#L59" target="_blank">https://github.com/ccrause/freepascal/blob/76911c528251b48e18c348de1758c098ee9fb763/rtl/freertos/xtensa/esp8266.pp#L59</a>) calls the normal write functionality and works, except for the last string before <span style="color:rgb(36,41,46);font-family:SFMono-Regular,Consolas,"Liberation Mono",Menlo,monospace;font-size:12px;white-space:pre-wrap">esp_deep_sleep</span> which doesn't reach the remote terminal. At the moment I fix this by directly calling the OS fflush function.</div><div><br></div>The only configuration option exposed via consoleio is OpenIO, which doesn't have a parameter for a low level flush function. I could create an overloaded OpenIO function with an extra parameter for a flush function pointer, and call this, if assigned, at the end of Console_Write. Is this kind of the lower level detail behind your suggestion Michael?<div><br></div><div>Best regards,</div><div>Christo</div><div><br></div><div><div class="gmail_quote"><div dir="ltr" class="gmail_attr">On Mon, Jun 8, 2020 at 3:27 PM Michael Van Canneyt <<a href="mailto:michael@freepascal.org" target="_blank">michael@freepascal.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left:1px solid rgb(204,204,204);padding-left:1ex"><br>
<br>
On Mon, 8 Jun 2020, Christo Crause via fpc-devel wrote:<br>
<br>
> On Mon, Jun 8, 2020 at 12:15 PM Tomas Hajny <<a href="mailto:XHajT03@hajny.biz" target="_blank">XHajT03@hajny.biz</a>> wrote:<br>
><br>
>> On 2020-06-08 11:39, Michael Van Canneyt wrote:<br>
>>> On Mon, 8 Jun 2020, Christo Crause via fpc-devel wrote:<br>
>> .<br>
>> .<br>
>>>> Thanks for your response Michael. Using InOutFunc to also flush the<br>
>>>> output<br>
>>>> buffer will work, but that seems inefficient, since the flush needs to<br>
>>>> wait<br>
>>>> until the transmit buffer is empty (at slow UART speeds this could<br>
>>>> potentially take several ms to complete). Is there a specific reason<br>
>>>> why<br>
>>>> the RTL Flush procedure does not call the FlushFunc method?<br>
>>><br>
>>> I checked; That code is so old, no idea.<br>
>>><br>
>>> From what I can see the flush code could be changed to<br>
>>><br>
>>> if Assigned((TextRec(t).FlushFunc) then<br>
>>> FileFunc(TextRec(t).FlushFunc)(TextRec(t))<br>
>>> else<br>
>>> FileFunc(TextRec(t).InOutFunc)(TextRec(t));<br>
>>><br>
>>> But keep in mind that the InoutFunc() is only called when actually<br>
>>> writing<br>
>>> data, meaning: when the internal text buffer is full or on a terminal<br>
>>> with<br>
>>> every writeln(), so I don't think it is inefficient. Writeln() will do<br>
>>> a<br>
>>> flush. Whether this happens in .InOutFunc or .FlushFunc is largely<br>
>>> irrelevant.<br>
>><br>
>> The question is whether the potential change would make any difference.<br>
>> IMHO, the important points are:<br>
>><br>
>> 1) The point of flushing is making sure the I/O is really performed (the<br>
>> data are sent to the operating system _and_ flushed from internal<br>
>> buffers of the underlying operating system / platform). Doing the latter<br>
>> without the former makes no sense.<br>
>><br>
>> 2) From semantic point of view, all data should be sent to the final<br>
>> place (block device / console / ...) before the call to Flush is<br>
>> finished (otherwise the following actions may have incorrect results -<br>
>> the program might finish before all data are transmitted, other I/O may<br>
>> be invoked, etc.).<br>
>><br>
>> From this point of view, the proposed change would only lead to code<br>
>> duplication between FlushFunc and InOutFunc and / or to increased code -<br>
>> e.g. checking FlushFunc being nil before calling InOutFunc just to call<br>
>> InOutFunc (or to perform functionality currently included in InOutFunc)<br>
>> from within FlushFunc anyway.<br>
>> <<a href="https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel" rel="noreferrer" target="_blank">https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-devel</a>><br>
><br>
><br>
> Tomas and Michael, thank you for this discussion. I'm starting to think<br>
> the use case I'm considering is perhaps not covered by the current design.<br>
<br>
I don't understand why you don't do the flush in the InOutFunc ?<br>
<br>
That's what it is for: the text filetype already does the buffering for you.<br>
So any performance impact is IMO unavoidable: when InOutFunc is called, the<br>
RTL really needs it to clear the buffer.<br>
<br>
Michael.<br>
</blockquote></div></div></div>