~mysql/mysql-server/mysql-6.0

« back to all changes in this revision

Viewing changes to innobase/sync/ts/tssync.c

  • Committer: monty at mysql
  • Date: 2001-02-17 12:19:19 UTC
  • mto: (554.1.1)
  • mto: This revision was merged to the branch mainline in revision 556.
  • Revision ID: sp1r-monty@donna.mysql.com-20010217121919-07904
Added Innobase to source distribution

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/************************************************************************
 
2
The test module for the syncronization primitives
 
3
 
 
4
(c) 1995 Innobase Oy
 
5
 
 
6
Created 9/9/1995 Heikki Tuuri
 
7
*************************************************************************/
 
8
 
 
9
 
 
10
#include "../sync0sync.h"
 
11
#include "../sync0rw.h"
 
12
#include "../sync0arr.h"
 
13
#include "../sync0ipm.h"
 
14
#include "ut0ut.h"
 
15
#include "mem0mem.h"
 
16
#include "os0sync.h"
 
17
#include "os0thread.h"
 
18
#include "os0sync.h"
 
19
 
 
20
mutex_t mutex;
 
21
mutex_t mutex1;
 
22
mutex_t mutex2;
 
23
mutex_t mutex3;
 
24
mutex_t mutex4;
 
25
 
 
26
ip_mutex_t      ip_mutex;
 
27
 
 
28
ip_mutex_t      ip_mutex1;
 
29
ip_mutex_t      ip_mutex2;
 
30
ip_mutex_t      ip_mutex3;
 
31
ip_mutex_t      ip_mutex4;
 
32
 
 
33
ip_mutex_hdl_t* iph;
 
34
 
 
35
ip_mutex_hdl_t* iph1;
 
36
ip_mutex_hdl_t* iph2;
 
37
ip_mutex_hdl_t* iph3;
 
38
ip_mutex_hdl_t* iph4;
 
39
 
 
40
 
 
41
rw_lock_t       rw1;
 
42
rw_lock_t       rw2;
 
43
rw_lock_t       rw3;
 
44
rw_lock_t       rw4;
 
45
 
 
46
rw_lock_t       rw9;
 
47
rw_lock_t       rw10;
 
48
mutex_t         mutex9;
 
49
 
 
50
os_mutex_t      osm;
 
51
 
 
52
ulint   last_thr;
 
53
ulint   switch_count;
 
54
ulint   glob_count;
 
55
ulint   glob_inc;
 
56
ulint   rc;
 
57
 
 
58
bool    qprint          = FALSE;
 
59
 
 
60
/********************************************************************
 
61
Start function for thread 1 in test1. */
 
62
ulint
 
63
thread1(void* arg)
 
64
/*==============*/
 
65
{
 
66
        ulint   i, j;
 
67
        void*   arg2;
 
68
 
 
69
        arg2 = arg;
 
70
 
 
71
        printf("Thread1 started!\n");
 
72
 
 
73
        mutex_enter(&mutex);
 
74
 
 
75
        printf("Thread1 owns now the mutex!\n");
 
76
 
 
77
        j = 0;
 
78
        
 
79
        for (i = 1; i < 1000000; i++) {
 
80
                j += i;
 
81
        }
 
82
 
 
83
        printf("Thread1 releases now the mutex!\n");
 
84
        
 
85
        mutex_exit(&mutex);
 
86
 
 
87
        return(j);
 
88
}
 
89
 
 
90
/********************************************************************
 
91
Start function for thread 2 in test1. */
 
92
ulint
 
93
thread2(void* arg)
 
94
/*==============*/
 
95
{
 
96
        ulint   i, j;
 
97
        void*   arg2;
 
98
 
 
99
        arg2 = arg;
 
100
 
 
101
        printf("Thread2 started!\n");
 
102
 
 
103
        mutex_enter(&mutex);
 
104
 
 
105
        printf("Thread2 owns now the mutex!\n");
 
106
 
 
107
        j = 0;
 
108
        
 
109
        for (i = 1; i < 1000000; i++) {
 
110
                j += i;
 
111
        }
 
112
 
 
113
        printf("Thread2 releases now the mutex!\n");
 
114
        
 
115
        mutex_exit(&mutex);
 
116
 
 
117
        return(j);
 
118
}
 
119
 
 
120
/********************************************************************
 
121
Start function for the competing threads in test2. The function tests
 
122
the behavior lock-coupling through 4 mutexes. */
 
123
 
 
124
ulint
 
125
thread_n(volatile void* arg)
 
126
/*========================*/
 
127
{
 
128
        ulint   i, j, k, n;
 
129
 
 
130
        n = *((ulint*)arg);
 
131
 
 
132
        printf("Thread %ld started!\n", n);
 
133
 
 
134
        for (k = 0; k < 2000 * UNIV_DBC; k++) {
 
135
        
 
136
                mutex_enter(&mutex1);
 
137
 
 
138
                if (last_thr != n) {
 
139
                        switch_count++;
 
140
                        last_thr = n;
 
141
                }
 
142
                
 
143
                j = 0;
 
144
        
 
145
                for (i = 1; i < 400; i++) {
 
146
                        j += i;
 
147
                }
 
148
        
 
149
                mutex_enter(&mutex2);
 
150
 
 
151
                mutex_exit(&mutex1);
 
152
 
 
153
                for (i = 1; i < 400; i++) {
 
154
                        j += i;
 
155
                }
 
156
                mutex_enter(&mutex3);
 
157
 
 
158
                mutex_exit(&mutex2);
 
159
 
 
160
                for (i = 1; i < 400; i++) {
 
161
                        j += i;
 
162
                }
 
163
                mutex_enter(&mutex4);
 
164
 
 
165
                mutex_exit(&mutex3);
 
166
 
 
167
                for (i = 1; i < 400; i++) {
 
168
                        j += i;
 
169
                }
 
170
 
 
171
                mutex_exit(&mutex4);
 
172
        }
 
173
 
 
174
        printf("Thread %ld exits!\n", n);
 
175
        
 
176
        return(j);
 
177
}
 
178
 
 
179
/********************************************************************
 
180
Start function for mutex exclusion checking in test3. */
 
181
 
 
182
ulint
 
183
thread_x(void* arg)
 
184
/*===============*/
 
185
{
 
186
        ulint   k;
 
187
        void*   arg2;
 
188
 
 
189
        arg2 = arg;
 
190
 
 
191
        printf("Starting thread!\n");
 
192
        
 
193
        for (k = 0; k < 200000 * UNIV_DBC; k++) {
 
194
        
 
195
                mutex_enter(&mutex);
 
196
 
 
197
                glob_count += glob_inc;
 
198
                
 
199
                mutex_exit(&mutex);
 
200
 
 
201
        }
 
202
 
 
203
        printf("Exiting thread!\n");
 
204
        
 
205
        return(0);
 
206
}
 
207
 
 
208
 
 
209
 
 
210
void 
 
211
test1(void)
 
212
/*=======*/
 
213
{
 
214
        os_thread_t             thr1, thr2;
 
215
        os_thread_id_t          id1, id2;
 
216
        ulint                   i, j;
 
217
        ulint                   tm, oldtm;
 
218
        ulint*                  lp;
 
219
        
 
220
        printf("-------------------------------------------\n");
 
221
        printf("SYNC-TEST 1. Test of mutexes.\n");
 
222
 
 
223
 
 
224
        printf("Main thread %ld starts!\n",
 
225
                os_thread_get_curr_id());
 
226
 
 
227
        osm = os_mutex_create(NULL);    
 
228
 
 
229
        os_mutex_enter(osm);
 
230
        os_mutex_exit(osm);
 
231
        
 
232
        os_mutex_free(osm);
 
233
 
 
234
        
 
235
        mutex_create(&mutex);
 
236
 
 
237
        lp = &j;
 
238
        
 
239
        oldtm = ut_clock();
 
240
 
 
241
        for (i = 0; i < 1000000; i++) {
 
242
                id1 = os_thread_get_curr_id();
 
243
        }
 
244
 
 
245
        tm = ut_clock();
 
246
        printf("Wall clock time for %ld thread_get_id %ld milliseconds\n",
 
247
                        i, tm - oldtm);
 
248
 
 
249
 
 
250
        oldtm = ut_clock();
 
251
 
 
252
        for (i = 0; i < 100000 * UNIV_DBC; i++) {
 
253
 
 
254
                mutex_enter(&mutex);
 
255
                mutex_exit(&mutex);
 
256
        }
 
257
 
 
258
        tm = ut_clock();
 
259
        printf("Wall clock time for %ld mutex lock-unlock %ld milliseconds\n",
 
260
                        i, tm - oldtm);
 
261
 
 
262
        oldtm = ut_clock();
 
263
 
 
264
        for (i = 0; i < 1000000; i++) {
 
265
 
 
266
                mutex_fence();
 
267
        }
 
268
 
 
269
        tm = ut_clock();
 
270
        printf("Wall clock time for %ld fences %ld milliseconds\n",
 
271
                        i, tm - oldtm);
 
272
 
 
273
        mutex_enter(&mutex);
 
274
 
 
275
        mutex_list_print_info();
 
276
 
 
277
        ut_ad(1 == mutex_n_reserved());
 
278
        ut_ad(FALSE == sync_all_freed());
 
279
        
 
280
        thr1 = os_thread_create(thread1,
 
281
                                  NULL,
 
282
                                  &id1);
 
283
 
 
284
        printf("Thread1 created, id %ld \n", id1);
 
285
 
 
286
        thr2 = os_thread_create(thread2,
 
287
                                  NULL,
 
288
                                  &id2);
 
289
 
 
290
        printf("Thread2 created, id %ld \n", id2);
 
291
        
 
292
 
 
293
        j = 0;
 
294
        
 
295
        for (i = 1; i < 20000000; i++) {
 
296
                j += i;
 
297
        }
 
298
 
 
299
        sync_print();
 
300
 
 
301
        sync_array_validate(sync_primary_wait_array);
 
302
        
 
303
        printf("Main thread releases now mutex!\n");
 
304
 
 
305
        mutex_exit(&mutex);
 
306
 
 
307
        os_thread_wait(thr2);
 
308
 
 
309
        os_thread_wait(thr1);
 
310
}
 
311
 
 
312
/******************************************************************
 
313
Test function for possible convoy problem. */
 
314
 
 
315
void 
 
316
test2(void)
 
317
/*=======*/
 
318
{
 
319
        os_thread_t             thr1, thr2, thr3, thr4, thr5;
 
320
        os_thread_id_t          id1, id2, id3, id4, id5;
 
321
        ulint                   tm, oldtm;
 
322
        ulint                   n1, n2, n3, n4, n5;
 
323
 
 
324
        printf("-------------------------------------------\n");
 
325
        printf("SYNC-TEST 2. Test of possible convoy problem.\n");
 
326
 
 
327
        printf("System call count %lu\n", mutex_system_call_count);
 
328
        
 
329
        mutex_create(&mutex1);
 
330
        mutex_create(&mutex2);
 
331
        mutex_create(&mutex3);
 
332
        mutex_create(&mutex4);
 
333
 
 
334
        switch_count = 0;
 
335
        
 
336
        oldtm = ut_clock();
 
337
 
 
338
        n1 = 1;
 
339
        
 
340
        thr1 = os_thread_create(thread_n,
 
341
                                  &n1,
 
342
                                  &id1);
 
343
 
 
344
        os_thread_wait(thr1);
 
345
 
 
346
 
 
347
        tm = ut_clock();
 
348
        printf("Wall clock time for single thread %ld milliseconds\n",
 
349
                        tm - oldtm);
 
350
        printf("System call count %lu\n", mutex_system_call_count);
 
351
 
 
352
        switch_count = 0;
 
353
                        
 
354
        oldtm = ut_clock();
 
355
 
 
356
        n1 = 1;
 
357
        thr1 = os_thread_create(thread_n,
 
358
                                  &n1,
 
359
                                  &id1);
 
360
        n2 = 2;
 
361
        thr2 = os_thread_create(thread_n,
 
362
                                  &n2,
 
363
                                  &id2);
 
364
        n3 = 3;
 
365
        thr3 = os_thread_create(thread_n,
 
366
                                  &n3,
 
367
                                  &id3);
 
368
        n4 = 4;
 
369
        thr4 = os_thread_create(thread_n,
 
370
                                  &n4,
 
371
                                  &id4);
 
372
        n5 = 5;
 
373
        thr5 = os_thread_create(thread_n,
 
374
                                  &n5,
 
375
                                  &id5);
 
376
 
 
377
                                  
 
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);
 
383
 
 
384
 
 
385
        tm = ut_clock();
 
386
        printf("Wall clock time for 5 threads %ld milliseconds\n",
 
387
                        tm - oldtm);
 
388
        printf("%ld thread switches occurred\n", switch_count);
 
389
        
 
390
        printf("If this is not 5 x single thread time, possibly convoy!\n");
 
391
 
 
392
        printf("System call count %lu\n", mutex_system_call_count);
 
393
}
 
394
 
 
395
/******************************************************************
 
396
Test function for possible exclusion failure. */
 
397
 
 
398
void 
 
399
test3(void)
 
400
/*=======*/
 
401
{
 
402
        os_thread_t             thr1, thr2;
 
403
        os_thread_id_t          id1, id2;
 
404
 
 
405
        printf("-------------------------------------------\n");
 
406
        printf("SYNC-TEST 3. Test of possible exclusion failure.\n");
 
407
 
 
408
        glob_count = 0;
 
409
        glob_inc = 1;
 
410
        
 
411
        thr1 = os_thread_create(thread_x,
 
412
                                  NULL,
 
413
                                  &id1);
 
414
        thr2 = os_thread_create(thread_x,
 
415
                                  NULL,
 
416
                                  &id2);
 
417
 
 
418
        os_thread_wait(thr2);
 
419
        os_thread_wait(thr1);
 
420
 
 
421
        ut_a(glob_count == 400000 * UNIV_DBC);
 
422
}
 
423
 
 
424
/******************************************************************
 
425
Test function for measuring the spin wait loop cycle time. */
 
426
 
 
427
void 
 
428
test4(void)
 
429
/*=======*/
 
430
{
 
431
volatile ulint* ptr;
 
432
        ulint   i, tm, oldtm;   
 
433
 
 
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");
 
437
 
 
438
 
 
439
        glob_inc = 1;
 
440
        
 
441
        ptr = &glob_inc;
 
442
        
 
443
        oldtm = ut_clock();
 
444
 
 
445
        i = 0;
 
446
 
 
447
        while ((*ptr != 0) && (i < 10000000)) {
 
448
                i++;
 
449
        }
 
450
        
 
451
        tm = ut_clock();
 
452
        printf("Wall clock time for %ld cycles %ld milliseconds\n",
 
453
                        i, tm - oldtm);
 
454
}
 
455
 
 
456
/********************************************************************
 
457
Start function for s-lock thread in test5. */
 
458
ulint
 
459
thread_srw(void* arg)
 
460
/*==============*/
 
461
{
 
462
        ulint   i, j;
 
463
        void*   arg2;
 
464
 
 
465
        arg2 = arg;
 
466
 
 
467
        printf("Thread_srw started!\n");
 
468
 
 
469
        rw_lock_s_lock(&rw1);
 
470
 
 
471
        printf("Thread_srw has now s-lock!\n");
 
472
 
 
473
        j = 0;
 
474
        
 
475
        for (i = 1; i < 1000000; i++) {
 
476
                j += i;
 
477
        }
 
478
 
 
479
        printf("Thread_srw releases now the s-lock!\n");
 
480
        
 
481
        rw_lock_s_unlock(&rw1);
 
482
 
 
483
        return(j);
 
484
}
 
485
 
 
486
/********************************************************************
 
487
Start function for x-lock thread in test5. */
 
488
ulint
 
489
thread_xrw(void* arg)
 
490
/*==============*/
 
491
{
 
492
        ulint   i, j;
 
493
        void*   arg2;
 
494
 
 
495
        arg2 = arg;
 
496
 
 
497
        printf("Thread_xrw started!\n");
 
498
 
 
499
        rw_lock_x_lock(&rw1);
 
500
 
 
501
        printf("Thread_xrw has now x-lock!\n");
 
502
 
 
503
        j = 0;
 
504
        
 
505
        for (i = 1; i < 1000000; i++) {
 
506
                j += i;
 
507
        }
 
508
 
 
509
        printf("Thread_xrw releases now the x-lock!\n");
 
510
        
 
511
        rw_lock_x_unlock(&rw1);
 
512
 
 
513
        return(j);
 
514
}
 
515
 
 
516
 
 
517
void 
 
518
test5(void)
 
519
/*=======*/
 
520
{
 
521
        os_thread_t             thr1, thr2;
 
522
        os_thread_id_t          id1, id2;
 
523
        ulint                   i, j;
 
524
        ulint                   tm, oldtm;
 
525
        
 
526
        printf("-------------------------------------------\n");
 
527
        printf("SYNC-TEST 5. Test of read-write locks.\n");
 
528
 
 
529
 
 
530
        printf("Main thread %ld starts!\n",
 
531
                os_thread_get_curr_id());
 
532
 
 
533
        
 
534
        rw_lock_create(&rw1);
 
535
 
 
536
        oldtm = ut_clock();
 
537
 
 
538
 
 
539
        for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) {
 
540
 
 
541
                rw_lock_s_lock(&rw1);
 
542
 
 
543
                rw_lock_s_unlock(&rw1);
 
544
 
 
545
        }
 
546
 
 
547
        tm = ut_clock();
 
548
        printf("Wall clock time for %ld rw s-lock-unlock %ld milliseconds\n",
 
549
                        i, tm - oldtm);
 
550
 
 
551
 
 
552
        oldtm = ut_clock();
 
553
 
 
554
 
 
555
        for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) {
 
556
 
 
557
                mutex_enter(&mutex);
 
558
                rc++;
 
559
                mutex_exit(&mutex);
 
560
 
 
561
                mutex_enter(&mutex);
 
562
                rc--;
 
563
                mutex_exit(&mutex);
 
564
        }
 
565
 
 
566
        tm = ut_clock();
 
567
        printf("Wall clock time for %ld rw test %ld milliseconds\n",
 
568
                        i, tm - oldtm);
 
569
 
 
570
 
 
571
 
 
572
        oldtm = ut_clock();
 
573
 
 
574
        for (i = 0; i < 10000 * UNIV_DBC * UNIV_DBC; i++) {
 
575
 
 
576
                rw_lock_x_lock(&rw1);
 
577
                rw_lock_x_unlock(&rw1);
 
578
 
 
579
        }
 
580
 
 
581
        tm = ut_clock();
 
582
        printf("Wall clock time for %ld rw x-lock-unlock %ld milliseconds\n",
 
583
                        i, tm - oldtm);
 
584
 
 
585
 
 
586
        /* Test recursive x-locking */
 
587
        for (i = 0; i < 10000; i++) {
 
588
                rw_lock_x_lock(&rw1);
 
589
        }
 
590
 
 
591
        for (i = 0; i < 10000; i++) {
 
592
 
 
593
                rw_lock_x_unlock(&rw1);
 
594
        }
 
595
 
 
596
        /* Test recursive s-locking */
 
597
        for (i = 0; i < 10000; i++) {
 
598
 
 
599
                rw_lock_s_lock(&rw1);
 
600
        }
 
601
 
 
602
        for (i = 0; i < 10000; i++) {
 
603
 
 
604
                rw_lock_s_unlock(&rw1);
 
605
        }
 
606
 
 
607
        rw_lock_s_lock(&rw1);
 
608
 
 
609
        ut_ad(1 == rw_lock_n_locked());
 
610
 
 
611
        mem_print_info();
 
612
 
 
613
        rw_lock_list_print_info();
 
614
 
 
615
        thr2 = os_thread_create(thread_xrw,
 
616
                                  NULL,
 
617
                                  &id2);
 
618
 
 
619
        printf("Thread_xrw created, id %ld \n", id2);
 
620
        
 
621
 
 
622
        thr1 = os_thread_create(thread_srw,
 
623
                                  NULL,
 
624
                                  &id1);
 
625
 
 
626
        printf("Thread_srw created, id %ld \n", id1);
 
627
 
 
628
        j = 0;
 
629
        
 
630
        for (i = 1; i < 10000000; i++) {
 
631
                j += i;
 
632
        }
 
633
 
 
634
        rw_lock_list_print_info();
 
635
 
 
636
        sync_array_validate(sync_primary_wait_array);
 
637
        
 
638
        printf("Main thread releases now rw-lock!\n");
 
639
 
 
640
        rw_lock_s_unlock(&rw1);
 
641
 
 
642
        os_thread_wait(thr2);
 
643
 
 
644
        os_thread_wait(thr1);
 
645
 
 
646
        sync_array_print_info(sync_primary_wait_array);
 
647
}
 
648
 
 
649
/********************************************************************
 
650
Start function for the competing s-threads in test6. The function tests
 
651
the behavior lock-coupling through 4 rw-locks. */
 
652
 
 
653
ulint
 
654
thread_qs(volatile void* arg)
 
655
/*========================*/
 
656
{
 
657
        ulint   i, j, k, n;
 
658
 
 
659
        arg = arg;
 
660
        
 
661
        n = os_thread_get_curr_id();
 
662
 
 
663
        printf("S-Thread %ld started, thread id %lu\n", n,
 
664
                os_thread_get_curr_id());
 
665
 
 
666
        for (k = 0; k < 1000 * UNIV_DBC; k++) {
 
667
 
 
668
                if (qprint)
 
669
                printf("S-Thread %ld starts round %ld!\n", n, k);
 
670
                        
 
671
                rw_lock_s_lock(&rw1);
 
672
 
 
673
                if (qprint)     
 
674
                printf("S-Thread %ld got lock 1 on round %ld!\n", n, k);
 
675
                 
 
676
                
 
677
                if (last_thr != n) {
 
678
                        switch_count++;
 
679
                        last_thr = n;
 
680
                }
 
681
                
 
682
                j = 0;
 
683
        
 
684
                for (i = 1; i < 400; i++) {
 
685
                        j += i;
 
686
                }
 
687
        
 
688
                rw_lock_s_lock(&rw2);
 
689
 
 
690
                if (qprint)     
 
691
                printf("S-Thread %ld got lock 2 on round %ld!\n", n, k);
 
692
                 
 
693
 
 
694
                rw_lock_s_unlock(&rw1);
 
695
 
 
696
                if (qprint)     
 
697
                printf("S-Thread %ld released lock 1 on round %ld!\n", n, k);
 
698
                 
 
699
 
 
700
                for (i = 1; i < 400; i++) {
 
701
                        j += i;
 
702
                }
 
703
                rw_lock_s_lock(&rw3);
 
704
 
 
705
                if (qprint)     
 
706
                printf("S-Thread %ld got lock 3 on round %ld!\n", n, k);
 
707
                 
 
708
 
 
709
                rw_lock_s_unlock(&rw2);
 
710
                if (qprint)     
 
711
                printf("S-Thread %ld released lock 2 on round %ld!\n", n, k);
 
712
                 
 
713
 
 
714
                for (i = 1; i < 400; i++) {
 
715
                        j += i;
 
716
                }
 
717
                rw_lock_s_lock(&rw4);
 
718
 
 
719
                if (qprint)     
 
720
                printf("S-Thread %ld got lock 4 on round %ld!\n", n, k);
 
721
                 
 
722
 
 
723
                rw_lock_s_unlock(&rw3);
 
724
                if (qprint)     
 
725
                printf("S-Thread %ld released lock 3 on round %ld!\n", n, k);
 
726
                 
 
727
 
 
728
                for (i = 1; i < 400; i++) {
 
729
                        j += i;
 
730
                }
 
731
 
 
732
                rw_lock_s_unlock(&rw4);
 
733
                if (qprint)     
 
734
                printf("S-Thread %ld released lock 4 on round %ld!\n", n, k);
 
735
                 
 
736
        }
 
737
 
 
738
        printf("S-Thread %ld exits!\n", n);
 
739
        
 
740
        return(j);
 
741
}
 
742
 
 
743
/********************************************************************
 
744
Start function for the competing x-threads in test6. The function tests
 
745
the behavior lock-coupling through 4 rw-locks. */
 
746
 
 
747
ulint
 
748
thread_qx(volatile void* arg)
 
749
/*========================*/
 
750
{
 
751
        ulint   i, j, k, n;
 
752
 
 
753
        arg = arg;
 
754
 
 
755
        n = os_thread_get_curr_id();
 
756
 
 
757
        printf("X-Thread %ld started, thread id %lu\n", n,
 
758
                os_thread_get_curr_id());
 
759
 
 
760
        for (k = 0; k < 1000 * UNIV_DBC; k++) {
 
761
                
 
762
                if (qprint)     
 
763
                printf("X-Thread %ld round %ld!\n", n, k);
 
764
                 
 
765
                        
 
766
                rw_lock_x_lock(&rw1);
 
767
                if (qprint)     
 
768
                printf("X-Thread %ld got lock 1 on round %ld!\n", n, k);
 
769
                 
 
770
 
 
771
                if (last_thr != n) {
 
772
                        switch_count++;
 
773
                        last_thr = n;
 
774
                }
 
775
                
 
776
                j = 0;
 
777
        
 
778
                for (i = 1; i < 400; i++) {
 
779
                        j += i;
 
780
                }
 
781
        
 
782
                rw_lock_x_lock(&rw2);
 
783
                if (qprint)     
 
784
                printf("X-Thread %ld got lock 2 on round %ld!\n", n, k);
 
785
                 
 
786
 
 
787
                rw_lock_x_unlock(&rw1);
 
788
                if (qprint)     
 
789
                printf("X-Thread %ld released lock 1 on round %ld!\n", n, k);
 
790
                 
 
791
 
 
792
                for (i = 1; i < 400; i++) {
 
793
                        j += i;
 
794
                }
 
795
                rw_lock_x_lock(&rw3);
 
796
                if (qprint)     
 
797
                printf("X-Thread %ld got lock 3 on round %ld!\n", n, k);
 
798
                 
 
799
 
 
800
                rw_lock_x_unlock(&rw2);
 
801
                if (qprint)     
 
802
                printf("X-Thread %ld released lock 2 on round %ld!\n", n, k);
 
803
                 
 
804
 
 
805
                for (i = 1; i < 400; i++) {
 
806
                        j += i;
 
807
                }
 
808
                rw_lock_x_lock(&rw4);
 
809
                if (qprint)     
 
810
                printf("X-Thread %ld got lock 4 on round %ld!\n", n, k);
 
811
 
 
812
                rw_lock_x_unlock(&rw3);
 
813
                if (qprint)     
 
814
                printf("X-Thread %ld released lock 3 on round %ld!\n", n, k);
 
815
                 
 
816
 
 
817
                for (i = 1; i < 400; i++) {
 
818
                        j += i;
 
819
                }
 
820
 
 
821
                rw_lock_x_unlock(&rw4);
 
822
                if (qprint)     
 
823
                printf("X-Thread %ld released lock 4 on round %ld!\n", n, k);
 
824
                 
 
825
        }
 
826
 
 
827
        printf("X-Thread %ld exits!\n", n);
 
828
        
 
829
        return(j);
 
830
}
 
831
 
 
832
/******************************************************************
 
833
Test function for possible queuing problems with rw-locks. */
 
834
 
 
835
void 
 
836
test6(void)
 
837
/*=======*/
 
838
{
 
839
        os_thread_t             thr1, thr2, thr3, thr4, thr5;
 
840
        os_thread_id_t          id1, id2, id3, id4, id5;
 
841
        ulint                   tm, oldtm;
 
842
        ulint                   n1, n2, n3, n4, n5;
 
843
 
 
844
        printf("-------------------------------------------\n");
 
845
        printf(
 
846
        "SYNC-TEST 6. Test of possible queuing problems with rw-locks.\n");
 
847
/*
 
848
        sync_array_print_info(sync_primary_wait_array);
 
849
*/
 
850
 
 
851
        rw_lock_create(&rw2);
 
852
        rw_lock_create(&rw3);
 
853
        rw_lock_create(&rw4);
 
854
 
 
855
        switch_count = 0;
 
856
        
 
857
 
 
858
        oldtm = ut_clock();
 
859
 
 
860
        n1 = 1;
 
861
        
 
862
        thr1 = os_thread_create(thread_qs,
 
863
                                  &n1,
 
864
                                  &id1);
 
865
 
 
866
        os_thread_wait(thr1);
 
867
 
 
868
 
 
869
        tm = ut_clock();
 
870
        printf("Wall clock time for single s-lock thread %ld milliseconds\n",
 
871
                        tm - oldtm);
 
872
 
 
873
        oldtm = ut_clock();
 
874
 
 
875
        n1 = 1;
 
876
        
 
877
        thr1 = os_thread_create(thread_qx,
 
878
                                  &n1,
 
879
                                  &id1);
 
880
 
 
881
        os_thread_wait(thr1);
 
882
 
 
883
 
 
884
        tm = ut_clock();
 
885
        printf("Wall clock time for single x-lock thread %ld milliseconds\n",
 
886
                        tm - oldtm);
 
887
 
 
888
        switch_count = 0;
 
889
                        
 
890
        oldtm = ut_clock();
 
891
 
 
892
        
 
893
        n1 = 1;
 
894
        thr1 = os_thread_create(thread_qx,
 
895
                                  &n1,
 
896
                                  &id1);
 
897
 
 
898
        n2 = 2;
 
899
        thr2 = os_thread_create(thread_qs,
 
900
                                  &n2,
 
901
                                  &id2);
 
902
 
 
903
        n3 = 3;
 
904
        thr3 = os_thread_create(thread_qx,
 
905
                                  &n3,
 
906
                                  &id3);
 
907
 
 
908
 
 
909
        n4 = 4;
 
910
        thr4 = os_thread_create(thread_qs,
 
911
                                  &n4,
 
912
                                  &id4);
 
913
                                  
 
914
        n5 = 5;
 
915
        thr5 = os_thread_create(thread_qx,
 
916
                                  &n5,
 
917
                                  &id5);
 
918
 
 
919
        os_thread_wait(thr1);
 
920
 
 
921
        os_thread_wait(thr2);
 
922
 
 
923
        os_thread_wait(thr3);
 
924
 
 
925
        os_thread_wait(thr4);
 
926
 
 
927
        os_thread_wait(thr5);
 
928
 
 
929
 
 
930
        tm = ut_clock();
 
931
        printf("Wall clock time for 5 threads %ld milliseconds\n",
 
932
                        tm - oldtm);
 
933
        printf("at least %ld thread switches occurred\n", switch_count);
 
934
        
 
935
        printf(
 
936
        "If this is not 2 x s-thread + 3 x x-thread time, possibly convoy!\n");
 
937
 
 
938
        rw_lock_list_print_info();
 
939
 
 
940
        sync_array_print_info(sync_primary_wait_array);
 
941
 
 
942
}
 
943
 
 
944
/********************************************************************
 
945
Start function for thread in test7. */
 
946
ulint
 
947
ip_thread(void* arg)
 
948
/*================*/
 
949
{
 
950
        ulint   i, j;
 
951
        void*   arg2;
 
952
        ulint   ret;
 
953
        ulint   tm, oldtm;
 
954
        
 
955
        arg2 = arg;
 
956
 
 
957
        printf("Thread started!\n");
 
958
 
 
959
        oldtm = ut_clock();
 
960
 
 
961
        ret = ip_mutex_enter(iph, 100000);
 
962
 
 
963
/*      ut_a(ret == SYNC_TIME_EXCEEDED);
 
964
*/      
 
965
        tm = ut_clock();
 
966
 
 
967
        printf("Wall clock time for wait failure %ld ms\n", tm - oldtm);
 
968
 
 
969
        ret = ip_mutex_enter(iph, SYNC_INFINITE_TIME);
 
970
 
 
971
        ut_a(ret == 0);
 
972
        
 
973
        printf("Thread owns now the ip mutex!\n");
 
974
 
 
975
        j = 0;
 
976
        
 
977
        for (i = 1; i < 1000000; i++) {
 
978
                j += i;
 
979
        }
 
980
 
 
981
        printf("Thread releases now the ip mutex!\n");
 
982
        
 
983
        ip_mutex_exit(iph);
 
984
 
 
985
        return(j);
 
986
}
 
987
 
 
988
/*********************************************************************
 
989
Test for interprocess mutex. */
 
990
void 
 
991
test7(void)
 
992
/*=======*/
 
993
{
 
994
        os_thread_t             thr1;
 
995
        os_thread_id_t          id1;
 
996
        ulint                   i, j;
 
997
        ulint                   tm, oldtm;
 
998
        
 
999
        printf("-------------------------------------------\n");
 
1000
        printf("SYNC-TEST 7. Test of ip mutex.\n");
 
1001
 
 
1002
 
 
1003
        printf("Main thread %ld starts!\n",
 
1004
                os_thread_get_curr_id());
 
1005
 
 
1006
        ip_mutex_create(&ip_mutex, "IPMUTEX", &iph);
 
1007
        
 
1008
        oldtm = ut_clock();
 
1009
 
 
1010
        for (i = 0; i < 100000 * UNIV_DBC; i++) {
 
1011
 
 
1012
                ip_mutex_enter(iph, SYNC_INFINITE_TIME);
 
1013
                ip_mutex_exit(iph);
 
1014
        }
 
1015
 
 
1016
        tm = ut_clock();
 
1017
        printf("Wall clock time for %ld ip mutex lock-unlock %ld ms\n",
 
1018
                        i, tm - oldtm);
 
1019
 
 
1020
 
 
1021
        ip_mutex_enter(iph, SYNC_INFINITE_TIME);
 
1022
 
 
1023
        thr1 = os_thread_create(ip_thread,
 
1024
                                  NULL,
 
1025
                                  &id1);
 
1026
 
 
1027
        printf("Thread created, id %ld \n", id1);
 
1028
 
 
1029
 
 
1030
        j = 0;
 
1031
        
 
1032
        for (i = 1; i < 100000000; i++) {
 
1033
                j += i;
 
1034
        }
 
1035
 
 
1036
        printf("Main thread releases now ip mutex!\n");
 
1037
 
 
1038
        ip_mutex_exit(iph);
 
1039
 
 
1040
        os_thread_wait(thr1);
 
1041
 
 
1042
        ip_mutex_free(iph);
 
1043
}
 
1044
 
 
1045
/********************************************************************
 
1046
Start function for the competing threads in test8. The function tests
 
1047
the behavior lock-coupling through 4 ip mutexes. */
 
1048
 
 
1049
ulint
 
1050
thread_ipn(volatile void* arg)
 
1051
/*========================*/
 
1052
{
 
1053
        ulint   i, j, k, n;
 
1054
 
 
1055
        n = *((ulint*)arg);
 
1056
 
 
1057
        printf("Thread %ld started!\n", n);
 
1058
 
 
1059
        for (k = 0; k < 2000 * UNIV_DBC; k++) {
 
1060
        
 
1061
                ip_mutex_enter(iph1, SYNC_INFINITE_TIME);
 
1062
 
 
1063
                if (last_thr != n) {
 
1064
                        switch_count++;
 
1065
                        last_thr = n;
 
1066
                }
 
1067
                
 
1068
                j = 0;
 
1069
        
 
1070
                for (i = 1; i < 400; i++) {
 
1071
                        j += i;
 
1072
                }
 
1073
        
 
1074
                ip_mutex_enter(iph2, SYNC_INFINITE_TIME);
 
1075
 
 
1076
                ip_mutex_exit(iph1);
 
1077
 
 
1078
                for (i = 1; i < 400; i++) {
 
1079
                        j += i;
 
1080
                }
 
1081
                ip_mutex_enter(iph3, SYNC_INFINITE_TIME);
 
1082
 
 
1083
                ip_mutex_exit(iph2);
 
1084
 
 
1085
                for (i = 1; i < 400; i++) {
 
1086
                        j += i;
 
1087
                }
 
1088
                ip_mutex_enter(iph4, SYNC_INFINITE_TIME);
 
1089
 
 
1090
                ip_mutex_exit(iph3);
 
1091
 
 
1092
                for (i = 1; i < 400; i++) {
 
1093
                        j += i;
 
1094
                }
 
1095
 
 
1096
                ip_mutex_exit(iph4);
 
1097
        }
 
1098
 
 
1099
        printf("Thread %ld exits!\n", n);
 
1100
        
 
1101
        return(j);
 
1102
}
 
1103
 
 
1104
/******************************************************************
 
1105
Test function for ip mutex. */
 
1106
 
 
1107
void 
 
1108
test8(void)
 
1109
/*=======*/
 
1110
{
 
1111
        os_thread_t             thr1, thr2, thr3, thr4, thr5;
 
1112
        os_thread_id_t          id1, id2, id3, id4, id5;
 
1113
        ulint                   tm, oldtm;
 
1114
        ulint                   n1, n2, n3, n4, n5;
 
1115
 
 
1116
        printf("-------------------------------------------\n");
 
1117
        printf("SYNC-TEST 8. Test for ip mutex.\n");
 
1118
 
 
1119
 
 
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);
 
1124
 
 
1125
        switch_count = 0;
 
1126
        
 
1127
        oldtm = ut_clock();
 
1128
 
 
1129
        n1 = 1;
 
1130
        
 
1131
        thr1 = os_thread_create(thread_ipn,
 
1132
                                  &n1,
 
1133
                                  &id1);
 
1134
 
 
1135
        os_thread_wait(thr1);
 
1136
 
 
1137
 
 
1138
        tm = ut_clock();
 
1139
        printf("Wall clock time for single thread %lu milliseconds\n",
 
1140
                        tm - oldtm);
 
1141
 
 
1142
        switch_count = 0;
 
1143
                        
 
1144
        oldtm = ut_clock();
 
1145
 
 
1146
        n1 = 1;
 
1147
        thr1 = os_thread_create(thread_ipn,
 
1148
                                  &n1,
 
1149
                                  &id1);
 
1150
        n2 = 2;
 
1151
        thr2 = os_thread_create(thread_ipn,
 
1152
                                  &n2,
 
1153
                                  &id2);
 
1154
        n3 = 3;
 
1155
        thr3 = os_thread_create(thread_ipn,
 
1156
                                  &n3,
 
1157
                                  &id3);
 
1158
        n4 = 4;
 
1159
        thr4 = os_thread_create(thread_ipn,
 
1160
                                  &n4,
 
1161
                                  &id4);
 
1162
        n5 = 5;
 
1163
        thr5 = os_thread_create(thread_ipn,
 
1164
                                  &n5,
 
1165
                                  &id5);
 
1166
 
 
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);
 
1172
 
 
1173
 
 
1174
        tm = ut_clock();
 
1175
        printf("Wall clock time for 5 threads %ld milliseconds\n",
 
1176
                        tm - oldtm);
 
1177
        printf("%ld thread switches occurred\n", switch_count);
 
1178
        
 
1179
        printf("If this is not 5 x single thread time, possibly convoy!\n");
 
1180
 
 
1181
        ip_mutex_free(iph1);
 
1182
        ip_mutex_free(iph2);
 
1183
        ip_mutex_free(iph3);
 
1184
        ip_mutex_free(iph4);
 
1185
}
 
1186
 
 
1187
 
 
1188
/********************************************************************
 
1189
Start function for s-lock thread in test9. */
 
1190
ulint
 
1191
thread_srw9(void* arg)
 
1192
/*==================*/
 
1193
{
 
1194
        void*   arg2;
 
1195
 
 
1196
        arg2 = arg;
 
1197
 
 
1198
        printf("Thread_srw9 started!\n");
 
1199
 
 
1200
        rw_lock_x_lock(&rw10);
 
1201
 
 
1202
        printf("Thread_srw9 has now x-lock on rw10, wait for mutex!\n");
 
1203
 
 
1204
        mutex_enter(&mutex9);
 
1205
 
 
1206
        return(0);
 
1207
}
 
1208
 
 
1209
/********************************************************************
 
1210
Start function for x-lock thread in test9. */
 
1211
ulint
 
1212
thread_xrw9(void* arg)
 
1213
/*==================*/
 
1214
{
 
1215
        void*   arg2;
 
1216
 
 
1217
        arg2 = arg;
 
1218
 
 
1219
        printf("Thread_xrw started!\n");
 
1220
 
 
1221
        mutex_enter(&mutex9);
 
1222
        printf("Thread_xrw9 has now mutex9, wait for rw9!\n");
 
1223
        
 
1224
        rw_lock_x_lock(&rw9);
 
1225
 
 
1226
        return(0);
 
1227
}
 
1228
 
 
1229
void 
 
1230
test9(void)
 
1231
/*=======*/
 
1232
{
 
1233
        os_thread_t             thr1, thr2;
 
1234
        os_thread_id_t          id1, id2;
 
1235
        
 
1236
        printf("-------------------------------------------\n");
 
1237
        printf("SYNC-TEST 9. Test of deadlock detection.\n");
 
1238
 
 
1239
 
 
1240
        printf("Main thread %ld starts!\n",
 
1241
                os_thread_get_curr_id());
 
1242
 
 
1243
        rw_lock_create(&rw9);
 
1244
        rw_lock_create(&rw10);
 
1245
        mutex_create(&mutex9);
 
1246
 
 
1247
        rw_lock_s_lock(&rw9);
 
1248
        printf("Main thread has now s-lock on rw9\n");
 
1249
                
 
1250
        thr2 = os_thread_create(thread_xrw9,
 
1251
                                  NULL,
 
1252
                                  &id2);
 
1253
 
 
1254
        printf("Thread_xrw9 created, id %ld \n", id2);
 
1255
 
 
1256
        os_thread_sleep(1000000);
 
1257
 
 
1258
        thr1 = os_thread_create(thread_srw9,
 
1259
                                  NULL,
 
1260
                                  &id1);
 
1261
 
 
1262
        printf("Thread_srw9 created, id %ld \n", id1);
 
1263
 
 
1264
        os_thread_sleep(1000000);
 
1265
 
 
1266
        sync_array_print_info(sync_primary_wait_array);
 
1267
 
 
1268
        printf("Now we should have a deadlock of 3 threads:\n");
 
1269
 
 
1270
        rw_lock_s_lock(&rw10);
 
1271
}
 
1272
 
 
1273
void 
 
1274
test10(void)
 
1275
/*=======*/
 
1276
{
 
1277
        printf("-------------------------------------------\n");
 
1278
        printf("SYNC-TEST 10. Test of deadlock detection on self-deadlock.\n");
 
1279
 
 
1280
 
 
1281
        printf("Main thread %ld starts!\n",
 
1282
                os_thread_get_curr_id());
 
1283
 
 
1284
        mutex_create(&mutex9);
 
1285
 
 
1286
        printf("Now we should have a deadlock of this thread on mutex:\n");
 
1287
 
 
1288
        mutex_enter(&mutex9);
 
1289
        mutex_enter(&mutex9);
 
1290
}
 
1291
 
 
1292
void 
 
1293
test11(void)
 
1294
/*=======*/
 
1295
{
 
1296
        printf("-------------------------------------------\n");
 
1297
        printf("SYNC-TEST 11. Test of deadlock detection on self-deadlock.\n");
 
1298
 
 
1299
 
 
1300
        printf("Main thread %ld starts!\n",
 
1301
                os_thread_get_curr_id());
 
1302
 
 
1303
        rw_lock_create(&rw9);
 
1304
 
 
1305
        printf("Now we should have a deadlock of this thread on X-lock:\n");
 
1306
 
 
1307
        rw_lock_x_lock(&rw9);
 
1308
        rw_lock_s_lock_gen(&rw9, 567);
 
1309
}
 
1310
 
 
1311
 
 
1312
/************************************************************************
 
1313
Main test function. */
 
1314
 
 
1315
void 
 
1316
main(void) 
 
1317
/*======*/
 
1318
{
 
1319
        ulint   tm, oldtm;
 
1320
 
 
1321
        sync_init();    
 
1322
        mem_init();
 
1323
        
 
1324
        oldtm = ut_clock();
 
1325
 
 
1326
        test1();
 
1327
 
 
1328
        test2();
 
1329
        
 
1330
        test3();
 
1331
 
 
1332
        test4();
 
1333
 
 
1334
        test5();
 
1335
        
 
1336
        test6();
 
1337
 
 
1338
        test7();
 
1339
 
 
1340
        test8();        
 
1341
 
 
1342
        /* This test SHOULD result in assert on deadlock! */
 
1343
/*      test9();*/
 
1344
 
 
1345
        /* This test SHOULD result in assert on deadlock! */
 
1346
/*      test10();*/
 
1347
 
 
1348
        /* This test SHOULD result in assert on deadlock! */
 
1349
/*      test11();*/
 
1350
 
 
1351
        ut_ad(0 == mutex_n_reserved());
 
1352
        ut_ad(0 == rw_lock_n_locked());
 
1353
        ut_ad(sync_all_freed());
 
1354
 
 
1355
        
 
1356
        ut_ad(mem_all_freed());
 
1357
        
 
1358
        sync_close();
 
1359
        
 
1360
        tm = ut_clock();
 
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");
 
1364
 
1365
 
 
1366