Message buffer and printf reentrancy patch
truckman at FreeBSD.org
Mon Jun 16 03:48:32 PDT 2003
On 16 Jun, Bruce Evans wrote:
> On Sun, 15 Jun 2003, Ian Dowse wrote:
>> In message <200306151826.h5FIPvM7046944 at gw.catspoiler.org>, Don Lewis writes:
>> >> +#define MSGBUF_SEQNORM(mbp, seq) ((seq) % (mbp)->msg_seqmod + ((seq) < 0 ?
>> >> + (mbp)->msg_seqmod : 0))
>> >> +#define MSGBUF_SEQ_TO_POS(mbp, seq) ((int)((u_int)(seq) % \
>> >> + (u_int)(mbp)->msg_size))
>> >> +#define MSGBUF_SEQSUB(mbp, seq1, seq2) (MSGBUF_SEQNORM(mbp, (seq1) - (seq2)
>> >> +
> Sorry I didn't reply to Ian's provate mail about all this last month. I'll
> try to get back to it.
>> >According to my copy of K&R, there is no guarantee that ((negative_int %
>> >postive_int) <= 0) on all platforms, though this is generally true.
> C99 guarantees this perfect brokenness of the % operator. Division should
> give remainders that have the same sign as the divisor, which corresponds
> to rounding towards minus infinity for positive divisors, but is now
> specified to be bug for bug compatible with most hardware and most C
> implementations (round towards zero).
> MSGBUF_SEQ_TO_POS() does extra work to get nonnegative remainders.
> This problem and many casts could be avoided by using unsigned types
> for most of the msgbuf fields. I forget the details of why we changed
> them back to signed. The log message for msgbuf.h 1.19 says that this
> is because we perform signed arithmetic on them. The details for this,
> can probably be handled by the macros now.
Using unsigned types was the first thing that I thought of. I was
wondering if the reason that this wasn't done was some sort of
portability problem with the atomic operations.
It looks like MSGBUF_SEQNORM() could avoid the conditional code and any
questions about signed remainders if it was defined like this:
#define MSGBUF_SEQNORM(mbp, seq) (((seq) + (mbp)->msg_seqmod) % \
as long as msg_seqmod < INT_MAX/2. MSGBUF_SEQNORM() could be simplified
further if msg_seqmod was added by the caller (such as MSGBUF_SEQSUB())
if the argument could be negative.
More information about the freebsd-arch