summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDave Barach <dave@barachs.net>2017-02-06 09:28:03 -0500
committerDamjan Marion <dmarion.lists@gmail.com>2017-02-06 23:34:56 +0000
commit614ac5da53bca8c8fad5733e6749ec8753c52f28 (patch)
tree86daea64a2865d5cb363f2735a4381b1a6b3952e
parent104543fa6a836df84b5b6d9b1909df3d5226a1e7 (diff)
Add pool_get[_aligned]_will_expand(...)
Change-Id: Iefffcf7843dc11803d69a875a72704a2543911a1 Signed-off-by: Dave Barach <dave@barachs.net>
-rw-r--r--src/vppinfra/pool.h27
-rw-r--r--src/vppinfra/vec.h40
2 files changed, 67 insertions, 0 deletions
diff --git a/src/vppinfra/pool.h b/src/vppinfra/pool.h
index e1c89e0a5fa..586d13e73a9 100644
--- a/src/vppinfra/pool.h
+++ b/src/vppinfra/pool.h
@@ -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) \
({ \
diff --git a/src/vppinfra/vec.h b/src/vppinfra/vec.h
index eed96d6b9c2..d70e9ce1276 100644
--- a/src/vppinfra/vec.h
+++ b/src/vppinfra/vec.h
@@ -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).