]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MEDIUM: shctx: Simplify shctx_row_reserve_hot loop
authorRemi Tricot-Le Breton <rlebreton@haproxy.com>
Thu, 16 Nov 2023 16:38:13 +0000 (17:38 +0100)
committerWilliam Lallemand <wlallemand@haproxy.com>
Thu, 16 Nov 2023 18:35:10 +0000 (19:35 +0100)
The shctx_row_reserve_hot relied on two loop levels in order to first
look for the first block of a preused row and then iterate on all the
blocks of this row to reserve them for the new row. This was not the
simplest nor the easiest to read way so this logic could be replaced by
a single iteration on the avail list members.
The two use cases of calling this function with or without a preexisting
"first" member were a bit cumbersome as well and were replaced by a more
straightforward approach.

src/shctx.c

index 19394fa175e37c6eaf7623467a0a19e5915e0729..604c343a9c79df3eafa87bf14f92bec2d5d88dae 100644 (file)
@@ -29,10 +29,9 @@ int use_shared_mem = 0;
 struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
                                            struct shared_block *first, int data_len)
 {
-       struct shared_block *last = NULL, *block, *sblock, *ret = NULL, *next;
-       int enough = 0;
-       int freed = 0;
-       int remain;
+       struct shared_block *last = NULL, *block, *sblock;
+       struct shared_block *ret = first;
+       int remain = 1;
 
        BUG_ON(data_len < 0);
 
@@ -47,8 +46,6 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
                        goto out;
        }
 
-       /* Note that <remain> is nul only if <first> is not nul. */
-       remain = 1;
        if (first) {
                /* Check that there is some block to reserve.
                 * In this first block of code we compute the remaining room in the
@@ -69,71 +66,43 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx,
                }
        }
 
-       while (!enough && !LIST_ISEMPTY(&shctx->avail)) {
-               int count = 0;
-               int first_count = 0, first_len = 0;
-
-               next = block = LIST_NEXT(&shctx->avail, struct shared_block *, list);
-               if (ret == NULL)
-                       ret = next;
-
-               first_count = next->block_count;
-               first_len = next->len;
-               /*
-               Should never been set to 0.
-               if (next->block_count == 0)
-               next->block_count = 1;
-               */
-
-               list_for_each_entry_safe_from(block, sblock, &shctx->avail, list) {
-
-                       /* release callback */
-                       if (first_len && shctx->free_block)
-                               shctx->free_block(next, block);
-
-                       block->block_count = 1;
-                       block->len = 0;
-
-                       freed++;
-
-                       BUG_ON(data_len < 0);
-                       data_len -= shctx->block_size;
-
-                       if (data_len > 0 || !enough) {
-                               if (last) {
-                                       shctx_block_append_hot(shctx, &last->list, block);
-                                       last = block;
-                               } else {
-                                       shctx_block_set_hot(shctx, block);
-                               }
-                               if (!remain) {
-                                       first->last_append = block;
-                                       remain = 1;
-                               }
-                               if (data_len <= 0) {
-                                       ret->block_count = freed;
-                                       ret->refcount = 1;
-                                       ret->last_reserved = block;
-                                       ret->last_append = NULL;
-                                       enough = 1;
-                                       break;
-                               }
-                       }
-                       count++;
-                       if (count >= first_count)
-                               break;
-               }
+       if (data_len <= 0 || LIST_ISEMPTY(&shctx->avail)) {
+               return NULL;
        }
 
-       if (first) {
-               first->block_count += ret->block_count;
-               first->last_reserved = ret->last_reserved;
-               /* Reset this block. */
-               ret->last_reserved = NULL;
-               ret->block_count = 1;
-               ret->refcount = 0;
-               /* Return the first block. */
-               ret = first;
+       /* Initialize the first block of a new row. */
+       if (!first) {
+               ret = LIST_NEXT(&shctx->avail, struct shared_block*, list);
+               ret->block_count = 0;
+               ret->last_append = NULL;
+               ret->refcount = 1;
+       }
+
+       list_for_each_entry_safe(block, sblock, &shctx->avail, list) {
+
+               /* release callback */
+               if (block->len && shctx->free_block)
+                       shctx->free_block(block, block);
+               block->len = 0;
+
+               if (last) {
+                       shctx_block_append_hot(shctx, &last->list, block);
+                       last = block;
+                       if (!remain) {
+                               first->last_append = block;
+                               remain = 1;
+                       }
+               } else
+                       shctx_block_set_hot(shctx, block);
+
+               ++ret->block_count;
+
+               data_len -= shctx->block_size;
+
+               if (data_len <= 0) {
+                       ret->last_reserved = block;
+                       break;
+               }
        }
 
 out: