X-Git-Url: https://codewiz.org/gitweb?a=blobdiff_plain;f=bertos%2Fstruct%2Fpool.h;h=f59fe2e4ba89a3fb720b9b5a63bef5b46a57c345;hb=97e93eec653e38a04e94e5191bdbf5ea48edde96;hp=40ac79c7c3813fee32a255bfa850c899c4a54143;hpb=bd8ab60a4880319bec0f04d75a7805aa687139af;p=bertos.git diff --git a/bertos/struct/pool.h b/bertos/struct/pool.h index 40ac79c7..f59fe2e4 100644 --- a/bertos/struct/pool.h +++ b/bertos/struct/pool.h @@ -26,12 +26,54 @@ * invalidate any other reasons why the executable file might be covered by * the GNU General Public License. * - * Copyright 2004, 2008 Develer S.r.l. (http://www.develer.com/) + * Copyright 2004, 2008, 2011 Develer S.r.l. (http://www.develer.com/) * --> * + * \defgroup pool Pool memory allocator + * \ingroup struct + * \{ + * * \brief Pool macros. * + * The pool module provides the boilerplate code to create a set of objects + * of the same type. + * It provides an interface similar to the heap module, with pool_alloc() and + * pool_free() functions that allocate and free an element respectively. + * In contrast with the heap module, you can specify exactly the number of + * items that you want to be in the pool. + * + * Items in the pool must be a derived class of Node *, which also + * means that they can be used as-is with list containers, eg. MsgPort. + * + * Example code: + * \code + * typedef struct MyType + * { + * Node *n; + * uint16_t *buf; + * // other members here... + * } MyType; + * + * DEFINE_POOL(mypool, MyType, POOL_SIZE); + * + * static void elem_init(MyType *e) + * { + * e->buf = NULL; + * // other initializations here + * } + * + * int main(void) + * { + * pool_init(&mypool, elem_init); + * + * MyType *foo = pool_alloc(&mypool); + * // do stuff with foo + * pool_free(&mypool, foo); + * } + * \endcode + * * \author Giovanni Bajo + * \author Luca Ottaviano */ #ifndef STRUCT_POOL_H @@ -40,10 +82,13 @@ #include #include +/** + * \brief Extern pool declaration + */ #define EXTERN_POOL(name) \ extern List name -#define DECLARE_POOL_WITH_STORAGE(name, type, num, storage) \ +#define DEFINE_POOL_WITH_STORAGE(name, type, num, storage) \ static type name##_items[num]; \ storage name; \ INLINE void name##_init(void (*init_func)(type*)) \ @@ -59,15 +104,83 @@ INLINE void name##_init(void (*init_func)(type*)) \ /**/ -#define DECLARE_POOL(name, type, num) \ - DECLARE_POOL_WITH_STORAGE(name, type, num, List) +/* For backwards compatibily */ +#define DECLARE_POOL_WITH_STORAGE DEFINE_POOL_WITH_STORAGE + +/** + * \brief Helper macro to declare a Pool data type. + * + * Data type inserted into the pool must be a Node * + * type. + * + * \param name Variable name of the pool. + * \param type Data type held by the pool. + * \param num Number of elements in pool. + */ +#define DEFINE_POOL(name, type, num) \ + DEFINE_POOL_WITH_STORAGE(name, type, num, List) + +/* For backwards compatibily */ +#define DECLARE_POOL DEFINE_POOL + +/** + * \brief Static Pool declaration + * + * \sa DEFINE_POOL + */ +#define DEFINE_POOL_STATIC(name, type, num) \ + DEFINE_POOL_WITH_STORAGE(name, type, num, static List) -#define DECLARE_POOL_STATIC(name, type, num) \ - DECLARE_POOL_WITH_STORAGE(name, type, num, static List) +/* For backwards compatibily */ +#define DECLARE_POOL_STATIC DEFINE_POOL_STATIC +/** + * Initialize the pool \a name, calling \a init_func on each element. + * + * The init function must have the following prototype: + * \code + * void init_func(type *) + * \endcode + * where \a type is the type of objects held in the pool. + * + * \param name Pool to initialize + * \param init_func Init function to be called on each element + */ #define pool_init(name, init_func) (*(name##_init))(init_func) + +/** + * \brief Allocate an element from the pool. + * + * The returned element is of type Node *, it's safe to + * cast it to the type contained in the pool. + * + * \note If the element was recycled with pool_free(), it will not be reset, + * so don't assume that the element has specific values. + * + * \param name Pointer to pool to alloc from. + * \return Element of the type present in the pool. + */ #define pool_alloc(name) list_remHead(name) + +/** + * \brief Recycle an element into the pool + * + * \note Element fields are not reset to its original values, keep that in + * mind when you alloc nodes. + * + * \param name Pointer to pool where the node should be recycled. + * \param elem Element to be recycled. + */ #define pool_free(name, elem) ADDHEAD(name, (Node*)elem) + +/** + * \brief Test if the pool is empty + * + * \param name Pointer to pool. + * \return True if the pool is empty, false otherwise. + */ #define pool_empty(name) LIST_EMPTY(name) + /** \} */ /* defgroup pool */ + #endif /* STRUCT_POOL_H */