IPv6 RA improvements
[vpp.git] / src / vppinfra / pool.h
index e1c89e0..57838e1 100644 (file)
@@ -199,6 +199,33 @@ do {                                                                       \
 /** Allocate an object E from a pool P (unspecified alignment). */
 #define pool_get(P,E) pool_get_aligned(P,E,0)
 
+/** See if pool_get will expand the pool or not */
+#define pool_get_aligned_will_expand (P,YESNO,A)                        \
+do {                                                                    \
+  pool_header_t * _pool_var (p) = pool_header (P);                      \
+  uword _pool_var (l);                                                  \
+                                                                        \
+  _pool_var (l) = 0;                                                    \
+  if (P)                                                                \
+    _pool_var (l) = vec_len (_pool_var (p)->free_indices);              \
+                                                                        \
+  /* Free elements, certainly won't expand */                           \
+  if (_pool_var (l) > 0)                                                \
+      YESNO=0;                                                          \
+  else                                                                  \
+    {                                                                   \
+      /* Nothing on free list, make a new element and return it. */     \
+      YESNO = _vec_resize_will_expand                                   \
+        (P,                                                             \
+         /* length_increment */ 1,                                      \
+         /* new size */ (vec_len (P) + 1) * sizeof (P[0]),              \
+         pool_aligned_header_bytes,                                     \
+         /* align */ (A));                                              \
+    }                                                                   \
+} while (0)
+
+#define pool_get_will_expand(P,YESNO) pool_get_aligned_will_expand(P,YESNO,0)
+
 /** Use free bitmap to query whether given element is free. */
 #define pool_is_free(P,E)                                              \
 ({                                                                     \
@@ -323,6 +350,7 @@ do {                                                                        \
 
     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.
+    Or call pool_flush.
 
 
     @par Example
@@ -394,6 +422,31 @@ do {                                                                       \
        do { body; } while (0);                 \
     }
 
+/**
+ * @brief Remove all elemenets from a pool in a safe way
+ *
+ * @param VAR each element in the pool
+ * @param POOL The pool to flush
+ * @param BODY The actions to perform on each element before it is returned to
+ *        the pool. i.e. before it is 'freed'
+ */
+#define pool_flush(VAR, POOL, BODY)                     \
+{                                                       \
+  uword *_pool_var(ii), *_pool_var(dv) = NULL;          \
+                                                        \
+  pool_foreach((VAR), (POOL),                           \
+  ({                                                    \
+    vec_add1(_pool_var(dv), (VAR) - (POOL));            \
+  }));                                                  \
+  vec_foreach(_pool_var(ii), _pool_var(dv))             \
+  {                                                     \
+    (VAR) = pool_elt_at_index((POOL), *_pool_var(ii));  \
+    do { BODY; } while (0);                             \
+    pool_put((POOL), (VAR));                            \
+  }                                                     \
+  vec_free(_pool_var(dv));                              \
+}
+
 #endif /* included_pool_h */
 
 /*