include/cc_pool.h (74 lines of code) (raw):

/* * ccommon - a cache common library. * Copyright (C) 2013 Twitter, Inc. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ #pragma once #ifdef __cplusplus extern "C" { #endif #include <cc_debug.h> #include <cc_queue.h> #include <inttypes.h> #include <stdbool.h> #define FREEPOOL(pool, name, type) \ STAILQ_HEAD(name, type); \ struct pool { \ struct name freeq; \ uint32_t nfree; \ uint32_t nused; \ uint32_t nmax; \ bool initialized; \ } #define FREEPOOL_CREATE(pool, max) do { \ ASSERT(!(pool)->initialized); \ STAILQ_INIT(&(pool)->freeq); \ (pool)->nmax = (max) > 0 ? (max) : UINT32_MAX; \ (pool)->nfree = 0; \ (pool)->nused = 0; \ (pool)->initialized = true; \ } while (0) #define FREEPOOL_DESTROY(var, tvar, pool, field, destroy) do { \ ASSERT((pool)->initialized); \ ASSERT((pool)->nused == 0); \ STAILQ_FOREACH_SAFE(var, &(pool)->freeq, field, tvar) { \ STAILQ_REMOVE_HEAD(&(pool)->freeq, next); \ (pool)->nfree--; \ destroy(&var); \ } \ (pool)->initialized = false; \ ASSERT((pool)->nfree == 0); \ ASSERT(STAILQ_EMPTY(&(pool)->freeq)); \ } while (0) #define FREEPOOL_PREALLOC(var, pool, size, field, create) do { \ ASSERT((pool)->initialized); \ while ((pool)->nfree < size) { \ (var) = create(); \ if ((var) != NULL) { \ STAILQ_INSERT_HEAD(&(pool)->freeq, var, field); \ (pool)->nfree++; \ } else { \ break; \ } \ } \ } while (0) #define FREEPOOL_BORROW(var, pool, field, create) do { \ ASSERT((pool)->initialized); \ if (!STAILQ_EMPTY(&(pool)->freeq)) { \ (var) = STAILQ_FIRST(&(pool)->freeq); \ STAILQ_REMOVE_HEAD(&(pool)->freeq, field); \ (pool)->nfree--; \ } else if ((pool)->nfree + (pool)->nused < (pool)->nmax) { \ (var) = create(); \ } else { \ (var) = NULL; \ } \ if ((var) != NULL) { \ (pool)->nused++; \ STAILQ_NEXT((var), field) = NULL; \ } \ } while (0) #define FREEPOOL_RETURN(var, pool, field) do { \ ASSERT((pool)->initialized); \ STAILQ_INSERT_HEAD(&(pool)->freeq, var, field); \ (pool)->nfree++; \ (pool)->nused--; \ } while (0) #ifdef __cplusplus } #endif