[Top][All Lists]

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [avr-libc-dev] fflush() implementation

From: Joerg Wunsch
Subject: Re: [avr-libc-dev] fflush() implementation
Date: Mon, 27 Aug 2012 18:44:54 +0200
User-agent: Mutt/1.5.20 (2009-06-14)

As Philipp Schafft wrote:

> Please note that fflush() doesn't do that on any system. It only flushes
> the buffers within the FILE* object.

This is the most convincing argument so far.  As avr-libc's stdio does
not perform any buffering at the stdio level, fflush() can only be
implemented as a no-op.

> Still it could be considered adding a new function similar to fsync() or
> fdatasync() to allow flushing data in the driver.

As any buffering has to be implemented at the driver level, I don't
really understand why the driver couldn't provide an appropriate
function of its own which can be called in the respective situation.
The actual driver implementation is always outside the scope of the
library, anyway.

If it is desired to tie the actual implementation to the __file object
in some way, this can be done through the "user data" pointer, by
using fdev_set_udata()/fdev_get_udata().

As Daniel Otte wrote:

> I do not have a copy of a ISO-C standard at hand, but I found a copy of a 
> Draft
> of ISO-C 99 [1] dated on August 3, 1998 which says (on page 255):

There are more recent drafts available than n843 which you are
referring to.  The most recent one is n1336.pdf which is basically the
complete and official ISO-C99 standard, with all three existing
technical corrigenda (TCs) included.

Anyway, their wording is identical.

>   If stream points to an output stream or an update stream in which the most
>   recent operation was not input, the fflush function causes any unwritten 
> data
>   for that stream to be delivered to the host environment to be written to the
>   file; otherwise, the behavior is undefined.
> I would interpret this in a way which means that fflush has to call a "host
> environment function" which serves the purpose of pushing the data further
> towards its final destination.

No.  Besides their grammar not being very well parsable, "to be
delivered to the host environment" means the stdio implementation
writes back its buffers to the OS environment.  In a unixoid
environment, it simply calls write() then.  Still, similar to your
microcontroller environment, the OS itself would return from the
write() syscall as soon as the UART data have been stored within the
OS-internal buffer, and it's the job of the (OS'es) interrupt service
handler to pick it up from there, and ship it to the UART, character
by character.  If your OS crashes right after the call to fflush(),
the terminal connected to the UART won't display any of those data.

> I am not aware of a very strict definition of ABI or ABI change, but since all
> functions handling with the internals of __file should be encapsulated within
> the library, a change to it would not touch the components of the ABI a user 
> is
> expected/recommended to use.

That's the API (application *programming* interface), yes, this wouldn't

Johann's argument was about the ABI (application *binary* interface),
and that one will change: if the __file structure is increased, any
object file that has been compiled with the existing <stdio.h> would
contain a structure which is smaller than the new one.  Consequently,
linking such an object file against the new library causes undefined

While this is not a big issue when using fdevopen() (as it allocates
the struct __file through malloc() and would thus automatically
generate an object that matches the library), as a special tribute to
our microcontroller users, we also offer API functions that allow
static (malloc()-free) allocation of the __file objects, namely the
FDEV_SETUP_STREAM() macro, and the fdev_setup_stream() function.

cheers, J"org               .-.-.   --... ...--   -.. .  DL8DTL

http://www.sax.de/~joerg/                        NIC: JW11-RIPE
Never trust an operating system you don't have sources for. ;-)

reply via email to

[Prev in Thread] Current Thread [Next in Thread]