hazard in serial ?

Has anybody else than me experienced hazard in serial when pressing it to the limit ?

SOME OF THE CODE IN QUESTION IS BELOW
Problem: ISR as well as userprogram manipulate head & tail. They are ints so they require more than one (atomic) machine instructions ...

inline void store_char(unsigned char c, ring_buffer *buffer)
{
int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;

// if we should be storing the received character into the location
// just before the tail (meaning that the head would advance to the
// current location of the tail), we're about to overflow the buffer
// and so we don't write the character or advance the head.
if (i != buffer->tail) {
buffer->buffer[buffer->head] = c;
buffer->head = i;
}
}
and
int HardwareSerial::available(void)
{
return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;
}

jensd:
Has anybody else than me experienced hazard in serial when pressing it to the limit ?

Never seen a problem - what's yours?

Hard to tell from that snippet.

http://snippets-r-us.com/

Read this about atomic reads/writes in interrupts:

jensd:
Has anybody else than me experienced hazard in serial when pressing it to the limit ?

It seems to work fine at 1,000,000 baud on my Uno.

...R

jensd:
Has anybody else than me experienced hazard in serial when pressing it to the limit ?

SOME OF THE CODE IN QUESTION IS BELOW
Problem: ISR as well as userprogram manipulate head & tail. They are ints so they require more than one (atomic) machine instructions ...

inline void store_char(unsigned char c, ring_buffer *buffer)

{
  int i = (unsigned int)(buffer->head + 1) % SERIAL_BUFFER_SIZE;

// if we should be storing the received character into the location
  // just before the tail (meaning that the head would advance to the
  // current location of the tail), we're about to overflow the buffer
  // and so we don't write the character or advance the head.
  if (i != buffer->tail) {
    buffer->buffer[buffer->head] = c;
    buffer->head = i;
  }
}



and


int HardwareSerial::available(void)
{
  return (unsigned int)(SERIAL_BUFFER_SIZE + _rx_buffer->head - _rx_buffer->tail) % SERIAL_BUFFER_SIZE;
}

Yes, the fields head and tail should be byte - however they never get larger than 63
on the Mega and 15 on the Uno so the high byte is always zero and nothing goes wrong.

Interestingly the code has been changed significantly for AVR in 1.5.7, with the type
being uint8_t/uint16_t conditional on the value of the buffer size #define,
but the bug was not spotted. Worth reporting.

however they never get larger than 63
on the Mega and 15 on the Uno

63 for both.