1
/************************************************************************
2
The test module for the syncronization primitives
6
Created 9/9/1995 Heikki Tuuri
7
*************************************************************************/
10
#include "../sync0sync.h"
11
#include "../sync0rw.h"
12
#include "../sync0arr.h"
13
#include "../sync0ipm.h"
17
#include "os0thread.h"
60
/********************************************************************
61
Start function for thread 1 in test1. */
71
printf("Thread1 started!\n");
75
printf("Thread1 owns now the mutex!\n");
79
for (i = 1; i < 1000000; i++) {
83
printf("Thread1 releases now the mutex!\n");
90
/********************************************************************
91
Start function for thread 2 in test1. */
101
printf("Thread2 started!\n");
105
printf("Thread2 owns now the mutex!\n");
109
for (i = 1; i < 1000000; i++) {
113
printf("Thread2 releases now the mutex!\n");
120
/********************************************************************
121
Start function for the competing threads in test2. The function tests
122
the behavior lock-coupling through 4 mutexes. */
125
thread_n(volatile void* arg)
126
/*========================*/
132
printf("Thread %ld started!\n", n);
134
for (k = 0; k < 2000 * UNIV_DBC; k++) {
136
mutex_enter(&mutex1);
145
for (i = 1; i < 400; i++) {
149
mutex_enter(&mutex2);
153
for (i = 1; i < 400; i++) {
156
mutex_enter(&mutex3);
160
for (i = 1; i < 400; i++) {
163
mutex_enter(&mutex4);
167
for (i = 1; i < 400; i++) {
174
printf("Thread %ld exits!\n", n);
179
/********************************************************************
180
Start function for mutex exclusion checking in test3. */
191
printf("Starting thread!\n");
193
for (k = 0; k < 200000 * UNIV_DBC; k++) {
197
glob_count += glob_inc;
203
printf("Exiting thread!\n");
214
os_thread_t thr1, thr2;
215
os_thread_id_t id1, id2;
220
printf("-------------------------------------------\n");
221
printf("SYNC-TEST 1. Test of mutexes.\n");
224
printf("Main thread %ld starts!\n",
225
os_thread_get_curr_id());
227
osm = os_mutex_create(NULL);
235
mutex_create(&mutex);
241
for (i = 0; i < 1000000; i++) {
242
id1 = os_thread_get_curr_id();
246
printf("Wall clock time for %ld thread_get_id %ld milliseconds\n",
252
for (i = 0; i < 100000 * UNIV_DBC; i++) {
259
printf("Wall clock time for %ld mutex lock-unlock %ld milliseconds\n",
264
for (i = 0; i < 1000000; i++) {
270
printf("Wall clock time for %ld fences %ld milliseconds\n",
275
mutex_list_print_info();
277
ut_ad(1 == mutex_n_reserved());
278
ut_ad(FALSE == sync_all_freed());
280
thr1 = os_thread_create(thread1,
284
printf("Thread1 created, id %ld \n", id1);
286
thr2 = os_thread_create(thread2,
290
printf("Thread2 created, id %ld \n", id2);
295
for (i = 1; i < 20000000; i++) {
301
sync_array_validate(sync_primary_wait_array);
303
printf("Main thread releases now mutex!\n");
307
os_thread_wait(thr2);
309
os_thread_wait(thr1);
312
/******************************************************************
313
Test function for possible convoy problem. */
319
os_thread_t thr1, thr2, thr3, thr4, thr5;
320
os_thread_id_t id1, id2, id3, id4, id5;
322
ulint n1, n2, n3, n4, n5;
324
printf("-------------------------------------------\n");
325
printf("SYNC-TEST 2. Test of possible convoy problem.\n");
327
printf("System call count %lu\n", mutex_system_call_count);
329
mutex_create(&mutex1);
330
mutex_create(&mutex2);
331
mutex_create(&mutex3);
332
mutex_create(&mutex4);
340
thr1 = os_thread_create(thread_n,
344
os_thread_wait(thr1);
348
printf("Wall clock time for single thread %ld milliseconds\n",
350
printf("System call count %lu\n", mutex_system_call_count);
357
thr1 = os_thread_create(thread_n,
361
thr2 = os_thread_create(thread_n,
365
thr3 = os_thread_create(thread_n,
369
thr4 = os_thread_create(thread_n,
373
thr5 = os_thread_create(thread_n,
378
os_thread_wait(thr1);
379
os_thread_wait(thr2);
380
os_thread_wait(thr3);
381
os_thread_wait(thr4);
382
os_thread_wait(thr5);
386
printf("Wall clock time for 5 threads %ld milliseconds\n",
388
printf("%ld thread switches occurred\n", switch_count);
390
printf("If this is not 5 x single thread time, possibly convoy!\n");
392
printf("System call count %lu\n", mutex_system_call_count);
395
/******************************************************************
396
Test function for possible exclusion failure. */
402
os_thread_t thr1, thr2;
403
os_thread_id_t id1, id2;
405
printf("-------------------------------------------\n");
406
printf("SYNC-TEST 3. Test of possible exclusion failure.\n");
411
thr1 = os_thread_create(thread_x,
414
thr2 = os_thread_create(thread_x,
418
os_thread_wait(thr2);
419
os_thread_wait(thr1);
421
ut_a(glob_count == 400000 * UNIV_DBC);
424
/******************************************************************
425
Test function for measuring the spin wait loop cycle time. */
434
printf("-------------------------------------------\n");
435
printf("SYNC-TEST 4. Test of spin wait loop cycle time.\n");
436
printf("Use this time to set the SYNC_SPIN_ROUNDS constant.\n");
447
while ((*ptr != 0) && (i < 10000000)) {
452
printf("Wall clock time for %ld cycles %ld milliseconds\n",
456
/********************************************************************
457
Start function for s-lock thread in test5. */
459
thread_srw(void* arg)
467
printf("Thread_srw started!\n");
469
rw_lock_s_lock(&rw1);
471
printf("Thread_srw has now s-lock!\n");
475
for (i = 1; i < 1000000; i++) {
479
printf("Thread_srw releases now the s-lock!\n");
481
rw_lock_s_unlock(&rw1);
486
/********************************************************************
487
Start function for x-lock thread in test5. */
489
thread_xrw(void* arg)
497
printf("Thread_xrw started!\n");
499
rw_lock_x_lock(&rw1);
501
printf("Thread_xrw has now x-lock!\n");
505
for (i = 1; i < 1000000; i++) {
509
printf("Thread_xrw releases now the x-lock!\n");
511
rw_lock_x_unlock(&rw1);
521
os_thread_t thr1, thr2;
522
os_thread_id_t id1, id2;
526
printf("-------------------------------------------\n");
527
printf("SYNC-TEST 5. Test of read-write locks.\n");
530
printf("Main thread %ld starts!\n",
531
os_thread_get_curr_id());
534
rw_lock_create(&rw1);
539
for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) {
541
rw_lock_s_lock(&rw1);
543
rw_lock_s_unlock(&rw1);
548
printf("Wall clock time for %ld rw s-lock-unlock %ld milliseconds\n",
555
for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) {
567
printf("Wall clock time for %ld rw test %ld milliseconds\n",
574
for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) {
576
rw_lock_x_lock(&rw1);
577
rw_lock_x_unlock(&rw1);
582
printf("Wall clock time for %ld rw x-lock-unlock %ld milliseconds\n",
586
/* Test recursive x-locking */
587
for (i = 0; i < 10000; i++) {
588
rw_lock_x_lock(&rw1);
591
for (i = 0; i < 10000; i++) {
593
rw_lock_x_unlock(&rw1);
596
/* Test recursive s-locking */
597
for (i = 0; i < 10000; i++) {
599
rw_lock_s_lock(&rw1);
602
for (i = 0; i < 10000; i++) {
604
rw_lock_s_unlock(&rw1);
607
rw_lock_s_lock(&rw1);
609
ut_ad(1 == rw_lock_n_locked());
613
rw_lock_list_print_info();
615
thr2 = os_thread_create(thread_xrw,
619
printf("Thread_xrw created, id %ld \n", id2);
622
thr1 = os_thread_create(thread_srw,
626
printf("Thread_srw created, id %ld \n", id1);
630
for (i = 1; i < 10000000; i++) {
634
rw_lock_list_print_info();
636
sync_array_validate(sync_primary_wait_array);
638
printf("Main thread releases now rw-lock!\n");
640
rw_lock_s_unlock(&rw1);
642
os_thread_wait(thr2);
644
os_thread_wait(thr1);
646
sync_array_print_info(sync_primary_wait_array);
649
/********************************************************************
650
Start function for the competing s-threads in test6. The function tests
651
the behavior lock-coupling through 4 rw-locks. */
654
thread_qs(volatile void* arg)
655
/*========================*/
661
n = os_thread_get_curr_id();
663
printf("S-Thread %ld started, thread id %lu\n", n,
664
os_thread_get_curr_id());
666
for (k = 0; k < 1000 * UNIV_DBC; k++) {
669
printf("S-Thread %ld starts round %ld!\n", n, k);
671
rw_lock_s_lock(&rw1);
674
printf("S-Thread %ld got lock 1 on round %ld!\n", n, k);
684
for (i = 1; i < 400; i++) {
688
rw_lock_s_lock(&rw2);
691
printf("S-Thread %ld got lock 2 on round %ld!\n", n, k);
694
rw_lock_s_unlock(&rw1);
697
printf("S-Thread %ld released lock 1 on round %ld!\n", n, k);
700
for (i = 1; i < 400; i++) {
703
rw_lock_s_lock(&rw3);
706
printf("S-Thread %ld got lock 3 on round %ld!\n", n, k);
709
rw_lock_s_unlock(&rw2);
711
printf("S-Thread %ld released lock 2 on round %ld!\n", n, k);
714
for (i = 1; i < 400; i++) {
717
rw_lock_s_lock(&rw4);
720
printf("S-Thread %ld got lock 4 on round %ld!\n", n, k);
723
rw_lock_s_unlock(&rw3);
725
printf("S-Thread %ld released lock 3 on round %ld!\n", n, k);
728
for (i = 1; i < 400; i++) {
732
rw_lock_s_unlock(&rw4);
734
printf("S-Thread %ld released lock 4 on round %ld!\n", n, k);
738
printf("S-Thread %ld exits!\n", n);
743
/********************************************************************
744
Start function for the competing x-threads in test6. The function tests
745
the behavior lock-coupling through 4 rw-locks. */
748
thread_qx(volatile void* arg)
749
/*========================*/
755
n = os_thread_get_curr_id();
757
printf("X-Thread %ld started, thread id %lu\n", n,
758
os_thread_get_curr_id());
760
for (k = 0; k < 1000 * UNIV_DBC; k++) {
763
printf("X-Thread %ld round %ld!\n", n, k);
766
rw_lock_x_lock(&rw1);
768
printf("X-Thread %ld got lock 1 on round %ld!\n", n, k);
778
for (i = 1; i < 400; i++) {
782
rw_lock_x_lock(&rw2);
784
printf("X-Thread %ld got lock 2 on round %ld!\n", n, k);
787
rw_lock_x_unlock(&rw1);
789
printf("X-Thread %ld released lock 1 on round %ld!\n", n, k);
792
for (i = 1; i < 400; i++) {
795
rw_lock_x_lock(&rw3);
797
printf("X-Thread %ld got lock 3 on round %ld!\n", n, k);
800
rw_lock_x_unlock(&rw2);
802
printf("X-Thread %ld released lock 2 on round %ld!\n", n, k);
805
for (i = 1; i < 400; i++) {
808
rw_lock_x_lock(&rw4);
810
printf("X-Thread %ld got lock 4 on round %ld!\n", n, k);
812
rw_lock_x_unlock(&rw3);
814
printf("X-Thread %ld released lock 3 on round %ld!\n", n, k);
817
for (i = 1; i < 400; i++) {
821
rw_lock_x_unlock(&rw4);
823
printf("X-Thread %ld released lock 4 on round %ld!\n", n, k);
827
printf("X-Thread %ld exits!\n", n);
832
/******************************************************************
833
Test function for possible queuing problems with rw-locks. */
839
os_thread_t thr1, thr2, thr3, thr4, thr5;
840
os_thread_id_t id1, id2, id3, id4, id5;
842
ulint n1, n2, n3, n4, n5;
844
printf("-------------------------------------------\n");
846
"SYNC-TEST 6. Test of possible queuing problems with rw-locks.\n");
848
sync_array_print_info(sync_primary_wait_array);
851
rw_lock_create(&rw2);
852
rw_lock_create(&rw3);
853
rw_lock_create(&rw4);
862
thr1 = os_thread_create(thread_qs,
866
os_thread_wait(thr1);
870
printf("Wall clock time for single s-lock thread %ld milliseconds\n",
877
thr1 = os_thread_create(thread_qx,
881
os_thread_wait(thr1);
885
printf("Wall clock time for single x-lock thread %ld milliseconds\n",
894
thr1 = os_thread_create(thread_qx,
899
thr2 = os_thread_create(thread_qs,
904
thr3 = os_thread_create(thread_qx,
910
thr4 = os_thread_create(thread_qs,
915
thr5 = os_thread_create(thread_qx,
919
os_thread_wait(thr1);
921
os_thread_wait(thr2);
923
os_thread_wait(thr3);
925
os_thread_wait(thr4);
927
os_thread_wait(thr5);
931
printf("Wall clock time for 5 threads %ld milliseconds\n",
933
printf("at least %ld thread switches occurred\n", switch_count);
936
"If this is not 2 x s-thread + 3 x x-thread time, possibly convoy!\n");
938
rw_lock_list_print_info();
940
sync_array_print_info(sync_primary_wait_array);
944
/********************************************************************
945
Start function for thread in test7. */
957
printf("Thread started!\n");
961
ret = ip_mutex_enter(iph, 100000);
963
/* ut_a(ret == SYNC_TIME_EXCEEDED);
967
printf("Wall clock time for wait failure %ld ms\n", tm - oldtm);
969
ret = ip_mutex_enter(iph, SYNC_INFINITE_TIME);
973
printf("Thread owns now the ip mutex!\n");
977
for (i = 1; i < 1000000; i++) {
981
printf("Thread releases now the ip mutex!\n");
988
/*********************************************************************
989
Test for interprocess mutex. */
999
printf("-------------------------------------------\n");
1000
printf("SYNC-TEST 7. Test of ip mutex.\n");
1003
printf("Main thread %ld starts!\n",
1004
os_thread_get_curr_id());
1006
ip_mutex_create(&ip_mutex, "IPMUTEX", &iph);
1010
for (i = 0; i < 100000 * UNIV_DBC; i++) {
1012
ip_mutex_enter(iph, SYNC_INFINITE_TIME);
1017
printf("Wall clock time for %ld ip mutex lock-unlock %ld ms\n",
1021
ip_mutex_enter(iph, SYNC_INFINITE_TIME);
1023
thr1 = os_thread_create(ip_thread,
1027
printf("Thread created, id %ld \n", id1);
1032
for (i = 1; i < 100000000; i++) {
1036
printf("Main thread releases now ip mutex!\n");
1040
os_thread_wait(thr1);
1045
/********************************************************************
1046
Start function for the competing threads in test8. The function tests
1047
the behavior lock-coupling through 4 ip mutexes. */
1050
thread_ipn(volatile void* arg)
1051
/*========================*/
1057
printf("Thread %ld started!\n", n);
1059
for (k = 0; k < 2000 * UNIV_DBC; k++) {
1061
ip_mutex_enter(iph1, SYNC_INFINITE_TIME);
1063
if (last_thr != n) {
1070
for (i = 1; i < 400; i++) {
1074
ip_mutex_enter(iph2, SYNC_INFINITE_TIME);
1076
ip_mutex_exit(iph1);
1078
for (i = 1; i < 400; i++) {
1081
ip_mutex_enter(iph3, SYNC_INFINITE_TIME);
1083
ip_mutex_exit(iph2);
1085
for (i = 1; i < 400; i++) {
1088
ip_mutex_enter(iph4, SYNC_INFINITE_TIME);
1090
ip_mutex_exit(iph3);
1092
for (i = 1; i < 400; i++) {
1096
ip_mutex_exit(iph4);
1099
printf("Thread %ld exits!\n", n);
1104
/******************************************************************
1105
Test function for ip mutex. */
1111
os_thread_t thr1, thr2, thr3, thr4, thr5;
1112
os_thread_id_t id1, id2, id3, id4, id5;
1114
ulint n1, n2, n3, n4, n5;
1116
printf("-------------------------------------------\n");
1117
printf("SYNC-TEST 8. Test for ip mutex.\n");
1120
ip_mutex_create(&ip_mutex1, "jhfhk", &iph1);
1121
ip_mutex_create(&ip_mutex2, "jggfg", &iph2);
1122
ip_mutex_create(&ip_mutex3, "hfdx", &iph3);
1123
ip_mutex_create(&ip_mutex4, "kjghg", &iph4);
1131
thr1 = os_thread_create(thread_ipn,
1135
os_thread_wait(thr1);
1139
printf("Wall clock time for single thread %lu milliseconds\n",
1147
thr1 = os_thread_create(thread_ipn,
1151
thr2 = os_thread_create(thread_ipn,
1155
thr3 = os_thread_create(thread_ipn,
1159
thr4 = os_thread_create(thread_ipn,
1163
thr5 = os_thread_create(thread_ipn,
1167
os_thread_wait(thr1);
1168
os_thread_wait(thr2);
1169
os_thread_wait(thr3);
1170
os_thread_wait(thr4);
1171
os_thread_wait(thr5);
1175
printf("Wall clock time for 5 threads %ld milliseconds\n",
1177
printf("%ld thread switches occurred\n", switch_count);
1179
printf("If this is not 5 x single thread time, possibly convoy!\n");
1181
ip_mutex_free(iph1);
1182
ip_mutex_free(iph2);
1183
ip_mutex_free(iph3);
1184
ip_mutex_free(iph4);
1188
/********************************************************************
1189
Start function for s-lock thread in test9. */
1191
thread_srw9(void* arg)
1192
/*==================*/
1198
printf("Thread_srw9 started!\n");
1200
rw_lock_x_lock(&rw10);
1202
printf("Thread_srw9 has now x-lock on rw10, wait for mutex!\n");
1204
mutex_enter(&mutex9);
1209
/********************************************************************
1210
Start function for x-lock thread in test9. */
1212
thread_xrw9(void* arg)
1213
/*==================*/
1219
printf("Thread_xrw started!\n");
1221
mutex_enter(&mutex9);
1222
printf("Thread_xrw9 has now mutex9, wait for rw9!\n");
1224
rw_lock_x_lock(&rw9);
1233
os_thread_t thr1, thr2;
1234
os_thread_id_t id1, id2;
1236
printf("-------------------------------------------\n");
1237
printf("SYNC-TEST 9. Test of deadlock detection.\n");
1240
printf("Main thread %ld starts!\n",
1241
os_thread_get_curr_id());
1243
rw_lock_create(&rw9);
1244
rw_lock_create(&rw10);
1245
mutex_create(&mutex9);
1247
rw_lock_s_lock(&rw9);
1248
printf("Main thread has now s-lock on rw9\n");
1250
thr2 = os_thread_create(thread_xrw9,
1254
printf("Thread_xrw9 created, id %ld \n", id2);
1256
os_thread_sleep(1000000);
1258
thr1 = os_thread_create(thread_srw9,
1262
printf("Thread_srw9 created, id %ld \n", id1);
1264
os_thread_sleep(1000000);
1266
sync_array_print_info(sync_primary_wait_array);
1268
printf("Now we should have a deadlock of 3 threads:\n");
1270
rw_lock_s_lock(&rw10);
1277
printf("-------------------------------------------\n");
1278
printf("SYNC-TEST 10. Test of deadlock detection on self-deadlock.\n");
1281
printf("Main thread %ld starts!\n",
1282
os_thread_get_curr_id());
1284
mutex_create(&mutex9);
1286
printf("Now we should have a deadlock of this thread on mutex:\n");
1288
mutex_enter(&mutex9);
1289
mutex_enter(&mutex9);
1296
printf("-------------------------------------------\n");
1297
printf("SYNC-TEST 11. Test of deadlock detection on self-deadlock.\n");
1300
printf("Main thread %ld starts!\n",
1301
os_thread_get_curr_id());
1303
rw_lock_create(&rw9);
1305
printf("Now we should have a deadlock of this thread on X-lock:\n");
1307
rw_lock_x_lock(&rw9);
1308
rw_lock_s_lock_gen(&rw9, 567);
1312
/************************************************************************
1313
Main test function. */
1342
/* This test SHOULD result in assert on deadlock! */
1345
/* This test SHOULD result in assert on deadlock! */
1348
/* This test SHOULD result in assert on deadlock! */
1351
ut_ad(0 == mutex_n_reserved());
1352
ut_ad(0 == rw_lock_n_locked());
1353
ut_ad(sync_all_freed());
1356
ut_ad(mem_all_freed());
1361
printf("Wall clock time for test %ld milliseconds\n", tm - oldtm);
1362
printf("System call count %lu\n", mutex_system_call_count);
1363
printf("TESTS COMPLETED SUCCESSFULLY!\n");