diff --git a/dmalloc_tab.c b/dmalloc_tab.c index a40b386..c301202 100644 --- a/dmalloc_tab.c +++ b/dmalloc_tab.c @@ -224,234 +224,6 @@ static int entry_cmp(const void *entry1_p, const void *entry2_p) } } -/* - * static void swap_bytes - * - * Swap the values between two items of a specified size. - * - * ARGUMENTS: - * - * item1_p -> Pointer to the first item. - * - * item2_p -> Pointer to the first item. - * - * ele_size -> Size of the two items. - */ -static void swap_bytes(unsigned char *item1_p, unsigned char *item2_p, - int ele_size) -{ - unsigned char char_temp; - - for (; ele_size > 0; ele_size--) { - char_temp = *item1_p; - *item1_p = *item2_p; - *item2_p = char_temp; - item1_p++; - item2_p++; - } -} - -/* - * static void insert_sort - * - * Do an insertion sort which is faster for small numbers of items and - * better if the items are already sorted. - * - * ARGUMENTS: - * - * first_p <-> Start of the list that we are splitting. - * - * last_p <-> Last entry in the list that we are splitting. - * - * holder_p <-> Location of hold area we can store an entry. - * - * ele_size -> Size of the each element in the list. - */ -static void insert_sort(unsigned char *first_p, unsigned char *last_p, - unsigned char *holder_p, - const unsigned int ele_size) -{ - unsigned char *inner_p, *outer_p; - - for (outer_p = first_p + ele_size; outer_p <= last_p; ) { - - /* look for the place to insert the entry */ - for (inner_p = outer_p - ele_size; - inner_p >= first_p && entry_cmp(outer_p, inner_p) < 0; - inner_p -= ele_size) { - } - inner_p += ele_size; - - /* do we need to insert the entry in? */ - if (outer_p != inner_p) { - /* - * Now we shift the entry down into its place in the already - * sorted list. - */ - memcpy(holder_p, outer_p, ele_size); - memmove(inner_p + ele_size, inner_p, outer_p - inner_p); - memcpy(inner_p, holder_p, ele_size); - } - - outer_p += ele_size; - } -} - -/* - * static void split - * - * This sorts an array of longs via the quick sort algorithm (it's pretty quick) - * - * ARGUMENTS: - * - * first_p -> Start of the list that we are splitting. - * - * last_p -> Last entry in the list that we are splitting. - * - * ele_size -> Size of the each element in the list. - */ -static void split(unsigned char *first_p, unsigned char *last_p, - const unsigned int ele_size) -{ - unsigned char *left_p, *right_p, *pivot_p, *left_last_p, *right_first_p; - unsigned char *firsts[MAX_QSORT_SPLITS], *lasts[MAX_QSORT_SPLITS]; - mem_table_t pivot; - unsigned int width, split_c = 0, min_qsort_size, size1, size2; - - min_qsort_size = MAX_QSORT_PARTITION * ele_size; - - while (1) { - - /* find the left, right, and mid point */ - left_p = first_p; - right_p = last_p; - /* is there a faster way to find this? */ - width = (last_p - first_p) / ele_size; - pivot_p = first_p + ele_size * (width >> 1); - - /* - * Find which of the left, middle, and right elements is the - * median (Knuth vol3 p123). - */ - if (entry_cmp(first_p, pivot_p) > 0) { - swap_bytes(first_p, pivot_p, ele_size); - } - if (entry_cmp(pivot_p, last_p) > 0) { - swap_bytes(pivot_p, last_p, ele_size); - if (entry_cmp(first_p, pivot_p) > 0) { - swap_bytes(first_p, pivot_p, ele_size); - } - } - - /* - * save our pivot so we don't have to worry about hitting and - * swapping it elsewhere while we iterate across the list below. - */ - memcpy(&pivot, pivot_p, ele_size); - - do { - - /* shift the left side up until we reach the pivot value */ - while (entry_cmp(left_p, &pivot) < 0) { - left_p += ele_size; - } - /* shift the right side down until we reach the pivot value */ - while (entry_cmp(&pivot, right_p) < 0) { - right_p -= ele_size; - } - - /* if we met in the middle then we are done */ - if (left_p == right_p) { - left_p += ele_size; - right_p -= ele_size; - break; - } - else if (left_p < right_p) { - /* - * swap the left and right since they both were on the wrong - * size of the pivot and continue - */ - swap_bytes(left_p, right_p, ele_size); - left_p += ele_size; - right_p -= ele_size; - } - } while (left_p <= right_p); - - /* Rename variables to make more sense. This will get optimized out. */ - right_first_p = left_p; - left_last_p = right_p; - - /* determine the size of the left and right hand parts */ - size1 = left_last_p - first_p; - size2 = last_p - right_first_p; - - /* is the 1st half small enough to just insert-sort? */ - if (size1 < min_qsort_size) { - - /* use the pivot as our temporary space */ - insert_sort(first_p, left_last_p, (unsigned char *)&pivot, ele_size); - - /* is the 2nd part small as well? */ - if (size2 < min_qsort_size) { - - /* use the pivot as our temporary space */ - insert_sort(right_first_p, last_p, (unsigned char *)&pivot, ele_size); - - /* pop a partition off our stack */ - if (split_c == 0) { - /* we are done */ - return; - } - split_c--; - first_p = firsts[split_c]; - last_p = lasts[split_c]; - } - else { - /* we can just handle the right side immediately */ - first_p = right_first_p; - /* last_p = last_p */ - } - } - else if (size2 < min_qsort_size) { - - /* use the pivot as our temporary space */ - insert_sort(right_first_p, last_p, (unsigned char *)&pivot, ele_size); - - /* we can just handle the left side immediately */ - /* first_p = first_p */ - last_p = left_last_p; - } - else { - /* - * neither partition is small, we'll have to push the larger one - * of them on the stack - */ - if (split_c >= MAX_QSORT_SPLITS) { - /* sanity check here -- we should never get here */ - abort(); - } - if (size1 > size2) { - /* push the left partition on the stack */ - firsts[split_c] = first_p; - lasts[split_c] = left_last_p; - split_c++; - /* continue handling the right side */ - first_p = right_first_p; - /* last_p = last_p */ - } - else { - /* push the right partition on the stack */ - firsts[split_c] = right_first_p; - lasts[split_c] = last_p; - split_c++; - /* continue handling the left side */ - /* first_p = first_p */ - last_p = left_last_p; - } - } - } -} - /* * static void log_slot * @@ -672,9 +444,10 @@ void _dmalloc_table_log_info(mem_table_t *mem_table, const int log_n, } /* sort the entries by their total-size */ - split((unsigned char *)mem_table->mt_entries, - (unsigned char *)(mem_table->mt_bounds_p - 1), - sizeof(*mem_table->mt_entries)); + qsort(mem_table->mt_entries, + mem_table->mt_entry_n, + sizeof(*mem_table->mt_entries), + entry_cmp); /* display the column headers */ if (in_use_column_b) { diff --git a/dmalloc_tab_loc.h b/dmalloc_tab_loc.h index 42219e6..fad6559 100644 --- a/dmalloc_tab_loc.h +++ b/dmalloc_tab_loc.h @@ -24,23 +24,6 @@ #include "conf.h" -/* - * Maximum number of splits. This should mean that these routines can - * handle at least 2^128 different values (that's _quite_ a few). And - * then you can always increase the value. - */ -#define MAX_QSORT_SPLITS 128 - -/* - * Maximum number of entries that must be in list for it to be - * partitioned. If there are fewer elements then just do our - * insertion sort. - */ -#define MAX_QSORT_PARTITION 8 - -/* comparison function */ -typedef int (*compare_t)(const void *element1_p, const void *element2_p); - /* * void HASH_MIX *