This is the mail archive of the libc-alpha@sourceware.org mailing list for the glibc project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

Re: [RFC] termios: non-standard baudrates are not handled properly on Linux-systems (BZ#10339)


On 10/4/18 5:47 AM, Adhemerval Zanella wrote:
> 
> The Bnnn change to match integer values has the advantage of one can
> infer speed_t can represent any integer value of the range is typedef.
> And possible future POSIX Bxxx additions won't require to change
> previous defined values. Portable applications will need to rely on
> POSIX Bxxx though.
> 

Yes, and the constants for the current values are ABI.

I posted this as part of the bug report recently, and I would love to hear
feedback on it:

I hacked on the above [an entirely new api called cf*baud() instead of
cf*speed()], and the more I work on it, the more I'm unhappy with the *baud()
functions.

The big problem that I see is that an existing application doing getxspeed()
... setxspeed() ought to have a reasonable expectation of returning to the
original baud rate in all circumstances, so an interface which doesn't encode
this information in speed_t is fundamentally broken.

So I came up with this idea:

    speed_t cfencspeed(baud_t)
    baud_t cfdecspeed(speed_t)

... keeping the interfaces using speed_t but having a system-independent way
to encode and decode this abstract type into a true integer. This also becomes
a trivial interface (null transformation) on systems which use speed_t == baud.

*** It also is trivial to build a wrapper function library on top of existing
legacy implementations using the gcc -Wp,-dM feature or extracting the
constants either by hand or by some kind of custom utility, e.g. sparse. An
actual implementation of such a library is at:

    https://git.zytor.com/pub/git/users/hpa/libs/termbaud.git


On Linux, in order to support the existing Bxxx constants without
modification, we can define the speed_t as a speed, *except* that the Bxxx
constants and their corresponding integers are swapped.  In other words, B300
== 7, so 7 baud would be represented by the value 300.  Although slightly
complicated, this encoding is 100% efficient, and has the important property
of being alias-free, so that a direct comparison cannot have false negatives.

So far, so good.

Now, assuming we really want to support baud rates over 4 Gbps, I'm thinking
of an interface which might amount to a 5:27 floating point number. no sign
bit, and biased for integers only.  Baud rates below 2^27 ~ 134 Mbps would be
encoded as "denormals"; above that the value will be encoded with an implicit
one, which means that values below 2^28 ~ 268 Mps will still be
identity-transformed with an integer (since 00001 ... would correspond to a
shift of 0 but with an implicit 1, and the implicit 1 would fall into exactly
the same bit position as the 1 in the exponent.)

This would be able to encode baud rates up to to ~288 Pbps with a maximum
error of 4 ppb, without breaking the round-trip property of speed_t and
without having to change the current termios structures (except for SPARC and
possibly MIPS.)

Thoughts?


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]