mirror of
https://github.com/warmcat/libwebsockets.git
synced 2025-03-09 00:00:04 +01:00
lwsac: fix header split optimization
This commit is contained in:
parent
6a56855284
commit
ce55c5dfe4
3 changed files with 76 additions and 18 deletions
|
@ -95,11 +95,36 @@ lws_list_ptr_insert(lws_list_ptr *phead, lws_list_ptr *add,
|
|||
* whatever is necessary to return you a pointer to ensure bytes of memory
|
||||
* reserved for the caller.
|
||||
*
|
||||
* This always allocates in the current chunk or a new chunk... see the
|
||||
* lwsac_use_backfill() variant to try first to find space in earlier chunks.
|
||||
*
|
||||
* Returns NULL if OOM.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN void *
|
||||
lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size);
|
||||
|
||||
/**
|
||||
* lwsac_use_backfill - allocate / use some memory from a lwsac
|
||||
*
|
||||
* \param head: pointer to the lwsac list object
|
||||
* \param ensure: the number of bytes we want to use
|
||||
* \param chunk_size: 0, or the size of the chunk to (over)allocate if
|
||||
* what we want won't fit in the current tail chunk. If
|
||||
* 0, the default value of 4000 is used. If ensure is
|
||||
* larger, it is used instead.
|
||||
*
|
||||
* This also serves to init the lwsac if *head is NULL. Basically it does
|
||||
* whatever is necessary to return you a pointer to ensure bytes of memory
|
||||
* reserved for the caller.
|
||||
*
|
||||
* Also checks if earlier blocks have enough remaining space to take the
|
||||
* allocation before making a new allocation.
|
||||
*
|
||||
* Returns NULL if OOM.
|
||||
*/
|
||||
LWS_VISIBLE LWS_EXTERN void *
|
||||
lwsac_use_backfill(struct lwsac **head, size_t ensure, size_t chunk_size);
|
||||
|
||||
/**
|
||||
* lwsac_use - allocate / use some memory from a lwsac
|
||||
*
|
||||
|
@ -191,8 +216,9 @@ lwsac_cached_file(const char *filepath, lwsac_cached_file_t *cache,
|
|||
|
||||
/* more advanced helpers */
|
||||
|
||||
/* offset from lac to start of payload, first = 1 = first lac in chain */
|
||||
LWS_VISIBLE LWS_EXTERN size_t
|
||||
lwsac_sizeof(void);
|
||||
lwsac_sizeof(int first);
|
||||
|
||||
LWS_VISIBLE LWS_EXTERN size_t
|
||||
lwsac_get_tail_pos(struct lwsac *lac);
|
||||
|
|
|
@ -71,6 +71,7 @@
|
|||
|
||||
#define cache_file_to_lac(c) ((struct lwsac *)((char *)c - \
|
||||
sizeof(struct cached_file_info) - \
|
||||
sizeof(struct lwsac_head) - \
|
||||
sizeof(struct lwsac)))
|
||||
|
||||
void
|
||||
|
@ -176,7 +177,7 @@ lwsac_cached_file(const char *filepath, lwsac_cached_file_t *cache, size_t *len)
|
|||
* it... reload in a new lac and then detach the old lac.
|
||||
*/
|
||||
|
||||
all = sizeof(*info) + s.st_size + 1;
|
||||
all = sizeof(*info) + s.st_size + 2;
|
||||
|
||||
info = lwsac_use(&lac, all, all);
|
||||
if (!info)
|
||||
|
|
|
@ -52,9 +52,9 @@ lwsac_align(size_t length)
|
|||
}
|
||||
|
||||
size_t
|
||||
lwsac_sizeof(void)
|
||||
lwsac_sizeof(int first)
|
||||
{
|
||||
return sizeof(struct lwsac);
|
||||
return sizeof(struct lwsac) + (first ? sizeof(struct lwsac_head) : 0);
|
||||
}
|
||||
|
||||
size_t
|
||||
|
@ -69,39 +69,59 @@ lwsac_get_next(struct lwsac *lac)
|
|||
return lac->next;
|
||||
}
|
||||
|
||||
void *
|
||||
lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size)
|
||||
static void *
|
||||
_lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size, char backfill)
|
||||
{
|
||||
size_t ofs, alloc, al;
|
||||
struct lwsac *bf = *head;
|
||||
struct lwsac_head *lachead = NULL;
|
||||
size_t ofs, alloc, al, hp;
|
||||
struct lwsac *bf = *head;
|
||||
|
||||
if (bf)
|
||||
lachead = (struct lwsac_head *)&bf[1];
|
||||
|
||||
/* check for something that can take it first */
|
||||
al = lwsac_align(ensure);
|
||||
|
||||
while (bf) {
|
||||
if (bf->alloc_size - bf->ofs >= ensure)
|
||||
goto do_use;
|
||||
/* backfill into earlier chunks if that is allowed */
|
||||
|
||||
bf = bf->next;
|
||||
if (backfill)
|
||||
/*
|
||||
* check if anything can take it, from the start
|
||||
*/
|
||||
while (bf) {
|
||||
if (bf->alloc_size - bf->ofs >= ensure)
|
||||
goto do_use;
|
||||
|
||||
bf = bf->next;
|
||||
}
|
||||
else {
|
||||
/*
|
||||
* If there's a current chunk, just check if he can take it
|
||||
*/
|
||||
if (lachead && lachead->curr) {
|
||||
bf = lachead->curr;
|
||||
if (bf->alloc_size - bf->ofs >= ensure)
|
||||
goto do_use;
|
||||
}
|
||||
}
|
||||
|
||||
/* nothing can currently take it... so we must allocate */
|
||||
|
||||
hp = sizeof(*bf); /* always need the normal header part... */
|
||||
if (!*head)
|
||||
hp += sizeof(struct lwsac_head);
|
||||
|
||||
if (!chunk_size)
|
||||
alloc = LWSAC_CHUNK_SIZE + sizeof(*bf);
|
||||
alloc = LWSAC_CHUNK_SIZE + hp;
|
||||
else
|
||||
alloc = chunk_size + sizeof(*bf);
|
||||
alloc = chunk_size + hp;
|
||||
|
||||
/*
|
||||
* If we get asked for something outside our expectation,
|
||||
* increase the allocation to meet it
|
||||
*/
|
||||
|
||||
if (ensure >= alloc - sizeof(*bf))
|
||||
alloc = ensure + sizeof(*bf);
|
||||
if (al >= alloc - hp)
|
||||
alloc = al + hp;
|
||||
|
||||
bf = malloc(alloc);
|
||||
if (!bf) {
|
||||
|
@ -142,7 +162,6 @@ do_use:
|
|||
|
||||
ofs = bf->ofs;
|
||||
|
||||
al = lwsac_align(ensure);
|
||||
if (al > ensure)
|
||||
/* zero down the alignment padding part */
|
||||
memset((char *)bf + ofs + ensure, 0, al - ensure);
|
||||
|
@ -154,6 +173,18 @@ do_use:
|
|||
return (char *)bf + ofs;
|
||||
}
|
||||
|
||||
void *
|
||||
lwsac_use(struct lwsac **head, size_t ensure, size_t chunk_size)
|
||||
{
|
||||
return _lwsac_use(head, ensure, chunk_size, 0);
|
||||
}
|
||||
|
||||
void *
|
||||
lwsac_use_backfill(struct lwsac **head, size_t ensure, size_t chunk_size)
|
||||
{
|
||||
return _lwsac_use(head, ensure, chunk_size, 1);
|
||||
}
|
||||
|
||||
uint8_t *
|
||||
lwsac_scan_extant(struct lwsac *head, uint8_t *find, size_t len, int nul)
|
||||
{
|
||||
|
|
Loading…
Add table
Reference in a new issue