|
Packit Service |
75d76b |
/*
|
|
Packit Service |
75d76b |
* Copyright (c) 2020 Red Hat, Inc.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* This program is free software; you can redistribute it and/or
|
|
Packit Service |
75d76b |
* modify it under the terms of the GNU General Public License
|
|
Packit Service |
75d76b |
* as published by the Free Software Foundation; either version 2
|
|
Packit Service |
75d76b |
* of the License, or (at your option) any later version.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* This program is distributed in the hope that it will be useful,
|
|
Packit Service |
75d76b |
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
Packit Service |
75d76b |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
Packit Service |
75d76b |
* GNU General Public License for more details.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* You should have received a copy of the GNU General Public License
|
|
Packit Service |
75d76b |
* along with this program; if not, write to the Free Software
|
|
Packit Service |
75d76b |
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA
|
|
Packit Service |
75d76b |
* 02110-1301, USA.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* $Id: //eng/vdo-releases/aluminum/src/c++/vdo/kernel/bufferPool.h#1 $
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
#ifndef BUFFERPOOL_H
|
|
Packit Service |
75d76b |
#define BUFFERPOOL_H
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/*
|
|
Packit Service |
75d76b |
* We need bug.h because in 3.10, kernel.h (indirectly) defines
|
|
Packit Service |
75d76b |
* ARRAY_SIZE as a macro which (indirectly and conditionally) uses
|
|
Packit Service |
75d76b |
* BUILD_BUG_ON_ZERO, which is defined in bug.h, which is *not*
|
|
Packit Service |
75d76b |
* included. In earlier versions like 3.2 it Just Worked.
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
#include <linux/bug.h>
|
|
Packit Service |
75d76b |
#include <linux/kernel.h>
|
|
Packit Service |
75d76b |
#include <linux/types.h>
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
typedef struct bufferPool BufferPool;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
typedef int BufferAllocateFunction(void *poolData, void **dataPtr);
|
|
Packit Service |
75d76b |
typedef void BufferFreeFunction(void *poolData, void *data);
|
|
Packit Service |
75d76b |
typedef void BufferDumpFunction(void *poolData, void *data);
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Creates a generic pool of buffer data. The elements in the pool are
|
|
Packit Service |
75d76b |
* allocated up front and placed on a free list, which manages the
|
|
Packit Service |
75d76b |
* reuse of the individual buffers in the pool.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] poolName Name of the pool
|
|
Packit Service |
75d76b |
* @param [in] size The number of elements to create for this pool
|
|
Packit Service |
75d76b |
* @param [in] allocateFunction The function to call to create the actual data
|
|
Packit Service |
75d76b |
* for each element
|
|
Packit Service |
75d76b |
* @param [in] freeFunction The function to call to free the actual data
|
|
Packit Service |
75d76b |
* for each element
|
|
Packit Service |
75d76b |
* @param [in] dumpFunction The function to call to dump the actual data
|
|
Packit Service |
75d76b |
* for each element into the log
|
|
Packit Service |
75d76b |
* @param [in] poolData A pointer to the pool's associated data
|
|
Packit Service |
75d76b |
* @param [out] poolPtr A pointer to hold the pool that was created
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @return a success or error code
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
int makeBufferPool(const char *poolName,
|
|
Packit Service |
75d76b |
unsigned int size,
|
|
Packit Service |
75d76b |
BufferAllocateFunction *allocateFunction,
|
|
Packit Service |
75d76b |
BufferFreeFunction *freeFunction,
|
|
Packit Service |
75d76b |
BufferDumpFunction *dumpFunction,
|
|
Packit Service |
75d76b |
void *poolData,
|
|
Packit Service |
75d76b |
BufferPool **poolPtr)
|
|
Packit Service |
75d76b |
__attribute__((warn_unused_result));
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Free a buffer pool and null out the reference to it. This will free
|
|
Packit Service |
75d76b |
* all the elements of the pool as well.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] poolPtr The reference to the pool to free
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
void freeBufferPool(BufferPool **poolPtr);
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Dump a buffer pool to the log.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] pool The buffer pool to allocate from
|
|
Packit Service |
75d76b |
* @param [in] dumpElements True for complete output, or false for a
|
|
Packit Service |
75d76b |
* one-line summary
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
void dumpBufferPool(BufferPool *pool, bool dumpElements);
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Acquires a free buffer from the free list of the pool and
|
|
Packit Service |
75d76b |
* returns it's associated data.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] pool The buffer pool to allocate from
|
|
Packit Service |
75d76b |
* @param [out] dataPtr A pointer to hold the buffer data
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @return a success or error code
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
int allocBufferFromPool(BufferPool *pool, void **dataPtr)
|
|
Packit Service |
75d76b |
__attribute__((warn_unused_result));
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Returns a buffer to the free list of a pool
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] pool The buffer pool to return the buffer to
|
|
Packit Service |
75d76b |
* @param [in] data The buffer data to return
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
void freeBufferToPool(BufferPool *pool, void *data);
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Returns a set of buffers to the free list of a pool
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] pool The buffer pool to return the buffer to
|
|
Packit Service |
75d76b |
* @param [in] data The buffer data to return
|
|
Packit Service |
75d76b |
* @param [in] count Number of entries in the data array
|
|
Packit Service |
75d76b |
*/
|
|
Packit Service |
75d76b |
void freeBuffersToPool(BufferPool *pool, void **data, int count);
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Control structure for freeing (releasing back to the pool) pointers
|
|
Packit Service |
75d76b |
* in batches.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* Since the objects stored in a buffer pool are completely opaque,
|
|
Packit Service |
75d76b |
* some external data structure is needed to manage a collection of
|
|
Packit Service |
75d76b |
* them. This is a simple helper for doing that, since we're freeing
|
|
Packit Service |
75d76b |
* batches of objects in a couple different places. Within the pool
|
|
Packit Service |
75d76b |
* itself there's a pair of linked lists, but getting at them requires
|
|
Packit Service |
75d76b |
* the locking that we're trying to minimize.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* We collect pointers until the array is full or until there are no
|
|
Packit Service |
75d76b |
* more available, and we call freeBuffersToPool to release a batch
|
|
Packit Service |
75d76b |
* all at once.
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
typedef struct freeBufferPointers {
|
|
Packit Service |
75d76b |
BufferPool *pool;
|
|
Packit Service |
75d76b |
int index;
|
|
Packit Service |
75d76b |
void *pointers[30]; // size is arbitrary
|
|
Packit Service |
75d76b |
} FreeBufferPointers;
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Initialize the control structure for batching buffer pointers to be
|
|
Packit Service |
75d76b |
* released to their pool.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [out] fbp The (caller-allocated) control structure
|
|
Packit Service |
75d76b |
* @param [in] pool The buffer pool to return objects to.
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
static inline void initFreeBufferPointers(FreeBufferPointers *fbp,
|
|
Packit Service |
75d76b |
BufferPool *pool)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
fbp->index = 0;
|
|
Packit Service |
75d76b |
fbp->pool = pool;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Release any buffers left in the collection.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] fbp The control structure
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
static inline void freeBufferPointers(FreeBufferPointers *fbp)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
freeBuffersToPool(fbp->pool, fbp->pointers, fbp->index);
|
|
Packit Service |
75d76b |
fbp->index = 0;
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
/**
|
|
Packit Service |
75d76b |
* Add another buffer pointer to the collection, and if we're full,
|
|
Packit Service |
75d76b |
* release the whole batch to the pool.
|
|
Packit Service |
75d76b |
*
|
|
Packit Service |
75d76b |
* @param [in] fbp The control structure
|
|
Packit Service |
75d76b |
* @param [in] pointer The buffer pointer to release
|
|
Packit Service |
75d76b |
**/
|
|
Packit Service |
75d76b |
static inline void addFreeBufferPointer(FreeBufferPointers *fbp,
|
|
Packit Service |
75d76b |
void *pointer)
|
|
Packit Service |
75d76b |
{
|
|
Packit Service |
75d76b |
fbp->pointers[fbp->index] = pointer;
|
|
Packit Service |
75d76b |
fbp->index++;
|
|
Packit Service |
75d76b |
if (fbp->index == ARRAY_SIZE(fbp->pointers)) {
|
|
Packit Service |
75d76b |
freeBufferPointers(fbp);
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
}
|
|
Packit Service |
75d76b |
|
|
Packit Service |
75d76b |
#endif /* BUFFERPOOL_H */
|