The term linear buffer is a generic reference to many buffers that are created with a single piece of linear contiguous memory that is controlled by pointers whose address increments linearly. The examples so far discussed are all of linear buffers.
The main point about them is that they will lose data when full and fail to provide data when empty. This is obvious but as will be shown, the way in which this happens with linear buffers compared to circular ones is different. With a linear buffer, it loses incoming data when full so that the data it does contain becomes older and older. This is the overrun condition. When it is empty, it will provide old data, usually the last entry, and so the processor will continue to process potentially incorrect data. This is the underrun condition.
Within a real-time system, these conditions are often but not always considered error conditions. In some cases, the loss of data is not critical but with any data processing that is based on regular sampling, it will introduce errors. There are further com-plications concerning how these conditions are prevented from occurring. The solution is to use a technique where the pointers are checked against certain values and the results used to trigger an action such as fetching more data and so on. These values are commonly referred to as high and low water marks, so named because they are similar to the high and low water marks seen at the coast that indicate the minimum and maximum levels that tidal water will fall and rise.
The number of entries below the low water mark determine how many entries the buffer still has and thus the amount of time that is available to start filling the buffer before the buffer empties and the underrun condition exists. The number of empty entries in the buffer above the high water mark determines the length of time that is available to stop the further filling of the buffer and thus prevent data loss through overrun. By comparing the various input and output pointers with these values, events can be gener-ated to start or stop filling the buffer. This could simply take the form of jumping to a subroutine, generating a software interrupt or within the context of an operating system posting a message to another task to fill the buffer.