changeset 157:dbfb30f43dae

val: preallocate all possible bool vals Since there are only two possible bool vals, we can preallocate all of them and then just return the right one when a new bool val is requested - avoiding a trip into the memory allocator. One of the consumers of libjeffpc saw almost a 1% reduction in struct val allocations during startup: cache buf buf buf buf memory alloc alloc name size in use in ptc total in use succeed fail ------------------------- ------ ------- ------- ------- ------- --------- ----- val-cache (before) 20 0 - 845 20K 24494 0 val-cache (after) 20 0 - 507 12K 24258 0 Note: This consumer is not a heavy user of VT_BOOL values. Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
date Tue, 11 Apr 2017 11:21:06 -0400
parents 9e156cc8bdb8
children 7cd03c69d379
files include/jeffpc/val.h val.c
diffstat 2 files changed, 28 insertions(+), 8 deletions(-) [+]
line wrap: on
line diff
--- a/include/jeffpc/val.h	Tue Apr 11 11:21:00 2017 -0400
+++ b/include/jeffpc/val.h	Tue Apr 11 11:21:06 2017 -0400
@@ -127,13 +127,8 @@
 		_x;				\
 	})
 
-#define VAL_ALLOC_BOOL(v)			\
-	({					\
-		struct val *_x;			\
-		_x = val_alloc_bool(v);		\
-		ASSERT(_x);			\
-		_x;				\
-	})
+/* never fails */
+#define VAL_ALLOC_BOOL(v)	val_alloc_bool(v)
 
 #define VAL_ALLOC_CONS(head, tail)		\
 	({					\
--- a/val.c	Tue Apr 11 11:21:00 2017 -0400
+++ b/val.c	Tue Apr 11 11:21:06 2017 -0400
@@ -33,6 +33,16 @@
 #include <jeffpc/jeffpc.h>
 #include <jeffpc/error.h>
 
+#define INIT_STATIC_VAL(t, memb, val)				\
+		{						\
+			.type = (t),				\
+			.static_alloc = true,			\
+			.memb = (val),				\
+		}
+
+static const struct val val_true = INIT_STATIC_VAL(VT_BOOL, b, true);
+static const struct val val_false = INIT_STATIC_VAL(VT_BOOL, b, false);
+
 static umem_cache_t *val_cache;
 
 void init_val_subsys(void)
@@ -98,9 +108,24 @@
 DEF_VAL_SET(int, VT_INT, i, uint64_t)
 DEF_VAL_SET(str, VT_STR, str, struct str *)
 DEF_VAL_SET(sym, VT_SYM, str, struct str *)
-DEF_VAL_SET(bool, VT_BOOL, b, bool)
 DEF_VAL_SET(char, VT_CHAR, i, uint64_t)
 
+struct val *val_alloc_bool(bool b)
+{
+	const struct val *ret;
+
+	ret = b ? &val_true : &val_false;
+
+	/*
+	 * Cast away the const - we define the static as const to get it
+	 * into .rodata, but we have to drop the const since everything
+	 * expects struct val to be writable (because refcounts modify it).
+	 * In this case, we won't get any modifications because we're marked
+	 * as static.
+	 */
+	return (struct val *) ret;
+}
+
 struct val *val_alloc_cons(struct val *head, struct val *tail)
 {
 	struct val *val;