summaryrefslogtreecommitdiff
path: root/ndb/src/common/portlib/memtest
diff options
context:
space:
mode:
Diffstat (limited to 'ndb/src/common/portlib/memtest')
-rw-r--r--ndb/src/common/portlib/memtest/Makefile12
-rw-r--r--ndb/src/common/portlib/memtest/memtest.c245
-rw-r--r--ndb/src/common/portlib/memtest/munmaptest/Makefile14
-rw-r--r--ndb/src/common/portlib/memtest/munmaptest/munmaptest.cpp251
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;
+}