wireshark/wsutil/wmem/wmem_test.c

1477 lines
48 KiB
C
Raw Normal View History

/* wmem_test.c
* Wireshark Memory Manager Tests
* Copyright 2012, Evan Huus <eapache@gmail.com>
*
* Wireshark - Network traffic analyzer
* By Gerald Combs <gerald@wireshark.org>
* Copyright 1998 Gerald Combs
*
* SPDX-License-Identifier: GPL-2.0-or-later
*/
#include "config.h"
#include <stdio.h>
#include <glib.h>
#include "wmem.h"
#include "wmem_tree-int.h"
#include "wmem_allocator.h"
#include "wmem_allocator_block.h"
#include "wmem_allocator_block_fast.h"
#include "wmem_allocator_simple.h"
#include "wmem_allocator_strict.h"
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
#include <wsutil/time_util.h>
#define STRING_80 "12345678901234567890123456789012345678901234567890123456789012345678901234567890"
#define MAX_ALLOC_SIZE (1024*64)
#define MAX_SIMULTANEOUS_ALLOCS 1024
#define CONTAINER_ITERS 10000
typedef void (*wmem_verify_func)(wmem_allocator_t *allocator);
/* A local copy of wmem_allocator_new that ignores the
* WIRESHARK_DEBUG_WMEM_OVERRIDE variable so that test functions are
* guaranteed to actually get the allocator type they asked for */
static wmem_allocator_t *
wmem_allocator_force_new(const wmem_allocator_type_t type)
{
wmem_allocator_t *allocator;
allocator = wmem_new(NULL, wmem_allocator_t);
allocator->type = type;
allocator->callbacks = NULL;
allocator->in_scope = TRUE;
switch (type) {
case WMEM_ALLOCATOR_SIMPLE:
wmem_simple_allocator_init(allocator);
break;
case WMEM_ALLOCATOR_BLOCK:
wmem_block_allocator_init(allocator);
break;
case WMEM_ALLOCATOR_BLOCK_FAST:
wmem_block_fast_allocator_init(allocator);
break;
case WMEM_ALLOCATOR_STRICT:
wmem_strict_allocator_init(allocator);
break;
default:
g_assert_not_reached();
/* This is necessary to squelch MSVC errors; is there
any way to tell it that g_assert_not_reached()
never returns? */
return NULL;
};
return allocator;
}
/* A helper for generating pseudo-random strings. Just uses glib's random number
* functions to generate 'numbers' in the printable character range. */
static gchar *
wmem_test_rand_string(wmem_allocator_t *allocator, gint minlen, gint maxlen)
{
gchar *str;
gint len, i;
len = g_random_int_range(minlen, maxlen);
/* +1 for null-terminator */
str = (gchar*)wmem_alloc(allocator, len + 1);
str[len] = '\0';
for (i=0; i<len; i++) {
/* ASCII normal printable range is 32 (space) to 126 (tilde) */
str[i] = (gchar) g_random_int_range(32, 126);
}
return str;
}
static int
wmem_test_compare_guint32(const void *a, const void *b)
{
guint32 l, r;
l = *(const guint32*)a;
r = *(const guint32*)b;
return l - r;
}
/* Some helpers for properly testing callback functionality */
wmem_allocator_t *expected_allocator;
void *expected_user_data;
wmem_cb_event_t expected_event;
int cb_called_count;
int cb_continue_count;
gboolean value_seen[CONTAINER_ITERS];
static gboolean
wmem_test_cb(wmem_allocator_t *allocator, wmem_cb_event_t event,
void *user_data)
{
g_assert_true(allocator == expected_allocator);
g_assert_true(event == expected_event);
cb_called_count++;
return *(gboolean*)user_data;
}
static gboolean
wmem_test_foreach_cb(const void *key _U_, void *value, void *user_data)
{
g_assert_true(user_data == expected_user_data);
g_assert_true(! value_seen[GPOINTER_TO_INT(value)]);
value_seen[GPOINTER_TO_INT(value)] = TRUE;
cb_called_count++;
cb_continue_count--;
return (cb_continue_count == 0);
}
/* ALLOCATOR TESTING FUNCTIONS (/wmem/allocator/) */
static void
wmem_test_allocator_callbacks(void)
{
wmem_allocator_t *allocator;
gboolean t = TRUE;
gboolean f = FALSE;
guint cb_id;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
expected_allocator = allocator;
wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
cb_id = wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
expected_event = WMEM_CB_FREE_EVENT;
cb_called_count = 0;
wmem_free_all(allocator);
g_assert_true(cb_called_count == 5);
cb_called_count = 0;
wmem_free_all(allocator);
g_assert_true(cb_called_count == 2);
cb_called_count = 0;
wmem_free_all(allocator);
g_assert_true(cb_called_count == 2);
wmem_unregister_callback(allocator, cb_id);
cb_called_count = 0;
wmem_free_all(allocator);
g_assert_true(cb_called_count == 1);
cb_id = wmem_register_callback(expected_allocator, &wmem_test_cb, &f);
wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
cb_called_count = 0;
wmem_free_all(allocator);
g_assert_true(cb_called_count == 3);
wmem_unregister_callback(allocator, cb_id);
cb_called_count = 0;
wmem_free_all(allocator);
g_assert_true(cb_called_count == 2);
wmem_register_callback(expected_allocator, &wmem_test_cb, &t);
expected_event = WMEM_CB_DESTROY_EVENT;
cb_called_count = 0;
wmem_destroy_allocator(allocator);
g_assert_true(cb_called_count == 3);
}
static void
wmem_test_allocator_det(wmem_allocator_t *allocator, wmem_verify_func verify,
guint len)
{
int i;
char *ptrs[MAX_SIMULTANEOUS_ALLOCS];
/* we use wmem_alloc0 in part because it tests slightly more code, but
* primarily so that if the allocator doesn't give us enough memory or
* gives us memory that includes its own metadata, we write to it and
* things go wrong, causing the tests to fail */
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
ptrs[i] = (char *)wmem_alloc0(allocator, len);
}
for (i=MAX_SIMULTANEOUS_ALLOCS-1; i>=0; i--) {
/* no wmem_realloc0 so just use memset manually */
ptrs[i] = (char *)wmem_realloc(allocator, ptrs[i], 4*len);
memset(ptrs[i], 0, 4*len);
}
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
wmem_free(allocator, ptrs[i]);
}
if (verify) (*verify)(allocator);
wmem_free_all(allocator);
wmem_gc(allocator);
if (verify) (*verify)(allocator);
}
static void
wmem_test_allocator_jumbo(wmem_allocator_type_t type, wmem_verify_func verify)
{
wmem_allocator_t *allocator;
char *ptr, *ptr1;
allocator = wmem_allocator_force_new(type);
ptr = (char*)wmem_alloc0(allocator, 4*1024*1024);
wmem_free(allocator, ptr);
wmem_gc(allocator);
ptr = (char*)wmem_alloc0(allocator, 4*1024*1024);
if (verify) (*verify)(allocator);
wmem_free(allocator, ptr);
wmem_gc(allocator);
if (verify) (*verify)(allocator);
ptr = (char *)wmem_alloc0(allocator, 10*1024*1024);
ptr1 = (char *)wmem_alloc0(allocator, 13*1024*1024);
ptr1 = (char *)wmem_realloc(allocator, ptr1, 10*1024*1024);
memset(ptr1, 0, 10*1024*1024);
ptr = (char *)wmem_realloc(allocator, ptr, 13*1024*1024);
memset(ptr, 0, 13*1024*1024);
if (verify) (*verify)(allocator);
wmem_gc(allocator);
if (verify) (*verify)(allocator);
wmem_free(allocator, ptr1);
if (verify) (*verify)(allocator);
wmem_free_all(allocator);
wmem_gc(allocator);
if (verify) (*verify)(allocator);
wmem_destroy_allocator(allocator);
}
static void
wmem_test_allocator(wmem_allocator_type_t type, wmem_verify_func verify,
int iterations)
{
int i;
char *ptrs[MAX_SIMULTANEOUS_ALLOCS];
wmem_allocator_t *allocator;
allocator = wmem_allocator_force_new(type);
if (verify) (*verify)(allocator);
/* start with some fairly simple deterministic tests */
wmem_test_allocator_det(allocator, verify, 8);
wmem_test_allocator_det(allocator, verify, 64);
wmem_test_allocator_det(allocator, verify, 512);
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
ptrs[i] = wmem_alloc0_array(allocator, char, 32);
}
if (verify) (*verify)(allocator);
wmem_free_all(allocator);
wmem_gc(allocator);
if (verify) (*verify)(allocator);
/* now do some random fuzz-like tests */
/* reset our ptr array */
for (i=0; i<MAX_SIMULTANEOUS_ALLOCS; i++) {
ptrs[i] = NULL;
}
/* Run enough iterations to fill the array 32 times */
for (i=0; i<iterations; i++) {
gint ptrs_index;
gint new_size;
/* returns value 0 <= x < MAX_SIMULTANEOUS_ALLOCS which is a valid
* index into ptrs */
ptrs_index = g_test_rand_int_range(0, MAX_SIMULTANEOUS_ALLOCS);
if (ptrs[ptrs_index] == NULL) {
/* if that index is unused, allocate some random amount of memory
* between 0 and MAX_ALLOC_SIZE */
new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE);
ptrs[ptrs_index] = (char *) wmem_alloc0(allocator, new_size);
}
else if (g_test_rand_bit()) {
/* the index is used, and our random bit has determined we will be
* reallocating instead of freeing. Do so to some random size
* between 0 and MAX_ALLOC_SIZE, then manually zero the
* new memory */
new_size = g_test_rand_int_range(0, MAX_ALLOC_SIZE);
ptrs[ptrs_index] = (char *) wmem_realloc(allocator,
ptrs[ptrs_index], new_size);
if (new_size)
memset(ptrs[ptrs_index], 0, new_size);
}
else {
/* the index is used, and our random bit has determined we will be
* freeing instead of reallocating. Do so and NULL the pointer for
* the next iteration. */
wmem_free(allocator, ptrs[ptrs_index]);
ptrs[ptrs_index] = NULL;
}
if (verify) (*verify)(allocator);
}
wmem_destroy_allocator(allocator);
}
static void
wmem_test_allocator_block(void)
{
wmem_test_allocator(WMEM_ALLOCATOR_BLOCK, &wmem_block_verify,
MAX_SIMULTANEOUS_ALLOCS*64);
wmem_test_allocator_jumbo(WMEM_ALLOCATOR_BLOCK, &wmem_block_verify);
}
static void
wmem_test_allocator_block_fast(void)
{
wmem_test_allocator(WMEM_ALLOCATOR_BLOCK_FAST, NULL,
MAX_SIMULTANEOUS_ALLOCS*4);
wmem_test_allocator_jumbo(WMEM_ALLOCATOR_BLOCK, NULL);
}
static void
wmem_test_allocator_simple(void)
{
wmem_test_allocator(WMEM_ALLOCATOR_SIMPLE, NULL,
MAX_SIMULTANEOUS_ALLOCS*64);
wmem_test_allocator_jumbo(WMEM_ALLOCATOR_SIMPLE, NULL);
}
static void
wmem_test_allocator_strict(void)
{
wmem_test_allocator(WMEM_ALLOCATOR_STRICT, &wmem_strict_check_canaries,
MAX_SIMULTANEOUS_ALLOCS*64);
wmem_test_allocator_jumbo(WMEM_ALLOCATOR_STRICT, &wmem_strict_check_canaries);
}
/* UTILITY TESTING FUNCTIONS (/wmem/utils/) */
static void
wmem_test_miscutls(void)
{
wmem_allocator_t *allocator;
const char *source = "ABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *ret;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
ret = (char*) wmem_memdup(allocator, NULL, 0);
g_assert_true(ret == NULL);
ret = (char*) wmem_memdup(allocator, source, 5);
ret[4] = '\0';
g_assert_cmpstr(ret, ==, "ABCD");
ret = (char*) wmem_memdup(allocator, source, 1);
g_assert_true(ret[0] == 'A');
wmem_strict_check_canaries(allocator);
ret = (char*) wmem_memdup(allocator, source, 10);
ret[9] = '\0';
g_assert_cmpstr(ret, ==, "ABCDEFGHI");
wmem_destroy_allocator(allocator);
}
static void
wmem_test_strutls(void)
{
wmem_allocator_t *allocator;
const char *orig_str;
char *new_str;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
orig_str = "TEST1";
new_str = wmem_strdup(allocator, orig_str);
g_assert_cmpstr(new_str, ==, orig_str);
new_str[0] = 'X';
g_assert_cmpstr(new_str, >, orig_str);
wmem_strict_check_canaries(allocator);
orig_str = "TEST123456789";
new_str = wmem_strndup(allocator, orig_str, 6);
g_assert_cmpstr(new_str, ==, "TEST12");
g_assert_cmpstr(new_str, <, orig_str);
new_str[0] = 'X';
g_assert_cmpstr(new_str, >, orig_str);
wmem_strict_check_canaries(allocator);
new_str = wmem_strdup_printf(allocator, "abc %s %% %d", "boo", 23);
g_assert_cmpstr(new_str, ==, "abc boo % 23");
new_str = wmem_strdup_printf(allocator, "%s", STRING_80);
g_assert_cmpstr(new_str, ==, STRING_80);
wmem_strict_check_canaries(allocator);
orig_str = "Short String";
2021-12-12 23:07:23 +00:00
new_str = wmem_strdup_printf(allocator, "TEST %s", orig_str);
g_assert_cmpstr(new_str, ==, "TEST Short String");
orig_str = "Very Long..............................."
"........................................"
"........................................"
"........................................"
"........................................"
"........................................"
"..................................String";
2021-12-12 23:07:23 +00:00
new_str = wmem_strdup_printf(allocator, "TEST %s", orig_str);
g_assert_cmpstr(new_str, ==,
"TEST Very Long..............................."
"........................................"
"........................................"
"........................................"
"........................................"
"........................................"
"..................................String");
2021-12-12 23:07:23 +00:00
wmem_destroy_allocator(allocator);
}
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
#define RESOURCE_USAGE_START get_resource_usage(&start_utime, &start_stime)
#define RESOURCE_USAGE_END \
get_resource_usage(&end_utime, &end_stime); \
utime_ms = (end_utime - start_utime) * 1000.0; \
stime_ms = (end_stime - start_stime) * 1000.0
/* NOTE: You have to run "wmem_test -m perf" to run the performance tests. */
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
static void
wmem_test_stringperf(void)
{
#define LOOP_COUNT (1 * 1000 * 1000)
wmem_allocator_t *allocator;
#ifdef _WIN32
char buffer[1];
#endif
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
char **str_ptr = g_new(char *, LOOP_COUNT);
char *s_val = "test string";
double d_val = 1000.2;
unsigned u_val = 54321;
int i_val = -12345;
int i;
double start_utime, start_stime, end_utime, end_stime, utime_ms, stime_ms;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_BLOCK);
/* C99 snprintf */
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
snprintf(NULL, 0, "%s", s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"snprintf 1 string: u %.3f ms s %.3f ms", utime_ms, stime_ms);
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
snprintf(NULL, 0, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"snprintf 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
snprintf(NULL, 0, "%s%u%3.5f%02d", s_val, u_val, d_val, i_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"snprintf mixed args: u %.3f ms s %.3f ms", utime_ms, stime_ms);
/* GLib g_snprintf (can use C99 or Gnulib) */
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
g_snprintf(NULL, 0, "%s", s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"g_printf_string_upper_bound (via g_snprintf) 1 string: u %.3f ms s %.3f ms", utime_ms, stime_ms);
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
g_snprintf(NULL, 0, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"g_printf_string_upper_bound (via g_snprintf) 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
g_snprintf(NULL, 0, "%s%u%3.5f%02d", s_val, u_val, d_val, i_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"g_printf_string_upper_bound (via g_snprintf) mixed args: u %.3f ms s %.3f ms", utime_ms, stime_ms);
/* Windows _snprintf_s */
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
#ifdef _WIN32
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
2021-12-18 13:07:00 +00:00
_snprintf_s(buffer, 1, _TRUNCATE, "%s", s_val);
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"_snprintf_s upper bound 1 string: u %.3f ms s %.3f ms", utime_ms, stime_ms);
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
2021-12-18 13:07:00 +00:00
_snprintf_s(buffer, 1, _TRUNCATE, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val);
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"_snprintf_s upper bound 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
2021-12-18 13:07:00 +00:00
_snprintf_s(buffer, 1, _TRUNCATE, "%s%u%3.5f%02d", s_val, u_val, d_val, i_val);
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"_snprintf_s upper bound mixed args: u %.3f ms s %.3f ms", utime_ms, stime_ms);
#endif
/* GLib strdup */
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
str_ptr[i] = g_strdup_printf("%s%s", s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"g_strdup_printf 2 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
for (i = 0; i < LOOP_COUNT; i++) {
g_free(str_ptr[i]);
}
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
str_ptr[i] = g_strdup_printf("%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"g_strdup_printf 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
for (i = 0; i < LOOP_COUNT; i++) {
g_free(str_ptr[i]);
}
/* wmem strdup null allocator */
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
str_ptr[i] = wmem_strdup_printf(NULL, "%s%s", s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"wmem_strdup_printf() 2 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
for (i = 0; i < LOOP_COUNT; i++) {
g_free(str_ptr[i]);
}
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
str_ptr[i] = wmem_strdup_printf(NULL, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"wmem_strdup_printf(NULL) 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
for (i = 0; i < LOOP_COUNT; i++) {
g_free(str_ptr[i]);
}
/* wmem strdup strict allocator */
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
wmem_strdup_printf(allocator, "%s%s", s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"wmem_strdup_printf(allocator) 2 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
RESOURCE_USAGE_START;
for (i = 0; i < LOOP_COUNT; i++) {
wmem_strdup_printf(allocator, "%s%s%s%s%s", s_val, s_val, s_val, s_val, s_val);
}
RESOURCE_USAGE_END;
g_test_minimized_result(utime_ms + stime_ms,
"wmem_strdup_printf(allocator) 5 strings: u %.3f ms s %.3f ms", utime_ms, stime_ms);
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
wmem_destroy_allocator(allocator);
g_free(str_ptr);
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
}
/* DATA STRUCTURE TESTING FUNCTIONS (/wmem/datastruct/) */
static void
wmem_test_array(void)
{
wmem_allocator_t *allocator;
wmem_array_t *array;
unsigned int i, j, k;
guint32 val, *buf;
guint32 vals[8];
guint32 *raw;
guint32 lastint;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
array = wmem_array_new(allocator, sizeof(guint32));
g_assert_true(array);
g_assert_true(wmem_array_get_count(array) == 0);
for (i=0; i<CONTAINER_ITERS; i++) {
val = i;
wmem_array_append_one(array, val);
g_assert_true(wmem_array_get_count(array) == i+1);
val = *(guint32*)wmem_array_index(array, i);
g_assert_true(val == i);
g_assert_true(wmem_array_try_index(array, i, &val) == 0);
g_assert_true(val == i);
g_assert_true(wmem_array_try_index(array, i+1, &val) < 0);
smb2: add support for decompression The latest iteration of Microsoft updates to SMB3 added compression to the protocol. This commit implements decompressing and dissecting compressed payloads. The compression algorithms that can be used are "Plain LZ77", "LZ77+Huffman" and "LZNT1" which you can read more about in the [MS-XCA] documentation. This set of algorithm is sometimes referred to as XPRESS. This commit reuses the existing uncompression API scheme already in place with zlib and brotli and adds 3 tvb_uncompress_*() function implemented in: * epan/tvbuff_lz77.c * epan/tvbuff_lz77huff.c * epan/tvbuff_lznt1.c A new function wmem_array_try_index() was added to the wmem_array API to make bound checked reads that fail gracefully. New tests for it have been added as well. Since both reads (tvb) and writes (wmem_array) are bound checked the risk for buffer overruns is drastically reduced. LZ77+Huffman has decoding tables and special care was taken to bound check these. Simplified versions of the implementations were succesfully tested against AFL (American Fuzzy Lop) for ~150 millions executions each. The SMB2/3 dissector was changed to deal with the new transform header for compressed packets (new protocol_id value) and READ request flags (COMPRESSED). Badly compressed or encrypted packets are now reported as such, and the decryption test suite was changed to reflect that. This commit also adds a test capture with 1 packet compressed with each algorithm as returned by Windows Server 2019, along with 3 matching tests in test/suite_dissection.py Change-Id: I2b84f56541f2f4ee7d886152794b993987dd10e7 Reviewed-on: https://code.wireshark.org/review/33855 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2019-07-05 14:08:18 +00:00
}
wmem_strict_check_canaries(allocator);
for (i=0; i<CONTAINER_ITERS; i++) {
val = *(guint32*)wmem_array_index(array, i);
g_assert_true(val == i);
g_assert_true(wmem_array_try_index(array, i, &val) == 0);
g_assert_true(val == i);
}
wmem_destroy_array(array);
array = wmem_array_sized_new(allocator, sizeof(guint32), 73);
wmem_array_set_null_terminator(array);
smb2: add support for decompression The latest iteration of Microsoft updates to SMB3 added compression to the protocol. This commit implements decompressing and dissecting compressed payloads. The compression algorithms that can be used are "Plain LZ77", "LZ77+Huffman" and "LZNT1" which you can read more about in the [MS-XCA] documentation. This set of algorithm is sometimes referred to as XPRESS. This commit reuses the existing uncompression API scheme already in place with zlib and brotli and adds 3 tvb_uncompress_*() function implemented in: * epan/tvbuff_lz77.c * epan/tvbuff_lz77huff.c * epan/tvbuff_lznt1.c A new function wmem_array_try_index() was added to the wmem_array API to make bound checked reads that fail gracefully. New tests for it have been added as well. Since both reads (tvb) and writes (wmem_array) are bound checked the risk for buffer overruns is drastically reduced. LZ77+Huffman has decoding tables and special care was taken to bound check these. Simplified versions of the implementations were succesfully tested against AFL (American Fuzzy Lop) for ~150 millions executions each. The SMB2/3 dissector was changed to deal with the new transform header for compressed packets (new protocol_id value) and READ request flags (COMPRESSED). Badly compressed or encrypted packets are now reported as such, and the decryption test suite was changed to reflect that. This commit also adds a test capture with 1 packet compressed with each algorithm as returned by Windows Server 2019, along with 3 matching tests in test/suite_dissection.py Change-Id: I2b84f56541f2f4ee7d886152794b993987dd10e7 Reviewed-on: https://code.wireshark.org/review/33855 Petri-Dish: Anders Broman <a.broman58@gmail.com> Tested-by: Petri Dish Buildbot Reviewed-by: Peter Wu <peter@lekensteyn.nl>
2019-07-05 14:08:18 +00:00
for (i=0; i<75; i++)
g_assert_true(wmem_array_try_index(array, i, &val) < 0);
for (i=0; i<CONTAINER_ITERS; i++) {
for (j=0; j<8; j++) {
vals[j] = i+j;
}
wmem_array_append(array, vals, 8);
g_assert_true(wmem_array_get_count(array) == 8*(i+1));
}
wmem_strict_check_canaries(allocator);
buf = (guint32*)wmem_array_get_raw(array);
for (i=0; i<CONTAINER_ITERS; i++) {
for (j=0; j<8; j++) {
g_assert_true(buf[i*8 + j] == i+j);
}
}
wmem_array_sort(array, wmem_test_compare_guint32);
for (i=0, k=0; i<8; i++) {
for (j=0; j<=i; j++, k++) {
val = *(guint32*)wmem_array_index(array, k);
g_assert_true(val == i);
g_assert_true(wmem_array_try_index(array, k, &val) == 0);
g_assert_true(val == i);
}
}
for (j=k; k<8*(CONTAINER_ITERS+1)-j; k++) {
val = *(guint32*)wmem_array_index(array, k);
g_assert_true(val == ((k-j)/8)+8);
g_assert_true(wmem_array_try_index(array, k, &val) == 0);
g_assert_true(val == ((k-j)/8)+8);
}
for (i=0; i<7; i++) {
for (j=0; j<7-i; j++, k++) {
val = *(guint32*)wmem_array_index(array, k);
g_assert_true(val == CONTAINER_ITERS+i);
g_assert_true(wmem_array_try_index(array, k, &val) == 0);
g_assert_true(val == CONTAINER_ITERS+i);
}
}
g_assert_true(k == wmem_array_get_count(array));
lastint = 77;
wmem_array_append_one(array, lastint);
raw = (guint32*)wmem_array_get_raw(array);
g_assert_true(raw[wmem_array_get_count(array)] == 0);
g_assert_true(raw[wmem_array_get_count(array) - 1] == lastint);
wmem_destroy_array(array);
wmem_destroy_allocator(allocator);
}
static void
check_val_list(gpointer val, gpointer val_to_check)
{
g_assert_true(val == val_to_check);
}
static gint
str_compare(gconstpointer a, gconstpointer b)
{
return strcmp((const char*)a, (const char*)b);
}
static void
wmem_test_list(void)
{
wmem_allocator_t *allocator;
wmem_list_t *list;
wmem_list_frame_t *frame;
unsigned int i;
int int1;
int int2;
char* str1;
char* str2;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
list = wmem_list_new(allocator);
g_assert_true(list);
g_assert_true(wmem_list_count(list) == 0);
frame = wmem_list_head(list);
g_assert_true(frame == NULL);
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_list_prepend(list, GINT_TO_POINTER(i));
g_assert_true(wmem_list_count(list) == i+1);
g_assert_true(wmem_list_find(list, GINT_TO_POINTER(i)));
frame = wmem_list_head(list);
g_assert_true(frame);
g_assert_true(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
}
wmem_strict_check_canaries(allocator);
i = CONTAINER_ITERS - 1;
frame = wmem_list_head(list);
while (frame) {
g_assert_true(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
i--;
frame = wmem_list_frame_next(frame);
}
i = 0;
frame = wmem_list_tail(list);
while (frame) {
g_assert_true(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
i++;
frame = wmem_list_frame_prev(frame);
}
i = CONTAINER_ITERS - 2;
while (wmem_list_count(list) > 1) {
wmem_list_remove(list, GINT_TO_POINTER(i));
i--;
}
wmem_list_remove(list, GINT_TO_POINTER(CONTAINER_ITERS - 1));
g_assert_true(wmem_list_count(list) == 0);
g_assert_true(wmem_list_head(list) == NULL);
g_assert_true(wmem_list_tail(list) == NULL);
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_list_append(list, GINT_TO_POINTER(i));
g_assert_true(wmem_list_count(list) == i+1);
frame = wmem_list_head(list);
g_assert_true(frame);
}
wmem_strict_check_canaries(allocator);
i = 0;
frame = wmem_list_head(list);
while (frame) {
g_assert_true(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
i++;
frame = wmem_list_frame_next(frame);
}
i = CONTAINER_ITERS - 1;
frame = wmem_list_tail(list);
while (frame) {
g_assert_true(wmem_list_frame_data(frame) == GINT_TO_POINTER(i));
i--;
frame = wmem_list_frame_prev(frame);
}
wmem_destroy_allocator(allocator);
list = wmem_list_new(NULL);
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_list_prepend(list, GINT_TO_POINTER(i));
}
g_assert_true(wmem_list_count(list) == CONTAINER_ITERS);
wmem_destroy_list(list);
list = wmem_list_new(NULL);
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_list_append(list, GINT_TO_POINTER(1));
}
wmem_list_foreach(list, check_val_list, GINT_TO_POINTER(1));
wmem_destroy_list(list);
list = wmem_list_new(NULL);
2021-11-27 17:31:16 +00:00
wmem_list_insert_sorted(list, GINT_TO_POINTER(5), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(8), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(1), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(2), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(9), wmem_compare_int);
frame = wmem_list_head(list);
int1 = GPOINTER_TO_INT(wmem_list_frame_data(frame));
while ((frame = wmem_list_frame_next(frame))) {
int2 = GPOINTER_TO_INT(wmem_list_frame_data(frame));
g_assert_true(int1 <= int2);
int1 = int2;
}
wmem_destroy_list(list);
list = wmem_list_new(NULL);
2021-11-27 17:31:16 +00:00
wmem_list_insert_sorted(list, GINT_TO_POINTER(5), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(1), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(7), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(3), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(2), wmem_compare_int);
wmem_list_insert_sorted(list, GINT_TO_POINTER(2), wmem_compare_int);
frame = wmem_list_head(list);
int1 = GPOINTER_TO_INT(wmem_list_frame_data(frame));
while ((frame = wmem_list_frame_next(frame))) {
int2 = GPOINTER_TO_INT(wmem_list_frame_data(frame));
g_assert_true(int1 <= int2);
int1 = int2;
}
wmem_destroy_list(list);
list = wmem_list_new(NULL);
wmem_list_insert_sorted(list, "abc", str_compare);
wmem_list_insert_sorted(list, "bcd", str_compare);
wmem_list_insert_sorted(list, "aaa", str_compare);
wmem_list_insert_sorted(list, "bbb", str_compare);
wmem_list_insert_sorted(list, "zzz", str_compare);
wmem_list_insert_sorted(list, "ggg", str_compare);
frame = wmem_list_head(list);
str1 = (char*)wmem_list_frame_data(frame);
while ((frame = wmem_list_frame_next(frame))) {
str2 = (char*)wmem_list_frame_data(frame);
g_assert_true(strcmp(str1, str2) <= 0);
str1 = str2;
}
wmem_destroy_list(list);
}
static void
check_val_map(gpointer key _U_, gpointer val, gpointer user_data)
{
g_assert_true(val == user_data);
}
static void
wmem_test_map(void)
{
wmem_allocator_t *allocator, *extra_allocator;
wmem_map_t *map;
gchar *str_key;
const void *str_key_ret;
unsigned int i;
unsigned int *key_ret;
unsigned int *value_ret;
void *ret;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
extra_allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
/* insertion, lookup and removal of simple integer keys */
map = wmem_map_new(allocator, g_direct_hash, g_direct_equal);
g_assert_true(map);
for (i=0; i<CONTAINER_ITERS; i++) {
ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(777777));
g_assert_true(ret == NULL);
ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(i));
g_assert_true(ret == GINT_TO_POINTER(777777));
ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(i));
g_assert_true(ret == GINT_TO_POINTER(i));
}
for (i=0; i<CONTAINER_ITERS; i++) {
ret = wmem_map_lookup(map, GINT_TO_POINTER(i));
g_assert_true(ret == GINT_TO_POINTER(i));
g_assert_true(wmem_map_contains(map, GINT_TO_POINTER(i)) == TRUE);
g_assert_true(wmem_map_lookup_extended(map, GINT_TO_POINTER(i), NULL, NULL));
key_ret = NULL;
g_assert_true(wmem_map_lookup_extended(map, GINT_TO_POINTER(i), GINT_TO_POINTER(&key_ret), NULL));
g_assert_true(key_ret == GINT_TO_POINTER(i));
value_ret = NULL;
g_assert_true(wmem_map_lookup_extended(map, GINT_TO_POINTER(i), NULL, GINT_TO_POINTER(&value_ret)));
g_assert_true(value_ret == GINT_TO_POINTER(i));
key_ret = NULL;
value_ret = NULL;
g_assert_true(wmem_map_lookup_extended(map, GINT_TO_POINTER(i), GINT_TO_POINTER(&key_ret), GINT_TO_POINTER(&value_ret)));
g_assert_true(key_ret == GINT_TO_POINTER(i));
g_assert_true(value_ret == GINT_TO_POINTER(i));
ret = wmem_map_remove(map, GINT_TO_POINTER(i));
g_assert_true(ret == GINT_TO_POINTER(i));
g_assert_true(wmem_map_contains(map, GINT_TO_POINTER(i)) == FALSE);
ret = wmem_map_lookup(map, GINT_TO_POINTER(i));
g_assert_true(ret == NULL);
ret = wmem_map_remove(map, GINT_TO_POINTER(i));
g_assert_true(ret == NULL);
}
wmem_free_all(allocator);
/* test auto-reset functionality */
map = wmem_map_new_autoreset(allocator, extra_allocator, g_direct_hash, g_direct_equal);
g_assert_true(map);
for (i=0; i<CONTAINER_ITERS; i++) {
ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(777777));
g_assert_true(ret == NULL);
ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(i));
g_assert_true(ret == GINT_TO_POINTER(777777));
ret = wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(i));
g_assert_true(ret == GINT_TO_POINTER(i));
}
wmem_free_all(extra_allocator);
for (i=0; i<CONTAINER_ITERS; i++) {
g_assert_true(wmem_map_lookup(map, GINT_TO_POINTER(i)) == NULL);
}
wmem_free_all(allocator);
map = wmem_map_new(allocator, wmem_str_hash, g_str_equal);
g_assert_true(map);
/* string keys and for-each */
for (i=0; i<CONTAINER_ITERS; i++) {
str_key = wmem_test_rand_string(allocator, 1, 64);
wmem_map_insert(map, str_key, GINT_TO_POINTER(i));
ret = wmem_map_lookup(map, str_key);
g_assert_true(ret == GINT_TO_POINTER(i));
g_assert_true(wmem_map_contains(map, str_key) == TRUE);
str_key_ret = NULL;
value_ret = NULL;
g_assert_true(wmem_map_lookup_extended(map, str_key, &str_key_ret, GINT_TO_POINTER(&value_ret)) == TRUE);
g_assert_true(g_str_equal(str_key_ret, str_key));
g_assert_true(value_ret == GINT_TO_POINTER(i));
}
/* test foreach */
map = wmem_map_new(allocator, wmem_str_hash, g_str_equal);
g_assert_true(map);
for (i=0; i<CONTAINER_ITERS; i++) {
str_key = wmem_test_rand_string(allocator, 1, 64);
wmem_map_insert(map, str_key, GINT_TO_POINTER(2));
}
wmem_map_foreach(map, check_val_map, GINT_TO_POINTER(2));
/* test size */
map = wmem_map_new(allocator, g_direct_hash, g_direct_equal);
g_assert_true(map);
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_map_insert(map, GINT_TO_POINTER(i), GINT_TO_POINTER(i));
}
g_assert_true(wmem_map_size(map) == CONTAINER_ITERS);
wmem_destroy_allocator(extra_allocator);
wmem_destroy_allocator(allocator);
}
static void
wmem_test_queue(void)
{
wmem_allocator_t *allocator;
wmem_queue_t *queue;
unsigned int i;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
queue = wmem_queue_new(allocator);
g_assert_true(queue);
g_assert_true(wmem_queue_count(queue) == 0);
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_queue_push(queue, GINT_TO_POINTER(i));
g_assert_true(wmem_queue_count(queue) == i+1);
g_assert_true(wmem_queue_peek(queue) == GINT_TO_POINTER(0));
}
wmem_strict_check_canaries(allocator);
for (i=0; i<CONTAINER_ITERS; i++) {
g_assert_true(wmem_queue_peek(queue) == GINT_TO_POINTER(i));
g_assert_true(wmem_queue_pop(queue) == GINT_TO_POINTER(i));
g_assert_true(wmem_queue_count(queue) == CONTAINER_ITERS-i-1);
}
g_assert_true(wmem_queue_count(queue) == 0);
wmem_destroy_queue(queue);
wmem_destroy_allocator(allocator);
}
static void
wmem_test_stack(void)
{
wmem_allocator_t *allocator;
wmem_stack_t *stack;
unsigned int i;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
stack = wmem_stack_new(allocator);
g_assert_true(stack);
g_assert_true(wmem_stack_count(stack) == 0);
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_stack_push(stack, GINT_TO_POINTER(i));
g_assert_true(wmem_stack_count(stack) == i+1);
g_assert_true(wmem_stack_peek(stack) == GINT_TO_POINTER(i));
}
wmem_strict_check_canaries(allocator);
for (i=CONTAINER_ITERS; i>0; i--) {
g_assert_true(wmem_stack_peek(stack) == GINT_TO_POINTER(i-1));
g_assert_true(wmem_stack_pop(stack) == GINT_TO_POINTER(i-1));
g_assert_true(wmem_stack_count(stack) == i-1);
}
g_assert_true(wmem_stack_count(stack) == 0);
wmem_destroy_stack(stack);
wmem_destroy_allocator(allocator);
}
static void
wmem_test_strbuf(void)
{
wmem_allocator_t *allocator;
wmem_strbuf_t *strbuf;
int i;
char *str;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
strbuf = wmem_strbuf_new(allocator, "TEST");
g_assert_true(strbuf);
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TEST");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 4);
wmem_strbuf_append(strbuf, "FUZZ");
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 8);
wmem_strbuf_append_printf(strbuf, "%d%s", 3, "a");
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3a");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 10);
wmem_strbuf_append_c(strbuf, 'q');
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 11);
wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9"));
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 13);
wmem_strbuf_truncate(strbuf, 32);
wmem_strbuf_truncate(strbuf, 24);
wmem_strbuf_truncate(strbuf, 16);
wmem_strbuf_truncate(strbuf, 13);
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ3aq\xC2\xA9");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 13);
wmem_strbuf_truncate(strbuf, 3);
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TES");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 3);
wmem_strbuf_append_len(strbuf, "TFUZZ1234", 5);
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "TESTFUZZ");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 8);
strbuf = wmem_strbuf_sized_new(allocator, 10, 10);
g_assert_true(strbuf);
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 0);
wmem_strbuf_append(strbuf, "FUZZ");
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 4);
wmem_strbuf_append_printf(strbuf, "%d%s", 3, "abcdefghijklmnop");
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 9);
wmem_strbuf_append(strbuf, "abcdefghijklmnopqrstuvwxyz");
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 9);
wmem_strbuf_append_c(strbuf, 'q');
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 9);
wmem_strbuf_append_unichar(strbuf, g_utf8_get_char("\xC2\xA9"));
g_assert_cmpstr(wmem_strbuf_get_str(strbuf), ==, "FUZZ3abcd");
g_assert_cmpuint(wmem_strbuf_get_len(strbuf), ==, 9);
str = wmem_strbuf_finalize(strbuf);
g_assert_cmpstr(str, ==, "FUZZ3abcd");
g_assert_cmpuint(strlen(str), ==, 9);
wmem_free_all(allocator);
strbuf = wmem_strbuf_new(allocator, "TEST");
for (i=0; i<1024; i++) {
if (g_test_rand_bit()) {
wmem_strbuf_append(strbuf, "ABC");
}
else {
wmem_strbuf_append_printf(strbuf, "%d%d", 3, 777);
}
wmem_strict_check_canaries(allocator);
}
g_assert_true(strlen(wmem_strbuf_get_str(strbuf)) ==
wmem_strbuf_get_len(strbuf));
wmem_destroy_allocator(allocator);
}
static void
wmem_test_tree(void)
{
wmem_allocator_t *allocator, *extra_allocator;
wmem_tree_t *tree;
guint32 i;
int seen_values = 0;
int j;
gchar *str_key;
#define WMEM_TREE_MAX_KEY_COUNT 8
#define WMEM_TREE_MAX_KEY_LEN 4
int key_count;
wmem_tree_key_t keys[WMEM_TREE_MAX_KEY_COUNT];
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
extra_allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
tree = wmem_tree_new(allocator);
g_assert_true(tree);
g_assert_true(wmem_tree_is_empty(tree));
/* test basic 32-bit key operations */
for (i=0; i<CONTAINER_ITERS; i++) {
g_assert_true(wmem_tree_lookup32(tree, i) == NULL);
if (i > 0) {
g_assert_true(wmem_tree_lookup32_le(tree, i) == GINT_TO_POINTER(i-1));
}
wmem_tree_insert32(tree, i, GINT_TO_POINTER(i));
g_assert_true(wmem_tree_lookup32(tree, i) == GINT_TO_POINTER(i));
g_assert_true(!wmem_tree_is_empty(tree));
}
g_assert_true(wmem_tree_count(tree) == CONTAINER_ITERS);
wmem_free_all(allocator);
tree = wmem_tree_new(allocator);
for (i=0; i<CONTAINER_ITERS; i++) {
guint32 rand_int;
do {
rand_int = g_test_rand_int();
} while (wmem_tree_lookup32(tree, rand_int));
wmem_tree_insert32(tree, rand_int, GINT_TO_POINTER(i));
g_assert_true(wmem_tree_lookup32(tree, rand_int) == GINT_TO_POINTER(i));
}
g_assert_true(wmem_tree_count(tree) == CONTAINER_ITERS);
wmem_free_all(allocator);
/* test auto-reset functionality */
tree = wmem_tree_new_autoreset(allocator, extra_allocator);
for (i=0; i<CONTAINER_ITERS; i++) {
g_assert_true(wmem_tree_lookup32(tree, i) == NULL);
wmem_tree_insert32(tree, i, GINT_TO_POINTER(i));
g_assert_true(wmem_tree_lookup32(tree, i) == GINT_TO_POINTER(i));
}
g_assert_true(wmem_tree_count(tree) == CONTAINER_ITERS);
wmem_free_all(extra_allocator);
g_assert_true(wmem_tree_count(tree) == 0);
for (i=0; i<CONTAINER_ITERS; i++) {
g_assert_true(wmem_tree_lookup32(tree, i) == NULL);
g_assert_true(wmem_tree_lookup32_le(tree, i) == NULL);
}
wmem_free_all(allocator);
/* test array key functionality */
tree = wmem_tree_new(allocator);
key_count = g_random_int_range(1, WMEM_TREE_MAX_KEY_COUNT);
for (j=0; j<key_count; j++) {
keys[j].length = g_random_int_range(1, WMEM_TREE_MAX_KEY_LEN);
}
keys[key_count].length = 0;
for (i=0; i<CONTAINER_ITERS; i++) {
for (j=0; j<key_count; j++) {
keys[j].key = (guint32*)wmem_test_rand_string(allocator,
(keys[j].length*4), (keys[j].length*4)+1);
}
wmem_tree_insert32_array(tree, keys, GINT_TO_POINTER(i));
g_assert_true(wmem_tree_lookup32_array(tree, keys) == GINT_TO_POINTER(i));
}
wmem_free_all(allocator);
tree = wmem_tree_new(allocator);
keys[0].length = 1;
keys[0].key = wmem_new(allocator, guint32);
*(keys[0].key) = 0;
keys[1].length = 0;
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_tree_insert32_array(tree, keys, GINT_TO_POINTER(i));
*(keys[0].key) += 4;
}
*(keys[0].key) = 0;
for (i=0; i<CONTAINER_ITERS; i++) {
g_assert_true(wmem_tree_lookup32_array(tree, keys) == GINT_TO_POINTER(i));
for (j=0; j<3; j++) {
(*(keys[0].key)) += 1;
g_assert_true(wmem_tree_lookup32_array_le(tree, keys) ==
GINT_TO_POINTER(i));
}
*(keys[0].key) += 1;
}
wmem_free_all(allocator);
/* test string key functionality */
tree = wmem_tree_new(allocator);
for (i=0; i<CONTAINER_ITERS; i++) {
str_key = wmem_test_rand_string(allocator, 1, 64);
wmem_tree_insert_string(tree, str_key, GINT_TO_POINTER(i), 0);
g_assert_true(wmem_tree_lookup_string(tree, str_key, 0) ==
GINT_TO_POINTER(i));
}
wmem_free_all(allocator);
tree = wmem_tree_new(allocator);
for (i=0; i<CONTAINER_ITERS; i++) {
str_key = wmem_test_rand_string(allocator, 1, 64);
wmem_tree_insert_string(tree, str_key, GINT_TO_POINTER(i),
WMEM_TREE_STRING_NOCASE);
g_assert_true(wmem_tree_lookup_string(tree, str_key,
WMEM_TREE_STRING_NOCASE) == GINT_TO_POINTER(i));
}
wmem_free_all(allocator);
/* test for-each functionality */
tree = wmem_tree_new(allocator);
expected_user_data = GINT_TO_POINTER(g_test_rand_int());
for (i=0; i<CONTAINER_ITERS; i++) {
gint tmp;
do {
tmp = g_test_rand_int();
} while (wmem_tree_lookup32(tree, tmp));
value_seen[i] = FALSE;
wmem_tree_insert32(tree, tmp, GINT_TO_POINTER(i));
}
cb_called_count = 0;
cb_continue_count = CONTAINER_ITERS;
wmem_tree_foreach(tree, wmem_test_foreach_cb, expected_user_data);
g_assert_true(cb_called_count == CONTAINER_ITERS);
g_assert_true(cb_continue_count == 0);
for (i=0; i<CONTAINER_ITERS; i++) {
g_assert_true(value_seen[i]);
value_seen[i] = FALSE;
}
cb_called_count = 0;
cb_continue_count = 10;
wmem_tree_foreach(tree, wmem_test_foreach_cb, expected_user_data);
g_assert_true(cb_called_count == 10);
g_assert_true(cb_continue_count == 0);
for (i=0; i<CONTAINER_ITERS; i++) {
if (value_seen[i]) {
seen_values++;
}
}
g_assert_true(seen_values == 10);
wmem_destroy_allocator(extra_allocator);
wmem_destroy_allocator(allocator);
}
/* to be used as userdata in the callback wmem_test_itree_check_overlap_cb*/
typedef struct wmem_test_itree_user_data {
wmem_range_t range;
guint counter;
} wmem_test_itree_user_data_t;
/* increase userData counter in case the range match the userdata range */
static gboolean
wmem_test_itree_check_overlap_cb (const void *key, void *value _U_, void *userData)
{
const wmem_range_t *ckey = (const wmem_range_t *)key;
struct wmem_test_itree_user_data * d = (struct wmem_test_itree_user_data *)userData;
g_assert_true(key);
g_assert_true(d);
if(wmem_itree_range_overlap(ckey, &d->range)) {
d->counter++;
}
return FALSE;
}
static gboolean
wmem_test_overlap(guint64 low, guint64 high, guint64 lowbis, guint64 highbis)
{
wmem_range_t r1 = {low, high, 0};
wmem_range_t r2 = {lowbis, highbis, 0};
return wmem_itree_range_overlap(&r1, &r2);
}
static void
wmem_test_itree(void)
{
wmem_allocator_t *allocator, *extra_allocator;
wmem_itree_t *tree;
int i = 0;
gint32 max_rand = 0;
wmem_test_itree_user_data_t userData;
wmem_range_t range, r2;
allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
extra_allocator = wmem_allocator_new(WMEM_ALLOCATOR_STRICT);
tree = wmem_itree_new(allocator);
g_assert_true(tree);
g_assert_true(wmem_itree_is_empty(tree));
wmem_free_all(allocator);
/* make sure that wmem_test_overlap is correct (well it's no proof but...)*/
g_assert_true(wmem_test_overlap(0, 10, 0, 4));
g_assert_true(wmem_test_overlap(0, 10, 9, 14));
g_assert_true(wmem_test_overlap(5, 10, 3, 8));
g_assert_true(wmem_test_overlap(5, 10, 1, 12));
g_assert_true(!wmem_test_overlap(0, 10, 11, 12));
/* Generate a reference range, then fill an itree with random ranges,
then we count greedily the number of overlapping ranges and compare
the result with the optimized result
*/
userData.counter = 0;
tree = wmem_itree_new(allocator);
/* even though keys are uint64_t, we use G_MAXINT32 as a max because of the type returned by
g_test_rand_int_range.
*/
max_rand = G_MAXINT32;
r2.max_edge = range.max_edge = 0;
range.low = g_test_rand_int_range(0, max_rand);
range.high = g_test_rand_int_range( (gint32)range.low, (gint32)max_rand);
userData.range = range;
for (i=0; i<CONTAINER_ITERS; i++) {
wmem_list_t *results = NULL;
/* reset the search */
userData.counter = 0;
r2.low = (guint64)g_test_rand_int_range(0, 100);
r2.high = (guint64)g_test_rand_int_range( (gint32)r2.low, 100);
wmem_itree_insert(tree, r2.low, r2.high, GINT_TO_POINTER(i));
/* greedy search */
wmem_tree_foreach(tree, wmem_test_itree_check_overlap_cb, &userData);
/* Optimized search */
results = wmem_itree_find_intervals(tree, allocator, range.low, range.high);
/* keep it as a loop instead of wmem_list_count in case one */
g_assert_true(wmem_list_count(results) == userData.counter);
}
wmem_destroy_allocator(extra_allocator);
wmem_destroy_allocator(allocator);
}
int
main(int argc, char **argv)
{
int ret;
wmem_init();
g_test_init(&argc, &argv, NULL);
g_test_add_func("/wmem/allocator/block", wmem_test_allocator_block);
g_test_add_func("/wmem/allocator/blk_fast", wmem_test_allocator_block_fast);
g_test_add_func("/wmem/allocator/simple", wmem_test_allocator_simple);
g_test_add_func("/wmem/allocator/strict", wmem_test_allocator_strict);
g_test_add_func("/wmem/allocator/callbacks", wmem_test_allocator_callbacks);
g_test_add_func("/wmem/utils/misc", wmem_test_miscutls);
g_test_add_func("/wmem/utils/strings", wmem_test_strutls);
if (g_test_perf()) {
Add string function times to wmem_test. The system, GLib, and wmem string functions can perform differently, particularly on Windows. Start adding performance tests to wmem_test so that we can see the differences. With this change applied "wmem_test --verbose" prints out the following on a Windows 7 x64 VM here. wmem_test is linked against GLib 2.4.20. (MINPERF:g_printf_string_upper_bound (via g_snprintf) 1 string: u 327.602 ms s 0 .000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) 5 strings: u 1419.609 ms s 0.000 ms) (MINPERF:g_printf_string_upper_bound (via g_snprintf) mixed args: u 1606.810 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 1 string: u 124.801 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound 5 strings: u 140.401 ms s 0.000 ms) (MINPERF:_snprintf_s upper bound mixed args: u 124.801 ms s 0.000 ms) (MINPERF:g_strdup_printf 2 strings: u 702.005 ms s 0.156 ms) (MINPERF:g_strconcat 2 strings: u 78.000 ms s 0.000 ms) (MINPERF:g_strdup_printf 5 strings: u 1419.609 ms s 0.156 ms) (MINPERF:g_strconcat 5 strings: u 93.601 ms s 0.156 ms) (MINPERF:wmem_strdup_printf 2 strings: u 343.202 ms s 0.312 ms) (MINPERF:wmem_strconcat 2 strings: u 93.601 ms s 0.468 ms) (MINPERF:wmem_strdup_printf 5 strings: u 327.602 ms s 8.268 ms) (MINPERF:wmem_strconcat 5 strings: u 62.400 ms s 3.432 ms) Change-Id: Id9b23918829db1719d141e7f830b9eba6245a25b Reviewed-on: https://code.wireshark.org/review/14857 Reviewed-by: Gerald Combs <gerald@wireshark.org> Petri-Dish: Gerald Combs <gerald@wireshark.org> Tested-by: Petri Dish Buildbot <buildbot-no-reply@wireshark.org> Reviewed-by: Michael Mann <mmann78@netscape.net>
2016-04-07 22:31:21 +00:00
g_test_add_func("/wmem/utils/stringperf", wmem_test_stringperf);
}
g_test_add_func("/wmem/datastruct/array", wmem_test_array);
g_test_add_func("/wmem/datastruct/list", wmem_test_list);
g_test_add_func("/wmem/datastruct/map", wmem_test_map);
g_test_add_func("/wmem/datastruct/queue", wmem_test_queue);
g_test_add_func("/wmem/datastruct/stack", wmem_test_stack);
g_test_add_func("/wmem/datastruct/strbuf", wmem_test_strbuf);
g_test_add_func("/wmem/datastruct/tree", wmem_test_tree);
g_test_add_func("/wmem/datastruct/itree", wmem_test_itree);
ret = g_test_run();
wmem_cleanup();
return ret;
}
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
*
* Local variables:
* c-basic-offset: 4
* tab-width: 8
* indent-tabs-mode: nil
* End:
*
* vi: set shiftwidth=4 tabstop=8 expandtab:
* :indentSize=4:tabSize=8:noTabs=true:
*/