From 2da2db01b8e191c17611482e5282f8a59dc18ecd Mon Sep 17 00:00:00 2001 From: Maximiliano Geier Date: Thu, 31 Jan 2013 11:59:44 +0100 Subject: [PATCH] Added xbt_dynar_remove_n_at to remove an n-sized slice from a dynar This function is used to speed up pulling out trace events from the buffer --- include/xbt/dynar.h | 3 +++ src/instr/instr_paje_trace.c | 7 ++++--- src/xbt/dynar.c | 39 ++++++++++++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 3 deletions(-) diff --git a/include/xbt/dynar.h b/include/xbt/dynar.h index 79b590d6d0..1e710f4493 100644 --- a/include/xbt/dynar.h +++ b/include/xbt/dynar.h @@ -92,6 +92,9 @@ XBT_PUBLIC(void) xbt_dynar_insert_at(xbt_dynar_t const dynar, const int idx, const void *src); XBT_PUBLIC(void) xbt_dynar_remove_at(xbt_dynar_t const dynar, const int idx, void *const dst); +XBT_PUBLIC(void) xbt_dynar_remove_n_at(xbt_dynar_t const dynar, + const unsigned int n, const int idx); + XBT_PUBLIC(unsigned int) xbt_dynar_search(xbt_dynar_t const dynar, void *elem); XBT_PUBLIC(signed int) xbt_dynar_search_or_negative(xbt_dynar_t const dynar, void *const elem); diff --git a/src/instr/instr_paje_trace.c b/src/instr/instr_paje_trace.c index 555ac028e8..e3d78b2f0b 100644 --- a/src/instr/instr_paje_trace.c +++ b/src/instr/instr_paje_trace.c @@ -224,15 +224,16 @@ void TRACE_paje_dump_buffer (int force) buffer = xbt_dynar_new (sizeof(paje_event_t), NULL); }else{ paje_event_t event; - while (!xbt_dynar_is_empty(buffer)){ - double head_timestamp = (*(paje_event_t*)xbt_dynar_get_ptr(buffer, 0))->timestamp; + unsigned int cursor; + xbt_dynar_foreach(buffer, cursor, event) { + double head_timestamp = event->timestamp; if (head_timestamp > TRACE_last_timestamp_to_dump){ break; } - xbt_dynar_remove_at (buffer, 0, &event); event->print (event); event->free (event); } + xbt_dynar_remove_n_at(buffer, cursor, 0); } XBT_DEBUG("%s: ends", __FUNCTION__); } diff --git a/src/xbt/dynar.c b/src/xbt/dynar.c index 0fa7f41328..720b376b89 100644 --- a/src/xbt/dynar.c +++ b/src/xbt/dynar.c @@ -425,6 +425,45 @@ xbt_dynar_remove_at(xbt_dynar_t const dynar, dynar->used--; } +/** @brief Remove a slice of the dynar, sliding the rest of the values to the left + * + * This function removes an n-sized slice that starts at element idx. It is equivalent + * to xbt_dynar_remove_at with a NULL object argument if n equals to 1. + * + * Each of the removed elements is freed using the free_f function passed at dynar + * creation. + */ +void +xbt_dynar_remove_n_at(xbt_dynar_t const dynar, + const unsigned int n, const int idx) +{ + unsigned long nb_shift; + unsigned long offset; + unsigned long cur; + + if (!n) return; + + _sanity_check_dynar(dynar); + _check_inbound_idx(dynar, idx); + _check_inbound_idx(dynar, idx + n - 1); + + if (dynar->free_f) { + for (cur = idx; cur < idx + n; cur++) { + dynar->free_f(_xbt_dynar_elm(dynar, cur)); + } + } + + nb_shift = dynar->used - n - idx; + + if (nb_shift) { + offset = nb_shift * dynar->elmsize; + memmove(_xbt_dynar_elm(dynar, idx), _xbt_dynar_elm(dynar, idx + n), + offset); + } + + dynar->used -= n; +} + /** @brief Returns the position of the element in the dynar * * Raises not_found_error if not found. If you have less than 2 millions elements, -- 2.20.1