@@ -7,7 +7,6 @@ type ready =
7
7
| Spawn of Fiber .t * (unit -> unit )
8
8
| Continue of Fiber .t * (unit , unit ) Effect.Deep .continuation
9
9
| Resume of Fiber .t * (Exn_bt .t option , unit ) Effect.Deep .continuation
10
- | Resume_forbidden of (Exn_bt .t option , unit ) Effect.Deep .continuation
11
10
12
11
type t = {
13
12
ready : ready Queue .t ;
@@ -77,70 +76,10 @@ let rec next t =
77
76
Effect.Deep. continue k ()
78
77
| Some exn_bt -> Exn_bt. discontinue k exn_bt)
79
78
| Trigger. Await trigger ->
80
- (* We handle [Await] last as it is probably the least latency
81
- sensitive effect. It could also be that another fiber running in
82
- parallel is just about to signal the trigger, so checking the
83
- trigger last gives a tiny bit of time for that to happen and
84
- potentially allows us to make better/different decisions here. *)
85
79
Some
86
80
(fun k ->
87
- (* The non-blocking logic below for suspending a fiber with
88
- support for parallelism safe cancelation is somewhat
89
- intricate. Hopefully the comments help to understand it. *)
90
- if Fiber. has_forbidden fiber then begin
91
- (* Fiber has forbidden propagation of cancelation. This is
92
- the easy case to handle. *)
93
- if Trigger. on_signal trigger fiber k t.resume then begin
94
- (* Fiber is now suspended and can be resumed through the
95
- trigger. We just continue the next ready fiber. *)
96
- next t
97
- end
98
- else begin
99
- (* The trigger was already signaled. We could now freely
100
- choose which fiber to continue here, but in this
101
- scheduler we choose to continue the current fiber. *)
102
- Effect.Deep. continue k None
103
- end
104
- end
105
- else begin
106
- (* Fiber permits propagation of cancelation. We support
107
- cancelation and so first try to attach the trigger to the
108
- computation of the fiber. *)
109
- if Fiber. try_attach fiber trigger then begin
110
- (* The trigger was successfully attached, which means the
111
- computation has not been canceled. *)
112
- if Trigger. on_signal trigger fiber k t.resume then begin
113
- (* Fiber is now suspended and can be resumed through the
114
- trigger. That can now happen by signaling the trigger
115
- directly or by canceling the computation of the fiber,
116
- which will also signal the trigger. We just continue
117
- the next ready fiber. *)
118
- next t
119
- end
120
- else begin
121
- (* The trigger was already signaled. We first need to
122
- ensure that the trigger is detached from the
123
- computation of the fiber. *)
124
- Fiber. detach fiber trigger;
125
- (* We could now freely decide which fiber to continue, but
126
- in this scheduler we choose to continue the current
127
- fiber. *)
128
- Fiber. resume fiber k
129
- end
130
- end
131
- else begin
132
- (* We could not attach the trigger to the computation of the
133
- fiber, which means that either the computation has been
134
- canceled or the trigger has been signaled. We still need
135
- to ensure that the trigger really is put into the
136
- signaled state before the fiber is continued. *)
137
- Trigger. dispose trigger;
138
- (* We could now freely decide which fiber to continue, but
139
- in this scheduler we choose to continue the current
140
- fiber. *)
141
- Fiber. resume fiber k
142
- end
143
- end )
81
+ if Fiber. try_suspend fiber trigger fiber k t.resume then next t
82
+ else Fiber. resume fiber k)
144
83
| _ -> None
145
84
and retc () =
146
85
Atomic. decr t.num_alive_fibers;
@@ -149,7 +88,6 @@ let rec next t =
149
88
Effect.Deep. match_with main () { retc; exnc = raise; effc }
150
89
| Continue (fiber , k ) -> Fiber. continue fiber k ()
151
90
| Resume (fiber , k ) -> Fiber. resume fiber k
152
- | Resume_forbidden k -> Effect.Deep. continue k None
153
91
| exception Queue. Empty ->
154
92
if Atomic. get t.num_alive_fibers <> 0 then begin
155
93
if Atomic. get t.needs_wakeup then begin
@@ -171,33 +109,14 @@ let run ~forbid main =
171
109
and mc = Picos_ptmc. get () in
172
110
let rec t = { ready; needs_wakeup; num_alive_fibers; mc; resume }
173
111
and resume trigger fiber k =
174
- begin
175
- if Fiber. has_forbidden fiber then
176
- (* Fiber has forbidden propagation of cancelation. This is the easy
177
- case. *)
178
- Queue. push t.ready (Resume_forbidden k)
179
- else
180
- let resume = Resume (fiber, k) in
181
- if Fiber. is_canceled fiber then begin
182
- (* The fiber has been canceled so we give priority to it in this
183
- scheduler.
184
-
185
- Assuming fibers are written to cooperate and perform cleanup
186
- promptly, this can be advantageous as it allows resources to be
187
- released more quickly. However, malicious or buggy fibers could
188
- use this to prevent other fibers from running. *)
189
- Queue. push_head t.ready resume
190
- end
191
- else begin
192
- (* The fiber hasn't yet been canceled.
193
-
194
- As propagation of cancelation was not forbidden, and we have
195
- attached a trigger, we need to ensure that the trigger will not be
196
- leaked. *)
197
- Fiber. detach fiber trigger;
198
- Queue. push t.ready resume
199
- end
200
- end ;
112
+ let resume = Resume (fiber, k) in
113
+ if Fiber. unsuspend fiber trigger then
114
+ (* The fiber has not been canceled, so we queue the fiber normally. *)
115
+ Queue. push t.ready resume
116
+ else
117
+ (* The fiber has been canceled, so we give priority to it in this
118
+ scheduler. *)
119
+ Queue. push_head t.ready resume;
201
120
(* As the trigger might have been signaled from another domain or systhread
202
121
outside of the scheduler, we check whether the scheduler needs to be
203
122
woken up and take care of it if necessary. *)
0 commit comments