dpdk: add rte_delay_us_callback
[vpp.git] / vppinfra / vppinfra / pool.h
index c6235e6..e1c89e0 100644 (file)
   OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
   WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 */
+/** @file
+ * @brief Fixed length block allocator.
+   Pools are built from clib vectors and bitmaps. Use pools when
+   repeatedly allocating and freeing fixed-size data. Pools are
+   fast, and avoid memory fragmentation.
+ */
 
 #ifndef included_pool_h
 #define included_pool_h
 #include <vppinfra/error.h>
 #include <vppinfra/mheap.h>
 
-/* Pools are built from clib vectors and bitmaps. Use pools when
-   repeatedly allocating and freeing fixed-size data. Pools are
-   fast, and avoid memory fragmentation. */
 
-typedef struct {
-  /* Bitmap of indices of free objects. */
-  uword * free_bitmap;
+typedef struct
+{
+  /** Bitmap of indices of free objects. */
+  uword *free_bitmap;
 
-  /* Vector of free indices.  One element for each set bit in bitmap. */
-  u32 * free_indices;
+  /** Vector of free indices.  One element for each set bit in bitmap. */
+  u32 *free_indices;
 } pool_header_t;
 
-/* Align pool header so that pointers are naturally aligned. */
+/** Align pool header so that pointers are naturally aligned. */
 #define pool_aligned_header_bytes \
   vec_aligned_header_bytes (sizeof (pool_header_t), sizeof (void *))
 
-/* Get pool header from user pool pointer */
-always_inline pool_header_t * pool_header (void * v)
-{ return vec_aligned_header (v, sizeof (pool_header_t), sizeof (void *)); }
+/** Get pool header from user pool pointer */
+always_inline pool_header_t *
+pool_header (void *v)
+{
+  return vec_aligned_header (v, sizeof (pool_header_t), sizeof (void *));
+}
 
-/* Validate a pool */
-always_inline void pool_validate (void * v)
+/** Validate a pool */
+always_inline void
+pool_validate (void *v)
 {
-  pool_header_t * p = pool_header (v);
+  pool_header_t *p = pool_header (v);
   uword i, n_free_bitmap;
 
-  if (! v)
+  if (!v)
     return;
 
   n_free_bitmap = clib_bitmap_count_set_bits (p->free_bitmap);
@@ -77,9 +85,10 @@ always_inline void pool_validate (void * v)
     ASSERT (clib_bitmap_get (p->free_bitmap, p->free_indices[i]) == 1);
 }
 
-always_inline void pool_header_validate_index (void * v, uword index)
+always_inline void
+pool_header_validate_index (void *v, uword index)
 {
-  pool_header_t * p = pool_header (v);
+  pool_header_t *p = pool_header (v);
 
   if (v)
     vec_validate (p->free_bitmap, index / BITS (uword));
@@ -93,8 +102,11 @@ do {                                                                \
   pool_header_validate_index ((v), __pool_validate_index);     \
 } while (0)
 
-/* Number of active elements in a pool */
-always_inline uword pool_elts (void * v)
+/** Number of active elements in a pool.
+ * @return Number of active elements in a pool
+ */
+always_inline uword
+pool_elts (void *v)
 {
   uword ret = vec_len (v);
   if (v)
@@ -102,55 +114,57 @@ always_inline uword pool_elts (void * v)
   return ret;
 }
 
-/* Number of elements in pool vector
+/** Number of elements in pool vector.
 
-    Note: you probably want to call pool_elts() instead
+    @note You probably want to call pool_elts() instead.
 */
 #define pool_len(p)    vec_len(p)
-/* Number of elements in pool vector (usable as an lvalue)
 
-    Note: you probably don't want to use this macro
+/** Number of elements in pool vector (usable as an lvalue)
+
+    @note You probably don't want to use this macro.
 */
 #define _pool_len(p)   _vec_len(p)
 
-/*Memory usage of pool header */
+/** Memory usage of pool header. */
 always_inline uword
-pool_header_bytes (void * v)
+pool_header_bytes (void *v)
 {
-  pool_header_t * p = pool_header (v);
+  pool_header_t *p = pool_header (v);
 
-  if (! v)
+  if (!v)
     return 0;
 
   return vec_bytes (p->free_bitmap) + vec_bytes (p->free_indices);
 }
 
-/*Memory usage of pool */
+/** Memory usage of pool. */
 #define pool_bytes(P) (vec_bytes (P) + pool_header_bytes (P))
 
-/*Local variable naming macro. */
+/*Local variable naming macro. */
 #define _pool_var(v) _pool_##v
 
-/*Queries whether pool has at least N_FREE free elements. */
+/*Queries whether pool has at least N_FREE free elements. */
 always_inline uword
-pool_free_elts (void * v)
+pool_free_elts (void *v)
 {
-  pool_header_t * p = pool_header (v);
+  pool_header_t *p = pool_header (v);
   uword n_free = 0;
 
-  if (v) {
-    n_free += vec_len (p->free_indices);
+  if (v)
+    {
+      n_free += vec_len (p->free_indices);
 
-    /* Space left at end of vector? */
-    n_free += vec_capacity (v, sizeof (p[0])) - vec_len (v);
-  }
+      /* Space left at end of vector? */
+      n_free += vec_capacity (v, sizeof (p[0])) - vec_len (v);
+    }
 
   return n_free;
 }
 
-/* Allocate an object E from a pool P (general version)
+/** Allocate an object E from a pool P (general version).
 
-   First search free list.  If nothing is free extend vector of objects
+   First search free list.  If nothing is free extend vector of objects.
 */
 #define pool_get_aligned(P,E,A)                                                \
 do {                                                                   \
@@ -182,21 +196,21 @@ do {                                                                      \
     }                                                                  \
 } while (0)
 
-/* Allocate an object E from a pool P (unspecified alignment) */
+/** Allocate an object E from a pool P (unspecified alignment). */
 #define pool_get(P,E) pool_get_aligned(P,E,0)
 
-/* Use free bitmap to query whether given element is free */
+/** Use free bitmap to query whether given element is free. */
 #define pool_is_free(P,E)                                              \
 ({                                                                     \
   pool_header_t * _pool_var (p) = pool_header (P);                     \
   uword _pool_var (i) = (E) - (P);                                     \
   (_pool_var (i) < vec_len (P)) ? clib_bitmap_get (_pool_var (p)->free_bitmap, _pool_i) : 1; \
 })
-  
-/* Use free bitmap to query whether given index is free */
+
+/** Use free bitmap to query whether given index is free */
 #define pool_is_free_index(P,I) pool_is_free((P),(P)+(I))
 
-/* Free an object E in pool P */
+/** Free an object E in pool P. */
 #define pool_put(P,E)                                                  \
 do {                                                                   \
   pool_header_t * _pool_var (p) = pool_header (P);                     \
@@ -210,14 +224,14 @@ do {                                                                      \
   vec_add1 (_pool_var (p)->free_indices, _pool_var (l));               \
 } while (0)
 
-/* Free pool element with given index. */
+/** Free pool element with given index. */
 #define pool_put_index(p,i)                    \
 do {                                           \
   typeof (p) _e = (p) + (i);                   \
   pool_put (p, _e);                            \
 } while (0)
 
-/* Allocate N more free elements to pool (general version) */
+/** Allocate N more free elements to pool (general version). */
 #define pool_alloc_aligned(P,N,A)                                      \
 do {                                                                   \
   pool_header_t * _p;                                                  \
@@ -229,14 +243,15 @@ do {                                                                      \
   _vec_len (_p->free_indices) -= (N);                                  \
 } while (0)
 
-/* Allocate N more free elements to pool (unspecified alignment) */
+/** Allocate N more free elements to pool (unspecified alignment). */
 #define pool_alloc(P,N) pool_alloc_aligned(P,N,0)
 
-/* low-level free pool operator (do not call directly) */
-always_inline void * _pool_free (void * v)
+/** Low-level free pool operator (do not call directly). */
+always_inline void *
+_pool_free (void *v)
 {
-  pool_header_t * p = pool_header (v);
-  if (! v)
+  pool_header_t *p = pool_header (v);
+  if (!v)
     return v;
   clib_bitmap_free (p->free_bitmap);
   vec_free (p->free_indices);
@@ -244,17 +259,17 @@ always_inline void * _pool_free (void * v)
   return 0;
 }
 
-/* Free a pool. */
+/** Free a pool. */
 #define pool_free(p) (p) = _pool_free(p)
 
-/* Optimized iteration through pool 
+/** Optimized iteration through pool.
 
     @param LO pointer to first element in chunk
     @param HI pointer to last element in chunk
     @param POOL pool to iterate across
     @param BODY operation to perform
 
-    Optimized version which assumes that BODY is smart enough to 
+    Optimized version which assumes that BODY is smart enough to
     process multiple (LOW,HI) chunks. See also pool_foreach().
  */
 #define pool_foreach_region(LO,HI,POOL,BODY)                           \
@@ -296,34 +311,39 @@ do {                                                                      \
     }                                                                  \
 } while (0)
 
-/* Iterate through pool 
+/** Iterate through pool.
 
-    @param VAR variable of same type as pool vector
-    @param POOL pool to iterate across
-    @param BODY operation to perform. See the example below.
+    @param VAR A variable of same type as pool vector to be used as an
+               iterator.
+    @param POOL The pool to iterate across.
+    @param BODY The operation to perform, typically a code block. See
+                the example below.
 
-    call BODY with each active pool element.
+    This macro will call @c BODY with each active pool element.
 
-    Example:
-    proc_t *procs;   // a pool of processes <br>
-    proc_t *proc;    // pointer to one process <br>
+    It is a bad idea to allocate or free pool element from within
+    @c pool_foreach. Build a vector of indices and dispose of them later.
 
-    pool_foreach (proc, procs, ({
-    <br>
-    &nbsp;&nbsp;if (proc->state != PROC_STATE_RUNNING)<br>
-    &nbsp;&nbsp;&nbsp;&nbsp;continue;
-    <br>
-    &nbsp;&nbsp;<i>check a running proc in some way</i><br>
-    &nbsp;&nbsp;}));
 
-    It is a bad idea to allocate or free pool element from within
-    pool_foreach. Build a vector of indices and dispose of them later.
+    @par Example
+    @code{.c}
+    proc_t *procs;   // a pool of processes.
+    proc_t *proc;    // pointer to one process; used as the iterator.
 
-    Because pool_foreach is a macro, syntax errors can be difficult to
-    find inside BODY, let alone actual code bugs. One can temporarily
-    split a complex pool_foreach into a trivial pool_foreach which
-    builds a vector of active indices, and a vec_foreach() (or plain
-    for-loop) to walk the active index vector.
+    pool_foreach (proc, procs, ({
+        if (proc->state != PROC_STATE_RUNNING)
+            continue;
+
+        // check a running proc in some way
+        ...
+    }));
+    @endcode
+
+    @warning Because @c pool_foreach is a macro, syntax errors can be
+    difficult to find inside @c BODY, let alone actual code bugs. One
+    can temporarily split a complex @c pool_foreach into a trivial
+    @c pool_foreach which builds a vector of active indices, and a
+    vec_foreach() (or plain for-loop) to walk the active index vector.
  */
 #define pool_foreach(VAR,POOL,BODY)                                    \
 do {                                                                   \
@@ -337,11 +357,14 @@ do {                                                                      \
     }));                                                               \
 } while (0)
 
-/* Returns pointer to element at given index
+/** Returns pointer to element at given index.
 
-    ASSERTs that the supplied index is valid. Even though
-    one can write correct code of the form "p = pool_base + index",
-    use of pool_elt_at_index is strongly suggested. 
+    ASSERTs that the supplied index is valid.
+    Even though one can write correct code of the form
+    @code
+        p = pool_base + index;
+    @endcode
+    use of @c pool_elt_at_index is strongly suggested.
  */
 #define pool_elt_at_index(p,i)                 \
 ({                                             \
@@ -350,7 +373,7 @@ do {                                                                        \
   _e;                                          \
 })
 
-/* Return next occupied pool index after i, useful for safe iteration */
+/** Return next occupied pool index after @c i, useful for safe iteration. */
 #define pool_next_index(P,I)                                            \
 ({                                                                      \
   pool_header_t * _pool_var (p) = pool_header (P);                      \
@@ -363,6 +386,7 @@ do {                                                                        \
   _pool_var(rv);                                                        \
 })
 
+/** Iterate pool by index. */
 #define pool_foreach_index(i,v,body)           \
   for ((i) = 0; (i) < vec_len (v); (i)++)      \
     {                                          \
@@ -371,3 +395,11 @@ do {                                                                       \
     }
 
 #endif /* included_pool_h */
+
+/*
+ * fd.io coding-style-patch-verification: ON
+ *
+ * Local Variables:
+ * eval: (c-set-style "gnu")
+ * End:
+ */