~ubuntu-branches/ubuntu/trusty/mysql-5.6/trusty

« back to all changes in this revision

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

  • Committer: Package Import Robot
  • Author(s): James Page
  • Date: 2014-02-12 11:54:27 UTC
  • Revision ID: package-import@ubuntu.com-20140212115427-oq6tfsqxl1wuwehi
Tags: upstream-5.6.15
ImportĀ upstreamĀ versionĀ 5.6.15

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
2
   Copyright (C) 2003-2006, 2008 MySQL AB
 
3
    All rights reserved. Use is subject to license terms.
 
4
 
 
5
   This program is free software; you can redistribute it and/or modify
 
6
   it under the terms of the GNU General Public License as published by
 
7
   the Free Software Foundation; version 2 of the License.
 
8
 
 
9
   This program is distributed in the hope that it will be useful,
 
10
   but WITHOUT ANY WARRANTY; without even the implied warranty of
 
11
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 
12
   GNU General Public License for more details.
 
13
 
 
14
   You should have received a copy of the GNU General Public License
 
15
   along with this program; if not, write to the Free Software
 
16
   Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301  USA
 
17
*/
 
18
 
 
19
/**
 
20
 *  NdbPortLibTest.cpp
 
21
 *  Test the functionality of portlib
 
22
 *  TODO - Add tests for NdbMem
 
23
 */
 
24
 
 
25
#include <ndb_global.h>
 
26
 
 
27
#include "NdbOut.hpp"
 
28
#include "NdbThread.h"
 
29
#include "NdbMutex.h"
 
30
#include "NdbCondition.h"
 
31
#include "NdbSleep.h"
 
32
#include "NdbTick.h"
 
33
#include "NdbEnv.h"
 
34
#include "NdbHost.h"
 
35
#include "NdbMain.h"
 
36
 
 
37
int TestHasFailed;
 
38
int verbose = 0;
 
39
 
 
40
static void fail(const char* test, const char* cause)
 
41
{
 
42
  TestHasFailed = 1;
 
43
  ndbout << test << " failed, " << cause << endl;
 
44
}
 
45
 
 
46
// test 1 variables and funcs
 
47
 
 
48
extern "C"  void* thread1func(void* arg)
 
49
{
 
50
  int arg1;
 
51
  int returnvalue = 8;
 
52
  arg1 = *(int*)arg;
 
53
  ndbout << "thread1: thread1func called with arg = " << arg1 << endl;
 
54
 
 
55
  //  delay(1000);
 
56
  if (arg1 != 7)
 
57
    fail("TEST1", "Wrong arg");
 
58
 
 
59
  return (void*) returnvalue;
 
60
}
 
61
 
 
62
// test 2 variables and funcs
 
63
 
 
64
NdbMutex* test2mutex;
 
65
 
 
66
extern "C" void* test2func(void* arg)
 
67
{
 
68
 
 
69
  int arg1;
 
70
  arg1 = *(int*)arg;
 
71
  ndbout << "thread" << arg1 << " started in test2func" << endl;
 
72
 
 
73
  if (NdbMutex_Lock(test2mutex) != 0)
 
74
    fail("TEST2", "Failed to lock mutex");
 
75
 
 
76
  ndbout << "thread" << arg1 << ", test2func " << endl;
 
77
 
 
78
  if (NdbMutex_Unlock(test2mutex) != 0)
 
79
    fail("TEST2", "Failed to unlock mutex");
 
80
 
 
81
  int returnvalue = arg1;
 
82
  return (void*) returnvalue;
 
83
}
 
84
 
 
85
 
 
86
// test 3 and 7 variables and funcs
 
87
 
 
88
NdbMutex* testmutex;
 
89
NdbCondition* testcond;
 
90
int testthreadsdone;
 
91
 
 
92
extern "C" void* testfunc(void* arg)
 
93
{
 
94
  int tmpVar;
 
95
  int threadno;
 
96
  int result;
 
97
 
 
98
  threadno = *(int*)arg;
 
99
 
 
100
  ndbout << "Thread" << threadno << " started in testfunc" << endl;
 
101
  do 
 
102
    {
 
103
 
 
104
      if ((threadno % 2) == 0)
 
105
        result = NdbSleep_SecSleep(1);
 
106
      else
 
107
        result = NdbSleep_MilliSleep(100);
 
108
 
 
109
      if (result != 0)
 
110
        fail("TEST3", "Wrong result from sleep function");
 
111
 
 
112
      if (NdbMutex_Lock(testmutex) != 0)
 
113
        fail("TEST3", "Wrong result from NdbMutex_Lock function");
 
114
  
 
115
      ndbout << "thread" << threadno << ", testfunc " << endl;
 
116
      testthreadsdone++;
 
117
      tmpVar = testthreadsdone;
 
118
 
 
119
      if (NdbCondition_Signal(testcond) != 0)
 
120
        fail("TEST3", "Wrong result from NdbCondition_Signal function");
 
121
  
 
122
      if (NdbMutex_Unlock(testmutex) != 0)
 
123
        fail("TEST3", "Wrong result from NdbMutex_Unlock function");
 
124
 
 
125
    }
 
126
  while(tmpVar<100);
 
127
  
 
128
  return 0;
 
129
}
 
130
 
 
131
extern "C" void* testTryLockfunc(void* arg)
 
132
{
 
133
  int tmpVar = 0;
 
134
  int threadno;
 
135
  int result;
 
136
 
 
137
  threadno = *(int*)arg;
 
138
 
 
139
  ndbout << "Thread" << threadno << " started" << endl;
 
140
  do 
 
141
    {
 
142
 
 
143
      if ((threadno % 2) == 0)
 
144
        result = NdbSleep_SecSleep(1);
 
145
      else
 
146
        result = NdbSleep_MilliSleep(100);
 
147
 
 
148
      if (result != 0)
 
149
        fail("TEST3", "Wrong result from sleep function");
 
150
 
 
151
      if (NdbMutex_Trylock(testmutex) == 0){
 
152
         
 
153
        ndbout << "thread" << threadno << ", testTryLockfunc locked" << endl;
 
154
        testthreadsdone++;
 
155
        tmpVar = testthreadsdone;
 
156
        
 
157
        if (NdbCondition_Signal(testcond) != 0)
 
158
          fail("TEST3", "Wrong result from NdbCondition_Signal function");
 
159
  
 
160
        if (NdbMutex_Unlock(testmutex) != 0)
 
161
          fail("TEST3", "Wrong result from NdbMutex_Unlock function");
 
162
      }
 
163
 
 
164
    }
 
165
  while(tmpVar<100);
 
166
  
 
167
  return 0;
 
168
}
 
169
 
 
170
 
 
171
 
 
172
void testMicros(int count);
 
173
Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2);
 
174
 
 
175
NDB_COMMAND(PortLibTest, "portlibtest", "portlibtest", "Test the portable function layer", 4096){
 
176
 
 
177
  ndbout << "= TESTING ARGUMENT PASSING ============" << endl;
 
178
  ndbout << "ARGC: " << argc << endl;
 
179
  for(int i = 1; i < argc; i++){
 
180
    ndbout << " ARGV"<<i<<": " << (char*)argv[i] << endl;
 
181
  }
 
182
  ndbout << endl << endl;
 
183
  
 
184
 
 
185
  struct NdbThread* thread1var;
 
186
  void *status = 0;
 
187
  int arg = 7;
 
188
 
 
189
  TestHasFailed = 0;
 
190
  // create one thread and wait for it to return
 
191
  ndbout << "= TEST1 ===============================" << endl;
 
192
 
 
193
  thread1var = NdbThread_Create(thread1func, // Function 
 
194
                                (void**)&arg,// Arg
 
195
                                2048,        // Stacksize
 
196
                                (char*)"thread1",  // Thread name
 
197
                                NDB_THREAD_PRIO_MEAN); // Thread priority
 
198
 
 
199
  
 
200
  if(NdbThread_WaitFor(thread1var, &status) != 0)
 
201
    fail("TEST1", "NdbThread_WaitFor failed");
 
202
  // NOTE! thread return value is not yet used in Ndb and thus not tested(does not work)
 
203
  //ndbout << "thread1 returned, status = " << status << endl;
 
204
  //if (status != 8) 
 
205
  // fail("TEST1", "Wrong status");
 
206
  ndbout << "TEST1 completed" << endl;
 
207
 
 
208
 
 
209
  NdbThread_Destroy(&thread1var);
 
210
 
 
211
  // Create 10 threads that will wait for a mutex before printing it's message to screen
 
212
  ndbout << "= TEST2 ===============================" << endl;
 
213
#define T2_THREADS 10
 
214
  NdbThread* threads[T2_THREADS];
 
215
  int   args[T2_THREADS];
 
216
  void *status2 = 0;
 
217
  test2mutex = NdbMutex_Create();
 
218
  NdbMutex_Lock(test2mutex);
 
219
 
 
220
  for (int i = 0; i < T2_THREADS; i++)
 
221
    {
 
222
      args[i] = i;
 
223
    threads[i] = NdbThread_Create(test2func, // Function 
 
224
                                  (void**)&args[i],// Arg
 
225
                                  2048,        // Stacksize
 
226
                                  (char*)"test2thread",  // Thread name
 
227
                                  NDB_THREAD_PRIO_MEAN); // Thread priority
 
228
    if (threads[i] == NULL)
 
229
      fail("TEST2", "NdbThread_Create failed");
 
230
    }
 
231
 
 
232
  ndbout << "All threads created" << endl;
 
233
 
 
234
  NdbMutex_Unlock(test2mutex);
 
235
 
 
236
  for (int i = 0; i < T2_THREADS; i++)
 
237
  {
 
238
    if (NdbThread_WaitFor(threads[i], &status2))
 
239
      fail("TEST2", "NdbThread_WaitFor failed");      
 
240
 
 
241
    NdbThread_Destroy(&threads[i]);
 
242
    // Don't test return values
 
243
    //    ndbout << "thread" << i << " returned, status = " << status2 << endl;
 
244
    //    if (status2 != i)
 
245
    //      fail("TEST2", "Wrong status");
 
246
  }
 
247
 
 
248
  if (NdbMutex_Lock(test2mutex) != 0)
 
249
    fail("TEST2", "NdbMutex_Lock failed");
 
250
  if (NdbMutex_Unlock(test2mutex) != 0)
 
251
    fail("TEST2", "NdbMutex_Unlock failed");
 
252
  if (NdbMutex_Destroy(test2mutex) != 0)
 
253
    fail("TEST2", "NdbMutex_Destroy failed");
 
254
  ndbout << "TEST2 completed" << endl;
 
255
 
 
256
  ndbout << "= TEST3 ===============================" << endl;
 
257
  // Create 10 threads that will by synchronised by a condition
 
258
  // When they are awakened and have the mutex they will increment a global variable
 
259
#define T3_THREADS 10
 
260
  NdbThread* t3threads[T3_THREADS];
 
261
  int   t3args[T3_THREADS];
 
262
  void *status3 = 0;
 
263
 
 
264
  testmutex = NdbMutex_Create();
 
265
  testcond = NdbCondition_Create();
 
266
  testthreadsdone = 0;
 
267
  
 
268
  for (int i = 0; i < T3_THREADS; i++)
 
269
    {
 
270
      t3args[i] = i;
 
271
      t3threads[i] = NdbThread_Create(testfunc, // Function 
 
272
                                      (void**)&t3args[i],// Arg
 
273
                                      2048,        // Stacksize
 
274
                                      (char*)"test3thread",  // Thread name
 
275
                                      NDB_THREAD_PRIO_MEAN); // Thread priority
 
276
    }
 
277
 
 
278
  ndbout << "All threads created" << endl;
 
279
 
 
280
  if (NdbMutex_Lock(testmutex) != 0)
 
281
    fail("TEST3", "NdbMutex_Lock failed");
 
282
  
 
283
  while (testthreadsdone < T3_THREADS*10)
 
284
    {
 
285
      if(NdbCondition_Wait(testcond, testmutex) != 0)
 
286
        fail("TEST3", "NdbCondition_Wait failed");
 
287
      ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
 
288
    }
 
289
  if (NdbMutex_Unlock(testmutex) != 0)
 
290
    fail("TEST3", "NdbMutex_Unlock failed");
 
291
 
 
292
  for (int i = 0; i < T3_THREADS; i++)
 
293
  {
 
294
    if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
 
295
      fail("TEST3", "NdbThread_WaitFor failed");
 
296
 
 
297
    NdbThread_Destroy(&t3threads[i]);
 
298
    //ndbout << "thread" << i << " returned, status = " << status3 << endl;
 
299
    //if (status3 != i)
 
300
    //  fail("TEST3", "Wrong status");
 
301
  }
 
302
 
 
303
  NdbMutex_Destroy(testmutex);
 
304
  NdbCondition_Destroy(testcond);
 
305
  ndbout << "TEST3 completed" << endl;
 
306
 
 
307
  ndbout << "= TEST4 ===============================" << endl;
 
308
  // Check tick functions
 
309
 
 
310
  //#if 0
 
311
 
 
312
  int sleeptimes[] = {78, 12, 199, 567, 899};
 
313
 
 
314
 
 
315
  for (int i = 0; i < 5; i++)
 
316
  {
 
317
  ndbout << "*------------------------------- Measure" << i << endl;
 
318
 
 
319
  NDB_TICKS millisec_now; 
 
320
  NDB_TICKS millisec_now2;
 
321
 
 
322
  millisec_now = NdbTick_CurrentMillisecond();
 
323
  NdbSleep_MilliSleep(sleeptimes[i]);
 
324
  millisec_now2 = NdbTick_CurrentMillisecond();
 
325
 
 
326
  ndbout << "  Time before sleep = " << millisec_now << endl;
 
327
  ndbout << "  Time after sleep =  " << millisec_now2 << endl;
 
328
  ndbout << "  Tried to sleep "<<sleeptimes[i]<<" milliseconds." << endl;
 
329
  ndbout << "  Sleep time was " << millisec_now2 -millisec_now <<" milliseconds." << endl;
 
330
 
 
331
  }
 
332
 
 
333
  ndbout << "TEST4 completed" << endl;
 
334
 
 
335
  ndbout << "= TEST5 ===============================" << endl;
 
336
  // Check NdbOut
 
337
 
 
338
  ndbout << "Testing hex and dec functions of NdbOut" << endl;
 
339
 
 
340
  for (int i = 0; i<= 0xFF; i++)
 
341
    {
 
342
      ndbout << i << "=" <<hex << i << "="<<dec << i << ", ";
 
343
    }
 
344
 
 
345
  ndbout << endl<< "Testing that hex is reset to dec by endl" << endl;
 
346
  ndbout << hex << 67 << endl;
 
347
  ndbout << 67 << endl;
 
348
  
 
349
  ndbout << "TEST5 completed" << endl;
 
350
 
 
351
 
 
352
  ndbout << "= TEST6 ===============================" << endl;
 
353
  const char* theEnvHostNamePtr;
 
354
  char buf[255];
 
355
  char theHostHostName[256];
 
356
  theEnvHostNamePtr = NdbEnv_GetEnv("HOSTNAME", buf, 255);
 
357
  if(theEnvHostNamePtr == NULL)
 
358
    fail("TEST6", "Could not get HOSTNAME from env");
 
359
  else{
 
360
    ndbout << "HOSTNAME from GetEnv" <<  theEnvHostNamePtr << endl;
 
361
 
 
362
    NdbHost_GetHostName(theHostHostName);
 
363
  
 
364
    ndbout << "HOSTNAME from GetHostName" <<theHostHostName << endl;
 
365
 
 
366
    if (strcmp(theEnvHostNamePtr, theHostHostName) != 0)
 
367
      fail("TEST6", "NdbHost_GetHostName or NdbEnv_GetEnv failed");
 
368
  }
 
369
 
 
370
  ndbout << "= TEST7 ===============================" << endl;
 
371
 
 
372
  testmutex = NdbMutex_Create();
 
373
  testcond = NdbCondition_Create();
 
374
  testthreadsdone = 0;
 
375
  
 
376
  for (int i = 0; i < T3_THREADS; i++)
 
377
    {
 
378
      t3args[i] = i;
 
379
      t3threads[i] = NdbThread_Create(testfunc, // Function 
 
380
                                      (void**)&t3args[i],// Arg
 
381
                                      2048,        // Stacksize
 
382
                                      (char*)"test7thread",  // Thread name
 
383
                                      NDB_THREAD_PRIO_MEAN); // Thread priority
 
384
    }
 
385
 
 
386
  ndbout << "All threads created" << endl;
 
387
 
 
388
  if (NdbMutex_Lock(testmutex) != 0)
 
389
    fail("TEST7", "NdbMutex_Lock failed");
 
390
 
 
391
  while (testthreadsdone < T3_THREADS*10)
 
392
    {
 
393
      // just testing the functionality without timing out, therefor 20 sec.
 
394
      if(NdbCondition_WaitTimeout(testcond, testmutex, 20000) != 0)
 
395
        fail("TEST7", "NdbCondition_WaitTimeout failed");
 
396
      ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
 
397
    }
 
398
  if (NdbMutex_Unlock(testmutex) != 0)
 
399
    fail("TEST7", "NdbMutex_Unlock failed");
 
400
 
 
401
  for (int i = 0; i < T3_THREADS; i++)
 
402
  {
 
403
    if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
 
404
      fail("TEST7", "NdbThread_WaitFor failed");
 
405
 
 
406
    NdbThread_Destroy(&t3threads[i]);
 
407
  }
 
408
 
 
409
  NdbMutex_Destroy(testmutex);
 
410
  NdbCondition_Destroy(testcond);
 
411
 
 
412
  ndbout << "TEST7 completed" << endl;
 
413
 
 
414
 
 
415
  ndbout << "= TEST8 ===============================" << endl;
 
416
  ndbout << "         NdbCondition_WaitTimeout" << endl;
 
417
  testmutex = NdbMutex_Create();
 
418
  testcond = NdbCondition_Create();
 
419
 
 
420
  for (int i = 0; i < 5; i++)
 
421
  {
 
422
    ndbout << "*------------------------------- Measure" << i << endl;
 
423
 
 
424
  NDB_TICKS millisec_now; 
 
425
  NDB_TICKS millisec_now2;
 
426
 
 
427
  millisec_now = NdbTick_CurrentMillisecond();
 
428
  if (NdbCondition_WaitTimeout(testcond, testmutex, sleeptimes[i]) != 0)
 
429
    fail("TEST8", "NdbCondition_WaitTimeout failed");
 
430
  millisec_now2 = NdbTick_CurrentMillisecond();
 
431
 
 
432
  ndbout << "  Time before WaitTimeout = " << millisec_now << endl;
 
433
  ndbout << "  Time after WaitTimeout =  " << millisec_now2 << endl;
 
434
  ndbout << "  Tried to wait "<<sleeptimes[i]<<" milliseconds." << endl;
 
435
  ndbout << "  Wait time was " << millisec_now2 -millisec_now <<" milliseconds." << endl;
 
436
 
 
437
  }
 
438
 
 
439
  ndbout << "TEST8 completed" << endl;
 
440
 
 
441
 
 
442
  ndbout << "= TEST9 ===============================" << endl;
 
443
  ndbout << "         NdbTick_CurrentXXXXXsecond compare" << endl;
 
444
 
 
445
  for (int i = 0; i < 5; i++)
 
446
  {
 
447
    ndbout << "*------------------------------- Measure" << i << endl;
 
448
 
 
449
  NDB_TICKS millisec_now; 
 
450
  NDB_TICKS millisec_now2;
 
451
  Uint32 usec_now, usec_now2;
 
452
  Uint64 msec_now, msec_now2;
 
453
 
 
454
 
 
455
  millisec_now = NdbTick_CurrentMillisecond();
 
456
  NdbTick_CurrentMicrosecond( &msec_now, &usec_now);
 
457
 
 
458
  NdbSleep_MilliSleep(sleeptimes[i]);
 
459
 
 
460
  millisec_now2 = NdbTick_CurrentMillisecond();
 
461
  NdbTick_CurrentMicrosecond( &msec_now2, &usec_now2);
 
462
 
 
463
  Uint64 usecdiff = time_diff(msec_now,msec_now2,usec_now,usec_now2);
 
464
  NDB_TICKS msecdiff = millisec_now2 -millisec_now;
 
465
 
 
466
  ndbout << "     Slept "<<sleeptimes[i]<<" milliseconds." << endl;
 
467
  ndbout << "  Measured " << msecdiff <<" milliseconds with milli function ." << endl;
 
468
  ndbout << "  Measured " << usecdiff/1000 << "," << usecdiff%1000<<" milliseconds with micro function ." << endl;
 
469
  }
 
470
 
 
471
  ndbout << "TEST9 completed" << endl;
 
472
 
 
473
 
 
474
  const int iter = 20;
 
475
  ndbout << "Testing microsecond timer - " << iter << " iterations" << endl;
 
476
  testMicros(iter);
 
477
  ndbout << "Testing microsecond timer - COMPLETED" << endl;
 
478
 
 
479
  ndbout << "= TEST10 ===============================" << endl;
 
480
 
 
481
  testmutex = NdbMutex_Create();
 
482
  testcond = NdbCondition_Create();
 
483
  testthreadsdone = 0;
 
484
  
 
485
  for (int i = 0; i < T3_THREADS; i++)
 
486
    {
 
487
      t3args[i] = i;
 
488
      t3threads[i] = NdbThread_Create(testTryLockfunc, // Function 
 
489
                                      (void**)&t3args[i],// Arg
 
490
                                      2048,        // Stacksize
 
491
                                      (char*)"test10thread",  // Thread name
 
492
                                      NDB_THREAD_PRIO_MEAN); // Thread priority
 
493
    }
 
494
 
 
495
  ndbout << "All threads created" << endl;
 
496
 
 
497
  if (NdbMutex_Lock(testmutex) != 0)
 
498
    fail("TEST10", "NdbMutex_Lock failed");
 
499
 
 
500
  while (testthreadsdone < T3_THREADS*10)
 
501
    {
 
502
      if(NdbCondition_Wait(testcond, testmutex) != 0)
 
503
        fail("TEST10", "NdbCondition_WaitTimeout failed");
 
504
      ndbout << "Condition signaled, there are " << testthreadsdone << " completed threads" << endl;
 
505
    }
 
506
  if (NdbMutex_Unlock(testmutex) != 0)
 
507
    fail("TEST10", "NdbMutex_Unlock failed");
 
508
 
 
509
  for (int i = 0; i < T3_THREADS; i++)
 
510
  {
 
511
    if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
 
512
      fail("TEST10", "NdbThread_WaitFor failed");
 
513
 
 
514
    NdbThread_Destroy(&t3threads[i]);
 
515
  }
 
516
 
 
517
  NdbMutex_Destroy(testmutex);
 
518
  NdbCondition_Destroy(testcond);
 
519
 
 
520
  ndbout << "TEST10 completed" << endl;
 
521
 
 
522
 
 
523
  // Check total status of test
 
524
 
 
525
  if (TestHasFailed == 1)
 
526
    ndbout << endl << "TEST FAILED!" << endl;
 
527
  else
 
528
    ndbout << endl << "TEST PASSED!" << endl;
 
529
 
 
530
  return TestHasFailed;
 
531
 
 
532
};
 
533
 
 
534
Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2){
 
535
 
 
536
  Uint64 diff = 0;
 
537
  diff += (s2 - s1) * 1000000;
 
538
  if(m2 >= m1)
 
539
    diff += (m2 - m1);
 
540
  else {
 
541
    diff += m2;
 
542
    diff -= m1;
 
543
  }
 
544
 
 
545
  //  if(0)
 
546
  // ndbout("(s1,m1) = (%d, %d) (s2,m2) = (%d, %d) -> diff = %d\n",
 
547
  //   (Uint32)s1,m1,(Uint32)s2,m2, (Uint32)diff);
 
548
  
 
549
  return diff;
 
550
};
 
551
 
 
552
void 
 
553
testMicros(int count){
 
554
  Uint32 avg = 0;
 
555
  Uint32 sum2 = 0;
 
556
 
 
557
  for(int i = 0; i<count; i++){
 
558
    Uint64 s1, s2;
 
559
    Uint32 m1, m2;
 
560
    if(NdbTick_CurrentMicrosecond(&s1, &m1) != 0){
 
561
      ndbout << "Failed to get current micro" << endl;
 
562
      TestHasFailed = 1; 
 
563
      return;
 
564
    }
 
565
    Uint32 r = (rand() % 1000) + 1;
 
566
    NdbSleep_MilliSleep(r);
 
567
    if(NdbTick_CurrentMicrosecond(&s2, &m2) != 0){
 
568
      ndbout << "Failed to get current micro" << endl;
 
569
      TestHasFailed = 1; 
 
570
      return;
 
571
    }
 
572
    Uint64 m = time_diff(s1,s2,m1,m2);
 
573
    if(verbose)
 
574
      ndbout << "Slept for " << r << " ms" 
 
575
             << " - Measured  " << m << " us" << endl;
 
576
    
 
577
    if(m > (r*1000)){
 
578
      avg += (m - (r*1000));
 
579
      sum2 += (m - (r*1000)) * (m - (r*1000));
 
580
    } else {
 
581
      avg += ((r*1000) - m);
 
582
      sum2 += ((r*1000) - m) * ((r*1000) - m);
 
583
    }
 
584
#if 0
 
585
    m /= 1000;
 
586
    if(m > r && ((m - r) > 10)){
 
587
      ndbout << "Difference to big: " << (m - r) << " - Test failed" << endl;
 
588
      TestHasFailed = 1;
 
589
    }
 
590
    if(m < r && ((r - m) > 10)){
 
591
      ndbout << "Difference to big: " << (r - m) << " - Test failed" << endl;
 
592
      TestHasFailed = 1;
 
593
    }
 
594
#endif
 
595
  }
 
596
 
 
597
  Uint32 dev = (avg * avg - sum2) / count; dev /= count;
 
598
  avg /= count;
 
599
 
 
600
  Uint32 t = 0;
 
601
  while((t*t)<dev) t++;
 
602
  ndbout << "NOTE - measure are compared to NdbSleep_MilliSleep(...)" << endl;
 
603
  ndbout << "Average error = " << avg << " us" << endl;
 
604
  ndbout << "Stddev  error = " << t << " us" << endl;
 
605
}