@@ -281,7 +281,20 @@ let[@inline never] try_resize t r new_capacity ~clear =
281281 true
282282 end
283283
284- let rec adjust_estimated_size t r mask delta result =
284+ (* * This only gives an "estimate" of the size, which can be off by one or more
285+ and even be negative, so this must be used with care. *)
286+ let [@ inline] non_linearizable_size r =
287+ let accum = ref 0 in
288+ let non_linearizable_size = r.non_linearizable_size in
289+ for i = 0 to Array. length non_linearizable_size - 1 do
290+ (* [fenceless_get] is fine here, because we are not even trying to get a
291+ precise linearizable size, i.e. it is fine to read past values. *)
292+ accum :=
293+ ! accum + Atomic. fenceless_get (Array. unsafe_get non_linearizable_size i)
294+ done ;
295+ ! accum
296+
297+ let rec adjust_size t r mask delta result =
285298 let i = Multicore_magic. instantaneous_domain_index () in
286299 let n = Array. length r.non_linearizable_size in
287300 if i < n then begin
@@ -295,20 +308,7 @@ let rec adjust_estimated_size t r mask delta result =
295308 && Int64. to_int (Random. bits64 () ) land mask = 0
296309 && Atomic. get t == r
297310 then begin
298- (* This only gives an "estimate" of the size, which can be off by one or
299- more and even be negative, so this must be used with care. *)
300- let estimated_size r =
301- let cs = r.non_linearizable_size in
302- let n = Array. length cs - 1 in
303- let rec estimated_size cs n sum =
304- let n = n - 1 in
305- if 0 < = n then
306- estimated_size cs n (sum + Atomic. get (Array. unsafe_get cs n))
307- else sum
308- in
309- estimated_size cs n (Atomic. get (Array. unsafe_get cs n))
310- in
311- let estimated_size = estimated_size r in
311+ let estimated_size = non_linearizable_size r in
312312 let capacity = Atomic_array. length r.buckets in
313313 if capacity < estimated_size && capacity < r.max_buckets then
314314 try_resize t r (capacity + capacity) ~clear: false |> ignore
@@ -330,7 +330,7 @@ let rec adjust_estimated_size t r mask delta result =
330330 in
331331 let new_r = { r with non_linearizable_size = new_cs } in
332332 let r = if Atomic. compare_and_set t r new_r then new_r else Atomic. get t in
333- adjust_estimated_size t r mask delta result
333+ adjust_size t r mask delta result
334334
335335(* *)
336336
@@ -396,14 +396,14 @@ let rec try_add t key value backoff =
396396 | B Nil ->
397397 let after = Cons { key; value; rest = Nil } in
398398 if Atomic_array. unsafe_compare_and_set r.buckets i (B Nil ) (B after) then
399- adjust_estimated_size t r mask 1 true
399+ adjust_size t r mask 1 true
400400 else try_add t key value (Backoff. once backoff)
401401 | B (Cons _ as before ) ->
402402 if exists r.equal key before then false
403403 else
404404 let after = Cons { key; value; rest = before } in
405405 if Atomic_array. unsafe_compare_and_set r.buckets i (B before) (B after)
406- then adjust_estimated_size t r mask 1 true
406+ then adjust_size t r mask 1 true
407407 else try_add t key value (Backoff. once backoff)
408408 | B (Resize _ ) ->
409409 let _ = finish t (Atomic. get t) in
@@ -515,7 +515,7 @@ let rec try_dissoc : type v c r. (_, v) t -> _ -> c -> (v, c, r) op -> _ -> r =
515515 | Exists -> true
516516 | Return -> cons_r.value
517517 in
518- adjust_estimated_size t r mask (- 1 ) res
518+ adjust_size t r mask (- 1 ) res
519519 else try_dissoc t key present op (Backoff. once backoff)
520520 else not_found op
521521 else
@@ -544,7 +544,7 @@ let rec try_dissoc : type v c r. (_, v) t -> _ -> c -> (v, c, r) op -> _ -> r =
544544 | Exists -> true
545545 | Return -> assoc r.equal key cons_r.rest
546546 in
547- adjust_estimated_size t r mask (- 1 ) res
547+ adjust_size t r mask (- 1 ) res
548548 else try_dissoc t key present op (Backoff. once backoff)
549549 | exception Not_found -> not_found op
550550 end
@@ -626,6 +626,10 @@ let find_random_exn t =
626626
627627(* *)
628628
629+ let non_linearizable_length t = non_linearizable_size (Atomic. get t)
630+
631+ (* *)
632+
629633let [@ inline] try_add t key value = try_add t key value Backoff. default
630634
631635(* *)
0 commit comments