Skip to content

Commit 8b5a1fd

Browse files
committed
BUILD: buffers: keep b_getblk_nc() and b_peek_varint() in buf.h
Some large functions were moved to buf.c by commit ac66df4 ("REORG: buffers: move some of the heavy functions from buf.h to buf.c"). However, as found by Amaury, haring doesn't build anymore. Upon close inspection, b_getblk_nc() isn't that big since it's very much inlinable, and a part of its apparently large size comes from the BUG_ON_HOT() that were implemented. Regarding b_peek_varint(), it doesn't have any dependency and is used only at 4 places in the DNS code, so its loop will not have big impacts, and the rest around can be optimised away by the compiler so it remains relevant to keep it inlined. Also it can serve as a base to deduplicate the code in b_get_varint(). No backport needed.
1 parent f33e907 commit 8b5a1fd

File tree

2 files changed

+74
-77
lines changed

2 files changed

+74
-77
lines changed

include/haproxy/buf.h

Lines changed: 74 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -35,8 +35,6 @@
3535

3636
size_t b_getblk_ofs(const struct buffer *buf, char *blk, size_t len, size_t offset);
3737
size_t b_getblk(const struct buffer *buf, char *blk, size_t len, size_t offset);
38-
size_t b_getblk_nc(const struct buffer *buf, const char **blk1, size_t *len1,
39-
const char **blk2, size_t *len2, size_t ofs, size_t max);
4038
size_t b_getdelim(const struct buffer *buf, size_t offset, size_t count,
4139
char *str, size_t len, const char *delim, char escape);
4240
size_t b_getline(const struct buffer *buf, size_t offset, size_t count,
@@ -53,7 +51,6 @@ int b_insert_blk(struct buffer *b, size_t off, const char *blk, size_t len);
5351
void __b_put_varint(struct buffer *b, uint64_t v);
5452
int b_put_varint(struct buffer *b, uint64_t v);
5553
int b_get_varint(struct buffer *b, uint64_t *vptr);
56-
int b_peek_varint(struct buffer *b, size_t ofs, uint64_t *vptr);
5754

5855
void bl_deinit(struct bl_elem *head);
5956
uint32_t bl_get(struct bl_elem *head, uint32_t idx);
@@ -463,6 +460,80 @@ static inline size_t b_force_xfer(struct buffer *dst, struct buffer *src, size_t
463460
return ret;
464461
}
465462

463+
/* b_getblk_nc() : gets one or two blocks of data at once from a buffer,
464+
* starting from offset <ofs> after the beginning of its output, and limited to
465+
* no more than <max> bytes. The caller is responsible for ensuring that
466+
* neither <ofs> nor <ofs>+<max> exceed the total number of bytes available in
467+
* the buffer. Return values :
468+
* >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2.
469+
* =0 : not enough data available. <blk*> are left undefined.
470+
* The buffer is left unaffected. Unused buffers are left in an undefined state.
471+
*/
472+
static inline size_t b_getblk_nc(const struct buffer *buf, const char **blk1, size_t *len1, const char **blk2, size_t *len2, size_t ofs, size_t max)
473+
{
474+
size_t l1;
475+
476+
BUG_ON_HOT(buf->data > buf->size);
477+
BUG_ON_HOT(ofs > buf->data);
478+
BUG_ON_HOT(ofs + max > buf->data);
479+
480+
if (!max)
481+
return 0;
482+
483+
*blk1 = b_peek(buf, ofs);
484+
l1 = b_wrap(buf) - *blk1;
485+
if (l1 < max) {
486+
*len1 = l1;
487+
*len2 = max - l1;
488+
*blk2 = b_orig(buf);
489+
return 2;
490+
}
491+
*len1 = max;
492+
return 1;
493+
}
494+
495+
/* b_peek_varint(): try to decode a varint from buffer <b> at offset <ofs>
496+
* relative to head, into value <vptr>. Returns the number of bytes parsed in
497+
* case of success, or 0 if there were not enough bytes, in which case the
498+
* contents of <vptr> are not updated. Wrapping is supported. The buffer's head
499+
* will NOT be updated. It is illegal to call this function with <ofs> greater
500+
* than b->data.
501+
*/
502+
static inline int b_peek_varint(struct buffer *b, size_t ofs, uint64_t *vptr)
503+
{
504+
const uint8_t *head = (const uint8_t *)b_peek(b, ofs);
505+
const uint8_t *wrap = (const uint8_t *)b_wrap(b);
506+
size_t data = b_data(b) - ofs;
507+
size_t size = b_size(b);
508+
uint64_t v = 0;
509+
int bits = 0;
510+
511+
BUG_ON_HOT(ofs > b_data(b));
512+
513+
if (data != 0 && (*head >= 0xF0)) {
514+
v = *head;
515+
bits += 4;
516+
while (1) {
517+
if (++head == wrap)
518+
head -= size;
519+
data--;
520+
if (!data || !(*head & 0x80))
521+
break;
522+
v += (uint64_t)*head << bits;
523+
bits += 7;
524+
}
525+
}
526+
527+
/* last byte */
528+
if (!data)
529+
return 0;
530+
531+
v += (uint64_t)*head << bits;
532+
*vptr = v;
533+
data--;
534+
size = b->data - ofs - data;
535+
return size;
536+
}
466537

467538

468539
/*

src/buf.c

Lines changed: 0 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -81,38 +81,6 @@ size_t b_getblk(const struct buffer *buf, char *blk, size_t len, size_t offset)
8181
return len;
8282
}
8383

84-
/* b_getblk_nc() : gets one or two blocks of data at once from a buffer,
85-
* starting from offset <ofs> after the beginning of its output, and limited to
86-
* no more than <max> bytes. The caller is responsible for ensuring that
87-
* neither <ofs> nor <ofs>+<max> exceed the total number of bytes available in
88-
* the buffer. Return values :
89-
* >0 : number of blocks filled (1 or 2). blk1 is always filled before blk2.
90-
* =0 : not enough data available. <blk*> are left undefined.
91-
* The buffer is left unaffected. Unused buffers are left in an undefined state.
92-
*/
93-
size_t b_getblk_nc(const struct buffer *buf, const char **blk1, size_t *len1, const char **blk2, size_t *len2, size_t ofs, size_t max)
94-
{
95-
size_t l1;
96-
97-
BUG_ON_HOT(buf->data > buf->size);
98-
BUG_ON_HOT(ofs > buf->data);
99-
BUG_ON_HOT(ofs + max > buf->data);
100-
101-
if (!max)
102-
return 0;
103-
104-
*blk1 = b_peek(buf, ofs);
105-
l1 = b_wrap(buf) - *blk1;
106-
if (l1 < max) {
107-
*len1 = l1;
108-
*len2 = max - l1;
109-
*blk2 = b_orig(buf);
110-
return 2;
111-
}
112-
*len1 = max;
113-
return 1;
114-
}
115-
11684
/* Locates the longest part of the buffer that is composed exclusively of
11785
* characters not in the <delim> set, and delimited by one of these characters,
11886
* and returns the initial part and the first of such delimiters. A single
@@ -688,48 +656,6 @@ int b_get_varint(struct buffer *b, uint64_t *vptr)
688656
return size;
689657
}
690658

691-
/* b_peek_varint(): try to decode a varint from buffer <b> at offset <ofs>
692-
* relative to head, into value <vptr>. Returns the number of bytes parsed in
693-
* case of success, or 0 if there were not enough bytes, in which case the
694-
* contents of <vptr> are not updated. Wrapping is supported. The buffer's head
695-
* will NOT be updated. It is illegal to call this function with <ofs> greater
696-
* than b->data.
697-
*/
698-
int b_peek_varint(struct buffer *b, size_t ofs, uint64_t *vptr)
699-
{
700-
const uint8_t *head = (const uint8_t *)b_peek(b, ofs);
701-
const uint8_t *wrap = (const uint8_t *)b_wrap(b);
702-
size_t data = b_data(b) - ofs;
703-
size_t size = b_size(b);
704-
uint64_t v = 0;
705-
int bits = 0;
706-
707-
BUG_ON_HOT(ofs > b_data(b));
708-
709-
if (data != 0 && (*head >= 0xF0)) {
710-
v = *head;
711-
bits += 4;
712-
while (1) {
713-
if (++head == wrap)
714-
head -= size;
715-
data--;
716-
if (!data || !(*head & 0x80))
717-
break;
718-
v += (uint64_t)*head << bits;
719-
bits += 7;
720-
}
721-
}
722-
723-
/* last byte */
724-
if (!data)
725-
return 0;
726-
727-
v += (uint64_t)*head << bits;
728-
*vptr = v;
729-
data--;
730-
size = b->data - ofs - data;
731-
return size;
732-
}
733659

734660
/*
735661
* Buffer List management.

0 commit comments

Comments
 (0)