Mercurial > libjeffpc
annotate val.c @ 158:7cd03c69d379
val: preallocate int vals for [0,10)
Since many programs use small integers often, we can preallocate them and just
return the right one when a new int is requested. This avoids a trip to the
heap. If we don't have a preallocated one, we just allocate a new one from the
heap.
One of the consumers of libjeffpc saw almost a 4% 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 - 507 12K 24258 0
val-cache (after) 20 0 - 507 12K 23341 0
Note: This consumer is not a heavy user of VT_INT values.
Signed-off-by: Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
author | Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
---|---|
date | Tue, 11 Apr 2017 11:21:20 -0400 |
parents | dbfb30f43dae |
children | 11d55479b0e1 |
rev | line source |
---|---|
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
1 /* |
129
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
2 * Copyright (c) 2014-2017 Josef 'Jeff' Sipek <jeffpc@josefsipek.net> |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
3 * |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
4 * Permission is hereby granted, free of charge, to any person obtaining a copy |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
5 * of this software and associated documentation files (the "Software"), to deal |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
6 * in the Software without restriction, including without limitation the rights |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
8 * copies of the Software, and to permit persons to whom the Software is |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
9 * furnished to do so, subject to the following conditions: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
10 * |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
11 * The above copyright notice and this permission notice shall be included in |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
12 * all copies or substantial portions of the Software. |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
13 * |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
20 * SOFTWARE. |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
21 */ |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
22 |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
23 #include <string.h> |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
24 #include <errno.h> |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
25 #include <stddef.h> |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
26 #include <stdio.h> |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
27 #include <stdbool.h> |
129
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
28 #include <ctype.h> |
58
260a210c9e84
val: include inttypes.h for PRIu64
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
19
diff
changeset
|
29 #include <inttypes.h> |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
30 #include <umem.h> |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
31 |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
32 #include <jeffpc/val.h> |
19
017a4abcfe3d
init: add a single initialize-the-library function
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
9
diff
changeset
|
33 #include <jeffpc/jeffpc.h> |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
34 #include <jeffpc/error.h> |
158
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
35 #include <jeffpc/types.h> |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
36 |
157
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
37 #define INIT_STATIC_VAL(t, memb, val) \ |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
38 { \ |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
39 .type = (t), \ |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
40 .static_alloc = true, \ |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
41 .memb = (val), \ |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
42 } |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
43 |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
44 static const struct val val_true = INIT_STATIC_VAL(VT_BOOL, b, true); |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
45 static const struct val val_false = INIT_STATIC_VAL(VT_BOOL, b, false); |
158
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
46 static const struct val val_ints[10] = { |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
47 [0] = INIT_STATIC_VAL(VT_INT, i, 0), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
48 [1] = INIT_STATIC_VAL(VT_INT, i, 1), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
49 [2] = INIT_STATIC_VAL(VT_INT, i, 2), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
50 [3] = INIT_STATIC_VAL(VT_INT, i, 3), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
51 [4] = INIT_STATIC_VAL(VT_INT, i, 4), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
52 [5] = INIT_STATIC_VAL(VT_INT, i, 5), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
53 [6] = INIT_STATIC_VAL(VT_INT, i, 6), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
54 [7] = INIT_STATIC_VAL(VT_INT, i, 7), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
55 [8] = INIT_STATIC_VAL(VT_INT, i, 8), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
56 [9] = INIT_STATIC_VAL(VT_INT, i, 9), |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
57 }; |
157
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
58 |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
59 static umem_cache_t *val_cache; |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
60 |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
61 void init_val_subsys(void) |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
62 { |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
63 val_cache = umem_cache_create("val-cache", sizeof(struct val), |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
64 0, NULL, NULL, NULL, NULL, NULL, 0); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
65 ASSERT(val_cache); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
66 } |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
67 |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
68 static struct val *__val_alloc(enum val_type type) |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
69 { |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
70 struct val *val; |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
71 |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
72 val = umem_cache_alloc(val_cache, 0); |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
73 if (!val) |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
74 return val; |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
75 |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
76 val->type = type; |
156
9e156cc8bdb8
val: add support for static vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
153
diff
changeset
|
77 val->static_alloc = false; |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
78 |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
79 refcnt_init(&val->refcnt, 1); |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
80 |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
81 return val; |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
82 } |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
83 |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
84 void val_free(struct val *val) |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
85 { |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
86 ASSERT(val); |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
87 ASSERT3U(refcnt_read(&val->refcnt), ==, 0); |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
88 |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
89 switch (val->type) { |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
90 case VT_INT: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
91 case VT_BOOL: |
129
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
92 case VT_CHAR: |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
93 break; |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
94 case VT_STR: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
95 case VT_SYM: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
96 str_putref(val->str); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
97 break; |
9
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
98 case VT_CONS: |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
99 val_putref(val->cons.head); |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
100 val_putref(val->cons.tail); |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
101 break; |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
102 } |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
103 |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
104 umem_cache_free(val_cache, val); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
105 } |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
106 |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
107 #define DEF_VAL_SET(fxn, vttype, valelem, ctype) \ |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
108 struct val *val_alloc_##fxn(ctype v) \ |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
109 { \ |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
110 struct val *val; \ |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
111 \ |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
112 val = __val_alloc(vttype); \ |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
113 if (!val) \ |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
114 return NULL; \ |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
115 \ |
153
e6764c2b9d5d
val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
152
diff
changeset
|
116 val->_set_##valelem = v; \ |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
117 \ |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
118 return val; \ |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
119 } |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
120 |
158
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
121 static DEF_VAL_SET(int_heap, VT_INT, i, uint64_t) |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
122 DEF_VAL_SET(str, VT_STR, str, struct str *) |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
123 DEF_VAL_SET(sym, VT_SYM, str, struct str *) |
129
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
124 DEF_VAL_SET(char, VT_CHAR, i, uint64_t) |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
125 |
158
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
126 struct val *val_alloc_int(uint64_t i) |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
127 { |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
128 if (i < ARRAY_LEN(val_ints)) { |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
129 /* |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
130 * Cast away the const - we define the static as const to get it |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
131 * into .rodata, but we have to drop the const since everything |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
132 * expects struct val to be writable (because refcounts modify it). |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
133 * In this case, we won't get any modifications because we're marked |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
134 * as static. |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
135 */ |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
136 return (struct val *) &val_ints[i]; |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
137 } |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
138 |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
139 return val_alloc_int_heap(i); |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
140 } |
7cd03c69d379
val: preallocate int vals for [0,10)
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
157
diff
changeset
|
141 |
157
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
142 struct val *val_alloc_bool(bool b) |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
143 { |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
144 const struct val *ret; |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
145 |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
146 ret = b ? &val_true : &val_false; |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
147 |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
148 /* |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
149 * Cast away the const - we define the static as const to get it |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
150 * into .rodata, but we have to drop the const since everything |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
151 * expects struct val to be writable (because refcounts modify it). |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
152 * In this case, we won't get any modifications because we're marked |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
153 * as static. |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
154 */ |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
155 return (struct val *) ret; |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
156 } |
dbfb30f43dae
val: preallocate all possible bool vals
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
156
diff
changeset
|
157 |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
158 struct val *val_alloc_cons(struct val *head, struct val *tail) |
9
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
159 { |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
160 struct val *val; |
9
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
161 |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
162 val = __val_alloc(VT_CONS); |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
163 if (!val) |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
164 return NULL; |
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
165 |
153
e6764c2b9d5d
val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
152
diff
changeset
|
166 val->_set_cons.head = head; |
e6764c2b9d5d
val: make the value union members const
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
152
diff
changeset
|
167 val->_set_cons.tail = tail; |
9
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
168 |
152
3d2fdf4385bf
val: use allocate-and-set appreach to avoid tempting users to modify the val
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
129
diff
changeset
|
169 return val; |
9
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
170 } |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
171 |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
172 void val_dump(struct val *val, int indent) |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
173 { |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
174 if (!val) |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
175 return; |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
176 |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
177 switch (val->type) { |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
178 case VT_STR: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
179 case VT_SYM: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
180 fprintf(stderr, "%*s'%s'\n", indent, "", str_cstr(val->str)); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
181 break; |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
182 case VT_INT: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
183 fprintf(stderr, "%*s%"PRIu64"\n", indent, "", val->i); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
184 break; |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
185 case VT_BOOL: |
110
afacfc4a7fdf
val: dumped bools need a trailing newline
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
58
diff
changeset
|
186 fprintf(stderr, "%*s%s\n", indent, "", |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
187 val->b ? "true" : "false"); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
188 break; |
129
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
189 case VT_CHAR: |
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
190 if (isprint(val->i)) |
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
191 fprintf(stderr, "%*s\\u%04"PRIX64": '%c'\n", |
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
192 indent, "", val->i, (char) val->i); |
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
193 else |
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
194 fprintf(stderr, "%*s\\u%04"PRIX64"\n", indent, |
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
195 "", val->i); |
f3e6fce14902
val: introduce VT_CHAR
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
110
diff
changeset
|
196 break; |
9
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
197 case VT_CONS: |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
198 fprintf(stderr, "%*scons head:\n", indent, ""); |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
199 val_dump(val->cons.head, indent + 2); |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
200 fprintf(stderr, "%*scons tail:\n", indent, ""); |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
201 val_dump(val->cons.tail, indent + 2); |
4c067f4ec57f
val: include a cons cell type
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
8
diff
changeset
|
202 break; |
8
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
203 default: |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
204 fprintf(stderr, "Unknown type %d\n", val->type); |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
205 break; |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
206 } |
083d11258db6
val: a generic typed value structure
Josef 'Jeff' Sipek <jeffpc@josefsipek.net>
parents:
diff
changeset
|
207 } |