It reports the difference between the head and the tail of the circular buffer the incoming characters are stored in.
The way serial reception on the Arduino works is:
- A character is received into the internal hardware RX buffer (
UDRx)
- An interrupt is triggered
- An interrupt service routine (ISR) is executed
- The character in
UDRx is read and, if there is room, stored in a circular buffer (_rx_buffer).
- The
head pointer of _rx_buffer is incremented and wrapped if needed.
When you actually read a character with Serial.read() the following happens:
- If the
head and tail of rx_buffer are equal, return -1
- Get the character at
tail from _rx_buffer
- Increment
tail and wrap if needed
- Return the character
So when you use Serial.available() it just returns head - tail (taking into account the wrapping, so the sum is slightly more complex than a simple subtraction).
You should examine the files HardwareSerial.h and HardwareSerial.cpp in the Ardino AVR core software.