extern THREAD_LOCAL size_t pool_cache_bytes; /* total cache size */
extern THREAD_LOCAL size_t pool_cache_count; /* #cache objects */
-void pool_evict_from_local_cache(struct pool_head *pool);
+void pool_evict_from_local_cache(struct pool_head *pool, int full);
void pool_evict_from_local_caches(void);
void pool_put_to_cache(struct pool_head *pool, void *ptr, const void *caller);
* objects is no more than 16+1/8 of the total number of locally cached objects
* or the total size of the local cache is no more than 75% of its maximum (i.e.
* we don't want a single cache to use all the cache for itself). For this, the
- * list is scanned in reverse.
+ * list is scanned in reverse. If <full> is non-null, all objects are evicted.
*/
-void pool_evict_from_local_cache(struct pool_head *pool)
+void pool_evict_from_local_cache(struct pool_head *pool, int full)
{
struct pool_cache_head *ph = &pool->cache[tid];
- while (ph->count >= CONFIG_HAP_POOL_CLUSTER_SIZE &&
- ph->count >= 16 + pool_cache_count / 8 &&
- pool_cache_bytes > CONFIG_HAP_POOL_CACHE_SIZE * 3 / 4) {
+ while ((ph->count && full) ||
+ (ph->count >= CONFIG_HAP_POOL_CLUSTER_SIZE &&
+ ph->count >= 16 + pool_cache_count / 8 &&
+ pool_cache_bytes > CONFIG_HAP_POOL_CACHE_SIZE * 3 / 4)) {
pool_evict_last_items(pool, ph, CONFIG_HAP_POOL_CLUSTER_SIZE);
}
}
if (unlikely(pool_cache_bytes > CONFIG_HAP_POOL_CACHE_SIZE * 3 / 4)) {
if (ph->count >= 16 + pool_cache_count / 8 + CONFIG_HAP_POOL_CLUSTER_SIZE)
- pool_evict_from_local_cache(pool);
+ pool_evict_from_local_cache(pool, 0);
if (pool_cache_bytes > CONFIG_HAP_POOL_CACHE_SIZE)
pool_evict_from_local_caches();
}
void *pool_destroy(struct pool_head *pool)
{
if (pool) {
+#ifdef CONFIG_HAP_POOLS
+ pool_evict_from_local_cache(pool, 1);
+#endif
pool_flush(pool);
if (pool->used)
return pool;