Add pool_get[_aligned]_will_expand(...) 40/5040/2
authorDave Barach <dave@barachs.net>
Mon, 6 Feb 2017 14:28:03 +0000 (09:28 -0500)
committerDamjan Marion <dmarion.lists@gmail.com>
Mon, 6 Feb 2017 23:34:56 +0000 (23:34 +0000)
Change-Id: Iefffcf7843dc11803d69a875a72704a2543911a1
Signed-off-by: Dave Barach <dave@barachs.net>
src/vppinfra/pool.h
src/vppinfra/vec.h

index e1c89e0..586d13e 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)                                              \
 ({                                                                     \
index eed96d6..d70e9ce 100644 (file)
@@ -145,6 +145,46 @@ _vec_resize (void *v,
                                               data_align));
 }
 
+/** \brief Low-level vector resize predicate
+
+    @param v pointer to a vector
+    @param length_increment length increment in elements
+    @param data_bytes requested size in bytes
+    @param header_bytes header size in bytes (may be zero)
+    @param data_align alignment (may be zero)
+    @return v_prime pointer to resized vector, may or may not equal v
+*/
+
+always_inline int
+_vec_resize_will_expand (void *v,
+                        word length_increment,
+                        uword data_bytes, uword header_bytes,
+                        uword data_align)
+{
+  vec_header_t *vh = _vec_find (v);
+  uword new_data_bytes, aligned_header_bytes;
+
+  aligned_header_bytes = vec_header_bytes (header_bytes);
+
+  new_data_bytes = data_bytes + aligned_header_bytes;
+
+  if (PREDICT_TRUE (v != 0))
+    {
+      void *p = v - aligned_header_bytes;
+
+      /* Vector header must start heap object. */
+      ASSERT (clib_mem_is_heap_object (p));
+
+      /* Typically we'll not need to resize. */
+      if (new_data_bytes <= clib_mem_size (p))
+       {
+         vh->len += length_increment;
+         return 0;
+       }
+    }
+  return 1;
+}
+
 /** \brief Predicate function, says whether the supplied vector is a clib heap
     object (general version).