25 #include <ndb_global.h>
28 #include "NdbThread.h"
30 #include "NdbCondition.h"
40 static void fail(
const char*
test,
const char* cause)
43 ndbout << test <<
" failed, " << cause << endl;
48 extern "C" void* thread1func(
void* arg)
53 ndbout <<
"thread1: thread1func called with arg = " << arg1 << endl;
57 fail(
"TEST1",
"Wrong arg");
59 return (
void*) returnvalue;
66 extern "C" void* test2func(
void* arg)
71 ndbout <<
"thread" << arg1 <<
" started in test2func" << endl;
73 if (NdbMutex_Lock(test2mutex) != 0)
74 fail(
"TEST2",
"Failed to lock mutex");
76 ndbout <<
"thread" << arg1 <<
", test2func " << endl;
78 if (NdbMutex_Unlock(test2mutex) != 0)
79 fail(
"TEST2",
"Failed to unlock mutex");
81 int returnvalue = arg1;
82 return (
void*) returnvalue;
92 extern "C" void* testfunc(
void* arg)
98 threadno = *(
int*)arg;
100 ndbout <<
"Thread" << threadno <<
" started in testfunc" << endl;
104 if ((threadno % 2) == 0)
105 result = NdbSleep_SecSleep(1);
107 result = NdbSleep_MilliSleep(100);
110 fail(
"TEST3",
"Wrong result from sleep function");
112 if (NdbMutex_Lock(testmutex) != 0)
113 fail(
"TEST3",
"Wrong result from NdbMutex_Lock function");
115 ndbout <<
"thread" << threadno <<
", testfunc " << endl;
117 tmpVar = testthreadsdone;
119 if (NdbCondition_Signal(testcond) != 0)
120 fail(
"TEST3",
"Wrong result from NdbCondition_Signal function");
122 if (NdbMutex_Unlock(testmutex) != 0)
123 fail(
"TEST3",
"Wrong result from NdbMutex_Unlock function");
131 extern "C" void* testTryLockfunc(
void* arg)
137 threadno = *(
int*)arg;
139 ndbout <<
"Thread" << threadno <<
" started" << endl;
143 if ((threadno % 2) == 0)
144 result = NdbSleep_SecSleep(1);
146 result = NdbSleep_MilliSleep(100);
149 fail(
"TEST3",
"Wrong result from sleep function");
151 if (NdbMutex_Trylock(testmutex) == 0){
153 ndbout <<
"thread" << threadno <<
", testTryLockfunc locked" << endl;
155 tmpVar = testthreadsdone;
157 if (NdbCondition_Signal(testcond) != 0)
158 fail(
"TEST3",
"Wrong result from NdbCondition_Signal function");
160 if (NdbMutex_Unlock(testmutex) != 0)
161 fail(
"TEST3",
"Wrong result from NdbMutex_Unlock function");
172 void testMicros(
int count);
173 Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2);
175 NDB_COMMAND(PortLibTest,
"portlibtest",
"portlibtest",
"Test the portable function layer", 4096){
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;
182 ndbout << endl << endl;
191 ndbout <<
"= TEST1 ===============================" << endl;
193 thread1var = NdbThread_Create(thread1func,
197 NDB_THREAD_PRIO_MEAN);
200 if(NdbThread_WaitFor(thread1var, &status) != 0)
201 fail(
"TEST1",
"NdbThread_WaitFor failed");
206 ndbout <<
"TEST1 completed" << endl;
209 NdbThread_Destroy(&thread1var);
212 ndbout <<
"= TEST2 ===============================" << endl;
213 #define T2_THREADS 10
215 int args[T2_THREADS];
217 test2mutex = NdbMutex_Create();
218 NdbMutex_Lock(test2mutex);
220 for (
int i = 0;
i < T2_THREADS;
i++)
223 threads[
i] = NdbThread_Create(test2func,
226 (
char*)
"test2thread",
227 NDB_THREAD_PRIO_MEAN);
228 if (threads[i] == NULL)
229 fail(
"TEST2",
"NdbThread_Create failed");
232 ndbout <<
"All threads created" << endl;
234 NdbMutex_Unlock(test2mutex);
236 for (
int i = 0; i < T2_THREADS; i++)
238 if (NdbThread_WaitFor(threads[i], &status2))
239 fail(
"TEST2",
"NdbThread_WaitFor failed");
241 NdbThread_Destroy(&threads[i]);
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;
256 ndbout <<
"= TEST3 ===============================" << endl;
259 #define T3_THREADS 10
261 int t3args[T3_THREADS];
264 testmutex = NdbMutex_Create();
265 testcond = NdbCondition_Create();
268 for (
int i = 0; i < T3_THREADS; i++)
271 t3threads[
i] = NdbThread_Create(testfunc,
274 (
char*)
"test3thread",
275 NDB_THREAD_PRIO_MEAN);
278 ndbout <<
"All threads created" << endl;
280 if (NdbMutex_Lock(testmutex) != 0)
281 fail(
"TEST3",
"NdbMutex_Lock failed");
283 while (testthreadsdone < T3_THREADS*10)
285 if(NdbCondition_Wait(testcond, testmutex) != 0)
286 fail(
"TEST3",
"NdbCondition_Wait failed");
287 ndbout <<
"Condition signaled, there are " << testthreadsdone <<
" completed threads" << endl;
289 if (NdbMutex_Unlock(testmutex) != 0)
290 fail(
"TEST3",
"NdbMutex_Unlock failed");
292 for (
int i = 0; i < T3_THREADS; i++)
294 if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
295 fail(
"TEST3",
"NdbThread_WaitFor failed");
297 NdbThread_Destroy(&t3threads[i]);
303 NdbMutex_Destroy(testmutex);
304 NdbCondition_Destroy(testcond);
305 ndbout <<
"TEST3 completed" << endl;
307 ndbout <<
"= TEST4 ===============================" << endl;
312 int sleeptimes[] = {78, 12, 199, 567, 899};
315 for (
int i = 0; i < 5; i++)
317 ndbout <<
"*------------------------------- Measure" << i << endl;
319 NDB_TICKS millisec_now;
320 NDB_TICKS millisec_now2;
322 millisec_now = NdbTick_CurrentMillisecond();
323 NdbSleep_MilliSleep(sleeptimes[i]);
324 millisec_now2 = NdbTick_CurrentMillisecond();
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;
333 ndbout <<
"TEST4 completed" << endl;
335 ndbout <<
"= TEST5 ===============================" << endl;
338 ndbout <<
"Testing hex and dec functions of NdbOut" << endl;
340 for (
int i = 0; i<= 0xFF; i++)
342 ndbout << i <<
"=" <<hex << i <<
"="<<dec << i <<
", ";
345 ndbout << endl<<
"Testing that hex is reset to dec by endl" << endl;
346 ndbout << hex << 67 << endl;
347 ndbout << 67 << endl;
349 ndbout <<
"TEST5 completed" << endl;
352 ndbout <<
"= TEST6 ===============================" << endl;
353 const char* theEnvHostNamePtr;
355 char theHostHostName[256];
356 theEnvHostNamePtr = NdbEnv_GetEnv(
"HOSTNAME", buf, 255);
357 if(theEnvHostNamePtr == NULL)
358 fail(
"TEST6",
"Could not get HOSTNAME from env");
360 ndbout <<
"HOSTNAME from GetEnv" << theEnvHostNamePtr << endl;
362 NdbHost_GetHostName(theHostHostName);
364 ndbout <<
"HOSTNAME from GetHostName" <<theHostHostName << endl;
366 if (strcmp(theEnvHostNamePtr, theHostHostName) != 0)
367 fail(
"TEST6",
"NdbHost_GetHostName or NdbEnv_GetEnv failed");
370 ndbout <<
"= TEST7 ===============================" << endl;
372 testmutex = NdbMutex_Create();
373 testcond = NdbCondition_Create();
376 for (
int i = 0; i < T3_THREADS; i++)
379 t3threads[
i] = NdbThread_Create(testfunc,
382 (
char*)
"test7thread",
383 NDB_THREAD_PRIO_MEAN);
386 ndbout <<
"All threads created" << endl;
388 if (NdbMutex_Lock(testmutex) != 0)
389 fail(
"TEST7",
"NdbMutex_Lock failed");
391 while (testthreadsdone < T3_THREADS*10)
394 if(NdbCondition_WaitTimeout(testcond, testmutex, 20000) != 0)
395 fail(
"TEST7",
"NdbCondition_WaitTimeout failed");
396 ndbout <<
"Condition signaled, there are " << testthreadsdone <<
" completed threads" << endl;
398 if (NdbMutex_Unlock(testmutex) != 0)
399 fail(
"TEST7",
"NdbMutex_Unlock failed");
401 for (
int i = 0; i < T3_THREADS; i++)
403 if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
404 fail(
"TEST7",
"NdbThread_WaitFor failed");
406 NdbThread_Destroy(&t3threads[i]);
409 NdbMutex_Destroy(testmutex);
410 NdbCondition_Destroy(testcond);
412 ndbout <<
"TEST7 completed" << endl;
415 ndbout <<
"= TEST8 ===============================" << endl;
416 ndbout <<
" NdbCondition_WaitTimeout" << endl;
417 testmutex = NdbMutex_Create();
418 testcond = NdbCondition_Create();
420 for (
int i = 0; i < 5; i++)
422 ndbout <<
"*------------------------------- Measure" << i << endl;
424 NDB_TICKS millisec_now;
425 NDB_TICKS millisec_now2;
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();
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;
439 ndbout <<
"TEST8 completed" << endl;
442 ndbout <<
"= TEST9 ===============================" << endl;
443 ndbout <<
" NdbTick_CurrentXXXXXsecond compare" << endl;
445 for (
int i = 0; i < 5; i++)
447 ndbout <<
"*------------------------------- Measure" << i << endl;
449 NDB_TICKS millisec_now;
450 NDB_TICKS millisec_now2;
451 Uint32 usec_now, usec_now2;
452 Uint64 msec_now, msec_now2;
455 millisec_now = NdbTick_CurrentMillisecond();
456 NdbTick_CurrentMicrosecond( &msec_now, &usec_now);
458 NdbSleep_MilliSleep(sleeptimes[i]);
460 millisec_now2 = NdbTick_CurrentMillisecond();
461 NdbTick_CurrentMicrosecond( &msec_now2, &usec_now2);
463 Uint64 usecdiff = time_diff(msec_now,msec_now2,usec_now,usec_now2);
464 NDB_TICKS msecdiff = millisec_now2 -millisec_now;
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;
471 ndbout <<
"TEST9 completed" << endl;
475 ndbout <<
"Testing microsecond timer - " << iter <<
" iterations" << endl;
477 ndbout <<
"Testing microsecond timer - COMPLETED" << endl;
479 ndbout <<
"= TEST10 ===============================" << endl;
481 testmutex = NdbMutex_Create();
482 testcond = NdbCondition_Create();
485 for (
int i = 0; i < T3_THREADS; i++)
488 t3threads[
i] = NdbThread_Create(testTryLockfunc,
491 (
char*)
"test10thread",
492 NDB_THREAD_PRIO_MEAN);
495 ndbout <<
"All threads created" << endl;
497 if (NdbMutex_Lock(testmutex) != 0)
498 fail(
"TEST10",
"NdbMutex_Lock failed");
500 while (testthreadsdone < T3_THREADS*10)
502 if(NdbCondition_Wait(testcond, testmutex) != 0)
503 fail(
"TEST10",
"NdbCondition_WaitTimeout failed");
504 ndbout <<
"Condition signaled, there are " << testthreadsdone <<
" completed threads" << endl;
506 if (NdbMutex_Unlock(testmutex) != 0)
507 fail(
"TEST10",
"NdbMutex_Unlock failed");
509 for (
int i = 0; i < T3_THREADS; i++)
511 if (NdbThread_WaitFor(t3threads[i], &status3) != 0)
512 fail(
"TEST10",
"NdbThread_WaitFor failed");
514 NdbThread_Destroy(&t3threads[i]);
517 NdbMutex_Destroy(testmutex);
518 NdbCondition_Destroy(testcond);
520 ndbout <<
"TEST10 completed" << endl;
525 if (TestHasFailed == 1)
526 ndbout << endl <<
"TEST FAILED!" << endl;
528 ndbout << endl <<
"TEST PASSED!" << endl;
530 return TestHasFailed;
534 Uint64 time_diff(Uint64 s1, Uint64 s2, Uint32 m1, Uint32 m2){
537 diff += (s2 - s1) * 1000000;
553 testMicros(
int count){
557 for(
int i = 0; i<count; i++){
560 if(NdbTick_CurrentMicrosecond(&s1, &m1) != 0){
561 ndbout <<
"Failed to get current micro" << endl;
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;
572 Uint64 m = time_diff(s1,s2,m1,m2);
574 ndbout <<
"Slept for " << r <<
" ms"
575 <<
" - Measured " << m <<
" us" << endl;
578 avg += (m - (r*1000));
579 sum2 += (m - (r*1000)) * (m - (r*1000));
581 avg += ((r*1000) - m);
582 sum2 += ((r*1000) - m) * ((r*1000) - m);
586 if(m > r && ((m - r) > 10)){
587 ndbout <<
"Difference to big: " << (m - r) <<
" - Test failed" << endl;
590 if(m < r && ((r - m) > 10)){
591 ndbout <<
"Difference to big: " << (r - m) <<
" - Test failed" << endl;
597 Uint32 dev = (avg * avg - sum2) / count; dev /= count;
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;