Merge pull request #15953 from keszybz/gdb-script

Update gdb script to match current sources and other hashmap improvements
This commit is contained in:
Lennart Poettering 2020-06-09 09:31:49 +02:00 committed by GitHub
commit d3d0b763b4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 207 additions and 209 deletions

3
.gitignore vendored
View File

@ -12,6 +12,8 @@
.config.args
.gdb_history
.deps/
.mypy_cache/
__pycache__/
/*.gcda
/*.gcno
/*.tar.bz2
@ -34,4 +36,3 @@
/mkosi.builddir/
/mkosi.output/
/tags
__pycache__/

View File

@ -145,12 +145,7 @@ struct hashmap_debug_info {
/* Tracks all existing hashmaps. Get at it from gdb. See sd_dump_hashmaps.py */
static LIST_HEAD(struct hashmap_debug_info, hashmap_debug_list);
static pthread_mutex_t hashmap_debug_list_mutex = PTHREAD_MUTEX_INITIALIZER;
#define HASHMAP_DEBUG_FIELDS struct hashmap_debug_info debug;
#else /* !ENABLE_DEBUG_HASHMAP */
#define HASHMAP_DEBUG_FIELDS
#endif /* ENABLE_DEBUG_HASHMAP */
#endif
enum HashmapType {
HASHMAP_TYPE_PLAIN,
@ -212,7 +207,10 @@ struct HashmapBase {
bool from_pool:1; /* whether was allocated from mempool */
bool dirty:1; /* whether dirtied since last iterated_cache_get() */
bool cached:1; /* whether this hashmap is being cached */
HASHMAP_DEBUG_FIELDS /* optional hashmap_debug_info */
#if ENABLE_DEBUG_HASHMAP
struct hashmap_debug_info debug;
#endif
};
/* Specific hash types
@ -254,7 +252,7 @@ struct hashmap_type_info {
unsigned n_direct_buckets;
};
static const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
static _used_ const struct hashmap_type_info hashmap_type_info[_HASHMAP_TYPE_MAX] = {
[HASHMAP_TYPE_PLAIN] = {
.head_size = sizeof(Hashmap),
.entry_size = sizeof(struct plain_hashmap_entry),
@ -707,7 +705,7 @@ static unsigned hashmap_iterate_entry(HashmapBase *h, Iterator *i) {
: hashmap_iterate_in_internal_order(h, i);
}
bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key) {
bool _hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key) {
struct hashmap_base_entry *e;
void *data;
unsigned idx;
@ -733,7 +731,7 @@ bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const v
}
bool set_iterate(const Set *s, Iterator *i, void **value) {
return internal_hashmap_iterate(HASHMAP_BASE((Set*) s), i, value, NULL);
return _hashmap_iterate(HASHMAP_BASE((Set*) s), i, value, NULL);
}
#define HASHMAP_FOREACH_IDX(idx, h, i) \
@ -741,7 +739,7 @@ bool set_iterate(const Set *s, Iterator *i, void **value) {
(idx != IDX_NIL); \
(idx) = hashmap_iterate_entry((h), &(i)))
IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h) {
IteratedCache *_hashmap_iterated_cache_new(HashmapBase *h) {
IteratedCache *cache;
assert(h);
@ -809,15 +807,15 @@ static struct HashmapBase *hashmap_base_new(const struct hash_ops *hash_ops, enu
return h;
}
Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
Hashmap *_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return (Hashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
}
OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
OrderedHashmap *_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return (OrderedHashmap*) hashmap_base_new(hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
}
Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
Set *_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return (Set*) hashmap_base_new(hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
}
@ -838,15 +836,15 @@ static int hashmap_base_ensure_allocated(HashmapBase **h, const struct hash_ops
return 0;
}
int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_PLAIN HASHMAP_DEBUG_PASS_ARGS);
}
int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return hashmap_base_ensure_allocated((HashmapBase**)h, hash_ops, HASHMAP_TYPE_ORDERED HASHMAP_DEBUG_PASS_ARGS);
}
int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS) {
return hashmap_base_ensure_allocated((HashmapBase**)s, hash_ops, HASHMAP_TYPE_SET HASHMAP_DEBUG_PASS_ARGS);
}
@ -868,16 +866,16 @@ static void hashmap_free_no_clear(HashmapBase *h) {
free(h);
}
HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
HashmapBase *_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
if (h) {
internal_hashmap_clear(h, default_free_key, default_free_value);
_hashmap_clear(h, default_free_key, default_free_value);
hashmap_free_no_clear(h);
}
return NULL;
}
void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
void _hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value) {
free_func_t free_key, free_value;
if (!h)
return;
@ -891,11 +889,11 @@ void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_f
* hash table, and only then call the destructor functions. If these destructors then try to unregister
* themselves from our hash table a second time, the entry is already gone. */
while (internal_hashmap_size(h) > 0) {
while (_hashmap_size(h) > 0) {
void *k = NULL;
void *v;
v = internal_hashmap_first_key_and_value(h, true, &k);
v = _hashmap_first_key_and_value(h, true, &k);
if (free_key)
free_key(k);
@ -1301,7 +1299,7 @@ int hashmap_update(Hashmap *h, const void *key, void *value) {
return 0;
}
void *internal_hashmap_get(HashmapBase *h, const void *key) {
void *_hashmap_get(HashmapBase *h, const void *key) {
struct hashmap_base_entry *e;
unsigned hash, idx;
@ -1336,7 +1334,7 @@ void *hashmap_get2(Hashmap *h, const void *key, void **key2) {
return e->value;
}
bool internal_hashmap_contains(HashmapBase *h, const void *key) {
bool _hashmap_contains(HashmapBase *h, const void *key) {
unsigned hash;
if (!h)
@ -1346,7 +1344,7 @@ bool internal_hashmap_contains(HashmapBase *h, const void *key) {
return bucket_scan(h, hash, key) != IDX_NIL;
}
void *internal_hashmap_remove(HashmapBase *h, const void *key) {
void *_hashmap_remove(HashmapBase *h, const void *key) {
struct hashmap_base_entry *e;
unsigned hash, idx;
void *data;
@ -1484,7 +1482,7 @@ int hashmap_remove_and_replace(Hashmap *h, const void *old_key, const void *new_
return 0;
}
void *internal_hashmap_remove_value(HashmapBase *h, const void *key, void *value) {
void *_hashmap_remove_value(HashmapBase *h, const void *key, void *value) {
struct hashmap_base_entry *e;
unsigned hash, idx;
@ -1514,7 +1512,7 @@ static unsigned find_first_entry(HashmapBase *h) {
return hashmap_iterate_entry(h, &i);
}
void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key) {
void *_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key) {
struct hashmap_base_entry *e;
void *key, *data;
unsigned idx;
@ -1539,21 +1537,21 @@ void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **r
return data;
}
unsigned internal_hashmap_size(HashmapBase *h) {
unsigned _hashmap_size(HashmapBase *h) {
if (!h)
return 0;
return n_entries(h);
}
unsigned internal_hashmap_buckets(HashmapBase *h) {
unsigned _hashmap_buckets(HashmapBase *h) {
if (!h)
return 0;
return n_buckets(h);
}
int internal_hashmap_merge(Hashmap *h, Hashmap *other) {
int _hashmap_merge(Hashmap *h, Hashmap *other) {
Iterator i;
unsigned idx;
@ -1589,7 +1587,7 @@ int set_merge(Set *s, Set *other) {
return 0;
}
int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add) {
int _hashmap_reserve(HashmapBase *h, unsigned entries_add) {
int r;
assert(h);
@ -1607,7 +1605,7 @@ int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add) {
* Returns: 0 on success.
* -ENOMEM on alloc failure, in which case no move has been done.
*/
int internal_hashmap_move(HashmapBase *h, HashmapBase *other) {
int _hashmap_move(HashmapBase *h, HashmapBase *other) {
struct swap_entries swap;
struct hashmap_base_entry *e, *n;
Iterator i;
@ -1652,7 +1650,7 @@ int internal_hashmap_move(HashmapBase *h, HashmapBase *other) {
return 0;
}
int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key) {
int _hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key) {
struct swap_entries swap;
unsigned h_hash, other_hash, idx;
struct hashmap_base_entry *e, *n;
@ -1689,7 +1687,7 @@ int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *ke
return 0;
}
HashmapBase *internal_hashmap_copy(HashmapBase *h) {
HashmapBase *_hashmap_copy(HashmapBase *h) {
HashmapBase *copy;
int r;
@ -1712,14 +1710,14 @@ HashmapBase *internal_hashmap_copy(HashmapBase *h) {
}
if (r < 0) {
internal_hashmap_free(copy, false, false);
_hashmap_free(copy, false, false);
return NULL;
}
return copy;
}
char **internal_hashmap_get_strv(HashmapBase *h) {
char **_hashmap_get_strv(HashmapBase *h) {
char **sv;
Iterator i;
unsigned idx, n;

View File

@ -14,7 +14,7 @@
* will be treated as empty hashmap for all read operations. That way it is not
* necessary to instantiate an object for each Hashmap use.
*
* If ENABLE_DEBUG_HASHMAP is defined (by configuring with --enable-debug=hashmap),
* If ENABLE_DEBUG_HASHMAP is defined (by configuring with -Ddebug-extra=hashmap),
* the implementation will:
* - store extra data for debugging and statistics (see tools/gdb-sd_dump_hashmaps.py)
* - perform extra checks for invalid use of iterators
@ -24,10 +24,9 @@
typedef void* (*hashmap_destroy_t)(void *p);
/* The base type for all hashmap and set types. Many functions in the
* implementation take (HashmapBase*) parameters and are run-time polymorphic,
* though the API is not meant to be polymorphic (do not call functions
* internal_*() directly). */
/* The base type for all hashmap and set types. Many functions in the implementation take (HashmapBase*)
* parameters and are run-time polymorphic, though the API is not meant to be polymorphic (do not call
* underscore-prefixed functions directly). */
typedef struct HashmapBase HashmapBase;
/* Specific hashmap/set types */
@ -84,10 +83,10 @@ typedef struct {
# define HASHMAP_DEBUG_PASS_ARGS
#endif
Hashmap *internal_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define hashmap_new(ops) internal_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
#define ordered_hashmap_new(ops) internal_ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
Hashmap *_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
OrderedHashmap *_ordered_hashmap_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define hashmap_new(ops) _hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
#define ordered_hashmap_new(ops) _ordered_hashmap_new(ops HASHMAP_DEBUG_SRC_ARGS)
#define hashmap_free_and_replace(a, b) \
({ \
@ -97,57 +96,57 @@ OrderedHashmap *internal_ordered_hashmap_new(const struct hash_ops *hash_ops HA
0; \
})
HashmapBase *internal_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
HashmapBase *_hashmap_free(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
static inline Hashmap *hashmap_free(Hashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL);
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, NULL);
}
static inline OrderedHashmap *ordered_hashmap_free(OrderedHashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, NULL);
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, NULL);
}
static inline Hashmap *hashmap_free_free(Hashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free);
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, free);
}
static inline OrderedHashmap *ordered_hashmap_free_free(OrderedHashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), NULL, free);
return (void*) _hashmap_free(HASHMAP_BASE(h), NULL, free);
}
static inline Hashmap *hashmap_free_free_key(Hashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL);
return (void*) _hashmap_free(HASHMAP_BASE(h), free, NULL);
}
static inline OrderedHashmap *ordered_hashmap_free_free_key(OrderedHashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, NULL);
return (void*) _hashmap_free(HASHMAP_BASE(h), free, NULL);
}
static inline Hashmap *hashmap_free_free_free(Hashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free);
return (void*) _hashmap_free(HASHMAP_BASE(h), free, free);
}
static inline OrderedHashmap *ordered_hashmap_free_free_free(OrderedHashmap *h) {
return (void*) internal_hashmap_free(HASHMAP_BASE(h), free, free);
return (void*) _hashmap_free(HASHMAP_BASE(h), free, free);
}
IteratedCache *iterated_cache_free(IteratedCache *cache);
int iterated_cache_get(IteratedCache *cache, const void ***res_keys, const void ***res_values, unsigned *res_n_entries);
HashmapBase *internal_hashmap_copy(HashmapBase *h);
HashmapBase *_hashmap_copy(HashmapBase *h);
static inline Hashmap *hashmap_copy(Hashmap *h) {
return (Hashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
return (Hashmap*) _hashmap_copy(HASHMAP_BASE(h));
}
static inline OrderedHashmap *ordered_hashmap_copy(OrderedHashmap *h) {
return (OrderedHashmap*) internal_hashmap_copy(HASHMAP_BASE(h));
return (OrderedHashmap*) _hashmap_copy(HASHMAP_BASE(h));
}
int internal_hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
int internal_ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define hashmap_ensure_allocated(h, ops) internal_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
#define ordered_hashmap_ensure_allocated(h, ops) internal_ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
int _hashmap_ensure_allocated(Hashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
int _ordered_hashmap_ensure_allocated(OrderedHashmap **h, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define hashmap_ensure_allocated(h, ops) _hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
#define ordered_hashmap_ensure_allocated(h, ops) _ordered_hashmap_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
IteratedCache *internal_hashmap_iterated_cache_new(HashmapBase *h);
IteratedCache *_hashmap_iterated_cache_new(HashmapBase *h);
static inline IteratedCache *hashmap_iterated_cache_new(Hashmap *h) {
return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h));
}
static inline IteratedCache *ordered_hashmap_iterated_cache_new(OrderedHashmap *h) {
return (IteratedCache*) internal_hashmap_iterated_cache_new(HASHMAP_BASE(h));
return (IteratedCache*) _hashmap_iterated_cache_new(HASHMAP_BASE(h));
}
int hashmap_put(Hashmap *h, const void *key, void *value);
@ -167,12 +166,12 @@ static inline int ordered_hashmap_replace(OrderedHashmap *h, const void *key, vo
return hashmap_replace(PLAIN_HASHMAP(h), key, value);
}
void *internal_hashmap_get(HashmapBase *h, const void *key);
void *_hashmap_get(HashmapBase *h, const void *key);
static inline void *hashmap_get(Hashmap *h, const void *key) {
return internal_hashmap_get(HASHMAP_BASE(h), key);
return _hashmap_get(HASHMAP_BASE(h), key);
}
static inline void *ordered_hashmap_get(OrderedHashmap *h, const void *key) {
return internal_hashmap_get(HASHMAP_BASE(h), key);
return _hashmap_get(HASHMAP_BASE(h), key);
}
void *hashmap_get2(Hashmap *h, const void *key, void **rkey);
@ -180,20 +179,20 @@ static inline void *ordered_hashmap_get2(OrderedHashmap *h, const void *key, voi
return hashmap_get2(PLAIN_HASHMAP(h), key, rkey);
}
bool internal_hashmap_contains(HashmapBase *h, const void *key);
bool _hashmap_contains(HashmapBase *h, const void *key);
static inline bool hashmap_contains(Hashmap *h, const void *key) {
return internal_hashmap_contains(HASHMAP_BASE(h), key);
return _hashmap_contains(HASHMAP_BASE(h), key);
}
static inline bool ordered_hashmap_contains(OrderedHashmap *h, const void *key) {
return internal_hashmap_contains(HASHMAP_BASE(h), key);
return _hashmap_contains(HASHMAP_BASE(h), key);
}
void *internal_hashmap_remove(HashmapBase *h, const void *key);
void *_hashmap_remove(HashmapBase *h, const void *key);
static inline void *hashmap_remove(Hashmap *h, const void *key) {
return internal_hashmap_remove(HASHMAP_BASE(h), key);
return _hashmap_remove(HASHMAP_BASE(h), key);
}
static inline void *ordered_hashmap_remove(OrderedHashmap *h, const void *key) {
return internal_hashmap_remove(HASHMAP_BASE(h), key);
return _hashmap_remove(HASHMAP_BASE(h), key);
}
void *hashmap_remove2(Hashmap *h, const void *key, void **rkey);
@ -201,9 +200,9 @@ static inline void *ordered_hashmap_remove2(OrderedHashmap *h, const void *key,
return hashmap_remove2(PLAIN_HASHMAP(h), key, rkey);
}
void *internal_hashmap_remove_value(HashmapBase *h, const void *key, void *value);
void *_hashmap_remove_value(HashmapBase *h, const void *key, void *value);
static inline void *hashmap_remove_value(Hashmap *h, const void *key, void *value) {
return internal_hashmap_remove_value(HASHMAP_BASE(h), key, value);
return _hashmap_remove_value(HASHMAP_BASE(h), key, value);
}
static inline void *ordered_hashmap_remove_value(OrderedHashmap *h, const void *key, void *value) {
@ -222,41 +221,41 @@ static inline int ordered_hashmap_remove_and_replace(OrderedHashmap *h, const vo
/* Since merging data from a OrderedHashmap into a Hashmap or vice-versa
* should just work, allow this by having looser type-checking here. */
int internal_hashmap_merge(Hashmap *h, Hashmap *other);
#define hashmap_merge(h, other) internal_hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other))
int _hashmap_merge(Hashmap *h, Hashmap *other);
#define hashmap_merge(h, other) _hashmap_merge(PLAIN_HASHMAP(h), PLAIN_HASHMAP(other))
#define ordered_hashmap_merge(h, other) hashmap_merge(h, other)
int internal_hashmap_reserve(HashmapBase *h, unsigned entries_add);
int _hashmap_reserve(HashmapBase *h, unsigned entries_add);
static inline int hashmap_reserve(Hashmap *h, unsigned entries_add) {
return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
return _hashmap_reserve(HASHMAP_BASE(h), entries_add);
}
static inline int ordered_hashmap_reserve(OrderedHashmap *h, unsigned entries_add) {
return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
return _hashmap_reserve(HASHMAP_BASE(h), entries_add);
}
int internal_hashmap_move(HashmapBase *h, HashmapBase *other);
int _hashmap_move(HashmapBase *h, HashmapBase *other);
/* Unlike hashmap_merge, hashmap_move does not allow mixing the types. */
static inline int hashmap_move(Hashmap *h, Hashmap *other) {
return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
return _hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
}
static inline int ordered_hashmap_move(OrderedHashmap *h, OrderedHashmap *other) {
return internal_hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
return _hashmap_move(HASHMAP_BASE(h), HASHMAP_BASE(other));
}
int internal_hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key);
int _hashmap_move_one(HashmapBase *h, HashmapBase *other, const void *key);
static inline int hashmap_move_one(Hashmap *h, Hashmap *other, const void *key) {
return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
return _hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
}
static inline int ordered_hashmap_move_one(OrderedHashmap *h, OrderedHashmap *other, const void *key) {
return internal_hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
return _hashmap_move_one(HASHMAP_BASE(h), HASHMAP_BASE(other), key);
}
unsigned internal_hashmap_size(HashmapBase *h) _pure_;
unsigned _hashmap_size(HashmapBase *h) _pure_;
static inline unsigned hashmap_size(Hashmap *h) {
return internal_hashmap_size(HASHMAP_BASE(h));
return _hashmap_size(HASHMAP_BASE(h));
}
static inline unsigned ordered_hashmap_size(OrderedHashmap *h) {
return internal_hashmap_size(HASHMAP_BASE(h));
return _hashmap_size(HASHMAP_BASE(h));
}
static inline bool hashmap_isempty(Hashmap *h) {
@ -266,49 +265,49 @@ static inline bool ordered_hashmap_isempty(OrderedHashmap *h) {
return ordered_hashmap_size(h) == 0;
}
unsigned internal_hashmap_buckets(HashmapBase *h) _pure_;
unsigned _hashmap_buckets(HashmapBase *h) _pure_;
static inline unsigned hashmap_buckets(Hashmap *h) {
return internal_hashmap_buckets(HASHMAP_BASE(h));
return _hashmap_buckets(HASHMAP_BASE(h));
}
static inline unsigned ordered_hashmap_buckets(OrderedHashmap *h) {
return internal_hashmap_buckets(HASHMAP_BASE(h));
return _hashmap_buckets(HASHMAP_BASE(h));
}
bool internal_hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
bool _hashmap_iterate(HashmapBase *h, Iterator *i, void **value, const void **key);
static inline bool hashmap_iterate(Hashmap *h, Iterator *i, void **value, const void **key) {
return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
return _hashmap_iterate(HASHMAP_BASE(h), i, value, key);
}
static inline bool ordered_hashmap_iterate(OrderedHashmap *h, Iterator *i, void **value, const void **key) {
return internal_hashmap_iterate(HASHMAP_BASE(h), i, value, key);
return _hashmap_iterate(HASHMAP_BASE(h), i, value, key);
}
void internal_hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
void _hashmap_clear(HashmapBase *h, free_func_t default_free_key, free_func_t default_free_value);
static inline void hashmap_clear(Hashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
}
static inline void ordered_hashmap_clear(OrderedHashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
_hashmap_clear(HASHMAP_BASE(h), NULL, NULL);
}
static inline void hashmap_clear_free(Hashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), NULL, free);
_hashmap_clear(HASHMAP_BASE(h), NULL, free);
}
static inline void ordered_hashmap_clear_free(OrderedHashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), NULL, free);
_hashmap_clear(HASHMAP_BASE(h), NULL, free);
}
static inline void hashmap_clear_free_key(Hashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), free, NULL);
_hashmap_clear(HASHMAP_BASE(h), free, NULL);
}
static inline void ordered_hashmap_clear_free_key(OrderedHashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), free, NULL);
_hashmap_clear(HASHMAP_BASE(h), free, NULL);
}
static inline void hashmap_clear_free_free(Hashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), free, free);
_hashmap_clear(HASHMAP_BASE(h), free, free);
}
static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
internal_hashmap_clear(HASHMAP_BASE(h), free, free);
_hashmap_clear(HASHMAP_BASE(h), free, free);
}
/*
@ -322,50 +321,50 @@ static inline void ordered_hashmap_clear_free_free(OrderedHashmap *h) {
* the first entry is O(1).
*/
void *internal_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key);
void *_hashmap_first_key_and_value(HashmapBase *h, bool remove, void **ret_key);
static inline void *hashmap_steal_first_key_and_value(Hashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
}
static inline void *ordered_hashmap_steal_first_key_and_value(OrderedHashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, ret);
}
static inline void *hashmap_first_key_and_value(Hashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
}
static inline void *ordered_hashmap_first_key_and_value(OrderedHashmap *h, void **ret) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, ret);
}
static inline void *hashmap_steal_first(Hashmap *h) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
}
static inline void *ordered_hashmap_steal_first(OrderedHashmap *h) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), true, NULL);
}
static inline void *hashmap_first(Hashmap *h) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
}
static inline void *ordered_hashmap_first(OrderedHashmap *h) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
return _hashmap_first_key_and_value(HASHMAP_BASE(h), false, NULL);
}
static inline void *internal_hashmap_first_key(HashmapBase *h, bool remove) {
static inline void *_hashmap_first_key(HashmapBase *h, bool remove) {
void *key = NULL;
(void) internal_hashmap_first_key_and_value(HASHMAP_BASE(h), remove, &key);
(void) _hashmap_first_key_and_value(HASHMAP_BASE(h), remove, &key);
return key;
}
static inline void *hashmap_steal_first_key(Hashmap *h) {
return internal_hashmap_first_key(HASHMAP_BASE(h), true);
return _hashmap_first_key(HASHMAP_BASE(h), true);
}
static inline void *ordered_hashmap_steal_first_key(OrderedHashmap *h) {
return internal_hashmap_first_key(HASHMAP_BASE(h), true);
return _hashmap_first_key(HASHMAP_BASE(h), true);
}
static inline void *hashmap_first_key(Hashmap *h) {
return internal_hashmap_first_key(HASHMAP_BASE(h), false);
return _hashmap_first_key(HASHMAP_BASE(h), false);
}
static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
return internal_hashmap_first_key(HASHMAP_BASE(h), false);
return _hashmap_first_key(HASHMAP_BASE(h), false);
}
#define hashmap_clear_with_destructor(_s, _f) \
@ -394,12 +393,12 @@ static inline void *ordered_hashmap_first_key(OrderedHashmap *h) {
/* no hashmap_next */
void *ordered_hashmap_next(OrderedHashmap *h, const void *key);
char **internal_hashmap_get_strv(HashmapBase *h);
char **_hashmap_get_strv(HashmapBase *h);
static inline char **hashmap_get_strv(Hashmap *h) {
return internal_hashmap_get_strv(HASHMAP_BASE(h));
return _hashmap_get_strv(HASHMAP_BASE(h));
}
static inline char **ordered_hashmap_get_strv(OrderedHashmap *h) {
return internal_hashmap_get_strv(HASHMAP_BASE(h));
return _hashmap_get_strv(HASHMAP_BASE(h));
}
/*

View File

@ -59,7 +59,7 @@ static inline void* ordered_set_steal_first(OrderedSet *s) {
}
static inline char **ordered_set_get_strv(OrderedSet *s) {
return internal_hashmap_get_strv(HASHMAP_BASE((OrderedHashmap*) s));
return _hashmap_get_strv(HASHMAP_BASE((OrderedHashmap*) s));
}
int ordered_set_consume(OrderedSet *s, void *p);

View File

@ -13,40 +13,40 @@
0; \
})
Set *internal_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define set_new(ops) internal_set_new(ops HASHMAP_DEBUG_SRC_ARGS)
Set *_set_new(const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define set_new(ops) _set_new(ops HASHMAP_DEBUG_SRC_ARGS)
static inline Set *set_free(Set *s) {
return (Set*) internal_hashmap_free(HASHMAP_BASE(s), NULL, NULL);
return (Set*) _hashmap_free(HASHMAP_BASE(s), NULL, NULL);
}
static inline Set *set_free_free(Set *s) {
return (Set*) internal_hashmap_free(HASHMAP_BASE(s), free, NULL);
return (Set*) _hashmap_free(HASHMAP_BASE(s), free, NULL);
}
/* no set_free_free_free */
static inline Set *set_copy(Set *s) {
return (Set*) internal_hashmap_copy(HASHMAP_BASE(s));
return (Set*) _hashmap_copy(HASHMAP_BASE(s));
}
int internal_set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define set_ensure_allocated(h, ops) internal_set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
int _set_ensure_allocated(Set **s, const struct hash_ops *hash_ops HASHMAP_DEBUG_PARAMS);
#define set_ensure_allocated(h, ops) _set_ensure_allocated(h, ops HASHMAP_DEBUG_SRC_ARGS)
int set_put(Set *s, const void *key);
/* no set_update */
/* no set_replace */
static inline void *set_get(const Set *s, void *key) {
return internal_hashmap_get(HASHMAP_BASE((Set *) s), key);
return _hashmap_get(HASHMAP_BASE((Set *) s), key);
}
/* no set_get2 */
static inline bool set_contains(const Set *s, const void *key) {
return internal_hashmap_contains(HASHMAP_BASE((Set *) s), key);
return _hashmap_contains(HASHMAP_BASE((Set *) s), key);
}
static inline void *set_remove(Set *s, const void *key) {
return internal_hashmap_remove(HASHMAP_BASE(s), key);
return _hashmap_remove(HASHMAP_BASE(s), key);
}
/* no set_remove2 */
@ -56,19 +56,19 @@ int set_remove_and_put(Set *s, const void *old_key, const void *new_key);
int set_merge(Set *s, Set *other);
static inline int set_reserve(Set *h, unsigned entries_add) {
return internal_hashmap_reserve(HASHMAP_BASE(h), entries_add);
return _hashmap_reserve(HASHMAP_BASE(h), entries_add);
}
static inline int set_move(Set *s, Set *other) {
return internal_hashmap_move(HASHMAP_BASE(s), HASHMAP_BASE(other));
return _hashmap_move(HASHMAP_BASE(s), HASHMAP_BASE(other));
}
static inline int set_move_one(Set *s, Set *other, const void *key) {
return internal_hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key);
return _hashmap_move_one(HASHMAP_BASE(s), HASHMAP_BASE(other), key);
}
static inline unsigned set_size(const Set *s) {
return internal_hashmap_size(HASHMAP_BASE((Set *) s));
return _hashmap_size(HASHMAP_BASE((Set *) s));
}
static inline bool set_isempty(const Set *s) {
@ -76,23 +76,23 @@ static inline bool set_isempty(const Set *s) {
}
static inline unsigned set_buckets(const Set *s) {
return internal_hashmap_buckets(HASHMAP_BASE((Set *) s));
return _hashmap_buckets(HASHMAP_BASE((Set *) s));
}
bool set_iterate(const Set *s, Iterator *i, void **value);
static inline void set_clear(Set *s) {
internal_hashmap_clear(HASHMAP_BASE(s), NULL, NULL);
_hashmap_clear(HASHMAP_BASE(s), NULL, NULL);
}
static inline void set_clear_free(Set *s) {
internal_hashmap_clear(HASHMAP_BASE(s), free, NULL);
_hashmap_clear(HASHMAP_BASE(s), free, NULL);
}
/* no set_clear_free_free */
static inline void *set_steal_first(Set *s) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE(s), true, NULL);
return _hashmap_first_key_and_value(HASHMAP_BASE(s), true, NULL);
}
#define set_clear_with_destructor(_s, _f) \
@ -111,13 +111,13 @@ static inline void *set_steal_first(Set *s) {
/* no set_first_key */
static inline void *set_first(const Set *s) {
return internal_hashmap_first_key_and_value(HASHMAP_BASE((Set *) s), false, NULL);
return _hashmap_first_key_and_value(HASHMAP_BASE((Set *) s), false, NULL);
}
/* no set_next */
static inline char **set_get_strv(Set *s) {
return internal_hashmap_get_strv(HASHMAP_BASE(s));
return _hashmap_get_strv(HASHMAP_BASE(s));
}
int set_consume(Set *s, void *value);

View File

@ -946,20 +946,20 @@ static int string_strv_hashmap_put_internal(Hashmap *h, const char *key, const c
return 1;
}
int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value) {
int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) {
int r;
r = hashmap_ensure_allocated(h, &string_strv_hash_ops);
r = _hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;
return string_strv_hashmap_put_internal(*h, key, value);
}
int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value) {
int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS) {
int r;
r = ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops);
r = _ordered_hashmap_ensure_allocated(h, &string_strv_hash_ops HASHMAP_DEBUG_PASS_ARGS);
if (r < 0)
return r;

View File

@ -226,5 +226,7 @@ int fputstrv(FILE *f, char * const *l, const char *separator, bool *space);
})
extern const struct hash_ops string_strv_hash_ops;
int string_strv_hashmap_put(Hashmap **h, const char *key, const char *value);
int string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value);
int _string_strv_hashmap_put(Hashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS);
int _string_strv_ordered_hashmap_put(OrderedHashmap **h, const char *key, const char *value HASHMAP_DEBUG_PARAMS);
#define string_strv_hashmap_put(h, k, v) _string_strv_hashmap_put(h, k, v HASHMAP_DEBUG_SRC_ARGS)
#define string_strv_ordered_hashmap_put(h, k, v) _string_strv_ordered_hashmap_put(h, k, v HASHMAP_DEBUG_SRC_ARGS)

View File

@ -1,79 +1,77 @@
#!/usr/bin/env python3
# SPDX-License-Identifier: LGPL-2.1+
from __future__ import print_function
import gdb
class sd_dump_hashmaps(gdb.Command):
"dump systemd's hashmaps"
"dump systemd's hashmaps"
def __init__(self):
super(sd_dump_hashmaps, self).__init__("sd_dump_hashmaps", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
def __init__(self):
super().__init__("sd_dump_hashmaps", gdb.COMMAND_DATA, gdb.COMPLETE_NONE)
def invoke(self, arg, from_tty):
d = gdb.parse_and_eval("hashmap_debug_list")
all_entry_sizes = gdb.parse_and_eval("all_entry_sizes")
all_direct_buckets = gdb.parse_and_eval("all_direct_buckets")
uchar_t = gdb.lookup_type("unsigned char")
ulong_t = gdb.lookup_type("unsigned long")
debug_offset = gdb.parse_and_eval("(unsigned long)&((HashmapBase*)0)->debug")
def invoke(self, arg, from_tty):
d = gdb.parse_and_eval("hashmap_debug_list")
hashmap_type_info = gdb.parse_and_eval("hashmap_type_info")
uchar_t = gdb.lookup_type("unsigned char")
ulong_t = gdb.lookup_type("unsigned long")
debug_offset = gdb.parse_and_eval("(unsigned long)&((HashmapBase*)0)->debug")
print("type, hash, indirect, entries, max_entries, buckets, creator")
while d:
h = gdb.parse_and_eval("(HashmapBase*)((char*)%d - %d)" % (int(d.cast(ulong_t)), debug_offset))
print("type, hash, indirect, entries, max_entries, buckets, creator")
while d:
h = gdb.parse_and_eval(f"(HashmapBase*)((char*){int(d.cast(ulong_t))} - {debug_offset})")
if h["has_indirect"]:
storage_ptr = h["indirect"]["storage"].cast(uchar_t.pointer())
n_entries = h["indirect"]["n_entries"]
n_buckets = h["indirect"]["n_buckets"]
else:
storage_ptr = h["direct"]["storage"].cast(uchar_t.pointer())
n_entries = h["n_direct_entries"]
n_buckets = all_direct_buckets[int(h["type"])];
if h["has_indirect"]:
storage_ptr = h["indirect"]["storage"].cast(uchar_t.pointer())
n_entries = h["indirect"]["n_entries"]
n_buckets = h["indirect"]["n_buckets"]
else:
storage_ptr = h["direct"]["storage"].cast(uchar_t.pointer())
n_entries = h["n_direct_entries"]
n_buckets = hashmap_type_info[h["type"]]["n_direct_buckets"]
t = ["plain", "ordered", "set"][int(h["type"])]
t = ["plain", "ordered", "set"][int(h["type"])]
print("{}, {}, {}, {}, {}, {}, {} ({}:{})".format(t, h["hash_ops"], bool(h["has_indirect"]), n_entries, d["max_entries"], n_buckets, d["func"], d["file"], d["line"]))
print(f'{t}, {h["hash_ops"]}, {bool(h["has_indirect"])}, {n_entries}, {d["max_entries"]}, {n_buckets}, {d["func"].string()}, {d["file"].string()}:{d["line"]}')
if arg != "" and n_entries > 0:
dib_raw_addr = storage_ptr + (all_entry_sizes[h["type"]] * n_buckets)
if arg != "" and n_entries > 0:
dib_raw_addr = storage_ptr + hashmap_type_info[h["type"]]["entry_size"] * n_buckets
histogram = {}
for i in xrange(0, n_buckets):
dib = int(dib_raw_addr[i])
histogram[dib] = histogram.get(dib, 0) + 1
histogram = {}
for i in range(0, n_buckets):
dib = int(dib_raw_addr[i])
histogram[dib] = histogram.get(dib, 0) + 1
for dib in sorted(iter(histogram)):
if dib != 255:
print("{:>3} {:>8} {} of entries".format(dib, histogram[dib], 100.0*histogram[dib]/n_entries))
else:
print("{:>3} {:>8} {} of slots".format(dib, histogram[dib], 100.0*histogram[dib]/n_buckets))
print("mean DIB of entries: {}".format(sum([dib*histogram[dib] for dib in iter(histogram) if dib != 255])*1.0/n_entries))
for dib in sorted(histogram):
if dib != 255:
print(f"{dib:>3} {histogram[dib]:>8} {float(histogram[dib]/n_entries):.0%} of entries")
else:
print(f"{dib:>3} {histogram[dib]:>8} {float(histogram[dib]/n_buckets):.0%} of slots")
s = sum(dib*count for (dib, count) in histogram.items() if dib != 255) / n_entries
print(f"mean DIB of entries: {s}")
blocks = []
current_len = 1
prev = int(dib_raw_addr[0])
for i in xrange(1, n_buckets):
dib = int(dib_raw_addr[i])
if (dib == 255) != (prev == 255):
if prev != 255:
blocks += [[i, current_len]]
current_len = 1
else:
current_len += 1
blocks = []
current_len = 1
prev = int(dib_raw_addr[0])
for i in range(1, n_buckets):
dib = int(dib_raw_addr[i])
if (dib == 255) != (prev == 255):
if prev != 255:
blocks += [[i, current_len]]
current_len = 1
else:
current_len += 1
prev = dib
if prev != 255:
blocks += [[i, current_len]]
# a block may be wrapped around
if len(blocks) > 1 and blocks[0][0] == blocks[0][1] and blocks[-1][0] == n_buckets - 1:
blocks[0][1] += blocks[-1][1]
blocks = blocks[0:-1]
print("max block: {}".format(max(blocks, key=lambda a: a[1])))
print("sum block lens: {}".format(sum(b[1] for b in blocks)))
print("mean block len: {}".format((1.0 * sum(b[1] for b in blocks) / len(blocks))))
prev = dib
if prev != 255:
blocks += [[i, current_len]]
# a block may be wrapped around
if len(blocks) > 1 and blocks[0][0] == blocks[0][1] and blocks[-1][0] == n_buckets - 1:
blocks[0][1] += blocks[-1][1]
blocks = blocks[0:-1]
print("max block: {}".format(max(blocks, key=lambda a: a[1])))
print("sum block lens: {}".format(sum(b[1] for b in blocks)))
print("mean block len: {}".format(sum(b[1] for b in blocks) / len(blocks)))
d = d["debug_list_next"]
d = d["debug_list_next"]
sd_dump_hashmaps()