/* ==================================================================== * The Apache Software License, Version 1.1 * * Copyright (c) 2000-2001 The Apache Software Foundation. All rights * reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * * 1. Redistributions of source code must retain the above copyright * notice, this list of conditions and the following disclaimer. * * 2. Redistributions in binary form must reproduce the above copyright * notice, this list of conditions and the following disclaimer in * the documentation and/or other materials provided with the * distribution. * * 3. The end-user documentation included with the redistribution, * if any, must include the following acknowledgment: * "This product includes software developed by the * Apache Software Foundation (http://www.apache.org/)." * Alternately, this acknowledgment may appear in the software itself, * if and wherever such third-party acknowledgments normally appear. * * 4. The names "Apache" and "Apache Software Foundation" must * not be used to endorse or promote products derived from this * software without prior written permission. For written * permission, please contact apache@apache.org. * * 5. Products derived from this software may not be called "Apache", * nor may "Apache" appear in their name, without prior written * permission of the Apache Software Foundation. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED. IN NO EVENT SHALL THE APACHE SOFTWARE FOUNDATION OR * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF * SUCH DAMAGE. * ==================================================================== * * This software consists of voluntary contributions made by many * individuals on behalf of the Apache Software Foundation. For more * information on the Apache Software Foundation, please see * . */ #include "apr_sms.h" #include "apr_sms_tracking.h" #include "apr_sms_trivial.h" #include "apr_sms_blocks.h" #include "apr_errno.h" #include "apr_general.h" #include "apr_lib.h" #include "apr_strings.h" #include "apr_time.h" #include "test_apr.h" #include #include #include #include "test_apr.h" #define LUMPS 10 #define LUMP_SIZE 1024 #define TIMED_RUNS 10 #define TIMED_LOOPS 50 char *ptrs[1000]; typedef struct _test_ { void * (*malloc_fn) (void *memsys, apr_size_t size); void * (*calloc_fn) (void *memsys, apr_size_t size); void * (*free_fn) (void *memsys, void *memptr); void * (*reset_fn) (void *memsys); void * memory; char * title; int large_tests; apr_time_t howlong; } _test_; #define T_QTY 5 /* how many tests do we have?? */ static _test_ t[T_QTY]; static void its_an_sms(apr_sms_t *ams, _test_ *t, char *name, int lt) { t->malloc_fn = (void*)apr_sms_malloc; t->calloc_fn = (void*)apr_sms_calloc; t->free_fn = (void*)apr_sms_free; t->reset_fn = (void*)apr_sms_reset; t->memory = ams; t->title = name; t->large_tests = lt; t->howlong = 0; } static void its_a_pool(apr_pool_t *pool, _test_ *t, char *name, int lt) { t->malloc_fn = (void*)apr_palloc; t->calloc_fn = (void*)apr_pcalloc; t->free_fn = NULL; t->reset_fn = (void*)apr_pool_clear; t->memory = pool; t->title = name; t->large_tests = lt; t->howlong = 0; } static int malloc_test(_test_ *t, apr_size_t size, int howmany, int verbose) { int cntr; if (verbose) printf(" Malloc'ing %d lumps of memory, each of %" APR_SIZE_T_FMT " bytes ", howmany, size); for (cntr = 0;cntr < howmany;cntr ++){ ptrs[cntr] = t->malloc_fn(t->memory, size); if (!ptrs[cntr]){ printf("Failed\n"); fprintf(stderr,"Failed @ lump %d of %d\n", cntr + 1, howmany); return 1; } } if (verbose) printf ("OK\n"); return 0; } static int calloc_test(_test_ *t, apr_size_t size, int howmany, int verbose) { int cntr, cntr2; if (verbose) printf(" Calloc'ing %d lumps of memory, each %" APR_SIZE_T_FMT " bytes ", howmany, size); for (cntr = 0;cntr < howmany;cntr ++){ ptrs[cntr] = t->calloc_fn(t->memory, size); if (!ptrs[cntr]){ printf("Failed\n"); fprintf(stderr, "Failed @ lump %d of %d\n", cntr + 1, howmany); return 1; } } if (verbose) { printf ("OK\n"); printf(" (checking that memory is zeroed "); } for (cntr = 0;cntr < howmany;cntr++){ for (cntr2 = 0;cntr2 < size; cntr2 ++){ if (*(ptrs[cntr] + cntr2) != 0){ printf("Failed\n"); fprintf(stderr, "Failed!\nGot %d instead of 0 at byte %d of chunk %d [%p]\n", *(ptrs[cntr] + cntr2), cntr2 + 1, cntr + 1, ptrs[cntr] + cntr2); return 1; } } } if (verbose) printf("OK)\n"); return 0; } static int write_test(apr_size_t size, int howmany, int verbose) { int cntr,cntr2; int val; if (verbose) printf("%-60s", " Writing to the lumps of memory"); for (cntr = 0;cntr < howmany;cntr ++){ if (size == 64) { /* we go past 256 in our tests, so use a different value :) */ val = 99; } else { val = cntr; } if (memset(ptrs[cntr], val, size) != ptrs[cntr]){ printf("Failed\n"); fprintf(stderr,"Failed to write into lump %d\n", cntr + 1); return 1; } } if (verbose) { printf("OK\n"); printf("%-60s", " Check what we wrote"); } for (cntr = 0;cntr < howmany;cntr++){ if (size == 64) { val = 99; } else { val = cntr; } for (cntr2 = 0;cntr2 < size; cntr2 ++){ if (*(ptrs[cntr] + cntr2) != val){ printf("Failed\n"); fprintf(stderr,"Got %d instead of %d at byte %d\n", *(ptrs[cntr] + cntr2), val, cntr2 + 1); return 1; } } } if (verbose) printf("OK\n"); return 0; } static int free_memory(_test_ *t, int qty, int verbose) { int cntr; if (verbose) printf(" Freeing the memory we created "); /* pools don't really do free... */ if (t->free_fn) { for (cntr = 0;cntr < qty;cntr ++){ if (t->free_fn(t->memory, ptrs[cntr]) != APR_SUCCESS){ printf("Failed\n"); fprintf(stderr,"Failed to free block %d\n", cntr + 1); return 1; } } } if (verbose) printf("OK\n"); return 0; } static int reset_memory(_test_ *t, int loops, int verbose) { if (verbose) printf(" Resetting the memory we created "); if (!t->reset_fn) { free_memory(t, loops, verbose); } else { t->reset_fn(t->memory); } if (verbose) printf("OK\n"); return 0; } static int simple_test(_test_ *t, int verbose) { char msg[60]; if (t->large_tests == 0) return 0; sprintf(msg, " Big allocation test for %s", t->title); printf("%-60s", msg); if (malloc_test(t, 4096, 100, verbose)) return 1; if (write_test(4096, 100, verbose)) return 1; if (free_memory(t, 100, verbose)) return 1; if (calloc_test(t, 4096, 100, verbose)) return 1; if (write_test(4096, 100, verbose)) return 1; if (free_memory(t, 100, verbose)) return 1; printf("OK\n"); return 0; } static int small_test(_test_ *t, int verbose) { char msg[60]; sprintf(msg, " Small allocation test for %s", t->title); printf("%-60s", msg); if (malloc_test(t, 64, 100, verbose)) return 1; if (write_test(64, 100, verbose)) return 1; if (free_memory(t, 100, verbose)) return 1; printf("OK\n"); return 0; } static int timed_test(_test_ *t, int verbose) { int iloop, oloop, ooloop, rv; apr_time_t t1=0, t2=0, t3=0, t4 = 0, tmp = 0, total = 0; char msg[60]; apr_size_t sz[5] = {1024, 4096, 256, 8 * 1024, 1024}; if (t->large_tests == 0) return 0; sprintf(msg, " Timed alloc test (%d - %d) for %s", LUMPS, LUMPS + ( 3 * LUMPS), t->title); if (verbose) { printf("%s\n", msg); printf(" alloc <-------- timings (usecs) -------->\n"); printf(" size malloc / calloc / reset / total\n"); } else { printf("%-60s", msg); } for (ooloop = 0; ooloop < 5; ooloop ++) { for (oloop = 0; oloop < TIMED_LOOPS;oloop ++) { for (iloop = 0; iloop < TIMED_RUNS; iloop ++) { TIME_FUNCTION(tmp, (rv = malloc_test(t, sz[ooloop], 100, 0))) t1 += tmp; if (rv) return 1; TIME_FUNCTION(tmp, (rv = write_test(sz[ooloop], 100, 0))) if (rv) return 1; TIME_FUNCTION(tmp, (rv = reset_memory(t, 100, 0))) t2 += tmp; if (rv) return 1; } for (iloop = 0; iloop < TIMED_RUNS; iloop++) { TIME_FUNCTION(tmp, (rv = calloc_test(t, sz[ooloop], 100, 0))) t3 += tmp; if (rv) return 1; TIME_FUNCTION(tmp, (rv = write_test(sz[ooloop], 100, 0))) if (rv) return 1; TIME_FUNCTION(tmp, (rv = reset_memory(t, 100, 0))) t4 += tmp; if (rv) return 1; } } if (verbose) printf(" %4" APR_SIZE_T_FMT " %10lld / %10lld / %10lld / %10lld\n", sz[ooloop], t1, t3, t2 + t4, t1 + t2 + t3 + t4); total += (t1 + t2 + t3 + t4); t1=0;t2=0;t3=0;t4=0; } if (verbose) { printf(" average = %lld\n", (total / TIMED_LOOPS)); } else { printf("OK\n"); } t->howlong = (total / TIMED_LOOPS); return 0; } static int timed_test_64byte(_test_ *t, int small, int verbose) { apr_size_t sz[4] = {100,300,600,1000}; int iloop, oloop, ooloop, rv; apr_time_t t1=0, t2=0, t3=0, tmp = 0, total = 0; apr_time_t tt1=0, tt2=0, tt3=0; char msg[80]; if (small) { sz[0] = 100; sz[1] = 100; sz[2] = 100; sz[3] = 100; } sprintf(msg, " 64 byte alloc test (%" APR_SIZE_T_FMT " - %" APR_SIZE_T_FMT " loops) %s", sz[0], sz[3], t->title); if (verbose) { printf("%s\n", msg); printf(" <------ timings (usecs) ------>\n"); printf(" allocations alloc / reset / total\n"); } else { printf("%-60s", msg); } for (ooloop = 0; ooloop < 4; ooloop ++) { t1=0;t2=0;t3=0; for (oloop = 0; oloop < TIMED_LOOPS * 2;oloop ++) { for (iloop = 0; iloop < TIMED_RUNS; iloop ++) { TIME_FUNCTION(tmp, (rv = malloc_test(t, 64, sz[ooloop], 0))) t1 += tmp; if (rv) return 1; tmp = apr_time_now(); if (write_test(64, sz[ooloop], 0)) return 1; t2 += (apr_time_now() - tmp); tmp = apr_time_now(); if (reset_memory(t, sz[ooloop], 0)) return 1; t3 += (apr_time_now() - tmp); } } if (verbose) { printf(" %4" APR_SIZE_T_FMT " %10lld / %10lld / %10lld\n", sz[ooloop], t1, t2, t1 + t2); } tt1 += t1;tt2 += t2;tt3 += t3; total += (t1 + t2 + t3); t1 = 0; t2 = 0; } if (verbose) printf(" average over 4 runs = %lld\n\n", total / 4); else printf("OK\n"); t->howlong = total / 4; return 0; } static void print_timed_results(void) { int i; printf(" Percentage Results averages %% of pools %% of std sms\n"); for (i=0;i < T_QTY; i++) { float pa = (float)t[i].howlong / (float)t[0].howlong; float pb = (float)t[i].howlong / (float)t[1].howlong; printf(" %-20s %-8lld %7.02f %% %7.02f %%\n", t[i].title, t[i].howlong, pa * 100, pb * 100); } printf("\n"); for (i=0;i