~jlukas79/+junk/mysql-server

« back to all changes in this revision

Viewing changes to mysys/thr_lock.c

manual merge 6.0-main --> 6.0-bka-review

Show diffs side-by-side

added added

removed removed

Lines of Context:
24
24
 
25
25
The current lock types are:
26
26
 
27
 
TL_READ                 # Low priority read
 
27
TL_READ                 # Low priority read
28
28
TL_READ_WITH_SHARED_LOCKS
29
29
TL_READ_HIGH_PRIORITY   # High priority read
30
30
TL_READ_NO_INSERT       # Read without concurrent inserts
57
57
         In MyISAM this is a simple check if the insert can be done
58
58
         at the end of the datafile.
59
59
update_status:
60
 
        Before a write lock is released, this function is called.
61
 
        In MyISAM this functions updates the count and length of the datafile
 
60
        in thr_reschedule_write_lock(), when an insert delayed thread
 
61
        downgrades TL_WRITE lock to TL_WRITE_DELAYED, to allow SELECT
 
62
        threads to proceed.
 
63
        A storage engine should also call update_status internally
 
64
        in the ::external_lock(F_UNLCK) method.
 
65
        In MyISAM and CSV this functions updates the length of the datafile.
62
66
get_status:
63
67
        When one gets a lock this functions is called.
64
68
        In MyISAM this stores the number of rows and size of the datafile
65
69
        for concurrent reads.
66
70
 
67
71
The lock algorithm allows one to have one TL_WRITE_ALLOW_READ,
68
 
TL_WRITE_CONCURRENT_INSERT or one TL_WRITE_DELAYED lock at the same time as
69
 
multiple read locks.
 
72
TL_WRITE_CONCURRENT_INSERT or one TL_WRITE_DELAYED lock at the same
 
73
time as multiple read locks.
70
74
 
 
75
In addition, if lock->allow_multiple_concurrent_insert is set then there can
 
76
be any number of TL_WRITE_CONCURRENT_INSERT locks aktive at the same time.
71
77
*/
72
78
 
73
79
#if !defined(MAIN) && !defined(DBUG_OFF) && !defined(EXTRA_DEBUG)
148
154
      }
149
155
      if (same_owner &&
150
156
          !thr_lock_owner_equal(data->owner, first_owner) &&
151
 
          last_lock_type != TL_WRITE_ALLOW_WRITE)
 
157
          last_lock_type != TL_WRITE_ALLOW_WRITE &&
 
158
          last_lock_type != TL_WRITE_CONCURRENT_INSERT)
152
159
      {
153
160
        fprintf(stderr,
154
161
                "Warning: Found locks from different threads in %s: %s\n",
201
208
      THR_LOCK_DATA *data;
202
209
      for (data=lock->read.data ; data ; data=data->next)
203
210
      {
204
 
        if ((int) data->type == (int) TL_READ_NO_INSERT)
 
211
        if (data->type == TL_READ_NO_INSERT)
205
212
          count++;
206
213
        /* Protect against infinite loop. */
207
214
        DBUG_ASSERT(count <= lock->read_no_write_count);
250
257
        }             
251
258
      }
252
259
      else
253
 
      {                                         /* Have write lock */
 
260
      {
 
261
        /* We have at least one write lock */
 
262
        if (lock->write.data->type == TL_WRITE_CONCURRENT_INSERT)
 
263
        {
 
264
          THR_LOCK_DATA *data;
 
265
          for (data=lock->write.data->next ; data ; data=data->next)
 
266
          {
 
267
            if (data->type != TL_WRITE_CONCURRENT_INSERT)
 
268
            {
 
269
              fprintf(stderr,
 
270
                      "Warning at '%s': Found TL_WRITE_CONCURRENT_INSERT lock mixed with other write locks\n",
 
271
                      where);
 
272
              break;
 
273
            }
 
274
          }
 
275
        }
254
276
        if (lock->write_wait.data)
255
277
        {
256
278
          if (!allow_no_locks && 
316
338
{
317
339
  DBUG_ENTER("thr_lock_init");
318
340
  bzero((char*) lock,sizeof(*lock));
319
 
  VOID(pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST));
 
341
  pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST);
320
342
  lock->read.last= &lock->read.data;
321
343
  lock->read_wait.last= &lock->read_wait.data;
322
344
  lock->write_wait.last= &lock->write_wait.data;
333
355
void thr_lock_delete(THR_LOCK *lock)
334
356
{
335
357
  DBUG_ENTER("thr_lock_delete");
336
 
  VOID(pthread_mutex_destroy(&lock->mutex));
337
358
  pthread_mutex_lock(&THR_LOCK_lock);
338
359
  thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
339
360
  pthread_mutex_unlock(&THR_LOCK_lock);
 
361
  pthread_mutex_destroy(&lock->mutex);
340
362
  DBUG_VOID_RETURN;
341
363
}
342
364
 
386
408
 
387
409
static void wake_up_waiters(THR_LOCK *lock);
388
410
 
 
411
#if defined(ENABLED_DEBUG_SYNC)
 
412
/**
 
413
  Global pointer to be set if callback function is defined
 
414
  (e.g. in mysqld). See debug_sync.cc.
 
415
*/
 
416
void (*debug_sync_wait_for_lock_callback_ptr)(void);
 
417
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
418
 
389
419
 
390
420
static enum enum_thr_lock_result
391
421
wait_for_lock(struct st_lock_list *wait, THR_LOCK_DATA *data,
398
428
  my_bool can_deadlock= test(data->owner->info->n_cursors);
399
429
  DBUG_ENTER("wait_for_lock");
400
430
 
 
431
#if defined(ENABLED_DEBUG_SYNC)
 
432
  /*
 
433
    One can use this to signal when a thread is going to wait for a lock.
 
434
    See debug_sync.cc.
 
435
  */
 
436
  if (debug_sync_wait_for_lock_callback_ptr)
 
437
    (*debug_sync_wait_for_lock_callback_ptr)();
 
438
#endif /* defined(ENABLED_DEBUG_SYNC) */
 
439
 
401
440
  if (!in_wait_list)
402
441
  {
403
442
    (*wait->last)=data;                         /* Wait for lock */
500
539
  data->cond=0;                                 /* safety */
501
540
  data->type=lock_type;
502
541
  data->owner= owner;                           /* Must be reset ! */
503
 
  VOID(pthread_mutex_lock(&lock->mutex));
504
 
  DBUG_PRINT("lock",("data: 0x%lx  thread: 0x%lx  lock: 0x%lx  type: %d",
505
 
                     (long) data, data->owner->info->thread_id,
506
 
                     (long) lock, (int) lock_type));
 
542
  pthread_mutex_lock(&lock->mutex);
 
543
  DBUG_PRINT("lock",("data: %p  thread: 0x%lx  lock: %p  type: %d",
 
544
                     data, data->owner->info->thread_id,
 
545
                     lock, (int) lock_type));
507
546
  check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
508
547
              "enter read_lock" : "enter write_lock",0);
509
548
  if ((int) lock_type <= (int) TL_READ_NO_INSERT)
511
550
    /* Request for READ lock */
512
551
    if (lock->write.data)
513
552
    {
514
 
      /* We can allow a read lock even if there is already a write lock
 
553
      /*
 
554
        We can allow a read lock even if there is already a write lock
515
555
         on the table in one the following cases:
516
556
         - This thread alread have a write lock on the table
517
557
         - The write lock is TL_WRITE_ALLOW_READ or TL_WRITE_DELAYED
555
595
      (*lock->read.last)=data;                  /* Add to running FIFO */
556
596
      data->prev=lock->read.last;
557
597
      lock->read.last= &data->next;
558
 
      if (lock->get_status)
559
 
        (*lock->get_status)(data->status_param, 0);
560
598
      if (lock_type == TL_READ_NO_INSERT)
561
599
        lock->read_no_write_count++;
562
600
      check_locks(lock,"read lock with no write locks",0);
 
601
      if (lock->get_status)
 
602
        (*lock->get_status)(data->status_param, 0);
563
603
      statistic_increment(locks_immediate,&THR_LOCK_lock);
564
604
      goto end;
565
605
    }
609
649
    {
610
650
      if (lock->write.data->type == TL_WRITE_ONLY)
611
651
      {
 
652
        /* purecov: begin tested */
612
653
        /* Allow lock owner to bypass TL_WRITE_ONLY. */
613
654
        if (!thr_lock_owner_equal(data->owner, lock->write.data->owner))
614
655
        {
617
658
          result= THR_LOCK_ABORTED;               /* Can't wait for this one */
618
659
          goto end;
619
660
        }
 
661
        /* purecov: end */
620
662
      }
621
663
 
622
664
      /*
623
665
        The following test will not work if the old lock was a
624
666
        TL_WRITE_ALLOW_WRITE, TL_WRITE_ALLOW_READ or TL_WRITE_DELAYED in
625
667
        the same thread, but this will never happen within MySQL.
 
668
 
 
669
        The idea is to allow us to get a lock at once if we already have
 
670
        a write lock or if there is no pending write locks and if all
 
671
        write locks are of the same type and are either
 
672
        TL_WRITE_ALLOW_WRITE or TL_WRITE_CONCURRENT_INSERT
626
673
      */
627
674
      if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
628
 
          (lock_type == TL_WRITE_ALLOW_WRITE &&
629
 
           !lock->write_wait.data &&
630
 
           lock->write.data->type == TL_WRITE_ALLOW_WRITE))
 
675
          (!lock->write_wait.data && lock_type == lock->write.data->type &&
 
676
           (lock_type == TL_WRITE_ALLOW_WRITE ||
 
677
            (lock_type == TL_WRITE_CONCURRENT_INSERT &&
 
678
             lock->allow_multiple_concurrent_insert))))
631
679
      {
632
 
        /*
633
 
          We have already got a write lock or all locks are
634
 
          TL_WRITE_ALLOW_WRITE
635
 
        */
636
 
        DBUG_PRINT("info", ("write_wait.data: 0x%lx  old_type: %d",
637
 
                            (ulong) lock->write_wait.data,
 
680
        DBUG_PRINT("info", ("write_wait.data: %p  old_type: %d",
 
681
                            lock->write_wait.data,
638
682
                            lock->write.data->type));
639
683
 
640
684
        (*lock->write.last)=data;       /* Add to running fifo */
641
685
        data->prev=lock->write.last;
642
686
        lock->write.last= &data->next;
643
687
        check_locks(lock,"second write lock",0);
644
 
        if (data->lock->get_status)
645
 
          (*data->lock->get_status)(data->status_param, 0);
 
688
        if (lock->get_status)
 
689
          (*lock->get_status)(data->status_param,
 
690
                              lock_type == TL_WRITE_CONCURRENT_INSERT);
646
691
        statistic_increment(locks_immediate,&THR_LOCK_lock);
647
692
        goto end;
648
693
      }
651
696
    }
652
697
    else
653
698
    {
654
 
      DBUG_PRINT("info", ("write_wait.data: 0x%lx",
655
 
                          (ulong) lock->write_wait.data));
 
699
      DBUG_PRINT("info", ("write_wait.data: %p",
 
700
                          lock->write_wait.data));
656
701
      if (!lock->write_wait.data)
657
702
      {                                         /* no scheduled write locks */
658
703
        my_bool concurrent_insert= 0;
675
720
          (*lock->write.last)=data;             /* Add as current write lock */
676
721
          data->prev=lock->write.last;
677
722
          lock->write.last= &data->next;
678
 
          if (data->lock->get_status)
679
 
            (*data->lock->get_status)(data->status_param, concurrent_insert);
 
723
          if (lock->get_status)
 
724
            (*lock->get_status)(data->status_param, concurrent_insert);
680
725
          check_locks(lock,"only write lock",0);
681
726
          statistic_increment(locks_immediate,&THR_LOCK_lock);
682
727
          goto end;
750
795
                       data->owner->info->thread_id));
751
796
    /* purecov: end */
752
797
    data->cond=0;                               /* Mark thread free */
753
 
    VOID(pthread_cond_signal(cond));
 
798
    pthread_cond_signal(cond);
754
799
  } while ((data=data->next));
755
800
  *lock->read_wait.last=0;
756
801
  if (!lock->read_wait.data)
765
810
  THR_LOCK *lock=data->lock;
766
811
  enum thr_lock_type lock_type=data->type;
767
812
  DBUG_ENTER("thr_unlock");
768
 
  DBUG_PRINT("lock",("data: 0x%lx  thread: 0x%lx  lock: 0x%lx",
769
 
                     (long) data, data->owner->info->thread_id, (long) lock));
 
813
  DBUG_PRINT("lock",("data: %p  thread: 0x%lx  lock: %p",
 
814
                     data, data->owner->info->thread_id, lock));
770
815
  pthread_mutex_lock(&lock->mutex);
771
816
  check_locks(lock,"start of release lock",0);
772
817
 
784
829
  }
785
830
  else
786
831
    lock->write.last=data->prev;
787
 
  if (lock_type >= TL_WRITE_CONCURRENT_INSERT)
788
 
  {
789
 
    if (lock->update_status)
790
 
      (*lock->update_status)(data->status_param);
791
 
  }
792
 
  else
793
 
  {
794
 
    if (lock->restore_status)
795
 
      (*lock->restore_status)(data->status_param);
796
 
  }
797
832
  if (lock_type == TL_READ_NO_INSERT)
798
833
    lock->read_no_write_count--;
799
834
  data->type=TL_UNLOCK;                         /* Mark unlocked */
816
851
{
817
852
  THR_LOCK_DATA *data;
818
853
  enum thr_lock_type lock_type;
819
 
 
820
854
  DBUG_ENTER("wake_up_waiters");
821
855
 
822
856
  if (!lock->write.data)                        /* If no active write locks */
860
894
          {
861
895
            pthread_cond_t *cond=data->cond;
862
896
            data->cond=0;                               /* Mark thread free */
863
 
            VOID(pthread_cond_signal(cond));    /* Start waiting thread */
 
897
            pthread_cond_signal(cond);  /* Start waiting thread */
864
898
          }
865
899
          if (data->type != TL_WRITE_ALLOW_WRITE ||
866
900
              !lock->write_wait.data ||
911
945
        lock->write.last= &data->next;
912
946
        data->next=0;                           /* Only one write lock */
913
947
        data->cond=0;                           /* Mark thread free */
914
 
        VOID(pthread_cond_signal(cond));        /* Start waiting thread */
 
948
        pthread_cond_signal(cond);      /* Start waiting thread */
915
949
      } while (lock_type == TL_WRITE_ALLOW_WRITE &&
916
950
               (data=lock->write_wait.data) &&
917
951
               data->type == TL_WRITE_ALLOW_WRITE);
964
998
{
965
999
  THR_LOCK_DATA **pos,**end;
966
1000
  DBUG_ENTER("thr_multi_lock");
967
 
  DBUG_PRINT("lock",("data: 0x%lx  count: %d", (long) data, count));
 
1001
  DBUG_PRINT("lock",("data: %p  count: %d", data, count));
968
1002
  if (count > 1)
969
1003
    sort_locks(data,count);
970
1004
  /* lock everything */
981
1015
           (long) pos[0]->lock, pos[0]->type); fflush(stdout);
982
1016
#endif
983
1017
  }
984
 
  /*
985
 
    Ensure that all get_locks() have the same status
986
 
    If we lock the same table multiple times, we must use the same
987
 
    status_param!
988
 
  */
 
1018
  thr_lock_merge_status(data, count);
 
1019
  DBUG_RETURN(THR_LOCK_SUCCESS);
 
1020
}
 
1021
 
 
1022
 
 
1023
/**
 
1024
  Ensure that all locks for a given table have the same
 
1025
  status_param.
 
1026
 
 
1027
  This is a MyISAM and possibly Maria specific crutch. MyISAM
 
1028
  engine stores data file length, record count and other table
 
1029
  properties in status_param member of handler. When a table is
 
1030
  locked, connection-local copy is made from a global copy
 
1031
  (myisam_share) by mi_get_status(). When a table is unlocked,
 
1032
  the changed status is transferred back to the global share by
 
1033
  mi_update_status().
 
1034
 
 
1035
  One thing MyISAM doesn't do is to ensure that when the same
 
1036
  table is opened twice in a connection all instances share the
 
1037
  same status_param. This is necessary, however: for one, to keep
 
1038
  all instances of a connection "on the same page" with regard to
 
1039
  the current state of the table. For other, unless this is done,
 
1040
  myisam_share will always get updated from the last unlocked
 
1041
  instance (in mi_update_status()), and when this instance was not
 
1042
  the one that was used to update data, records may be lost.
 
1043
 
 
1044
  For each table, this function looks up the last lock_data in the
 
1045
  list of acquired locks, and makes sure that all other instances
 
1046
  share status_param with it.
 
1047
*/
 
1048
 
 
1049
void
 
1050
thr_lock_merge_status(THR_LOCK_DATA **data, uint count)
 
1051
{
989
1052
#if !defined(DONT_USE_RW_LOCKS)
 
1053
  THR_LOCK_DATA **pos= data;
 
1054
  THR_LOCK_DATA **end= data + count;
990
1055
  if (count > 1)
991
1056
  {
992
1057
    THR_LOCK_DATA *last_lock= end[-1];
1028
1093
    } while (pos != data);
1029
1094
  }
1030
1095
#endif
1031
 
  DBUG_RETURN(THR_LOCK_SUCCESS);
1032
1096
}
1033
1097
 
1034
1098
  /* free all locks */
1037
1101
{
1038
1102
  THR_LOCK_DATA **pos,**end;
1039
1103
  DBUG_ENTER("thr_multi_unlock");
1040
 
  DBUG_PRINT("lock",("data: 0x%lx  count: %d", (long) data, count));
 
1104
  DBUG_PRINT("lock",("data: %p  count: %d", data, count));
1041
1105
 
1042
1106
  for (pos=data,end=data+count; pos < end ; pos++)
1043
1107
  {
1050
1114
      thr_unlock(*pos);
1051
1115
    else
1052
1116
    {
1053
 
      DBUG_PRINT("lock",("Free lock: data: 0x%lx  thread: 0x%lx  lock: 0x%lx",
1054
 
                         (long) *pos, (*pos)->owner->info->thread_id,
1055
 
                         (long) (*pos)->lock));
 
1117
      DBUG_PRINT("lock",("Free lock: data: %p  thread: 0x%lx  lock: %p",
 
1118
                         *pos, (*pos)->owner->info->thread_id,
 
1119
                         (*pos)->lock));
1056
1120
    }
1057
1121
  }
1058
1122
  DBUG_VOID_RETURN;
1379
1443
  {
1380
1444
    if (!lock->read.data)                       /* No read locks */
1381
1445
    {                                           /* We have the lock */
1382
 
      if (data->lock->get_status)
1383
 
        (*data->lock->get_status)(data->status_param, 0);
 
1446
      if (lock->get_status)
 
1447
        (*lock->get_status)(data->status_param, 0);
1384
1448
      pthread_mutex_unlock(&lock->mutex);
1385
1449
      DBUG_RETURN(0);
1386
1450
    }
1478
1542
       list= list_rest(list))
1479
1543
  {
1480
1544
    THR_LOCK *lock=(THR_LOCK*) list->data;
1481
 
    VOID(pthread_mutex_lock(&lock->mutex));
 
1545
    pthread_mutex_lock(&lock->mutex);
1482
1546
    printf("lock: 0x%lx:",(ulong) lock);
1483
1547
    if ((lock->write_wait.data || lock->read_wait.data) &&
1484
1548
        (! lock->read.data && ! lock->write.data))
1496
1560
    thr_print_lock("write_wait",&lock->write_wait);
1497
1561
    thr_print_lock("read",&lock->read);
1498
1562
    thr_print_lock("read_wait",&lock->read_wait);
1499
 
    VOID(pthread_mutex_unlock(&lock->mutex));
 
1563
    pthread_mutex_unlock(&lock->mutex);
1500
1564
    puts("");
1501
1565
  }
1502
1566
  fflush(stdout);
1518
1582
  enum thr_lock_type lock_type;
1519
1583
};
1520
1584
 
1521
 
THR_LOCK locks[5];                      /* 4 locks */
 
1585
THR_LOCK locks[6];                      /* Number of locks +1 */
1522
1586
 
1523
1587
struct st_test test_0[] = {{0,TL_READ}};        /* One lock */
1524
1588
struct st_test test_1[] = {{0,TL_READ},{0,TL_WRITE}}; /* Read and write lock of lock 0 */
1538
1602
struct st_test test_15[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_READ}};
1539
1603
struct st_test test_16[] = {{0,TL_WRITE_ALLOW_WRITE},{1,TL_WRITE_ALLOW_WRITE}};
1540
1604
 
1541
 
struct st_test *tests[] = {test_0,test_1,test_2,test_3,test_4,test_5,test_6,
1542
 
                           test_7,test_8,test_9,test_10,test_11,test_12,
1543
 
                           test_13,test_14,test_15,test_16};
 
1605
struct st_test test_17[] = {{5,TL_WRITE_CONCURRENT_INSERT}};
 
1606
struct st_test test_18[] = {{5,TL_WRITE_CONCURRENT_INSERT}};
 
1607
struct st_test test_19[] = {{5,TL_READ}};
 
1608
struct st_test test_20[] = {{5,TL_READ_NO_INSERT}};
 
1609
struct st_test test_21[] = {{5,TL_WRITE}};
 
1610
 
 
1611
 
 
1612
struct st_test *tests[]=
 
1613
{
 
1614
  test_0, test_1, test_2, test_3, test_4, test_5, test_6, test_7, test_8,
 
1615
  test_9, test_10, test_11, test_12, test_13, test_14, test_15, test_16,
 
1616
  test_17, test_18, test_19, test_20, test_21
 
1617
};
 
1618
 
1544
1619
int lock_counts[]= {sizeof(test_0)/sizeof(struct st_test),
1545
1620
                    sizeof(test_1)/sizeof(struct st_test),
1546
1621
                    sizeof(test_2)/sizeof(struct st_test),
1557
1632
                    sizeof(test_13)/sizeof(struct st_test),
1558
1633
                    sizeof(test_14)/sizeof(struct st_test),
1559
1634
                    sizeof(test_15)/sizeof(struct st_test),
1560
 
                    sizeof(test_16)/sizeof(struct st_test)
 
1635
                    sizeof(test_16)/sizeof(struct st_test),
 
1636
                    sizeof(test_17)/sizeof(struct st_test),
 
1637
                    sizeof(test_18)/sizeof(struct st_test),
 
1638
                    sizeof(test_19)/sizeof(struct st_test),
 
1639
                    sizeof(test_20)/sizeof(struct st_test),
 
1640
                    sizeof(test_21)/sizeof(struct st_test)
1561
1641
};
1562
1642
 
1563
1643
 
1601
1681
 
1602
1682
  printf("Thread %s (%d) started\n",my_thread_name(),param); fflush(stdout);
1603
1683
 
1604
 
 
1605
1684
  thr_lock_info_init(&lock_info);
1606
1685
  thr_lock_owner_init(&owner, &lock_info);
1607
1686
  for (i=0; i < lock_counts[param] ; i++)
1636
1715
  thr_print_locks();
1637
1716
  pthread_mutex_lock(&LOCK_thread_count);
1638
1717
  thread_count--;
1639
 
  VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
 
1718
  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
1640
1719
  pthread_mutex_unlock(&LOCK_thread_count);
1641
1720
  free((uchar*) arg);
1642
1721
  return 0;
1647
1726
{
1648
1727
  pthread_t tid;
1649
1728
  pthread_attr_t thr_attr;
1650
 
  int i,*param,error;
 
1729
  int *param,error;
 
1730
  uint i;
1651
1731
  MY_INIT(argv[0]);
1652
1732
  if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
1653
1733
    DBUG_PUSH(argv[1]+2);
1667
1747
    exit(1);
1668
1748
  }
1669
1749
 
1670
 
  for (i=0 ; i < (int) array_elements(locks) ; i++)
 
1750
  for (i=0 ; i < array_elements(locks) ; i++)
1671
1751
  {
1672
1752
    thr_lock_init(locks+i);
1673
1753
    locks[i].check_status= test_check_status;
1674
1754
    locks[i].update_status=test_update_status;
1675
1755
    locks[i].copy_status=  test_copy_status;
1676
1756
    locks[i].get_status=   test_get_status;
 
1757
    locks[i].allow_multiple_concurrent_insert= 1;
1677
1758
  }
1678
1759
  if ((error=pthread_attr_init(&thr_attr)))
1679
1760
  {
1697
1778
  }
1698
1779
#endif
1699
1780
#ifdef HAVE_THR_SETCONCURRENCY
1700
 
  VOID(thr_setconcurrency(2));
 
1781
  (void) thr_setconcurrency(2);
1701
1782
#endif
1702
 
  for (i=0 ; i < (int) array_elements(lock_counts) ; i++)
 
1783
  for (i=0 ; i < array_elements(lock_counts) ; i++)
1703
1784
  {
1704
1785
    param=(int*) malloc(sizeof(int));
1705
1786
    *param=i;
1731
1812
  }
1732
1813
  if ((error=pthread_mutex_unlock(&LOCK_thread_count)))
1733
1814
    fprintf(stderr,"Got error: %d from pthread_mutex_unlock\n",error);
1734
 
  for (i=0 ; i < (int) array_elements(locks) ; i++)
 
1815
  for (i=0 ; i < array_elements(locks) ; i++)
1735
1816
    thr_lock_delete(locks+i);
1736
1817
#ifdef EXTRA_DEBUG
1737
1818
  if (found_errors)