diff options
author | Costa Tsaousis <costa@netdata.cloud> | 2022-06-28 17:48:11 +0300 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-06-28 17:48:11 +0300 |
commit | aa3be2f0647ace385e5ffb475a3e145f38458e6e (patch) | |
tree | 23ad01136e8ccf855483a91c4881dd0ca5a85830 /daemon | |
parent | c3dfbe52a61dd0d1995bc420b0e0576cf058fd74 (diff) |
Dictionaries with reference counters and full deletion support during traversal (#13195)
* dont use atomic operations when not needed; detect misuse of the the unsafe functions
* use relaxed atomic operations for statistics
* use relaxed atomic operations for statistics
* dictionaries now use reference counters, allowing deletetions of any item while traversing it
* added acquire/release interface to dictionaries
* added unittest for reference counters
* added NETDATA_INTERNAL_CHECKS logs to detect non-exclusive access to crusial parts of the dictionaries
* dictionaries cannot be deleted while there are referenced items in them - they will be deleted once the last item gets unreferenced
* cleanup
* properly cleanup released items
* maintain counters for readers and writers; defer all deletes on sorted walkthrough; cleaner internal_error();
* somewhat faster reference counters on single threaded dictionaries
* minor optimizations; allow compiling without internal checks
Diffstat (limited to 'daemon')
-rw-r--r-- | daemon/global_statistics.c | 57 |
1 files changed, 28 insertions, 29 deletions
diff --git a/daemon/global_statistics.c b/daemon/global_statistics.c index 1d268ce81f..983bb2d7fb 100644 --- a/daemon/global_statistics.c +++ b/daemon/global_statistics.c @@ -46,9 +46,9 @@ static struct global_statistics { }; void rrdr_query_completed(uint64_t db_points_read, uint64_t result_points_generated) { - __atomic_fetch_add(&global_statistics.rrdr_queries_made, 1, __ATOMIC_SEQ_CST); - __atomic_fetch_add(&global_statistics.rrdr_db_points_read, db_points_read, __ATOMIC_SEQ_CST); - __atomic_fetch_add(&global_statistics.rrdr_result_points_generated, result_points_generated, __ATOMIC_SEQ_CST); + __atomic_fetch_add(&global_statistics.rrdr_queries_made, 1, __ATOMIC_RELAXED); + __atomic_fetch_add(&global_statistics.rrdr_db_points_read, db_points_read, __ATOMIC_RELAXED); + __atomic_fetch_add(&global_statistics.rrdr_result_points_generated, result_points_generated, __ATOMIC_RELAXED); } void finished_web_request_statistics(uint64_t dt, @@ -58,45 +58,44 @@ void finished_web_request_statistics(uint64_t dt, uint64_t compressed_content_size) { uint64_t old_web_usec_max = global_statistics.web_usec_max; while(dt > old_web_usec_max) - __atomic_compare_exchange(&global_statistics.web_usec_max, &old_web_usec_max, &dt, 1, __ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST); - - __atomic_fetch_add(&global_statistics.web_requests, 1, __ATOMIC_SEQ_CST); - __atomic_fetch_add(&global_statistics.web_usec, dt, __ATOMIC_SEQ_CST); - __atomic_fetch_add(&global_statistics.bytes_received, bytes_received, __ATOMIC_SEQ_CST); - __atomic_fetch_add(&global_statistics.bytes_sent, bytes_sent, __ATOMIC_SEQ_CST); - __atomic_fetch_add(&global_statistics.content_size, content_size, __ATOMIC_SEQ_CST); - __atomic_fetch_add(&global_statistics.compressed_content_size, compressed_content_size, __ATOMIC_SEQ_CST); + __atomic_compare_exchange(&global_statistics.web_usec_max, &old_web_usec_max, &dt, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED); + + __atomic_fetch_add(&global_statistics.web_requests, 1, __ATOMIC_RELAXED); + __atomic_fetch_add(&global_statistics.web_usec, dt, __ATOMIC_RELAXED); + __atomic_fetch_add(&global_statistics.bytes_received, bytes_received, __ATOMIC_RELAXED); + __atomic_fetch_add(&global_statistics.bytes_sent, bytes_sent, __ATOMIC_RELAXED); + __atomic_fetch_add(&global_statistics.content_size, content_size, __ATOMIC_RELAXED); + __atomic_fetch_add(&global_statistics.compressed_content_size, compressed_content_size, __ATOMIC_RELAXED); } uint64_t web_client_connected(void) { - __atomic_fetch_add(&global_statistics.connected_clients, 1, __ATOMIC_SEQ_CST); - return __atomic_fetch_add(&global_statistics.web_client_count, 1, __ATOMIC_SEQ_CST); + __atomic_fetch_add(&global_statistics.connected_clients, 1, __ATOMIC_RELAXED); + return __atomic_fetch_add(&global_statistics.web_client_count, 1, __ATOMIC_RELAXED); } void web_client_disconnected(void) { - __atomic_fetch_sub(&global_statistics.connected_clients, 1, __ATOMIC_SEQ_CST); + __atomic_fetch_sub(&global_statistics.connected_clients, 1, __ATOMIC_RELAXED); } static inline void global_statistics_copy(struct global_statistics *gs, uint8_t options) { - gs->connected_clients = __atomic_fetch_add(&global_statistics.connected_clients, 0, __ATOMIC_SEQ_CST); - gs->web_requests = __atomic_fetch_add(&global_statistics.web_requests, 0, __ATOMIC_SEQ_CST); - gs->web_usec = __atomic_fetch_add(&global_statistics.web_usec, 0, __ATOMIC_SEQ_CST); - gs->web_usec_max = __atomic_fetch_add(&global_statistics.web_usec_max, 0, __ATOMIC_SEQ_CST); - gs->bytes_received = __atomic_fetch_add(&global_statistics.bytes_received, 0, __ATOMIC_SEQ_CST); - gs->bytes_sent = __atomic_fetch_add(&global_statistics.bytes_sent, 0, __ATOMIC_SEQ_CST); - gs->content_size = __atomic_fetch_add(&global_statistics.content_size, 0, __ATOMIC_SEQ_CST); - gs->compressed_content_size = __atomic_fetch_add(&global_statistics.compressed_content_size, 0, __ATOMIC_SEQ_CST); - gs->web_client_count = __atomic_fetch_add(&global_statistics.web_client_count, 0, __ATOMIC_SEQ_CST); - - gs->rrdr_queries_made = __atomic_fetch_add(&global_statistics.rrdr_queries_made, 0, __ATOMIC_SEQ_CST); - gs->rrdr_db_points_read = __atomic_fetch_add(&global_statistics.rrdr_db_points_read, 0, __ATOMIC_SEQ_CST); - gs->rrdr_result_points_generated = __atomic_fetch_add(&global_statistics.rrdr_result_points_generated, 0, __ATOMIC_SEQ_CST); + gs->connected_clients = __atomic_fetch_add(&global_statistics.connected_clients, 0, __ATOMIC_RELAXED); + gs->web_requests = __atomic_fetch_add(&global_statistics.web_requests, 0, __ATOMIC_RELAXED); + gs->web_usec = __atomic_fetch_add(&global_statistics.web_usec, 0, __ATOMIC_RELAXED); + gs->web_usec_max = __atomic_fetch_add(&global_statistics.web_usec_max, 0, __ATOMIC_RELAXED); + gs->bytes_received = __atomic_fetch_add(&global_statistics.bytes_received, 0, __ATOMIC_RELAXED); + gs->bytes_sent = __atomic_fetch_add(&global_statistics.bytes_sent, 0, __ATOMIC_RELAXED); + gs->content_size = __atomic_fetch_add(&global_statistics.content_size, 0, __ATOMIC_RELAXED); + gs->compressed_content_size = __atomic_fetch_add(&global_statistics.compressed_content_size, 0, __ATOMIC_RELAXED); + gs->web_client_count = __atomic_fetch_add(&global_statistics.web_client_count, 0, __ATOMIC_RELAXED); + + gs->rrdr_queries_made = __atomic_fetch_add(&global_statistics.rrdr_queries_made, 0, __ATOMIC_RELAXED); + gs->rrdr_db_points_read = __atomic_fetch_add(&global_statistics.rrdr_db_points_read, 0, __ATOMIC_RELAXED); + gs->rrdr_result_points_generated = __atomic_fetch_add(&global_statistics.rrdr_result_points_generated, 0, __ATOMIC_RELAXED); if(options & GLOBAL_STATS_RESET_WEB_USEC_MAX) { uint64_t n = 0; - __atomic_compare_exchange(&global_statistics.web_usec_max, (uint64_t *) &gs->web_usec_max, &n, 1, __ATOMIC_SEQ_CST, - __ATOMIC_SEQ_CST); + __atomic_compare_exchange(&global_statistics.web_usec_max, (uint64_t *) &gs->web_usec_max, &n, 1, __ATOMIC_RELAXED, __ATOMIC_RELAXED); } } |