]> git.ipfire.org Git - thirdparty/haproxy.git/commitdiff
MINOR: pool: add a function to estimate how many may be released at once
authorWilly Tarreau <w@1wt.eu>
Sat, 1 Jan 2022 23:21:46 +0000 (00:21 +0100)
committerWilly Tarreau <w@1wt.eu>
Sun, 2 Jan 2022 18:35:26 +0000 (19:35 +0100)
At the moment we count the number of releasable objects to a shared pool
one by one. The way the formula is made allows to pre-compute the number
of available slots, so let's add a function for that so that callers can
do it once before iterating.

This takes into account the average number of entries needed and the
minimum availability per pool. The function is not used yet.

include/haproxy/pool.h

index 6ee411066fdabe4c5d674d34c6ff0b84a23f3a70..714a843d576e79aa081fc7515eb81a9a6d6060f4 100644 (file)
@@ -118,6 +118,12 @@ static inline int pool_is_crowded(const struct pool_head *pool)
        return 1;
 }
 
+static inline uint pool_releasable(const struct pool_head *pool)
+{
+       /* no room left */
+       return 0;
+}
+
 static inline void pool_refill_local_from_shared(struct pool_head *pool, struct pool_cache_head *pch)
 {
        /* ignored without shared pools */
@@ -140,6 +146,33 @@ static inline int pool_is_crowded(const struct pool_head *pool)
               (int)(pool->allocated - pool->used) >= pool->minavail;
 }
 
+/* Returns the max number of entries that may be brought back to the pool
+ * before it's considered as full. Note that it is only usable for releasing
+ * objects, hence the function assumes that no more than ->used entries will
+ * be released in the worst case, and that this value is always lower than or
+ * equal to ->allocated. It's important to understand that under thread
+ * contention these values may not always be accurate but the principle is that
+ * any deviation remains contained.
+ */
+static inline uint pool_releasable(const struct pool_head *pool)
+{
+       uint alloc, used;
+
+       alloc = HA_ATOMIC_LOAD(&pool->allocated);
+       used = HA_ATOMIC_LOAD(&pool->used);
+       if (used < alloc)
+               used = alloc;
+
+       if (alloc < swrate_avg(pool->needed_avg + pool->needed_avg / 4, POOL_AVG_SAMPLES))
+               return used; // less than needed is allocated, can release everything
+
+       if ((uint)(alloc - used) < pool->minavail)
+               return pool->minavail - (alloc - used); // less than minimum available
+
+       /* there are enough objects in this pool */
+       return 0;
+}
+
 
 #endif /* CONFIG_HAP_NO_GLOBAL_POOLS */