~ubuntu-branches/ubuntu/precise/mysql-5.1/precise

« back to all changes in this revision

Viewing changes to storage/ndb/src/common/portlib/munmaptest.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Norbert Tretkowski
  • Date: 2010-03-17 14:56:02 UTC
  • Revision ID: james.westby@ubuntu.com-20100317145602-x7e30l1b2sb5s6w6
Tags: upstream-5.1.45
ImportĀ upstreamĀ versionĀ 5.1.45

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* Copyright (C) 2003 MySQL AB
 
2
 
 
3
   This program is free software; you can redistribute it and/or modify
 
4
   it under the terms of the GNU General Public License as published by
 
5
   the Free Software Foundation; version 2 of the License.
 
6
 
 
7
   This program is distributed in the hope that it will be useful,
 
8
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
9
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
10
   GNU General Public License for more details.
 
11
 
 
12
   You should have received a copy of the GNU General Public License
 
13
   along with this program; if not, write to the Free Software
 
14
   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA */
 
15
 
 
16
 
 
17
 
 
18
 
 
19
#include <ndb_global.h>
 
20
 
 
21
#include <NdbOut.hpp>
 
22
#include <NdbThread.h>
 
23
#include <NdbMutex.h>
 
24
#include <NdbCondition.h>
 
25
#include <NdbSleep.h>
 
26
#include <NdbTick.h>
 
27
#include <NdbEnv.h>
 
28
#include <NdbHost.h>
 
29
#include <NdbMain.h>
 
30
#include <getarg.h>
 
31
 
 
32
struct ThreadData
 
33
{
 
34
  char * mapAddr;
 
35
  Uint32 mapSize;
 
36
  Uint32 chunk;
 
37
  Uint32 idx;
 
38
  
 
39
};
 
40
 
 
41
long long getMilli();
 
42
long long getMicro();
 
43
 
 
44
 
 
45
void* mapSegment(void * arg);
 
46
void* unmapSegment(void * arg);
 
47
 
 
48
 
 
49
void* mapSegment(void * arg) {
 
50
  
 
51
  ThreadData * threadArgs;
 
52
  long long start=0;
 
53
  int total=0;
 
54
  int id = *(int *)arg;
 
55
  threadArgs = new ThreadData [1];
 
56
  Uint32 size=5*1024*1024;
 
57
  struct NdbThread* unmapthread_var;
 
58
  void *status = 0;  
 
59
  int run = 1;
 
60
  int max=0, min =100000000, sum=0;
 
61
  while(run < 1001) {
 
62
    start=getMicro(); 
 
63
    char * ptr =(char*) mmap(0, 
 
64
                             size, 
 
65
                             PROT_READ|PROT_WRITE, 
 
66
                             MAP_PRIVATE|MAP_ANONYMOUS, 
 
67
                             0,
 
68
                             0);
 
69
 
 
70
    total=(int)(getMicro()-start);
 
71
    
 
72
    ndbout << "T"  << id << ": mmap took : " << total << " microsecs. " 
 
73
           << " Run: " << run ;
 
74
    ndbout_c(" mapped @ %p \n", ptr);
 
75
    
 
76
    if(total>max)
 
77
      max = total;
 
78
    if(total<min)
 
79
      min=total;
 
80
    
 
81
    sum+=total;
 
82
    
 
83
    if(ptr<0) {
 
84
      ndbout << "failed to mmap!" << endl;
 
85
      exit(1);
 
86
    }
 
87
 
 
88
    
 
89
    threadArgs[0].mapAddr = (char *)ptr;
 
90
    threadArgs[0].mapSize = size;
 
91
    threadArgs[0].chunk = 4096;
 
92
    threadArgs[0].idx = 0;
 
93
    
 
94
    
 
95
    for(Uint32 j=0; j<size; j=j+4096)
 
96
      ptr[j]='1';
 
97
    
 
98
    unmapthread_var = NdbThread_Create(unmapSegment, // Function 
 
99
                                       (void**)&threadArgs[0],// Arg
 
100
                                       32768,        // Stacksize
 
101
                                       (char*)"unmapthread",  // Thread name
 
102
                                       NDB_THREAD_PRIO_MEAN); // Thread prio
 
103
    
 
104
    
 
105
    if(NdbThread_WaitFor(unmapthread_var, &status) != 0) {
 
106
      ndbout << "test failed - exitting " << endl;
 
107
      exit(1);
 
108
    }
 
109
    run++;
 
110
  }
 
111
  
 
112
  ndbout << "MAX: " << max << " MIN: " << min;
 
113
  float mean = (float) ((float)sum/(float)run);
 
114
  ndbout_c(" AVERAGE: %2.5f\n",mean);
 
115
}
 
116
 
 
117
 
 
118
 
 
119
void* unmapSegment(void * arg)
 
120
{
 
121
  
 
122
  char * freeAddr;
 
123
  char * mapAddr;
 
124
  ThreadData * threadData = (ThreadData*) arg;
 
125
  int start=0;
 
126
  int total=0;
 
127
  Uint32 mapSize = threadData->mapSize;
 
128
  Uint32 chunk = threadData->chunk;
 
129
  mapAddr = threadData->mapAddr;
 
130
 
 
131
  
 
132
  
 
133
  freeAddr = mapAddr+mapSize-chunk;
 
134
  NdbSleep_MilliSleep(100);  
 
135
  for(Uint32 i=0;i<mapSize; i = i+chunk) {
 
136
    start=getMicro(); 
 
137
    if(munmap(freeAddr, chunk) < 0){
 
138
      ndbout << "munmap failed" << endl;
 
139
      exit(1);
 
140
    }
 
141
    total=(int)(getMicro()-start);
 
142
    freeAddr = freeAddr - chunk;
 
143
    NdbSleep_MilliSleep(10);
 
144
    ndbout << "unmap 4096 bytes : " << total << "microsecs" << endl;
 
145
  }
 
146
  return NULL;
 
147
}
 
148
 
 
149
 
 
150
static int trash;
 
151
static int segmentsize=1;
 
152
 
 
153
 
 
154
static struct getargs args[] = {
 
155
  { "trash", 't', arg_integer, &trash,
 
156
    "trash the memory before (1 to trash 0 to not trash)", "trash"},
 
157
  { "segment", 's', arg_integer, &segmentsize,
 
158
    "segment size (in MB)", "segment"},
 
159
};
 
160
 
 
161
 
 
162
static const int num_args = sizeof(args) / sizeof(args[0]);
 
163
 
 
164
NDB_MAIN(munmaptest) {
 
165
   
 
166
  const char *progname = "munmaptest"; 
 
167
  int optind = 0;
 
168
 
 
169
  if(getarg(args, num_args, argc, argv, &optind)) {
 
170
    arg_printusage(args, num_args, progname, "");
 
171
    exit(1);
 
172
  }
 
173
  
 
174
  int size;
 
175
  char * ptr;
 
176
  if(trash) {
 
177
    for(int i=0; i<100; i++) {
 
178
      size=1+(int) (10.0*rand()/(RAND_MAX+1.0));
 
179
      NdbSleep_MilliSleep(10);
 
180
      ptr =(char*) mmap(0, 
 
181
                        size*1024*1024, 
 
182
                        PROT_READ|PROT_WRITE, 
 
183
                        MAP_PRIVATE|MAP_ANONYMOUS, 
 
184
                        0,
 
185
                        0);      
 
186
      for(int i=0;i<(size*1024*1024); i=i+4096) {
 
187
        *(ptr+i)='1';
 
188
      }
 
189
      NdbSleep_MilliSleep(10);
 
190
     
 
191
      munmap(ptr,size);
 
192
 
 
193
    }
 
194
    
 
195
    
 
196
  }
 
197
 
 
198
  int noThreads = 1;
 
199
  struct NdbThread*  mapthread_var;
 
200
  int id[noThreads];
 
201
  void *status=0;
 
202
 
 
203
  ThreadData * threadArgs = new ThreadData[noThreads];
 
204
 
 
205
 
 
206
 
 
207
 
 
208
  for(int i=0; i < noThreads; i++) {
 
209
    threadArgs[i].mapSize = segmentsize*1024*1024;
 
210
    threadArgs[i].idx = i;
 
211
    mapthread_var = NdbThread_Create(mapSegment, // Function
 
212
                                     (void**)&threadArgs[i],// Arg
 
213
                                     32768,        // Stacksize
 
214
                                     (char*)"mapthread",  // Thread name
 
215
                                     NDB_THREAD_PRIO_MEAN); // Thread prio
 
216
    
 
217
  }
 
218
  
 
219
  
 
220
  if(NdbThread_WaitFor(mapthread_var, &status) != 0) {
 
221
    ndbout << "test failed - exitting " << endl;
 
222
    exit(1);
 
223
  }
 
224
 
 
225
}
 
226
 
 
227
long long getMilli() {
 
228
  struct timeval tick_time;
 
229
  gettimeofday(&tick_time, 0);
 
230
 
 
231
  return 
 
232
    ((long long)tick_time.tv_sec)  * ((long long)1000) +
 
233
    ((long long)tick_time.tv_usec) / ((long long)1000);
 
234
}
 
235
 
 
236
long long getMicro(){
 
237
  struct timeval tick_time;
 
238
  int res = gettimeofday(&tick_time, 0);
 
239
 
 
240
  long long secs   = tick_time.tv_sec;
 
241
  long long micros = tick_time.tv_usec;
 
242
  
 
243
  micros = secs*1000000+micros;
 
244
  return micros;
 
245
}