~drizzle-trunk/drizzle/development

« back to all changes in this revision

Viewing changes to mysys/thr_lock.c

  • Committer: Monty Taylor
  • Date: 2008-10-16 06:32:30 UTC
  • mto: (511.1.5 codestyle)
  • mto: This revision was merged to the branch mainline in revision 521.
  • Revision ID: monty@inaugust.com-20081016063230-4brxsra0qsmsg84q
Added -Wunused-macros.

Show diffs side-by-side

added added

removed removed

Lines of Context:
70
70
 
71
71
*/
72
72
 
73
 
#if !defined(MAIN) && !defined(DBUG_OFF) && !defined(EXTRA_DEBUG)
74
 
#define FORCE_DBUG_OFF
75
 
#endif
76
 
 
77
73
#include "mysys_priv.h"
78
74
 
79
75
#include "thr_lock.h"
80
 
#include <m_string.h>
 
76
#include <mystrings/m_string.h>
81
77
#include <errno.h>
82
78
 
 
79
#if TIME_WITH_SYS_TIME
 
80
# include <sys/time.h>
 
81
# include <time.h>
 
82
#else
 
83
# if HAVE_SYS_TIME_H
 
84
#  include <sys/time.h>
 
85
# else
 
86
#  include <time.h>
 
87
# endif
 
88
#endif  
 
89
 
 
90
#include <drizzled/util/test.h>
 
91
 
83
92
bool thr_lock_inited=0;
84
 
ulong locks_immediate = 0L, locks_waited = 0L;
 
93
uint32_t locks_immediate = 0L, locks_waited = 0L;
85
94
ulong table_lock_wait_timeout;
86
95
enum thr_lock_type thr_upgraded_concurrent_insert_lock = TL_WRITE;
87
96
 
114
123
  return rhs == lhs;
115
124
}
116
125
 
117
 
 
118
126
#ifdef EXTRA_DEBUG
119
127
#define MAX_FOUND_ERRORS        10              /* Report 10 first errors */
120
 
static uint found_errors=0;
 
128
static uint32_t found_errors=0;
121
129
 
122
130
static int check_lock(struct st_lock_list *list, const char* lock_type,
123
131
                      const char *where, bool same_owner, bool no_cond)
124
132
{
125
133
  THR_LOCK_DATA *data,**prev;
126
 
  uint count=0;
 
134
  uint32_t count=0;
127
135
  THR_LOCK_OWNER *first_owner;
128
136
 
129
137
  prev= &list->data;
182
190
static void check_locks(THR_LOCK *lock, const char *where,
183
191
                        bool allow_no_locks)
184
192
{
185
 
  uint old_found_errors=found_errors;
186
 
  DBUG_ENTER("check_locks");
 
193
  uint32_t old_found_errors=found_errors;
187
194
 
188
195
  if (found_errors < MAX_FOUND_ERRORS)
189
196
  {
195
202
 
196
203
    if (found_errors < MAX_FOUND_ERRORS)
197
204
    {
198
 
      uint count=0;
 
205
      uint32_t count=0;
199
206
      THR_LOCK_DATA *data;
200
207
      for (data=lock->read.data ; data ; data=data->next)
201
208
      {
202
209
        if ((int) data->type == (int) TL_READ_NO_INSERT)
203
210
          count++;
204
211
        /* Protect against infinite loop. */
205
 
        DBUG_ASSERT(count <= lock->read_no_write_count);
 
212
        assert(count <= lock->read_no_write_count);
206
213
      }
207
214
      if (count != lock->read_no_write_count)
208
215
      {
275
282
            fprintf(stderr,
276
283
                    "Warning at '%s': Found lock of type %d that is write and read locked\n",
277
284
                    where, lock->write.data->type);
278
 
            DBUG_PRINT("warning",("At '%s': Found lock of type %d that is write and read locked\n",
279
 
                    where, lock->write.data->type));
280
 
 
281
285
          }
282
286
        }
283
287
        if (lock->read_wait.data)
295
299
        }
296
300
      }
297
301
    }
298
 
    if (found_errors != old_found_errors)
299
 
    {
300
 
      DBUG_PRINT("error",("Found wrong lock"));
301
 
    }
302
302
  }
303
 
  DBUG_VOID_RETURN;
 
303
  return;
304
304
}
305
305
 
306
306
#else /* EXTRA_DEBUG */
312
312
 
313
313
void thr_lock_init(THR_LOCK *lock)
314
314
{
315
 
  DBUG_ENTER("thr_lock_init");
316
 
  bzero((char*) lock,sizeof(*lock));
317
 
  VOID(pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST));
 
315
  memset(lock, 0, sizeof(*lock));
 
316
  pthread_mutex_init(&lock->mutex,MY_MUTEX_INIT_FAST);
318
317
  lock->read.last= &lock->read.data;
319
318
  lock->read_wait.last= &lock->read_wait.data;
320
319
  lock->write_wait.last= &lock->write_wait.data;
324
323
  lock->list.data=(void*) lock;
325
324
  thr_lock_thread_list=list_add(thr_lock_thread_list,&lock->list);
326
325
  pthread_mutex_unlock(&THR_LOCK_lock);
327
 
  DBUG_VOID_RETURN;
 
326
  return;
328
327
}
329
328
 
330
329
 
331
330
void thr_lock_delete(THR_LOCK *lock)
332
331
{
333
 
  DBUG_ENTER("thr_lock_delete");
334
 
  VOID(pthread_mutex_destroy(&lock->mutex));
 
332
  pthread_mutex_destroy(&lock->mutex);
335
333
  pthread_mutex_lock(&THR_LOCK_lock);
336
334
  thr_lock_thread_list=list_delete(thr_lock_thread_list,&lock->list);
337
335
  pthread_mutex_unlock(&THR_LOCK_lock);
338
 
  DBUG_VOID_RETURN;
 
336
  return;
339
337
}
340
338
 
341
339
 
394
392
  struct timespec wait_timeout;
395
393
  enum enum_thr_lock_result result= THR_LOCK_ABORTED;
396
394
  bool can_deadlock= test(data->owner->info->n_cursors);
397
 
  DBUG_ENTER("wait_for_lock");
398
395
 
399
396
  if (!in_wait_list)
400
397
  {
433
430
    */
434
431
    if (data->cond == 0)
435
432
    {
436
 
      DBUG_PRINT("thr_lock", ("lock granted/aborted"));
437
433
      break;
438
434
    }
439
435
    if (rc == ETIMEDOUT || rc == ETIME)
440
436
    {
441
437
      /* purecov: begin inspected */
442
 
      DBUG_PRINT("thr_lock", ("lock timed out"));
443
438
      result= THR_LOCK_WAIT_TIMEOUT;
444
439
      break;
445
440
      /* purecov: end */
446
441
    }
447
442
  }
448
 
  DBUG_PRINT("thr_lock", ("aborted: %d  in_wait_list: %d",
449
 
                          thread_var->abort, in_wait_list));
450
 
 
451
443
  if (data->cond || data->type == TL_UNLOCK)
452
444
  {
453
445
    if (data->cond)                             /* aborted or timed out */
462
454
    }
463
455
    else
464
456
    {
465
 
      DBUG_PRINT("thr_lock", ("lock aborted"));
466
457
      check_locks(data->lock, "aborted wait_for_lock", 0);
467
458
    }
468
459
  }
480
471
  thread_var->current_mutex= 0;
481
472
  thread_var->current_cond=  0;
482
473
  pthread_mutex_unlock(&thread_var->mutex);
483
 
  DBUG_RETURN(result);
 
474
  return(result);
484
475
}
485
476
 
486
477
 
492
483
  enum enum_thr_lock_result result= THR_LOCK_SUCCESS;
493
484
  struct st_lock_list *wait_queue;
494
485
  THR_LOCK_DATA *lock_owner;
495
 
  DBUG_ENTER("thr_lock");
496
486
 
497
487
  data->next=0;
498
488
  data->cond=0;                                 /* safety */
499
489
  data->type=lock_type;
500
490
  data->owner= owner;                           /* Must be reset ! */
501
 
  VOID(pthread_mutex_lock(&lock->mutex));
502
 
  DBUG_PRINT("lock",("data: 0x%lx  thread: 0x%lx  lock: 0x%lx  type: %d",
503
 
                     (long) data, data->owner->info->thread_id,
504
 
                     (long) lock, (int) lock_type));
 
491
  pthread_mutex_lock(&lock->mutex);
505
492
  check_locks(lock,(uint) lock_type <= (uint) TL_READ_NO_INSERT ?
506
493
              "enter read_lock" : "enter write_lock",0);
507
494
  if ((int) lock_type <= (int) TL_READ_NO_INSERT)
518
505
           and the read lock is not TL_READ_NO_INSERT
519
506
      */
520
507
 
521
 
      DBUG_PRINT("lock",("write locked 1 by thread: 0x%lx",
522
 
                         lock->write.data->owner->info->thread_id));
523
508
      if (thr_lock_owner_equal(data->owner, lock->write.data->owner) ||
524
509
          (lock->write.data->type <= TL_WRITE_DELAYED &&
525
510
           (((int) lock_type <= (int) TL_READ_HIGH_PRIORITY) ||
631
616
          We have already got a write lock or all locks are
632
617
          TL_WRITE_ALLOW_WRITE
633
618
        */
634
 
        DBUG_PRINT("info", ("write_wait.data: 0x%lx  old_type: %d",
635
 
                            (ulong) lock->write_wait.data,
636
 
                            lock->write.data->type));
637
619
 
638
620
        (*lock->write.last)=data;       /* Add to running fifo */
639
621
        data->prev=lock->write.last;
644
626
        statistic_increment(locks_immediate,&THR_LOCK_lock);
645
627
        goto end;
646
628
      }
647
 
      DBUG_PRINT("lock",("write locked 2 by thread: 0x%lx",
648
 
                         lock->write.data->owner->info->thread_id));
649
629
    }
650
630
    else
651
631
    {
652
 
      DBUG_PRINT("info", ("write_wait.data: 0x%lx",
653
 
                          (ulong) lock->write_wait.data));
654
632
      if (!lock->write_wait.data)
655
633
      {                                         /* no scheduled write locks */
656
634
        bool concurrent_insert= 0;
680
658
          goto end;
681
659
        }
682
660
      }
683
 
      DBUG_PRINT("lock",("write locked 3 by thread: 0x%lx  type: %d",
684
 
                         lock->read.data->owner->info->thread_id, data->type));
685
661
    }
686
662
    wait_queue= &lock->write_wait;
687
663
  }
694
670
  lock_owner= lock->read.data ? lock->read.data : lock->write.data;
695
671
  if (lock_owner && lock_owner->owner->info == owner->info)
696
672
  {
697
 
    DBUG_PRINT("lock",("deadlock"));
698
673
    result= THR_LOCK_DEADLOCK;
699
674
    goto end;
700
675
  }
701
676
  /* Can't get lock yet;  Wait for it */
702
 
  DBUG_RETURN(wait_for_lock(wait_queue, data, 0));
 
677
  return(wait_for_lock(wait_queue, data, 0));
703
678
end:
704
679
  pthread_mutex_unlock(&lock->mutex);
705
 
  DBUG_RETURN(result);
 
680
  return(result);
706
681
}
707
682
 
708
683
 
743
718
      }
744
719
      lock->read_no_write_count++;
745
720
    }      
746
 
    /* purecov: begin inspected */
747
 
    DBUG_PRINT("lock",("giving read lock to thread: 0x%lx",
748
 
                       data->owner->info->thread_id));
749
 
    /* purecov: end */
750
721
    data->cond=0;                               /* Mark thread free */
751
 
    VOID(pthread_cond_signal(cond));
 
722
    pthread_cond_signal(cond);
752
723
  } while ((data=data->next));
753
724
  *lock->read_wait.last=0;
754
725
  if (!lock->read_wait.data)
762
733
{
763
734
  THR_LOCK *lock=data->lock;
764
735
  enum thr_lock_type lock_type=data->type;
765
 
  DBUG_ENTER("thr_unlock");
766
 
  DBUG_PRINT("lock",("data: 0x%lx  thread: 0x%lx  lock: 0x%lx",
767
 
                     (long) data, data->owner->info->thread_id, (long) lock));
768
736
  pthread_mutex_lock(&lock->mutex);
769
737
  check_locks(lock,"start of release lock",0);
770
738
 
798
766
  check_locks(lock,"after releasing lock",1);
799
767
  wake_up_waiters(lock);
800
768
  pthread_mutex_unlock(&lock->mutex);
801
 
  DBUG_VOID_RETURN;
 
769
  return;
802
770
}
803
771
 
804
772
 
815
783
  THR_LOCK_DATA *data;
816
784
  enum thr_lock_type lock_type;
817
785
 
818
 
  DBUG_ENTER("wake_up_waiters");
819
 
 
820
786
  if (!lock->write.data)                        /* If no active write locks */
821
787
  {
822
788
    data=lock->write_wait.data;
833
799
          lock->write_lock_count=0;
834
800
          if (lock->read_wait.data)
835
801
          {
836
 
            DBUG_PRINT("info",("Freeing all read_locks because of max_write_lock_count"));
837
802
            free_all_read_locks(lock,0);
838
803
            goto end;
839
804
          }
851
816
          if (data->type == TL_WRITE_CONCURRENT_INSERT &&
852
817
              (*lock->check_status)(data->status_param))
853
818
            data->type=TL_WRITE;                        /* Upgrade lock */
854
 
          /* purecov: begin inspected */
855
 
          DBUG_PRINT("lock",("giving write lock of type %d to thread: 0x%lx",
856
 
                             data->type, data->owner->info->thread_id));
857
 
          /* purecov: end */
858
819
          {
859
820
            pthread_cond_t *cond=data->cond;
860
821
            data->cond=0;                               /* Mark thread free */
861
 
            VOID(pthread_cond_signal(cond));    /* Start waiting thread */
 
822
            pthread_cond_signal(cond);  /* Start waiting thread */
862
823
          }
863
824
          if (data->type != TL_WRITE_ALLOW_WRITE ||
864
825
              !lock->write_wait.data ||
875
836
                            data &&
876
837
                            (data->type == TL_WRITE_CONCURRENT_INSERT ||
877
838
                             data->type == TL_WRITE_ALLOW_WRITE));
878
 
      else
879
 
      {
880
 
        DBUG_PRINT("lock",("No waiting read locks to free"));
881
 
      }
882
839
    }
883
840
    else if (data &&
884
841
             (lock_type=data->type) <= TL_WRITE_DELAYED &&
909
866
        lock->write.last= &data->next;
910
867
        data->next=0;                           /* Only one write lock */
911
868
        data->cond=0;                           /* Mark thread free */
912
 
        VOID(pthread_cond_signal(cond));        /* Start waiting thread */
 
869
        pthread_cond_signal(cond);      /* Start waiting thread */
913
870
      } while (lock_type == TL_WRITE_ALLOW_WRITE &&
914
871
               (data=lock->write_wait.data) &&
915
872
               data->type == TL_WRITE_ALLOW_WRITE);
923
880
  }
924
881
end:
925
882
  check_locks(lock, "after waking up waiters", 0);
926
 
  DBUG_VOID_RETURN;
 
883
  return;
927
884
}
928
885
 
929
886
 
934
891
*/
935
892
 
936
893
 
937
 
#define LOCK_CMP(A,B) ((uchar*) (A->lock) - (uint) ((A)->type) < (uchar*) (B->lock)- (uint) ((B)->type))
 
894
#define LOCK_CMP(A,B) ((unsigned char*) (A->lock) - (uint) ((A)->type) < (unsigned char*) (B->lock)- (uint) ((B)->type))
938
895
 
939
 
static void sort_locks(THR_LOCK_DATA **data,uint count)
 
896
static void sort_locks(THR_LOCK_DATA **data,uint32_t count)
940
897
{
941
898
  THR_LOCK_DATA **pos,**end,**prev,*tmp;
942
899
 
958
915
 
959
916
 
960
917
enum enum_thr_lock_result
961
 
thr_multi_lock(THR_LOCK_DATA **data, uint count, THR_LOCK_OWNER *owner)
 
918
thr_multi_lock(THR_LOCK_DATA **data, uint32_t count, THR_LOCK_OWNER *owner)
962
919
{
963
920
  THR_LOCK_DATA **pos,**end;
964
 
  DBUG_ENTER("thr_multi_lock");
965
 
  DBUG_PRINT("lock",("data: 0x%lx  count: %d", (long) data, count));
966
921
  if (count > 1)
967
922
    sort_locks(data,count);
968
923
  /* lock everything */
972
927
    if (result != THR_LOCK_SUCCESS)
973
928
    {                                           /* Aborted */
974
929
      thr_multi_unlock(data,(uint) (pos-data));
975
 
      DBUG_RETURN(result);
 
930
      return(result);
976
931
    }
977
932
#ifdef MAIN
978
933
    printf("Thread: %s  Got lock: 0x%lx  type: %d\n",my_thread_name(),
1026
981
    } while (pos != data);
1027
982
  }
1028
983
#endif
1029
 
  DBUG_RETURN(THR_LOCK_SUCCESS);
 
984
  return(THR_LOCK_SUCCESS);
1030
985
}
1031
986
 
1032
987
  /* free all locks */
1033
988
 
1034
 
void thr_multi_unlock(THR_LOCK_DATA **data,uint count)
 
989
void thr_multi_unlock(THR_LOCK_DATA **data,uint32_t count)
1035
990
{
1036
991
  THR_LOCK_DATA **pos,**end;
1037
 
  DBUG_ENTER("thr_multi_unlock");
1038
 
  DBUG_PRINT("lock",("data: 0x%lx  count: %d", (long) data, count));
1039
992
 
1040
993
  for (pos=data,end=data+count; pos < end ; pos++)
1041
994
  {
1046
999
#endif
1047
1000
    if ((*pos)->type != TL_UNLOCK)
1048
1001
      thr_unlock(*pos);
1049
 
    else
1050
 
    {
1051
 
      DBUG_PRINT("lock",("Free lock: data: 0x%lx  thread: 0x%lx  lock: 0x%lx",
1052
 
                         (long) *pos, (*pos)->owner->info->thread_id,
1053
 
                         (long) (*pos)->lock));
1054
 
    }
1055
1002
  }
1056
 
  DBUG_VOID_RETURN;
 
1003
  return;
1057
1004
}
1058
1005
 
1059
1006
/*
1064
1011
void thr_abort_locks(THR_LOCK *lock, bool upgrade_lock)
1065
1012
{
1066
1013
  THR_LOCK_DATA *data;
1067
 
  DBUG_ENTER("thr_abort_locks");
1068
1014
  pthread_mutex_lock(&lock->mutex);
1069
1015
 
1070
1016
  for (data=lock->read_wait.data; data ; data=data->next)
1086
1032
  if (upgrade_lock && lock->write.data)
1087
1033
    lock->write.data->type=TL_WRITE_ONLY;
1088
1034
  pthread_mutex_unlock(&lock->mutex);
1089
 
  DBUG_VOID_RETURN;
 
1035
  return;
1090
1036
}
1091
1037
 
1092
1038
 
1100
1046
{
1101
1047
  THR_LOCK_DATA *data;
1102
1048
  bool found= false;
1103
 
  DBUG_ENTER("thr_abort_locks_for_thread");
1104
1049
 
1105
1050
  pthread_mutex_lock(&lock->mutex);
1106
1051
  for (data= lock->read_wait.data; data ; data= data->next)
1107
1052
  {
1108
1053
    if (data->owner->info->thread_id == thread_id)    /* purecov: tested */
1109
1054
    {
1110
 
      DBUG_PRINT("info",("Aborting read-wait lock"));
1111
1055
      data->type= TL_UNLOCK;                    /* Mark killed */
1112
1056
      /* It's safe to signal the cond first: we're still holding the mutex. */
1113
1057
      found= true;
1124
1068
  {
1125
1069
    if (data->owner->info->thread_id == thread_id) /* purecov: tested */
1126
1070
    {
1127
 
      DBUG_PRINT("info",("Aborting write-wait lock"));
1128
1071
      data->type= TL_UNLOCK;
1129
1072
      found= true;
1130
1073
      pthread_cond_signal(data->cond);
1138
1081
  }
1139
1082
  wake_up_waiters(lock);
1140
1083
  pthread_mutex_unlock(&lock->mutex);
1141
 
  DBUG_RETURN(found);
 
1084
  return(found);
1142
1085
}
1143
1086
 
1144
1087
 
1176
1119
                              enum thr_lock_type new_lock_type)
1177
1120
{
1178
1121
  THR_LOCK *lock=in_data->lock;
1179
 
#ifndef DBUG_OFF
1180
 
  enum thr_lock_type old_lock_type= in_data->type;
1181
 
#endif
1182
 
  DBUG_ENTER("thr_downgrade_write_only_lock");
1183
1122
 
1184
1123
  pthread_mutex_lock(&lock->mutex);
1185
 
  DBUG_ASSERT(old_lock_type == TL_WRITE_ONLY);
1186
 
  DBUG_ASSERT(old_lock_type > new_lock_type);
1187
1124
  in_data->type= new_lock_type;
1188
1125
  check_locks(lock,"after downgrading lock",0);
1189
1126
 
1190
1127
  pthread_mutex_unlock(&lock->mutex);
1191
 
  DBUG_VOID_RETURN;
 
1128
  return;
1192
1129
}
1193
1130
 
1194
1131
/* Upgrade a WRITE_DELAY lock to a WRITE_LOCK */
1196
1133
bool thr_upgrade_write_delay_lock(THR_LOCK_DATA *data)
1197
1134
{
1198
1135
  THR_LOCK *lock=data->lock;
1199
 
  DBUG_ENTER("thr_upgrade_write_delay_lock");
1200
1136
 
1201
1137
  pthread_mutex_lock(&lock->mutex);
1202
1138
  if (data->type == TL_UNLOCK || data->type >= TL_WRITE_LOW_PRIORITY)
1203
1139
  {
1204
1140
    pthread_mutex_unlock(&lock->mutex);
1205
 
    DBUG_RETURN(data->type == TL_UNLOCK);       /* Test if Aborted */
 
1141
    return(data->type == TL_UNLOCK);    /* Test if Aborted */
1206
1142
  }
1207
1143
  check_locks(lock,"before upgrading lock",0);
1208
1144
  /* TODO:  Upgrade to TL_WRITE_CONCURRENT_INSERT in some cases */
1216
1152
      if (data->lock->get_status)
1217
1153
        (*data->lock->get_status)(data->status_param, 0);
1218
1154
      pthread_mutex_unlock(&lock->mutex);
1219
 
      DBUG_RETURN(0);
 
1155
      return(0);
1220
1156
    }
1221
1157
 
1222
1158
    if (((*data->prev)=data->next))             /* remove from lock-list */
1236
1172
  {
1237
1173
    check_locks(lock,"waiting for lock",0);
1238
1174
  }
1239
 
  DBUG_RETURN(wait_for_lock(&lock->write_wait,data,1));
 
1175
  return(wait_for_lock(&lock->write_wait,data,1));
1240
1176
}
1241
1177
 
1242
1178
 
1245
1181
bool thr_reschedule_write_lock(THR_LOCK_DATA *data)
1246
1182
{
1247
1183
  THR_LOCK *lock=data->lock;
1248
 
  DBUG_ENTER("thr_reschedule_write_lock");
1249
1184
 
1250
1185
  pthread_mutex_lock(&lock->mutex);
1251
1186
  if (!lock->read_wait.data)                    /* No waiting read locks */
1252
1187
  {
1253
1188
    pthread_mutex_unlock(&lock->mutex);
1254
 
    DBUG_RETURN(0);
 
1189
    return(0);
1255
1190
  }
1256
1191
 
1257
1192
  data->type=TL_WRITE_DELAYED;
1272
1207
  free_all_read_locks(lock,0);
1273
1208
 
1274
1209
  pthread_mutex_unlock(&lock->mutex);
1275
 
  DBUG_RETURN(thr_upgrade_write_delay_lock(data));
 
1210
  return(thr_upgrade_write_delay_lock(data));
1276
1211
}
1277
1212
 
1278
1213
 
1279
1214
#include <my_sys.h>
1280
1215
 
1281
 
static void thr_print_lock(const char* name,struct st_lock_list *list)
1282
 
{
1283
 
  THR_LOCK_DATA *data,**prev;
1284
 
  uint count=0;
1285
 
 
1286
 
  if (list->data)
1287
 
  {
1288
 
    printf("%-10s: ",name);
1289
 
    prev= &list->data;
1290
 
    for (data=list->data; data && count++ < MAX_LOCKS ; data=data->next)
1291
 
    {
1292
 
      printf("0x%lx (%lu:%d); ", (ulong) data, data->owner->info->thread_id,
1293
 
             (int) data->type);
1294
 
      if (data->prev != prev)
1295
 
        printf("\nWarning: prev didn't point at previous lock\n");
1296
 
      prev= &data->next;
1297
 
    }
1298
 
    puts("");
1299
 
    if (prev != list->last)
1300
 
      printf("Warning: last didn't point at last lock\n");
1301
 
  }
1302
 
}
1303
 
 
1304
 
void thr_print_locks(void)
1305
 
{
1306
 
  LIST *list;
1307
 
  uint count=0;
1308
 
 
1309
 
  pthread_mutex_lock(&THR_LOCK_lock);
1310
 
  puts("Current locks:");
1311
 
  for (list= thr_lock_thread_list; list && count++ < MAX_THREADS;
1312
 
       list= list_rest(list))
1313
 
  {
1314
 
    THR_LOCK *lock=(THR_LOCK*) list->data;
1315
 
    VOID(pthread_mutex_lock(&lock->mutex));
1316
 
    printf("lock: 0x%lx:",(ulong) lock);
1317
 
    if ((lock->write_wait.data || lock->read_wait.data) &&
1318
 
        (! lock->read.data && ! lock->write.data))
1319
 
      printf(" WARNING: ");
1320
 
    if (lock->write.data)
1321
 
      printf(" write");
1322
 
    if (lock->write_wait.data)
1323
 
      printf(" write_wait");
1324
 
    if (lock->read.data)
1325
 
      printf(" read");
1326
 
    if (lock->read_wait.data)
1327
 
      printf(" read_wait");
1328
 
    puts("");
1329
 
    thr_print_lock("write",&lock->write);
1330
 
    thr_print_lock("write_wait",&lock->write_wait);
1331
 
    thr_print_lock("read",&lock->read);
1332
 
    thr_print_lock("read_wait",&lock->read_wait);
1333
 
    VOID(pthread_mutex_unlock(&lock->mutex));
1334
 
    puts("");
1335
 
  }
1336
 
  fflush(stdout);
1337
 
  pthread_mutex_unlock(&THR_LOCK_lock);
1338
 
}
1339
 
 
1340
1216
/*****************************************************************************
1341
1217
** Test of thread locks
1342
1218
****************************************************************************/
1344
1220
#ifdef MAIN
1345
1221
 
1346
1222
struct st_test {
1347
 
  uint lock_nr;
 
1223
  uint32_t lock_nr;
1348
1224
  enum thr_lock_type lock_type;
1349
1225
};
1350
1226
 
1393
1269
 
1394
1270
static pthread_cond_t COND_thread_count;
1395
1271
static pthread_mutex_t LOCK_thread_count;
1396
 
static uint thread_count;
1397
 
static ulong sum=0;
 
1272
static uint32_t thread_count;
 
1273
static uint32_t sum=0;
1398
1274
 
1399
1275
#define MAX_LOCK_COUNT 8
1400
1276
 
1453
1329
        sleep(2);
1454
1330
      else
1455
1331
      {
1456
 
        ulong k;
1457
 
        for (k=0 ; k < (ulong) (tmp-2)*100000L ; k++)
 
1332
        uint32_t k;
 
1333
        for (k=0 ; k < (uint32_t) (tmp-2)*100000L ; k++)
1458
1334
          sum+=k;
1459
1335
      }
1460
1336
    }
1466
1342
  thr_print_locks();
1467
1343
  pthread_mutex_lock(&LOCK_thread_count);
1468
1344
  thread_count--;
1469
 
  VOID(pthread_cond_signal(&COND_thread_count)); /* Tell main we are ready */
 
1345
  pthread_cond_signal(&COND_thread_count); /* Tell main we are ready */
1470
1346
  pthread_mutex_unlock(&LOCK_thread_count);
1471
 
  free((uchar*) arg);
 
1347
  free((unsigned char*) arg);
1472
1348
  return 0;
1473
1349
}
1474
1350
 
1479
1355
  pthread_attr_t thr_attr;
1480
1356
  int i,*param,error;
1481
1357
  MY_INIT(argv[0]);
1482
 
  if (argc > 1 && argv[1][0] == '-' && argv[1][1] == '#')
1483
 
    DBUG_PUSH(argv[1]+2);
1484
1358
 
1485
1359
  printf("Main thread: %s\n",my_thread_name());
1486
1360
 
1527
1401
  }
1528
1402
#endif
1529
1403
#ifdef HAVE_THR_SETCONCURRENCY
1530
 
  VOID(thr_setconcurrency(2));
 
1404
  thr_setconcurrency(2);
1531
1405
#endif
1532
1406
  for (i=0 ; i < (int) array_elements(lock_counts) ; i++)
1533
1407
  {