MINOR: vecpair: add necessary functions to use vecpairss from/to ring APIs

Many ring-based APIs need a tail and a head, with some extra assumption
that the user takes care of not filling the ring so that tail==head is
unambiguous. Vectors are particularly suited to this usage so here we
create 4 functions to create vectors representing free room or data
from a ring, as well as updating rings based on a pair of vectors that
represents either free space or data.
This commit is contained in:
Willy Tarreau 2024-02-26 19:53:34 +01:00
parent 63261aae39
commit c222cb8389

View File

@ -56,6 +56,8 @@
* *
* These functions do not need to know the allocated size nor any such thing, * These functions do not need to know the allocated size nor any such thing,
* it's the caller's job to know that and to build the relevant vector pair. * it's the caller's job to know that and to build the relevant vector pair.
* See the vp_{ring,data,room}_to_{ring,data,room}() functions at the end for
* this.
*/ */
/* vp_isempty(): returns true if both areas are empty */ /* vp_isempty(): returns true if both areas are empty */
@ -490,6 +492,92 @@ static inline size_t vp_peek_varint_ofs(struct ist v1, struct ist v2, size_t ofs
return vp_get_varint_ofs(&v1, &v2, ofs, vptr); return vp_get_varint_ofs(&v1, &v2, ofs, vptr);
} }
/************************************************************/
/* ring-buffer API */
/* This is used to manipulate rings made of (head,tail) */
/* It creates vectors for reading (data) and writing (room) */
/************************************************************/
/* build 2 vectors <v1> and <v2> corresponding to the available data in ring
* buffer of size <size>, starting at address <area>, with a head <head> and
* a tail <tail>. <v2> is non-empty only if the data wraps (i.e. tail<head).
*/
static inline void vp_ring_to_data(struct ist *v1, struct ist *v2, char *area, size_t size, size_t head, size_t tail)
{
v1->ptr = area + head;
v1->len = ((head <= tail) ? tail : size) - head;
v2->ptr = area;
v2->len = (tail < head) ? tail : 0;
}
/* build 2 vectors <v1> and <v2> corresponding to the available room in ring
* buffer of size <size>, starting at address <area>, with a head <head> and
* a tail <tail>. <v2> is non-empty only if the room wraps (i.e. head>tail).
*/
static inline void vp_ring_to_room(struct ist *v1, struct ist *v2, char *area, size_t size, size_t head, size_t tail)
{
v1->ptr = area + tail;
v1->len = ((tail <= head) ? head : size) - tail;
v2->ptr = area;
v2->len = (head < tail) ? head : 0;
}
/* Set a ring's <head> and <tail> according to the data area represented by the
* concatenation of <v1> and <v2> which must point to two adjacent areas within
* a ring buffer of <size> bytes starting at <area>. <v1>, if not empty, starts
* at the head and <v2>, if not empty, ends at the tail. If both vectors are of
* length zero, the ring is considered empty and both its head and tail will be
* reset.
*/
static inline void vp_data_to_ring(const struct ist v1, const struct ist v2, char *area, size_t size, size_t *head, size_t *tail)
{
size_t ofs;
if (!v1.len && !v2.len) {
*head = *tail = 0;
return;
}
ofs = (v1.len ? v1.ptr : v2.ptr) - area;
if (ofs >= size)
ofs -= size;
*head = ofs;
ofs = (v2.len ? v2.ptr + v2.len : v1.ptr + v1.len) - area;
if (ofs >= size)
ofs -= size;
*tail = ofs;
}
/* Set a ring's <head> and <tail> according to the room area represented by the
* concatenation of <v1> and <v2> which must point to two adjacent areas within
* a ring buffer of <size> bytes starting at <area>. <v1>, if not empty, starts
* at the tail and <v2>, if not empty, ends at the head. If both vectors are of
* length zero, the ring is considered full and both its head and tail will be
* reset (which cannot be distinguished from empty). The caller must make sure
* not to fill a ring with this API.
*/
static inline void vp_room_to_ring(const struct ist v1, const struct ist v2, char *area, size_t size, size_t *head, size_t *tail)
{
size_t ofs;
if (!v1.len && !v2.len) {
*head = *tail = 0;
return;
}
ofs = (v1.len ? v1.ptr : v2.ptr) - area;
if (ofs >= size)
ofs -= size;
*tail = ofs;
ofs = (v2.len ? v2.ptr + v2.len : v1.ptr + v1.len) - area;
if (ofs >= size)
ofs -= size;
*head = ofs;
}
#endif /* _HAPROXY_VECPAIR_H */ #endif /* _HAPROXY_VECPAIR_H */
/* /*