@@ -597,6 +597,8 @@ module State = struct
597
597
; mutable status : Status .t option
598
598
; hash : int
599
599
}
600
+ (* Thread-safety: We use double-checked locking to access field
601
+ [status] in function [status] below. *)
600
602
601
603
let pp fmt t = Desc. pp fmt t.desc
602
604
let [@ inline] idx t = t.idx
@@ -629,7 +631,8 @@ module State = struct
629
631
&& Desc. equal desc t.desc
630
632
;;
631
633
632
- let status s =
634
+ (* To be called when the mutex has already been acquired *)
635
+ let status_no_mutex s =
633
636
match s.status with
634
637
| Some s -> s
635
638
| None ->
@@ -638,6 +641,16 @@ module State = struct
638
641
st
639
642
;;
640
643
644
+ let status m s =
645
+ match s.status with
646
+ | Some s -> s
647
+ | None ->
648
+ Mutex. lock m;
649
+ let st = status_no_mutex s in
650
+ Mutex. unlock m;
651
+ st
652
+ ;;
653
+
641
654
module Table = Hashtbl. Make (struct
642
655
type nonrec t = t
643
656
@@ -652,10 +665,17 @@ module Working_area = struct
652
665
type t =
653
666
{ mutable ids : Bit_vector .t
654
667
; seen : Id.Hash_set .t
668
+ ; index_count : int Atomic .t
669
+ }
670
+
671
+ let create () =
672
+ { ids = Bit_vector. create_zero 1
673
+ ; seen = Id.Hash_set. create ()
674
+ ; index_count = Atomic. make 0
655
675
}
676
+ ;;
656
677
657
- let create () = { ids = Bit_vector. create_zero 1 ; seen = Id.Hash_set. create () }
658
- let index_count w = Bit_vector. length w.ids
678
+ let index_count w = Atomic. get w.index_count
659
679
660
680
let mark_used_indices tbl =
661
681
Desc. iter_marks ~f: (fun marks ->
@@ -672,7 +692,13 @@ module Working_area = struct
672
692
mark_used_indices t.ids l;
673
693
let len = Bit_vector. length t.ids in
674
694
let idx = find_free t.ids 0 len in
675
- if idx = len then t.ids < - Bit_vector. create_zero (2 * len);
695
+ if idx = len
696
+ then (
697
+ t.ids < - Bit_vector. create_zero (2 * len);
698
+ (* This function is only called when the mutex is locked. So we
699
+ are sure that this is always coherent with the length of
700
+ [t.ids]. *)
701
+ Atomic. set t.index_count (2 * len));
676
702
Idx. make idx
677
703
;;
678
704
end
0 commit comments