/* -*- linux-c -*- * Map Header File * Copyright (C) 2005-2016 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. */ #ifndef _MAP_H_ #define _MAP_H_ #ifdef __KERNEL__ #include #include "linux/map_list.h" #elif defined(__DYNINST__) #include "dyninst/ilog2.h" #include "dyninst/map_list.h" #endif /* Number of bits to add-to or subtract-from "natural" hash table size. 0 = natural hash table size = ilog2(max-table-elements) +1 = double of natural hash table size: saves time, spends space -1 = half of natural hash table size: saves space, spends time -many = minimum hash table size (1 entry) +many = build failure */ #ifndef MAPHASHBIAS #define MAPHASHBIAS 0 #endif #define HASHTABLESIZE(entries) (1 << max_t(int, ilog2(entries)+MAPHASHBIAS, 1)) /* NB: a power of two, since we truncate hv with & rather than % */ /** @file map.h * @brief Header file for maps and lists */ /** @addtogroup maps * @todo Needs a spinlock variable to help when locks are required on the map. * @{ */ /** Maximum length of strings in maps. This sets the amount of space reserved for each string. This should match MAXSTRINGLEN. If MAP_STRING_LENGTH is less than MAXSTRINGLEN, a user could get strings truncated that are stored in arrays. */ #ifndef MAP_STRING_LENGTH #define MAP_STRING_LENGTH MAXSTRINGLEN #endif /** @cond DONT_INCLUDE */ #define INT64 0 #define STRING 1 #define STAT 2 #define END 3 /** @endcond */ #include "stat.h" /* Keys are either int64 or strings, and values can also be stats */ typedef union { int64_t val; char *strp; stat_data *statp; } key_data; /* basic map element */ struct map_node { /* list of other nodes in the map */ struct mlist_head lnode; /* list of nodes with the same hash value */ struct mhlist_node hnode; }; #define mlist_map_node(head) mlist_entry((head), struct map_node, lnode) /* This structure contains all information about a map. * It is allocated once when _stp_map_new() is called. */ struct map_root { /* maximum number of elements allowed in the array. */ unsigned maxnum; /* current number of used elements */ unsigned num; /* when more than maxnum elements, wrap or discard? */ int wrap; /* scale factor for integer arithmetic */ int bit_shift; /* related statistical operators */ int stat_ops; #ifdef __KERNEL__ void *node_mem; #endif /* linked list of current entries */ struct mlist_head head; /* pool of unused entries. */ struct mlist_head pool; /* used if this map's nodes contain stats */ struct _Hist hist; /* the hash table for this array */ unsigned hash_table_mask; struct mhlist_head hashes[0]; /* dynamically allocated at tail */ }; /** All maps are of this type. */ typedef struct map_root *MAP; struct pmap; /* defined in map_runtime.h */ typedef struct pmap *PMAP; typedef key_data (*map_get_key_fn)(struct map_node *mn, int n, int *type); typedef void (*map_update_fn)(MAP m, struct map_node *dst, struct map_node *src, int add); typedef int (*map_cmp_fn)(struct map_node *dst, struct map_node *src); /** Loop through all elements of a map or list. * @param map * @param ptr pointer to a map_node_stat, map_node_int64 or map_node_str * * @b Example: * @include foreach.c */ #define foreach(map, ptr) \ for (ptr = _stp_map_start(map); ptr; ptr = _stp_map_iter (map, ptr)) /** @} */ #ifdef __KERNEL__ #include "linux/map_runtime.h" #elif defined(__DYNINST__) #include "dyninst/map_runtime.h" #endif /** @cond DONT_INCLUDE */ /************* prototypes for map.c ****************/ static int int64_eq_p(int64_t key1, int64_t key2); static void str_copy(char *dest, char *src); static void str_add(void *dest, char *val); static int str_eq_p(char *key1, char *key2); static MAP _stp_map_new(unsigned max_entries, int wrap, int node_size, int cpu); static PMAP _stp_pmap_new(unsigned max_entries, int wrap, int node_size); static MAP _stp_map_new_hstat(unsigned max_entries, int wrap, int node_size); static MAP _stp_map_new_hstat_log(unsigned max_entries, int wrap, int node_size); static MAP _stp_map_new_hstat_linear(unsigned max_entries, int wrap, int node_size, int start, int stop, int interval); static void _stp_map_print_histogram(MAP map, stat_data *s); static struct map_node * _stp_map_start(MAP map); static struct map_node * _stp_map_iter(MAP map, struct map_node *m); static void _stp_map_del(MAP map); static void _stp_map_clear(MAP map); static struct map_node *_new_map_create (MAP map, struct mhlist_head *head); static int _new_map_set_int64 (MAP map, int64_t *dst, int64_t val, int add); static int _new_map_set_str (MAP map, char* dst, char *val, int add); static void _new_map_del_node (MAP map, struct map_node *n); static PMAP _stp_pmap_new_hstat_linear (unsigned max_entries, int wrap, int node_size, int start, int stop, int interval); static PMAP _stp_pmap_new_hstat_log (unsigned max_entries, int wrap, int node_size); static PMAP _stp_pmap_new_hstat (unsigned max_entries, int wrap, int node_size); static void _stp_pmap_del(PMAP pmap); static MAP _stp_pmap_agg (PMAP pmap, map_update_fn update, map_cmp_fn cmp); static struct map_node *_stp_new_agg(MAP agg, struct mhlist_head *ahead, struct map_node *ptr, map_update_fn update); static int _new_map_set_stat (MAP map, struct stat_data *dst, int64_t val, int add, int s1, int s2, int s3, int s4, int s5); static int _new_map_copy_stat (MAP map, struct stat_data *dst, struct stat_data *src, int add); static void _stp_map_sort (MAP map, int keynum, int dir, map_get_key_fn get_key); static void _stp_map_sortn(MAP map, int n, int keynum, int dir, map_get_key_fn get_key); /** @endcond */ #endif /* _MAP_H_ */