@@ -164,11 +164,6 @@ module Pid : Sid = Int63
164
164
let user_package = " user"
165
165
let keyword_package = " keyword"
166
166
167
- type slot_status =
168
- | Sleep
169
- | Awoke
170
- | Ready
171
-
172
167
type fullname = {
173
168
package : string ;
174
169
name : string ;
@@ -2297,6 +2292,23 @@ module Knowledge = struct
2297
2292
| None -> Env. empty_class
2298
2293
| Some objs -> objs
2299
2294
2295
+ let update_objects {Class. name} f =
2296
+ get () >> = fun state ->
2297
+ let objs = f @@ match Map. find state.classes name with
2298
+ | None -> Env. empty_class
2299
+ | Some objs -> objs in
2300
+ put {state with classes = Map. set state.classes name objs}
2301
+
2302
+ let map_update_objects {Class. name} f =
2303
+ get () >> = fun state ->
2304
+ let objs = match Map. find state.classes name with
2305
+ | None -> Env. empty_class
2306
+ | Some objs -> objs in
2307
+ f objs @@ fun objs res ->
2308
+ put {state with classes = Map. set state.classes name objs} >> | fun () ->
2309
+ res
2310
+
2311
+
2300
2312
module Object = struct
2301
2313
type +'a t = 'a obj
2302
2314
type 'a ord = Oid .comparator_witness
@@ -2575,12 +2587,15 @@ module Knowledge = struct
2575
2587
2576
2588
let uid {Slot. name} = name
2577
2589
2578
- let is_empty
2579
- : _ slot -> _ -> _ obj -> bool =
2580
- fun slot vals obj -> match Map. find vals obj with
2581
- | None -> true
2582
- | Some v ->
2583
- Domain. is_empty slot.dom (Record. get slot.key slot.dom v)
2590
+
2591
+ type slot_status =
2592
+ | Sleep
2593
+ | Awoke
2594
+ | Ready of Dict .record
2595
+
2596
+ let is_empty {Slot. dom; key} v =
2597
+ Domain. is_empty dom (Record. get key dom v)
2598
+ [@@ inline]
2584
2599
2585
2600
let status
2586
2601
: ('a,_) slot -> 'a obj -> slot_status knowledge =
@@ -2589,22 +2604,24 @@ module Knowledge = struct
2589
2604
match Map. find comp obj with
2590
2605
| None -> Sleep
2591
2606
| Some slots -> match Map. find slots (uid slot) with
2592
- | None -> if is_empty slot vals obj then Sleep else Ready
2593
2607
| Some Work _ -> Awoke
2594
- | Some Done -> Ready
2608
+ | other -> match other,Map. find vals obj with
2609
+ | Some Work _ ,_ -> assert false
2610
+ | None ,None -> Sleep
2611
+ | Some Done ,None -> Ready Record. empty
2612
+ | Some Done ,Some v -> Ready v
2613
+ | None ,Some v -> if is_empty slot v then Sleep else Ready v
2595
2614
2596
2615
let update_slot
2597
2616
: ('a,_) slot -> 'a obj -> _ -> unit knowledge =
2598
2617
fun slot obj f ->
2599
- objects slot.cls >> = fun ({comp} as objs ) ->
2618
+ update_objects slot.cls @@ fun ({comp} as objs ) ->
2600
2619
let comp = Map. update comp obj ~f: (fun slots ->
2601
2620
let slots = match slots with
2602
2621
| None -> Map. empty (module Name )
2603
2622
| Some slots -> slots in
2604
2623
Map. update slots (uid slot) ~f ) in
2605
- get () >> = fun s ->
2606
- let classes = Map. set s.classes slot.cls.name {objs with comp} in
2607
- put {s with classes}
2624
+ {objs with comp}
2608
2625
2609
2626
let enter_slot : ('a,_) slot -> 'a obj -> unit knowledge = fun s x ->
2610
2627
update_slot s x @@ function
@@ -2636,21 +2653,24 @@ module Knowledge = struct
2636
2653
update_work s x @@ fun {waiting; current} ->
2637
2654
Work {waiting = Set. union current waiting; current}
2638
2655
2639
- let collect_waiting
2640
- : ('a,'p) slot -> 'a obj -> _ Knowledge.t = fun s x ->
2641
- objects s.cls >> | fun {comp} ->
2642
- Map. find_exn (Map. find_exn comp x) (uid s) |> function
2643
- | Env. Done -> assert false
2644
- | Env. Work {waiting} ->
2645
- Set. fold waiting ~init: [] ~f: (fun ps p ->
2646
- Hashtbl. find_exn s.Slot. promises p :: ps)
2647
-
2648
- let dequeue_waiting s x = update_work s x @@ fun _ ->
2649
- Work {
2656
+ let no_work = Env. Work {
2650
2657
waiting = Set. empty (module Pid );
2651
2658
current = Set. empty (module Pid )
2652
2659
}
2653
2660
2661
+ let dequeue_waiting
2662
+ : ('a,'p) slot -> 'a obj -> _ Knowledge.t = fun s x ->
2663
+ map_update_objects s.cls @@ fun ({comp} as objs ) k ->
2664
+ let works = Map. find_exn comp x in
2665
+ Map. find_exn works (uid s) |> function
2666
+ | Env. Done -> assert false
2667
+ | Env. Work {waiting} ->
2668
+ let waiting = Set. fold waiting ~init: [] ~f: (fun ps p ->
2669
+ Hashtbl. find_exn s.Slot. promises p :: ps) in
2670
+ let works = Map. set works (uid s) no_work in
2671
+ let objs = {objs with comp = Map. set comp x works} in
2672
+ k objs waiting
2673
+
2654
2674
let initial_promises {Slot. promises} = Hashtbl. data promises
2655
2675
2656
2676
let current : type a p. (a,p) slot -> a obj -> p Knowledge.t =
@@ -2668,8 +2688,7 @@ module Knowledge = struct
2668
2688
enter_promise slot obj pid >> = fun () ->
2669
2689
run obj >> = fun () ->
2670
2690
leave_promise slot obj pid) >> = fun () ->
2671
- collect_waiting slot obj >> = fun waiting ->
2672
- dequeue_waiting slot obj >> = fun () ->
2691
+ dequeue_waiting slot obj >> = fun waiting ->
2673
2692
match waiting with
2674
2693
| [] -> Knowledge. return ()
2675
2694
| promises ->
@@ -2678,15 +2697,13 @@ module Knowledge = struct
2678
2697
| EQ | LT -> Knowledge. return ()
2679
2698
| GT | NC -> collect_inner slot obj promises
2680
2699
2681
-
2682
-
2683
2700
let collect : type a p. (a,p) slot -> a obj -> p Knowledge.t =
2684
2701
fun slot id ->
2685
2702
if Object. is_null id
2686
2703
then !! (Domain. empty slot.dom)
2687
2704
else status slot id >> = function
2688
- | Ready ->
2689
- current slot id
2705
+ | Ready v ->
2706
+ Knowledge. return @@ Record. get slot.key slot.dom v
2690
2707
| Awoke ->
2691
2708
enqueue_promises slot id >> = fun () ->
2692
2709
current slot id
@@ -3067,7 +3084,7 @@ module Knowledge = struct
3067
3084
then None
3068
3085
else Some {key= oid; sym; data; comp}) in
3069
3086
cid,(last,data)) in {
3070
- version = V1 ;
3087
+ version = V2 ;
3071
3088
payload;
3072
3089
}
3073
3090
0 commit comments