From af5dd76bca996577262e447fd8bff1bd0df30db7 Mon Sep 17 00:00:00 2001 From: hunt Date: Wed, 26 Oct 2005 08:29:38 +0000 Subject: [PATCH] 2005-10-26 Martin Hunt * 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. --- runtime/ChangeLog | 18 ++ runtime/Doxyfile | 2 +- runtime/list.c | 16 +- runtime/map-gen.c | 557 +++++++++++++++++++++++++++++++++++++++++++ runtime/map-int.c | 14 +- runtime/map-keys.c | 12 - runtime/map-stat.c | 9 +- runtime/map-str.c | 16 +- runtime/map-values.c | 33 +-- runtime/map.c | 145 +++++++++-- runtime/map.doc | 2 - runtime/map.h | 15 +- 12 files changed, 752 insertions(+), 87 deletions(-) create mode 100644 runtime/map-gen.c diff --git a/runtime/ChangeLog b/runtime/ChangeLog index be02002b6..3065ff05b 100644 --- a/runtime/ChangeLog +++ b/runtime/ChangeLog @@ -1,3 +1,21 @@ +2005-10-26 Martin Hunt + + * 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 * runtime.h (_stp_kallsyms_lookup_tabled): Only diff --git a/runtime/Doxyfile b/runtime/Doxyfile index 7b1d802a1..230d55c1e 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 ce0141ec0..815b7bad5 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 000000000..418b5d526 --- /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 cf6363c6e..574b29f76 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 898e50a64..9bf756ac7 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 ea76d6546..85a50ee85 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 e5e5b5e4e..96eb5b5c7 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 638b3e230..743323e48 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 3fc2bb47a..9bf143e66 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 29d740f65..cf72b162c 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 857751d2f..9c0b1fc32 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 *); -- 2.43.5