diff options
Diffstat (limited to 'ndb/src/common/portlib/memtest')
-rw-r--r-- | ndb/src/common/portlib/memtest/Makefile | 12 | ||||
-rw-r--r-- | ndb/src/common/portlib/memtest/memtest.c | 245 | ||||
-rw-r--r-- | ndb/src/common/portlib/memtest/munmaptest/Makefile | 14 | ||||
-rw-r--r-- | ndb/src/common/portlib/memtest/munmaptest/munmaptest.cpp | 251 |
4 files changed, 522 insertions, 0 deletions
diff --git a/ndb/src/common/portlib/memtest/Makefile b/ndb/src/common/portlib/memtest/Makefile new file mode 100644 index 00000000000..716cdbdea82 --- /dev/null +++ b/ndb/src/common/portlib/memtest/Makefile @@ -0,0 +1,12 @@ +CC=gcc +LD=$(CC) +SOURCES=memtest.c +OUTPUT=memtest +all: + $(CC) $(SOURCES) -o $(OUTPUT) + +debug: + $(CC) -g $(SOURCES) -o $(OUTPUT) + +clean: rm -rf *.o + rm -rf core* diff --git a/ndb/src/common/portlib/memtest/memtest.c b/ndb/src/common/portlib/memtest/memtest.c new file mode 100644 index 00000000000..d23235b7aa2 --- /dev/null +++ b/ndb/src/common/portlib/memtest/memtest.c @@ -0,0 +1,245 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + + +#include <stdio.h> +#include <unistd.h> +#include <sys/time.h> +#include <sys/mman.h> +long long getMilli(); +long long getMicro(); +void malloctest(int loopcount, int memsize, int touch); +void freetest(int loopcount, int memsize); +void mmaptest(int loopcount, int memsize, int touch); +void unmaptest(int loopcount, int memsize); + + +main(int argc, char ** argv) +{ + + int loopcount; + int memsize; + if(argc < 4) { + printf("Usage: memtest X loopcount memsize(MB)\n"); + printf("where X = \n"); + printf("1 : malloc test \n"); + printf("2 : mmap test \n"); + printf("3 : malloc test + touch pages\n"); + printf("4 : mmap test + touch pages\n"); + printf("5 : malloc/free test \n"); + printf("6 : mmap/munmap test \n"); + printf("loopcount - number of loops\n"); + printf("memsize - memory segment size to allocate in MB.\n"); + exit(1); + } + + + loopcount = atoi(argv[2]); + memsize = atoi(argv[3]); + switch(atoi(argv[1])) { + case 1: malloctest(loopcount, memsize , 0 ); + break; + case 2: mmaptest(loopcount, memsize,0); + break; + case 3: malloctest(loopcount, memsize,1); + break; + case 4: mmaptest(loopcount, memsize,1); + break; + case 5: freetest(loopcount, memsize); + break; + case 6: unmaptest(loopcount, memsize); + break; + default: + break; + } +} + +long long getMilli() { + struct timeval tick_time; + gettimeofday(&tick_time, 0); + + return + ((long long)tick_time.tv_sec) * ((long long)1000) + + ((long long)tick_time.tv_usec) / ((long long)1000); +} + +long long getMicro(){ + struct timeval tick_time; + int res = gettimeofday(&tick_time, 0); + + long long secs = tick_time.tv_sec; + long long micros = tick_time.tv_usec; + + micros = secs*1000000+micros; + return micros; +} + +void malloctest(int loopcount, int memsize, int touch) { + long long start=0; + int total=0; + int i=0, j=0; + int size=memsize*1024*1024; //bytes; + float mean; + char * ptr =0; + + printf("Staring malloctest "); + if(touch) + printf("with touch\n"); + else + printf("\n"); + + start=getMicro(); + + for(i=0; i<loopcount; i++){ + ptr=(char *)malloc((size_t)(size)); + if(ptr==0) { + printf("failed to malloc!\n"); + return; + } + if(touch) { + for(j=0; j<size; j=j+4096) + ptr[j]=1; + } + } + total=(int)(getMicro()-start); + + mean=(float)((float)total/(float)loopcount); + printf("Total time malloc %d bytes: %2.3f microsecs loopcount %d touch %d \n", + size, mean,loopcount, touch); +} + + +void mmaptest(int loopcount, int memsize, int touch) { + long long start=0; + int total=0; + int i=0, j=0; + char * ptr; + int size=memsize*1024*1024; //bytes; + float mean; + + printf("Staring mmaptest "); + if(touch) + printf("with touch \n"); + else + printf("\n"); + + start=getMicro(); + for(i=0; i<loopcount; i++){ + ptr = mmap(0, + size, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, + 0, + 0); + if(ptr<0) { + printf("failed to mmap!\n"); + return; + } + + if(touch) { + for(j=0; j<size; j=j+4096) + ptr[j]=1; + } + } + total=(int)(getMicro()-start); + mean=(float)((float)total/(float)loopcount); + printf("Total time mmap %d bytes: %2.3f microsecs \n",size, mean); +} + + +void unmaptest(loopcount, memsize) +{ + long long start=0; + int total=0; + int i=0, j=0; + char * ptr; + int size=memsize*1024*1024; //bytes; + float mean; + + printf("Staring munmap test (loopcount = 1 no matter what you prev. set)\n"); + + loopcount = 1; + + + for(i=0; i<loopcount; i++){ + ptr =(char*) mmap(0, + size, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, + 0, + 0); + if(ptr<0) { + printf("failed to mmap!\n"); + return; + } + + + for(j=0; j<size; j=j+1) + ptr[j]='1'; + start=getMicro(); + if(munmap(ptr, size)<0) { + printf("failed to munmap!\n"); + return; + } + + total=(int)(getMicro()-start); + /* + for(j=8192; j<size; j=j+4096) { + + *(ptr+j)='1'; + } + + for(j=0; j<4096; j=j+4096) { + *(ptr+j)='1'; + } + + */ + } + mean=(float)((float)total/(float)loopcount); + printf("Total time unmap %d bytes: %2.3f microsecs \n",size, mean); +} + +void freetest(int loopcount, int memsize) { + long long start=0; + int total=0; + int i=0, j=0; + int size=memsize*1024*1024; //bytes; + float mean; + char * ptr =0; + + loopcount = 1; + printf("Staring free test (loopcount = 1 no matter what you prev. set)\n"); + + + for(i=0; i<loopcount; i++){ + ptr=(char*)malloc((size_t)(size)); + if(ptr==0) { + printf("failed to malloc!\n"); + return; + } + for(j=0; j<size; j=j+4096) + ptr[j]='1'; + start=getMicro(); + free(ptr); + total=(int)(getMicro()-start); + } + + + mean=(float)((float)total/(float)loopcount); + printf("Total time free %d bytes: %2.3f microsecs loopcount %d \n", + size, mean,loopcount); +} diff --git a/ndb/src/common/portlib/memtest/munmaptest/Makefile b/ndb/src/common/portlib/memtest/munmaptest/Makefile new file mode 100644 index 00000000000..ea8c5238d1c --- /dev/null +++ b/ndb/src/common/portlib/memtest/munmaptest/Makefile @@ -0,0 +1,14 @@ +include .defs.mk + +TYPE := ndbapitest +BIN_TARGET := munmaptest + + +SOURCES = munmaptest.cpp + +include $(NDB_TOP)/Epilogue.mk + + + + + diff --git a/ndb/src/common/portlib/memtest/munmaptest/munmaptest.cpp b/ndb/src/common/portlib/memtest/munmaptest/munmaptest.cpp new file mode 100644 index 00000000000..9e396cd98ee --- /dev/null +++ b/ndb/src/common/portlib/memtest/munmaptest/munmaptest.cpp @@ -0,0 +1,251 @@ +/* Copyright (C) 2003 MySQL AB + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 2 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ + + + + +#include <NdbOut.hpp> +#include <NdbThread.h> +#include <NdbMutex.h> +#include <NdbCondition.h> +#include <NdbSleep.h> +#include <NdbTick.h> +#include <NdbEnv.h> +#include <NdbHost.h> +#include <NdbMain.h> +#include <getarg.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> +#include <string.h> +#include <sys/time.h> +#include <sys/mman.h> + + +struct ThreadData +{ + char * mapAddr; + Uint32 mapSize; + Uint32 chunk; + Uint32 idx; + +}; + +long long getMilli(); +long long getMicro(); + + +void* mapSegment(void * arg); +void* unmapSegment(void * arg); + + +void* mapSegment(void * arg) { + + ThreadData * threadArgs; + long long start=0; + int total=0; + int id = *(int *)arg; + threadArgs = new ThreadData [1]; + Uint32 size=5*1024*1024; + struct NdbThread* unmapthread_var; + void *status = 0; + int run = 1; + int max=0, min =100000000, sum=0; + while(run < 1001) { + start=getMicro(); + char * ptr =(char*) mmap(0, + size, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, + 0, + 0); + + total=(int)(getMicro()-start); + + ndbout << "T" << id << ": mmap took : " << total << " microsecs. " + << " Run: " << run ; + ndbout_c(" mapped @ %p \n", ptr); + + if(total>max) + max = total; + if(total<min) + min=total; + + sum+=total; + + if(ptr<0) { + ndbout << "failed to mmap!" << endl; + exit(1); + } + + + threadArgs[0].mapAddr = (char *)ptr; + threadArgs[0].mapSize = size; + threadArgs[0].chunk = 4096; + threadArgs[0].idx = 0; + + + for(Uint32 j=0; j<size; j=j+4096) + ptr[j]='1'; + + unmapthread_var = NdbThread_Create(unmapSegment, // Function + (void**)&threadArgs[0],// Arg + 32768, // Stacksize + (char*)"unmapthread", // Thread name + NDB_THREAD_PRIO_MEAN); // Thread prio + + + if(NdbThread_WaitFor(unmapthread_var, &status) != 0) { + ndbout << "test failed - exitting " << endl; + exit(1); + } + run++; + } + + ndbout << "MAX: " << max << " MIN: " << min; + float mean = (float) ((float)sum/(float)run); + ndbout_c(" AVERAGE: %2.5f\n",mean); +} + + + +void* unmapSegment(void * arg) +{ + + char * freeAddr; + char * mapAddr; + ThreadData * threadData = (ThreadData*) arg; + int start=0; + int total=0; + Uint32 mapSize = threadData->mapSize; + Uint32 chunk = threadData->chunk; + mapAddr = threadData->mapAddr; + + + + freeAddr = mapAddr+mapSize-chunk; + NdbSleep_MilliSleep(100); + for(Uint32 i=0;i<mapSize; i = i+chunk) { + start=getMicro(); + if(munmap(freeAddr, chunk) < 0){ + ndbout << "munmap failed" << endl; + exit(1); + } + total=(int)(getMicro()-start); + freeAddr = freeAddr - chunk; + NdbSleep_MilliSleep(10); + ndbout << "unmap 4096 bytes : " << total << "microsecs" << endl; + } + return NULL; +} + + +static int trash; +static int segmentsize=1; + + +static struct getargs args[] = { + { "trash", 't', arg_integer, &trash, + "trash the memory before (1 to trash 0 to not trash)", "trash"}, + { "segment", 's', arg_integer, &segmentsize, + "segment size (in MB)", "segment"}, +}; + + +static const int num_args = sizeof(args) / sizeof(args[0]); + +NDB_MAIN(munmaptest) { + + const char *progname = "munmaptest"; + int optind = 0; + + if(getarg(args, num_args, argc, argv, &optind)) { + arg_printusage(args, num_args, progname, ""); + exit(1); + } + + int size; + char * ptr; + if(trash) { + for(int i=0; i<100; i++) { + size=1+(int) (10.0*rand()/(RAND_MAX+1.0)); + NdbSleep_MilliSleep(10); + ptr =(char*) mmap(0, + size*1024*1024, + PROT_READ|PROT_WRITE, + MAP_PRIVATE|MAP_ANONYMOUS, + 0, + 0); + for(int i=0;i<(size*1024*1024); i=i+4096) { + *(ptr+i)='1'; + } + NdbSleep_MilliSleep(10); + + munmap(ptr,size); + + } + + + } + + int noThreads = 1; + struct NdbThread* mapthread_var; + int id[noThreads]; + void *status=0; + + ThreadData * threadArgs = new ThreadData[noThreads]; + + + + + for(int i=0; i < noThreads; i++) { + threadArgs[i].mapSize = segmentsize*1024*1024; + threadArgs[i].idx = i; + mapthread_var = NdbThread_Create(mapSegment, // Function + (void**)&threadArgs[i],// Arg + 32768, // Stacksize + (char*)"mapthread", // Thread name + NDB_THREAD_PRIO_MEAN); // Thread prio + + } + + + if(NdbThread_WaitFor(mapthread_var, &status) != 0) { + ndbout << "test failed - exitting " << endl; + exit(1); + } + +} + +long long getMilli() { + struct timeval tick_time; + gettimeofday(&tick_time, 0); + + return + ((long long)tick_time.tv_sec) * ((long long)1000) + + ((long long)tick_time.tv_usec) / ((long long)1000); +} + +long long getMicro(){ + struct timeval tick_time; + int res = gettimeofday(&tick_time, 0); + + long long secs = tick_time.tv_sec; + long long micros = tick_time.tv_usec; + + micros = secs*1000000+micros; + return micros; +} |