summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorhunt <hunt>2005-10-26 08:29:38 +0000
committerhunt <hunt>2005-10-26 08:29:38 +0000
commitaf5dd76bca996577262e447fd8bff1bd0df30db7 (patch)
tree488419840e6841a1dcb022553cb33f6eccbbb3f5
parentd7c99876fec8867918d9f4f808edca985eb1fd67 (diff)
downloadsystemtap-steved-af5dd76bca996577262e447fd8bff1bd0df30db7.tar.gz
systemtap-steved-af5dd76bca996577262e447fd8bff1bd0df30db7.tar.xz
systemtap-steved-af5dd76bca996577262e447fd8bff1bd0df30db7.zip
2005-10-26 Martin Hunt <hunt@redhat.com>
* map.c (_new_map_create, _new_map_del_node, _new_map_del_node, _new_map_set_int64, _new_map_set_str,_new_map_get_int64, _new_map_get_str, _new_map_get_stat, _new_map_set_stat): New internal functions for the new API. * map-int.c (__stp_map_set_int64): Modify to return an error code. * map-stat.c (_stp_map_add_stat): Ditto. * map-str (_stp_map_set_str): Ditto. * Doxyfile: Remove predefines NEED_STRING_VALS, NEED_STATS, NEED_INT64. * map-keys.c: Ditto. * list.c (_stp_list_new): Ditto. Also set map->list. * map-values.c: Ditto.
-rw-r--r--runtime/ChangeLog18
-rw-r--r--runtime/Doxyfile2
-rw-r--r--runtime/list.c16
-rw-r--r--runtime/map-gen.c557
-rw-r--r--runtime/map-int.c14
-rw-r--r--runtime/map-keys.c12
-rw-r--r--runtime/map-stat.c9
-rw-r--r--runtime/map-str.c16
-rw-r--r--runtime/map-values.c33
-rw-r--r--runtime/map.c145
-rw-r--r--runtime/map.doc2
-rw-r--r--runtime/map.h15
12 files changed, 752 insertions, 87 deletions
diff --git a/runtime/ChangeLog b/runtime/ChangeLog
index be02002b..3065ff05 100644
--- a/runtime/ChangeLog
+++ b/runtime/ChangeLog
@@ -1,3 +1,21 @@
+2005-10-26 Martin Hunt <hunt@redhat.com>
+
+ * map.c (_new_map_create, _new_map_del_node, _new_map_del_node,
+ _new_map_set_int64, _new_map_set_str,_new_map_get_int64,
+ _new_map_get_str, _new_map_get_stat, _new_map_set_stat):
+ New internal functions for the new API.
+
+ * map-int.c (__stp_map_set_int64): Modify to return an
+ error code.
+ * map-stat.c (_stp_map_add_stat): Ditto.
+ * map-str (_stp_map_set_str): Ditto.
+
+ * Doxyfile: Remove predefines NEED_STRING_VALS,
+ NEED_STATS, NEED_INT64.
+ * map-keys.c: Ditto.
+ * list.c (_stp_list_new): Ditto. Also set map->list.
+ * map-values.c: Ditto.
+
2005-10-19 Martin Hunt <hunt@redhat.com>
* runtime.h (_stp_kallsyms_lookup_tabled): Only
diff --git a/runtime/Doxyfile b/runtime/Doxyfile
index 7b1d802a..230d55c1 100644
--- a/runtime/Doxyfile
+++ b/runtime/Doxyfile
@@ -961,7 +961,7 @@ INCLUDE_FILE_PATTERNS =
# undefined via #undef or recursively expanded use the := operator
# instead of the = operator.
-PREDEFINED = __i386__ NEED_INT64_VALS NEED_STRING_VALS NEED_STAT_VALS KEY1_TYPE_INT64 USE_RET_PROBES DEBUG
+PREDEFINED = __i386__ KEY1_TYPE_INT64 USE_RET_PROBES DEBUG
# If the MACRO_EXPANSION and EXPAND_ONLY_PREDEF tags are set to YES then
# this tag can be used to specify a list of macro names that should be expanded.
diff --git a/runtime/list.c b/runtime/list.c
index ce0141ec..815b7bad 100644
--- a/runtime/list.c
+++ b/runtime/list.c
@@ -1,14 +1,6 @@
#ifndef _LIST_C_ /* -*- linux-c -*- */
#define _LIST_C_
-#ifndef NEED_INT64_KEYS
-#error Before including list.c, "#define KEY1_TYPE INT64" and include "map-keys.c"
-#endif
-
-#if !defined(NEED_STRING_VALS) && !defined(NEED_INT64_VALS)
-#error Before including list.c, "#define VALUE_TYPE" to "INT64" or "STRING" and include "map-values.c"
-#endif
-
#include "map.c"
#include "copy.c"
@@ -37,7 +29,7 @@
MAP _stp_list_new(unsigned max_entries, int type)
{
MAP map = _stp_map_new_int64 (max_entries, type);
- map->no_wrap = 1;
+ map->list = 1;
return map;
}
@@ -75,7 +67,6 @@ void _stp_list_clear(MAP map)
}
}
-#ifdef NEED_STRING_VALS
/** Adds a C string to a list.
* @param map
* @param str
@@ -99,9 +90,7 @@ inline void _stp_list_add_string (MAP map, String str)
_stp_map_key_int64 (map, map->num);
_stp_map_set_str(map, str->buf);
}
-#endif /* NEED_STRING_VALS */
-#ifdef NEED_INT64_VALS
/** Adds an int64 to a list.
* @param map
* @param val
@@ -113,7 +102,6 @@ inline void _stp_list_add_int64(MAP map, int64_t val)
_stp_map_key_int64 (map, map->num);
_stp_map_set_int64(map, val);
}
-#endif /* NEED_INT64_VALS */
/** Get the number of elements in a list.
* @param map
@@ -125,7 +113,6 @@ inline int _stp_list_size(MAP map)
return map->num;
}
-#ifdef NEED_STRING_VALS
/** Copy an argv from user space to a List.
*
* @param list A list.
@@ -159,7 +146,6 @@ int _stp_copy_argv_from_user (MAP list, char __user *__user *argv)
}
return list->num;
}
-#endif /* NEED_STRING_VALS */
/** @} */
#endif /* _LIST_C_ */
diff --git a/runtime/map-gen.c b/runtime/map-gen.c
new file mode 100644
index 00000000..418b5d52
--- /dev/null
+++ b/runtime/map-gen.c
@@ -0,0 +1,557 @@
+/* -*- linux-c -*-
+ * map API generator
+ * Copyright (C) 2005 Red Hat Inc.
+ *
+ * This file is part of systemtap, and is free software. You can
+ * redistribute it and/or modify it under the terms of the GNU General
+ * Public License (GPL); either version 2, or (at your option) any
+ * later version.
+ */
+
+/** @file map-gen.c
+ * @brief Map function generator
+ * This file is a template designed to be included as many times as
+ * needed to generate the necessary map functions.
+ */
+
+#define JOIN(x,y) JOINx(x,y)
+#define JOINx(x,y) x##_##y
+#define JOIN2(x,y,z) JOIN2x(x,y,z)
+#define JOIN2x(x,y,z) x##_##y##z
+#define JOIN3(a,b,c,d) JOIN3x(a,b,c,d)
+#define JOIN3x(a,b,c,d) a##_##b##c##d
+#define JOIN4(a,b,c,d,e) JOIN4x(a,b,c,d,e)
+#define JOIN4x(a,b,c,d,e) a##_##b##c##d##e
+#define JOIN5(a,b,c,d,e,f) JOIN5x(a,b,c,d,e,f)
+#define JOIN5x(a,b,c,d,e,f) a##_##b##c##d##e##f
+#define JOIN6(a,b,c,d,e,f,g) JOIN6x(a,b,c,d,e,f,g)
+#define JOIN6x(a,b,c,d,e,f,g) a##_##b##c##d##e##f##g
+
+#include "map.h"
+
+#if !defined(VALUE_TYPE)
+#error Need to define VALUE_TYPE as STRING, STAT, or INT64
+#endif
+
+#if VALUE_TYPE == STRING
+#define VALTYPE char*
+#define VSTYPE char*
+#define VALNAME str
+#define VALN s
+#define MAP_SET_VAL(a,b,c,d) _new_map_set_str(a,b,c,d)
+#define MAP_GET_VAL(a,b) _new_map_get_str(a,b)
+#elif VALUE_TYPE == INT64
+#define VALTYPE int64_t
+#define VSTYPE int64_t
+#define VALNAME int64
+#define VALN i
+#define MAP_SET_VAL(a,b,c,d) _new_map_set_int64(a,b,c,d)
+#define MAP_GET_VAL(a,b) _new_map_get_int64(a,b)
+#elif VALUE_TYPE == STAT
+#define VALTYPE stat*
+#define VSTYPE int64_t
+#define VALNAME stat
+#define VALN x
+#define MAP_SET_VAL(a,b,c,d) _new_map_set_stat(a,b,c,d)
+#define MAP_GET_VAL(a,b) _new_map_get_stat(a,b)
+#else
+#error Need to define VALUE_TYPE as STRING, STAT, or INT64
+#endif /* VALUE_TYPE */
+
+//#define MAP_SET_VAL(a,b,c,d) _new_map_set_##VALNAME(a,b,c,d)
+
+#if defined (KEY1_TYPE)
+#define KEY_ARITY 1
+#if KEY1_TYPE == STRING
+#define KEY1TYPE char*
+#define KEY1NAME str
+#define KEY1N s
+#define KEY1STOR char key1[MAP_STRING_LENGTH]
+#define KEY1CPY(m) str_copy(m->key1, key1)
+#else
+#define KEY1TYPE int64_t
+#define KEY1NAME int64
+#define KEY1N i
+#define KEY1STOR int64_t key1
+#define KEY1CPY(m) m->key1=key1
+#endif
+#define KEY1_EQ_P JOIN(KEY1NAME,eq_p)
+#define KEY1_HASH JOIN(KEY1NAME,hash)
+#endif /* defined(KEY1_TYPE) */
+
+#if defined (KEY2_TYPE)
+#undef KEY_ARITY
+#define KEY_ARITY 2
+#if KEY2_TYPE == STRING
+#define KEY2TYPE char*
+#define KEY2NAME str
+#define KEY2N s
+#define KEY2STOR char key2[MAP_STRING_LENGTH]
+#define KEY2CPY(m) str_copy(m->key2, key2)
+#else
+#define KEY2TYPE int64_t
+#define KEY2NAME int64
+#define KEY2N i
+#define KEY2STOR int64_t key2
+#define KEY2CPY(m) m->key2=key2
+#endif
+#define KEY2_EQ_P JOIN(KEY2NAME,eq_p)
+#define KEY2_HASH JOIN(KEY2NAME,hash)
+#endif /* defined(KEY2_TYPE) */
+
+#if defined (KEY3_TYPE)
+#undef KEY_ARITY
+#define KEY_ARITY 3
+#if KEY3_TYPE == STRING
+#define KEY3TYPE char*
+#define KEY3NAME str
+#define KEY3N s
+#define KEY3STOR char key3[MAP_STRING_LENGTH]
+#define KEY3CPY(m) str_copy(m->key3, key3)
+#else
+#define KEY3TYPE int64_t
+#define KEY3NAME int64
+#define KEY3N i
+#define KEY3STOR int64_t key3
+#define KEY3CPY(m) m->key3=key3
+#endif
+#define KEY3_EQ_P JOIN(KEY3NAME,eq_p)
+#define KEY3_HASH JOIN(KEY3NAME,hash)
+#endif /* defined(KEY3_TYPE) */
+
+#if defined (KEY4_TYPE)
+#undef KEY_ARITY
+#define KEY_ARITY 4
+#if KEY4_TYPE == STRING
+#define KEY4TYPE char*
+#define KEY4NAME str
+#define KEY4N s
+#define KEY4STOR char key4[MAP_STRING_LENGTH]
+#define KEY4CPY(m) str_copy(m->key4, key4)
+#else
+#define KEY4TYPE int64_t
+#define KEY4NAME int64
+#define KEY4N i
+#define KEY4STOR int64_t key4
+#define KEY4CPY(4) m->key4=key4
+#endif
+#define KEY4_EQ_P JOIN(KEY4NAME,eq_p)
+#define KEY4_HASH JOIN(KEY4NAME,hash)
+#endif /* defined(KEY4_TYPE) */
+
+#if defined (KEY5_TYPE)
+#undef KEY_ARITY
+#define KEY_ARITY 5
+#if KEY5_TYPE == STRING
+#define KEY5TYPE char*
+#define KEY5NAME str
+#define KEY5N s
+#define KEY5STOR char key5[MAP_STRING_LENGTH]
+#define KEY5CPY(m) str_copy(m->key5, key5)
+#else
+#define KEY5TYPE int64_t
+#define KEY5NAME int64
+#define KEY5N i
+#define KEY5STOR int64_t key5
+#define KEY5CPY(m) m->key5=key5
+#endif
+#define KEY5_EQ_P JOIN(KEY5NAME,eq_p)
+#define KEY5_HASH JOIN(KEY5NAME,hash)
+#endif /* defined(KEY5_TYPE) */
+
+#if KEY_ARITY == 1
+#define KEYSYM(x) JOIN2(x,KEY1N,VALN)
+#define ALLKEYS(x) x##1
+#define ALLKEYSD(x) KEY1TYPE x##1
+#define KEYCPY(m) {KEY1CPY(m);}
+#elif KEY_ARITY == 2
+#define KEYSYM(x) JOIN3(x,KEY1N,KEY2N,VALN)
+#define ALLKEYS(x) x##1, x##2
+#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2
+#define KEYCPY(m) {KEY1CPY(m);KEY2CPY(m);}
+#elif KEY_ARITY == 3
+#define KEYSYM(x) JOIN4(x,KEY1N,KEY2N,KEY3N,VALN)
+#define ALLKEYS(x) x##1, x##2, x##3
+#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2, KEY3TYPE x##3
+#define KEYCPY(m) {KEY1CPY(m);KEY2CPY(m);KEY3CPY(m);}
+#elif KEY_ARITY == 4
+#define KEYSYM(x) JOIN5(x,KEY1N,KEY2N,KEY3N,KEY4N,VALN)
+#define ALLKEYS(x) x##1, x##2, x##3, x##4
+#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2, KEY3TYPE x##3, KEY4TYPE x##4
+#define KEYCPY(m) {KEY1CPY(m);KEY2CPY(m);KEY3CPY(m);KEY4CPY(m)}
+#elif KEY_ARITY == 5
+#define KEYSYM(x) JOIN6(x,KEY1N,KEY2N,KEY3N,KEY4N,KEY5N,VALN)
+#define ALLKEYS(x) x##1, x##2, x##3, x##4, x##5
+#define ALLKEYSD(x) KEY1TYPE x##1, KEY2TYPE x##2, KEY3TYPE x##3, KEY4TYPE x##4, KEY5TYPE x##5
+#define KEYCPY(m) {KEY1CPY(m);KEY2CPY(m);KEY3CPY(m);KEY4CPY(m);KEY5CPY(m);}
+#endif
+
+/* */
+
+struct KEYSYM(map_node) {
+ /* list of other nodes in the map */
+ struct list_head lnode;
+ /* list of nodes with the same hash value */
+ struct hlist_node hnode;
+ /* pointer back to the map struct */
+ struct map_root *map;
+
+ KEY1STOR;
+#if KEY_ARITY > 1
+ KEY2STOR;
+#if KEY_ARITY > 2
+ KEY3STOR;
+#if KEY_ARITY > 3
+ KEY4STOR;
+#if KEY_ARITY > 4
+ KEY5STOR;
+#endif
+#endif
+#endif
+#endif
+};
+
+#define type_to_enum(type) \
+ ({ \
+ int ret; \
+ if (__builtin_types_compatible_p (type, char*)) \
+ ret = STRING; \
+ else \
+ ret = INT64; \
+ ret; \
+ })
+
+static key_data KEYSYM(map_get_key) (struct map_node *mn, int n, int *type)
+{
+ key_data ptr;
+ struct KEYSYM(map_node) *m = (struct KEYSYM(map_node) *)mn;
+
+ // dbug ("m=%lx\n", (long)m);
+ if (n > KEY_ARITY || n < 1) {
+ if (type)
+ *type = END;
+ return (key_data)(int64_t)0;
+ }
+
+ switch (n) {
+ case 1:
+ ptr = (key_data)m->key1;
+ if (type)
+ *type = type_to_enum(KEY1TYPE);
+ break;
+#if KEY_ARITY > 1
+ case 2:
+ ptr = (key_data)m->key2;
+ if (type)
+ *type = type_to_enum(KEY2TYPE);
+
+ break;
+#if KEY_ARITY > 2
+ case 3:
+ ptr = (key_data)m->key3;
+ if (type)
+ *type = type_to_enum(KEY3TYPE);
+ break;
+#if KEY_ARITY > 3
+ case 4:
+ ptr = (key_data)m->key4;
+ if (type)
+ *type = type_to_enum(KEY4TYPE);
+ break;
+#if KEY_ARITY > 4
+ case 5:
+ ptr = (key_data)m->key5;
+ if (type)
+ *type = type_to_enum(KEY5TYPE);
+ break;
+#endif
+#endif
+#endif
+#endif
+ default:
+ ptr = (key_data)(int64_t)0;
+ if (type)
+ *type = END;
+ }
+ return ptr;
+}
+
+
+static unsigned int KEYSYM(keycheck) (ALLKEYSD(key))
+{
+#if KEY1_TYPE == STRING
+ if (key1 == NULL)
+ return 0;
+#endif
+
+#if KEY_ARITY > 1
+#if KEY2_TYPE == STRING
+ if (key2 == NULL)
+ return 0;
+#endif
+
+#if KEY_ARITY > 2
+#if KEY3_TYPE == STRING
+ if (key3 == NULL)
+ return 0;
+#endif
+
+#if KEY_ARITY > 3
+#if KEY4_TYPE == STRING
+ if (key4 == NULL)
+ return 0;
+#endif
+
+#if KEY_ARITY > 4
+#if KEY5_TYPE == STRING
+ if (key5 == NULL)
+ return 0;
+#endif
+#endif
+#endif
+#endif
+#endif
+ return 1;
+}
+
+static unsigned int KEYSYM(hash) (ALLKEYSD(key))
+{
+ unsigned int hash = KEY1_HASH(key1);
+#if KEY_ARITY > 1
+ hash ^= KEY2_HASH(key2);
+#if KEY_ARITY > 2
+ hash ^= KEY3_HASH(key3);
+#if KEY_ARITY > 3
+ hash ^= KEY4_HASH(key4);
+#if KEY_ARITY > 4
+ hash ^= KEY5_HASH(key5);
+#endif
+#endif
+#endif
+#endif
+ return (unsigned int) hash;
+}
+
+
+#if VALUE_TYPE == INT64
+MAP KEYSYM(_stp_map_new) (unsigned max_entries)
+{
+ MAP m = _stp_map_new (max_entries, INT64, sizeof(struct KEYSYM(map_node)), 0);
+ if (m)
+ m->get_key = KEYSYM(map_get_key);
+ return m;
+}
+#elif VALUE_TYPE == STRING
+MAP KEYSYM(_stp_map_new) (unsigned max_entries)
+{
+ MAP m = _stp_map_new (max_entries, STRING, sizeof(struct KEYSYM(map_node)), 0);
+ if (m)
+ m->get_key = KEYSYM(map_get_key);
+ return m;
+}
+#else
+/* _stp_map_new_key1_key2...val (num, HSTAT_LINEAR, start, end, interval) */
+/* _stp_map_new_key1_key2...val (num, HSTAT_LOG, buckets) */
+
+MAP KEYSYM(_stp_map_new) (unsigned max_entries, int htype, ...)
+{
+ int buckets=0, start=0, stop=0, interval=0;
+ MAP m;
+ va_list ap;
+
+ if (htype != HIST_NONE) {
+ va_start (ap, htype);
+ if (htype == HIST_LOG) {
+ buckets = va_arg(ap, int);
+ // dbug ("buckets=%d\n", buckets);
+ } else {
+ start = va_arg(ap, int);
+ stop = va_arg(ap, int);
+ interval = va_arg(ap, int);
+ // dbug ("start=%d stop=%d interval=%d\n", start, stop, interval);
+ }
+ va_end (ap);
+ }
+
+ switch (htype) {
+ case HIST_NONE:
+ m = _stp_map_new (max_entries, STAT, sizeof(struct KEYSYM(map_node)), 0);
+ break;
+ case HIST_LOG:
+ m = _stp_map_new_hstat_log (max_entries, sizeof(struct KEYSYM(map_node)),
+ buckets);
+ break;
+ case HIST_LINEAR:
+ m = _stp_map_new_hstat_linear (max_entries, sizeof(struct KEYSYM(map_node)),
+ start, stop, interval);
+ break;
+ default:
+ _stp_warn ("Unknown histogram type %d\n", htype);
+ m = NULL;
+ }
+
+ if (m)
+ m->get_key = KEYSYM(map_get_key);
+
+ return m;
+}
+
+#endif /* VALUE_TYPE */
+int KEYSYM(__stp_map_set) (MAP map, ALLKEYSD(key), VSTYPE val, int add)
+{
+ unsigned int hv;
+ struct hlist_head *head;
+ struct hlist_node *e;
+ struct KEYSYM(map_node) *n;
+ int res;
+
+ if (map == NULL)
+ return -2;
+
+ if (KEYSYM(keycheck) (ALLKEYS(key)) == 0)
+ return -2;
+
+ hv = KEYSYM(hash) (ALLKEYS(key));
+ head = &map->hashes[hv];
+
+ hlist_for_each(e, head) {
+ n = (struct KEYSYM(map_node) *)((long)e - sizeof(struct hlist_node));
+ dbug ("n=%lx key1=%ld n->key1=%ld\n", (long)n, key1, n->key1);
+ if (KEY1_EQ_P(n->key1, key1)
+#if KEY_ARITY > 1
+ && KEY2_EQ_P(n->key2, key2)
+#if KEY_ARITY > 2
+ && KEY3_EQ_P(n->key3, key3)
+#if KEY_ARITY > 3
+ && KEY4_EQ_P(n->key4, key4)
+#if KEY_ARITY > 4
+ && KEY5_EQ_P(n->key5, key5)
+#endif
+#endif
+#endif
+#endif
+ ) {
+#if VALUE_TYPE == STAT
+ return _new_map_set_stat(map,(struct map_node *)n, val, add, 0);
+#else
+ return MAP_SET_VAL(map,(struct map_node *)n, val, add);
+#endif
+ }
+ }
+ /* key not found */
+ dbug("key not found\n");
+ if (val == 0 && !add)
+ return 0;
+ n = (struct KEYSYM(map_node)*)_new_map_create (map, head);
+ if (n == NULL)
+ return -1;
+ dbug("keycpy\n");
+ KEYCPY(n);
+ dbug("done\n");
+#if VALUE_TYPE == STAT
+ return _new_map_set_stat(map,(struct map_node *)n, val, add, 1);
+#else
+ return MAP_SET_VAL(map,(struct map_node *)n, val, 0);
+#endif
+}
+
+int KEYSYM(_stp_map_set) (MAP map, ALLKEYSD(key), VSTYPE val)
+{
+ return KEYSYM(__stp_map_set) (map, ALLKEYS(key), val, 0);
+}
+
+int KEYSYM(_stp_map_add) (MAP map, ALLKEYSD(key), VSTYPE val)
+{
+ return KEYSYM(__stp_map_set) (map, ALLKEYS(key), val, 1);
+}
+
+
+VALTYPE KEYSYM(_stp_map_get) (MAP map, ALLKEYSD(key))
+{
+ unsigned int hv;
+ struct hlist_head *head;
+ struct hlist_node *e;
+ struct KEYSYM(map_node) *n;
+
+ if (map == NULL)
+ return (VALTYPE)0;
+
+ hv = KEYSYM(hash) (ALLKEYS(key));
+ head = &map->hashes[hv];
+
+ hlist_for_each(e, head) {
+ n = (struct KEYSYM(map_node) *)((long)e - sizeof(struct hlist_node));
+// dbug ("n =%lx key=" EACHKEY(%ld) "\n", (long)n, n->key1.val, n->key2.val);
+ if (KEY1_EQ_P(n->key1, key1)
+#if KEY_ARITY > 1
+ && KEY2_EQ_P(n->key2, key2)
+#if KEY_ARITY > 2
+ && KEY3_EQ_P(n->key3, key3)
+#if KEY_ARITY > 3
+ && KEY4_EQ_P(n->key4, key4)
+#if KEY_ARITY > 4
+ && KEY5_EQ_P(n->key5, key5)
+#endif
+#endif
+#endif
+#endif
+ ) {
+ return MAP_GET_VAL(map,(struct map_node *)n);
+ }
+ }
+ /* key not found */
+ return (VALTYPE)0;
+}
+
+
+#undef KEY1NAME
+#undef KEY1N
+#undef KEY1TYPE
+#undef KEY1_TYPE
+#undef KEY1STOR
+#undef KEY1CPY
+
+#undef KEY2NAME
+#undef KEY2N
+#undef KEY2TYPE
+#undef KEY2_TYPE
+#undef KEY2STOR
+#undef KEY2CPY
+
+#undef KEY3NAME
+#undef KEY3N
+#undef KEY3TYPE
+#undef KEY3_TYPE
+#undef KEY3STOR
+#undef KEY3CPY
+
+#undef KEY4NAME
+#undef KEY4N
+#undef KEY4TYPE
+#undef KEY4_TYPE
+#undef KEY4STOR
+#undef KEY4CPY
+
+#undef KEY5NAME
+#undef KEY5N
+#undef KEY5TYPE
+#undef KEY5_TYPE
+#undef KEY5STOR
+#undef KEY5CPY
+
+#undef KEY_ARITY
+#undef ALLKEYS
+#undef ALLKEYSD
+#undef KEYCPY
+#undef KEYSYM
+
+#undef VALUE_TYPE
+#undef VALNAME
+#undef VALTYPE
+#undef VSTYPE
+#undef VALN
+
+#undef MAP_SET_VAL
+#undef MAP_GET_VAL
+
+
diff --git a/runtime/map-int.c b/runtime/map-int.c
index cf6363c6..574b29f7 100644
--- a/runtime/map-int.c
+++ b/runtime/map-int.c
@@ -12,27 +12,27 @@
* @brief Map functions to set and get int64s
*/
-void __stp_map_set_int64 (MAP map, int64_t val, int add)
+int __stp_map_set_int64 (MAP map, int64_t val, int add)
{
struct map_node *m;
if (map == NULL)
- return;
+ return -2;
if (map->create) {
- if (val == 0 && !map->no_wrap)
- return;
+ if (val == 0 && !map->list)
+ return 0;
m = __stp_map_create (map);
if (!m)
- return;
+ return -1;
/* set the value */
//dbug ("m=%lx offset=%lx\n", (long)m, (long)map->data_offset);
*(int64_t *)((long)m + map->data_offset) = val;
} else {
if (map->key == NULL)
- return;
+ return -2;
if (val) {
if (add)
@@ -44,6 +44,7 @@ void __stp_map_set_int64 (MAP map, int64_t val, int add)
_stp_map_key_del(map);
}
}
+ return 0;
}
/** Set the current element's value to an int64.
* This sets the current element's value to an int64. The map must have been created
@@ -53,6 +54,7 @@ void __stp_map_set_int64 (MAP map, int64_t val, int add)
* is set for the map, this function does nothing.
* @param map
* @param val new value
+ * @returns \li \c 0 on success \li \c -1 on overflow \li \c -2 on bad map or key
* @sa _stp_map_add_int64()
* @sa _stp_map_set()
* @ingroup map_set
diff --git a/runtime/map-keys.c b/runtime/map-keys.c
index 898e50a6..9bf756ac 100644
--- a/runtime/map-keys.c
+++ b/runtime/map-keys.c
@@ -25,12 +25,10 @@
#define KEY1TYPE char*
#define KEY1NAME str
#define KEY1STOR char key1[MAP_STRING_LENGTH]
-#define NEED_STRING_KEYS
#else
#define KEY1TYPE int64_t
#define KEY1NAME int64
#define KEY1STOR int64_t key1
-#define NEED_INT64_KEYS
#endif
#define KEY1_EQ_P JOIN(KEY1NAME,eq_p)
#define KEY1_HASH JOIN(KEY1NAME,hash)
@@ -43,12 +41,10 @@
#define KEY2TYPE char*
#define KEY2NAME str
#define KEY2STOR char key2[MAP_STRING_LENGTH]
-#define NEED_STRING_KEYS
#else
#define KEY2TYPE int64_t
#define KEY2NAME int64
#define KEY2STOR int64_t key2
-#define NEED_INT64_KEYS
#endif
#define KEY2_EQ_P JOIN(KEY2NAME,eq_p)
#define KEY2_HASH JOIN(KEY2NAME,hash)
@@ -61,12 +57,10 @@
#define KEY3TYPE char*
#define KEY3NAME str
#define KEY3STOR char key3[MAP_STRING_LENGTH]
-#define NEED_STRING_KEYS
#else
#define KEY3TYPE int64_t
#define KEY3NAME int64
#define KEY3STOR int64_t key3
-#define NEED_INT64_KEYS
#endif
#define KEY3_EQ_P JOIN(KEY3NAME,eq_p)
#define KEY3_HASH JOIN(KEY3NAME,hash)
@@ -79,12 +73,10 @@
#define KEY4TYPE char*
#define KEY4NAME str
#define KEY4STOR char key4[MAP_STRING_LENGTH]
-#define NEED_STRING_KEYS
#else
#define KEY4TYPE int64_t
#define KEY4NAME int64
#define KEY4STOR int64_t key4
-#define NEED_INT64_KEYS
#endif
#define KEY4_EQ_P JOIN(KEY4NAME,eq_p)
#define KEY4_HASH JOIN(KEY4NAME,hash)
@@ -97,12 +89,10 @@
#define KEY5TYPE char*
#define KEY5NAME str
#define KEY5STOR char key5[MAP_STRING_LENGTH]
-#define NEED_STRING_KEYS
#else
#define KEY5TYPE int64_t
#define KEY5NAME int64
#define KEY5STOR int64_t key5
-#define NEED_INT64_KEYS
#endif
#define KEY5_EQ_P JOIN(KEY5NAME,eq_p)
#define KEY5_HASH JOIN(KEY5NAME,hash)
@@ -316,7 +306,6 @@ MAP KEYSYM(_stp_map_new) (unsigned max_entries, int valtype, ...)
m = _stp_map_new (max_entries, valtype & 0x0f,
sizeof(struct KEYSYM(map_node)), 0);
break;
-#ifdef NEED_STAT_VALS
case HIST_LOG:
m = _stp_map_new_hstat_log (max_entries, sizeof(struct KEYSYM(map_node)),
buckets);
@@ -325,7 +314,6 @@ MAP KEYSYM(_stp_map_new) (unsigned max_entries, int valtype, ...)
m = _stp_map_new_hstat_linear (max_entries, sizeof(struct KEYSYM(map_node)),
start, stop, interval);
break;
-#endif
default:
_stp_warn ("Unknown histogram type %d\n", htype);
m = NULL;
diff --git a/runtime/map-stat.c b/runtime/map-stat.c
index ea76d654..85a50ee8 100644
--- a/runtime/map-stat.c
+++ b/runtime/map-stat.c
@@ -15,29 +15,30 @@
#include "stat-common.c"
/* Adds an int64 to a stats map */
-static void _stp_map_add_stat (MAP map, int64_t val)
+static int _stp_map_add_stat (MAP map, int64_t val)
{
stat *d;
Stat st;
if (map == NULL)
- return;
+ return -2;
if (map->create) {
struct map_node *m = __stp_map_create (map);
if (!m)
- return;
+ return -1;
/* set the value */
d = (stat *)((long)m + map->data_offset);
d->count = 0;
} else {
if (map->key == NULL)
- return;
+ return -2;
d = (stat *)((long)map->key + map->data_offset);
}
st = (Stat)((long)map + offsetof(struct map_root, hist_type));
__stp_stat_add (st, d, val);
+ return 0;
}
diff --git a/runtime/map-str.c b/runtime/map-str.c
index e5e5b5e4..96eb5b5c 100644
--- a/runtime/map-str.c
+++ b/runtime/map-str.c
@@ -20,27 +20,27 @@ void str_add(void *dest, char *val)
dst[len + len1] = 0;
}
-void __stp_map_set_str (MAP map, char *val, int add)
+int __stp_map_set_str (MAP map, char *val, int add)
{
struct map_node *m;
if (map == NULL)
- return;
+ return -2;
if (map->create) {
- if (val == 0 && !map->no_wrap)
- return;
+ if (val == 0 && !map->list)
+ return 0;
m = __stp_map_create (map);
if (!m)
- return;
+ return -1;
/* set the value */
//dbug ("m=%lx offset=%lx\n", (long)m, (long)map->data_offset);
str_copy((void *)((long)m + map->data_offset), val);
} else {
if (map->key == NULL)
- return;
+ return -2;
if (val) {
if (add)
@@ -52,6 +52,7 @@ void __stp_map_set_str (MAP map, char *val, int add)
_stp_map_key_del(map);
}
}
+ return 0;
}
/** Set the current element's value to a string.
@@ -62,6 +63,7 @@ void __stp_map_set_str (MAP map, char *val, int add)
* is set for the map, this function does nothing.
* @param map
* @param str String containing new value.
+ * @returns \li \c 0 on success \li \c -1 on overflow \li \c -2 on bad map or key
* @sa _stp_map_set()
* @ingroup map_set
*/
@@ -75,6 +77,7 @@ void __stp_map_set_str (MAP map, char *val, int add)
* is set for the map, this function does nothing.
* @param map
* @param val String containing value to append.
+ * @returns \li \c 0 on success \li \c -1 on overflow \li \c -2 on bad map or key
* @ingroup map_set
*/
#define _stp_map_add_str(map,val) __stp_map_set_str(map,val,1)
@@ -107,6 +110,7 @@ char *_stp_map_get_str (MAP map)
* is set for the map, this function does nothing.
* @param map
* @param str String containing new value.
+ * @returns 0 on success, -1 on error.
* @sa _stp_map_set()
* @ingroup map_set
*/
diff --git a/runtime/map-values.c b/runtime/map-values.c
index 638b3e23..743323e4 100644
--- a/runtime/map-values.c
+++ b/runtime/map-values.c
@@ -6,25 +6,10 @@
*/
#include "map.h"
-
-#if !defined(NEED_STRING_VALS) && !defined(NEED_INT64_VALS) && !defined(NEED_STAT_VALS)
-#error Need to define at least one of NEED_STRING_VALS, NEED_INT64_VALS and NEED_STAT_VALS
-#endif
-
-#ifdef NEED_STRING_VALS
#include "map-str.c"
-#endif
-
-#ifdef NEED_STAT_VALS
#include "map-stat.c"
-#endif
-
-#ifdef NEED_INT64_VALS
#include "map-int.c"
-#endif
-
-#if defined(NEED_INT64_VALS) || defined (NEED_STAT_VALS)
/** Adds an int64 to the current element's value.
* This adds an int64 to the current element's value. The map must have been created
* to hold int64s or stats.
@@ -33,23 +18,23 @@
* is set for the map, this function does nothing.
* @param map
* @param val value
+ * @returns \li \c 0 on success \li \c -1 on overflow \li \c -2 on bad map or key
* @ingroup map_set
*/
-void _stp_map_add_int64 (MAP map, int64_t val)
+int _stp_map_add_int64 (MAP map, int64_t val)
{
if (map == NULL)
- return;
+ return -2;
-#ifdef NEED_INT64_VALS
if (map->type == INT64)
- __stp_map_set_int64 (map, val, 1);
-#endif
-#ifdef NEED_STAT_VALS
+ return __stp_map_set_int64 (map, val, 1);
+
if (map->type == STAT)
- _stp_map_add_stat (map, val);
-#endif
+ return _stp_map_add_stat (map, val);
+
+ /* shouldn't get here */
+ return -2;
}
-#endif
unsigned _stp_map_entry_exists (MAP map)
{
diff --git a/runtime/map.c b/runtime/map.c
index 3fc2bb47..9bf143e6 100644
--- a/runtime/map.c
+++ b/runtime/map.c
@@ -5,6 +5,7 @@
* @brief Implements maps (associative arrays) and lists
*/
+#include "map-values.c"
#include "alloc.c"
#include "sym.c"
@@ -15,7 +16,6 @@ static int map_sizes[] = {
0
};
-#ifdef NEED_INT64_KEYS
unsigned int int64_hash (const int64_t v)
{
return (unsigned int)hash_long ((unsigned long)v, HASH_TABLE_BITS);
@@ -25,11 +25,7 @@ int int64_eq_p (int64_t key1, int64_t key2)
{
return key1 == key2;
}
-#endif /* NEED_INT64_KEYS */
-
-
-#if defined (NEED_STRING_KEYS) || defined (NEED_STRING_VALS)
void str_copy(char *dest, char *src)
{
int len = strlen(src);
@@ -38,9 +34,7 @@ void str_copy(char *dest, char *src)
strncpy (dest, src, len);
dest[len] = 0;
}
-#endif
-#ifdef NEED_STRING_KEYS
int str_eq_p (char *key1, char *key2)
{
return strncmp(key1, key2, MAP_STRING_LENGTH - 1) == 0;
@@ -55,7 +49,6 @@ unsigned int str_hash(const char *key1)
}
return (unsigned int)hash_long((unsigned long)hash, HASH_TABLE_BITS);
}
-#endif /* NEED_STRING_KEYS */
/** @addtogroup maps
* Implements maps (associative arrays) and lists
@@ -172,7 +165,7 @@ static MAP _stp_map_new(unsigned max_entries, int type, int key_size, int data_s
for (i = max_entries - 1; i >= 0; i--) {
e = i * size + tmp;
- //dbug ("e=%lx\n", (long)e);
+ dbug ("e=%lx\n", (long)e);
list_add(e, &m->pool);
((struct map_node *)e)->map = m;
}
@@ -534,7 +527,6 @@ static void print_valtype (MAP map, char *fmt, struct map_node *ptr)
_stp_symbol_print ((unsigned long)val);
break;
}
-#ifdef NEED_STAT_VALS
case STAT:
{
Stat st = (Stat)((long)map + offsetof(struct map_root, hist_type));
@@ -542,7 +534,6 @@ static void print_valtype (MAP map, char *fmt, struct map_node *ptr)
_stp_stat_print_valtype (fmt, st, sd, 0);
break;
}
-#endif
default:
break;
}
@@ -600,8 +591,8 @@ static struct map_node *__stp_map_create (MAP map)
{
struct map_node *m;
if (list_empty(&map->pool)) {
- if (map->no_wrap) {
- /* ERROR. FIXME */
+ if (!map->wrap) {
+ /* ERROR. no space left */
return NULL;
}
m = (struct map_node *)map->head.next;
@@ -624,5 +615,131 @@ static struct map_node *__stp_map_create (MAP map)
map->num++;
return m;
}
-#endif
+
+static struct map_node *_new_map_create (MAP map, struct hlist_head *head)
+{
+ struct map_node *m;
+ dbug("map=%lx\n", map);
+ if (list_empty(&map->pool)) {
+ if (!map->wrap) {
+ /* ERROR. no space left */
+ return NULL;
+ }
+ m = (struct map_node *)map->head.next;
+ dbug ("got %lx off head\n", (long)m);
+ hlist_del_init(&m->hnode);
+ } else {
+ m = (struct map_node *)map->pool.next;
+ dbug ("got %lx off pool\n", (long)m);
+ }
+ list_move_tail(&m->lnode, &map->head);
+
+ /* add node to new hash list */
+ hlist_add_head(&m->hnode, head);
+
+ map->num++;
+ return m;
+}
+
+static void _new_map_del_node (MAP map, struct map_node *n)
+{
+ /* remove node from old hash list */
+ hlist_del_init(&n->hnode);
+
+ /* remove from entry list */
+ list_del(&n->lnode);
+
+ /* add it back to the pool */
+ list_add(&n->lnode, &map->pool);
+
+ map->num--;
+}
+
+static int _new_map_set_int64 (MAP map, struct map_node *n, int64_t val, int add)
+{
+ if (map == NULL || n == NULL)
+ return -2;
+
+ if (val || map->list) {
+ if (add)
+ *(int64_t *)((long)n + map->data_offset) += val;
+ else
+ *(int64_t *)((long)n + map->data_offset) = val;
+ } else if (!add) {
+ /* setting value to 0 is the same as deleting */
+ _new_map_del_node (map, n);
+ }
+ return 0;
+}
+
+static int _new_map_set_str (MAP map, struct map_node *n, char *val, int add)
+{
+ if (map == NULL || n == NULL)
+ return -2;
+
+ if (val || map->list) {
+ if (add)
+ str_add((void *)((long)n + map->data_offset), val);
+ else
+ str_copy((void *)((long)n + map->data_offset), val);
+ } else if (!add) {
+ /* setting value to 0 is the same as deleting */
+ _new_map_del_node (map, n);
+ }
+ return 0;
+}
+
+static int64_t _new_map_get_int64 (MAP map, struct map_node *n)
+{
+ if (map == NULL || n == NULL)
+ return 0;
+ return *(int64_t *)((long)n + map->data_offset);
+}
+
+static char *_new_map_get_str (MAP map, struct map_node *n)
+{
+ if (map == NULL || n == NULL)
+ return 0;
+ return (char *)((long)n + map->data_offset);
+}
+
+static stat *_new_map_get_stat (MAP map, struct map_node *n)
+{
+ if (map == NULL || n == NULL)
+ return 0;
+ return (stat *)((long)n + map->data_offset);
+}
+
+static int _new_map_set_stat (MAP map, struct map_node *n, int64_t val, int add, int new)
+{
+ stat *sd;
+ Stat st;
+
+ if (map == NULL || n == NULL)
+ return -2;
+
+ if (val == 0 && !add) {
+ _new_map_del_node (map, n);
+ return 0;
+ }
+
+ sd = (stat *)((long)n + map->data_offset);
+ st = (Stat)((long)map + offsetof(struct map_root, hist_type));
+
+ if (new || !add) {
+ int j;
+ sd->count = sd->sum = sd->min = sd->max = 0;
+ if (st->hist_type != HIST_NONE) {
+ for (j = 0; j < st->hist_buckets; j++)
+ sd->histogram[j] = 0;
+ }
+ }
+
+ __stp_stat_add (st, sd, val);
+
+ return 0;
+}
+
+
+#endif /* _MAP_C_ */
diff --git a/runtime/map.doc b/runtime/map.doc
index 29d740f6..cf72b162 100644
--- a/runtime/map.doc
+++ b/runtime/map.doc
@@ -7,8 +7,6 @@ include the proper files. For example, if you need a map with 3 keys, int64, in
that stores strings, you need to do
@code
-#define NEED_STRING_VALS
-
#define KEY1_TYPE INT64
#define KEY2_TYPE INT64
#define KEY3_TYPE STRING
diff --git a/runtime/map.h b/runtime/map.h
index 857751d2..9c0b1fc3 100644
--- a/runtime/map.h
+++ b/runtime/map.h
@@ -73,7 +73,10 @@ struct map_root {
int num;
/* when more than maxnum elements, wrap or discard? */
- int no_wrap;
+ int wrap;
+
+ /* is this a list? */
+ int list;
/* linked list of current entries */
struct list_head head;
@@ -218,12 +221,10 @@ char * _stp_get_str(struct map_node *m);
stat * _stp_get_stat(struct map_node *m);
unsigned int str_hash(const char *key1);
static MAP _stp_map_new(unsigned max_entries, int type, int key_size, int data_size);
-#ifdef NEED_STAT_VALS
static int msb64(int64_t x);
static MAP _stp_map_new_hstat_log(unsigned max_entries, int key_size, int buckets);
static MAP _stp_map_new_hstat_linear(unsigned max_entries, int ksize, int start, int stop, int interval);
static void _stp_map_print_histogram(MAP map, stat *s);
-#endif
void _stp_map_key_del(MAP map);
struct map_node * _stp_map_start(MAP map);
struct map_node * _stp_map_iter(MAP map, struct map_node *m);
@@ -231,6 +232,14 @@ void _stp_map_del(MAP map);
void _stp_map_print(MAP map, const char *fmt);
static struct map_node * __stp_map_create(MAP map);
+static struct map_node *_new_map_create (MAP map, struct hlist_head *head);
+static int _new_map_set_int64 (MAP map, struct map_node *n, int64_t val, int add);
+static int64_t _new_map_get_int64 (MAP map, struct map_node *n);
+static char *_new_map_get_str (MAP map, struct map_node *n);
+static int _new_map_set_str (MAP map, struct map_node *n, char *val, int add);
+static stat *_new_map_get_stat (MAP map, struct map_node *n);
+static int _new_map_set_stat (MAP map, struct map_node *n, int64_t val, int add, int new);
+
/* these prototypes suppress warnings from macros */
void _stp_map_key_str(MAP, char *);
void _stp_map_set_str(MAP, char *);