00001 /* Copyright (C) 2003 MySQL AB 00002 00003 This program is free software; you can redistribute it and/or modify 00004 it under the terms of the GNU General Public License as published by 00005 the Free Software Foundation; either version 2 of the License, or 00006 (at your option) any later version. 00007 00008 This program is distributed in the hope that it will be useful, 00009 but WITHOUT ANY WARRANTY; without even the implied warranty of 00010 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00011 GNU General Public License for more details. 00012 00013 You should have received a copy of the GNU General Public License 00014 along with this program; if not, write to the Free Software 00015 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */ 00016 00017 00018 00019 00020 #include <ndb_global.h> 00021 00022 #include <NdbOut.hpp> 00023 #include <NdbThread.h> 00024 #include <NdbMutex.h> 00025 #include <NdbCondition.h> 00026 #include <NdbSleep.h> 00027 #include <NdbTick.h> 00028 #include <NdbEnv.h> 00029 #include <NdbHost.h> 00030 #include <NdbMain.h> 00031 #include <getarg.h> 00032 00033 struct ThreadData 00034 { 00035 char * mapAddr; 00036 Uint32 mapSize; 00037 Uint32 chunk; 00038 Uint32 idx; 00039 00040 }; 00041 00042 long long getMilli(); 00043 long long getMicro(); 00044 00045 00046 void* mapSegment(void * arg); 00047 void* unmapSegment(void * arg); 00048 00049 00050 void* mapSegment(void * arg) { 00051 00052 ThreadData * threadArgs; 00053 long long start=0; 00054 int total=0; 00055 int id = *(int *)arg; 00056 threadArgs = new ThreadData [1]; 00057 Uint32 size=5*1024*1024; 00058 struct NdbThread* unmapthread_var; 00059 void *status = 0; 00060 int run = 1; 00061 int max=0, min =100000000, sum=0; 00062 while(run < 1001) { 00063 start=getMicro(); 00064 char * ptr =(char*) mmap(0, 00065 size, 00066 PROT_READ|PROT_WRITE, 00067 MAP_PRIVATE|MAP_ANONYMOUS, 00068 0, 00069 0); 00070 00071 total=(int)(getMicro()-start); 00072 00073 ndbout << "T" << id << ": mmap took : " << total << " microsecs. " 00074 << " Run: " << run ; 00075 ndbout_c(" mapped @ %p \n", ptr); 00076 00077 if(total>max) 00078 max = total; 00079 if(total<min) 00080 min=total; 00081 00082 sum+=total; 00083 00084 if(ptr<0) { 00085 ndbout << "failed to mmap!" << endl; 00086 exit(1); 00087 } 00088 00089 00090 threadArgs[0].mapAddr = (char *)ptr; 00091 threadArgs[0].mapSize = size; 00092 threadArgs[0].chunk = 4096; 00093 threadArgs[0].idx = 0; 00094 00095 00096 for(Uint32 j=0; j<size; j=j+4096) 00097 ptr[j]='1'; 00098 00099 unmapthread_var = NdbThread_Create(unmapSegment, // Function 00100 (void**)&threadArgs[0],// Arg 00101 32768, // Stacksize 00102 (char*)"unmapthread", // Thread name 00103 NDB_THREAD_PRIO_MEAN); // Thread prio 00104 00105 00106 if(NdbThread_WaitFor(unmapthread_var, &status) != 0) { 00107 ndbout << "test failed - exitting " << endl; 00108 exit(1); 00109 } 00110 run++; 00111 } 00112 00113 ndbout << "MAX: " << max << " MIN: " << min; 00114 float mean = (float) ((float)sum/(float)run); 00115 ndbout_c(" AVERAGE: %2.5f\n",mean); 00116 } 00117 00118 00119 00120 void* unmapSegment(void * arg) 00121 { 00122 00123 char * freeAddr; 00124 char * mapAddr; 00125 ThreadData * threadData = (ThreadData*) arg; 00126 int start=0; 00127 int total=0; 00128 Uint32 mapSize = threadData->mapSize; 00129 Uint32 chunk = threadData->chunk; 00130 mapAddr = threadData->mapAddr; 00131 00132 00133 00134 freeAddr = mapAddr+mapSize-chunk; 00135 NdbSleep_MilliSleep(100); 00136 for(Uint32 i=0;i<mapSize; i = i+chunk) { 00137 start=getMicro(); 00138 if(munmap(freeAddr, chunk) < 0){ 00139 ndbout << "munmap failed" << endl; 00140 exit(1); 00141 } 00142 total=(int)(getMicro()-start); 00143 freeAddr = freeAddr - chunk; 00144 NdbSleep_MilliSleep(10); 00145 ndbout << "unmap 4096 bytes : " << total << "microsecs" << endl; 00146 } 00147 return NULL; 00148 } 00149 00150 00151 static int trash; 00152 static int segmentsize=1; 00153 00154 00155 static struct getargs args[] = { 00156 { "trash", 't', arg_integer, &trash, 00157 "trash the memory before (1 to trash 0 to not trash)", "trash"}, 00158 { "segment", 's', arg_integer, &segmentsize, 00159 "segment size (in MB)", "segment"}, 00160 }; 00161 00162 00163 static const int num_args = sizeof(args) / sizeof(args[0]); 00164 00165 NDB_MAIN(munmaptest) { 00166 00167 const char *progname = "munmaptest"; 00168 int optind = 0; 00169 00170 if(getarg(args, num_args, argc, argv, &optind)) { 00171 arg_printusage(args, num_args, progname, ""); 00172 exit(1); 00173 } 00174 00175 int size; 00176 char * ptr; 00177 if(trash) { 00178 for(int i=0; i<100; i++) { 00179 size=1+(int) (10.0*rand()/(RAND_MAX+1.0)); 00180 NdbSleep_MilliSleep(10); 00181 ptr =(char*) mmap(0, 00182 size*1024*1024, 00183 PROT_READ|PROT_WRITE, 00184 MAP_PRIVATE|MAP_ANONYMOUS, 00185 0, 00186 0); 00187 for(int i=0;i<(size*1024*1024); i=i+4096) { 00188 *(ptr+i)='1'; 00189 } 00190 NdbSleep_MilliSleep(10); 00191 00192 munmap(ptr,size); 00193 00194 } 00195 00196 00197 } 00198 00199 int noThreads = 1; 00200 struct NdbThread* mapthread_var; 00201 int id[noThreads]; 00202 void *status=0; 00203 00204 ThreadData * threadArgs = new ThreadData[noThreads]; 00205 00206 00207 00208 00209 for(int i=0; i < noThreads; i++) { 00210 threadArgs[i].mapSize = segmentsize*1024*1024; 00211 threadArgs[i].idx = i; 00212 mapthread_var = NdbThread_Create(mapSegment, // Function 00213 (void**)&threadArgs[i],// Arg 00214 32768, // Stacksize 00215 (char*)"mapthread", // Thread name 00216 NDB_THREAD_PRIO_MEAN); // Thread prio 00217 00218 } 00219 00220 00221 if(NdbThread_WaitFor(mapthread_var, &status) != 0) { 00222 ndbout << "test failed - exitting " << endl; 00223 exit(1); 00224 } 00225 00226 } 00227 00228 long long getMilli() { 00229 struct timeval tick_time; 00230 gettimeofday(&tick_time, 0); 00231 00232 return 00233 ((long long)tick_time.tv_sec) * ((long long)1000) + 00234 ((long long)tick_time.tv_usec) / ((long long)1000); 00235 } 00236 00237 long long getMicro(){ 00238 struct timeval tick_time; 00239 int res = gettimeofday(&tick_time, 0); 00240 00241 long long secs = tick_time.tv_sec; 00242 long long micros = tick_time.tv_usec; 00243 00244 micros = secs*1000000+micros; 00245 return micros; 00246 }
1.4.7

