From eccb97f60e4b47b2511177b23dced6aadb7419da Mon Sep 17 00:00:00 2001 From: Remi Tricot-Le Breton Date: Thu, 16 Nov 2023 17:38:12 +0100 Subject: [PATCH] MEDIUM: shctx: Move list between hot and avail list in O(1) Instead of iterating over all the elements of a given row when moving it between the hot and available lists, we can make use of the last_reserved pointer that already points to the last block of the list to perform the move in O(1). --- src/shctx.c | 41 ++++++++++++++++++++--------------------- 1 file changed, 20 insertions(+), 21 deletions(-) diff --git a/src/shctx.c b/src/shctx.c index 862adb68b..19394fa17 100644 --- a/src/shctx.c +++ b/src/shctx.c @@ -145,21 +145,21 @@ struct shared_block *shctx_row_reserve_hot(struct shared_context *shctx, */ void shctx_row_inc_hot(struct shared_context *shctx, struct shared_block *first) { - struct shared_block *block, *sblock; - int count = 0; - if (first->refcount <= 0) { - block = first; + BUG_ON(!first->last_reserved); - list_for_each_entry_safe_from(block, sblock, &shctx->avail, list) { + /* Detach row from avail list, link first item's prev to last + * item's next. This allows to use the LIST_SPLICE_END_DETACHED + * macro. */ + first->list.p->n = first->last_reserved->list.n; + first->last_reserved->list.n->p = first->list.p; - shctx_block_set_hot(shctx, block); + /* Reattach to hot list */ + first->list.p = &first->last_reserved->list; + LIST_SPLICE_END_DETACHED(&shctx->hot, &first->list); - count++; - if (count >= first->block_count) - break; - } + shctx->nbav -= first->block_count; } first->refcount++; @@ -170,25 +170,24 @@ void shctx_row_inc_hot(struct shared_context *shctx, struct shared_block *first) */ void shctx_row_dec_hot(struct shared_context *shctx, struct shared_block *first) { - struct shared_block *block, *sblock; - int count = 0; - first->refcount--; if (first->refcount <= 0) { - block = first; + BUG_ON(!first->last_reserved); - list_for_each_entry_safe_from(block, sblock, &shctx->hot, list) { + /* Detach row from hot list, link first item's prev to last + * item's next. This allows to use the LIST_SPLICE_END_DETACHED + * macro. */ + first->list.p->n = first->last_reserved->list.n; + first->last_reserved->list.n->p = first->list.p; - shctx_block_set_avail(shctx, block); + /* Reattach to avail list */ + first->list.p = &first->last_reserved->list; + LIST_SPLICE_END_DETACHED(&shctx->avail, &first->list); - count++; - if (count >= first->block_count) - break; - } + shctx->nbav += first->block_count; } - }