package async_kernel

  1. Overview
  2. Docs
Legend:
Page
Library
Module
Module type
Parameter
Class
Class type
Source

Source file types.ml

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
(* This file defines the mutually recursive types at the heart of Async.  The functions
   associated with the types are defined in the corresponding file(s) for each module.
   This file should define only types, not functions, since functions defined inside the
   recursive modules are not inlined.

   If you need to add functionality to a module but doing so would create a dependency
   cycle, split the file into pieces as needed to break the cycle, e.g. scheduler0.ml,
   scheduler1.ml, scheduler.ml. *)

open! Core
open! Import

module rec Cell : sig
  type any =
    [ `Empty
    | `Empty_one_handler
    | `Empty_one_or_more_handlers
    | `Full
    | `Indir
    ]

  type ('a, 'b) t =
    | Empty_one_or_more_handlers :
        { mutable run : 'a -> unit
        ; execution_context : Execution_context.t
        ; mutable prev : 'a Handler.t
        ; mutable next : 'a Handler.t
        }
        -> ('a, [> `Empty_one_or_more_handlers ]) t
    | Empty_one_handler :
        ('a -> unit) * Execution_context.t
        -> ('a, [> `Empty_one_handler ]) t
    | Empty : ('a, [> `Empty ]) t
    | Full : 'a -> ('a, [> `Full ]) t
    | Indir : 'a Ivar.t -> ('a, [> `Indir ]) t
end =
  Cell

and Handler : sig
  type 'a t = ('a, [ `Empty_one_or_more_handlers ]) Cell.t
end =
  Handler

and Ivar : sig
  type 'a t = { mutable cell : ('a, Cell.any) Cell.t }

  module Immutable : sig
    type 'a t = { cell : ('a, Cell.any) Cell.t }
  end
end =
  Ivar

and Deferred : sig
  type +!'a t
end =
  Deferred

and Execution_context : sig
  type t =
    { monitor : Monitor.t
    ; priority : Priority.t
    ; local_storage : Univ_map.t
    ; backtrace_history : Backtrace.t list
    }
end =
  Execution_context

and Forwarding : sig
  type t =
    | Detached
    | Parent of Monitor.t
    | Report_uncaught_exn
end =
  Forwarding

and Monitor : sig
  type t =
    { name : Info.t
    ; here : Source_code_position.t option
    ; id : int
    ; mutable next_error : exn Ivar.t
    ; mutable handlers_for_all_errors : (Execution_context.t * (exn -> unit)) Bag.t
    ; mutable tails_for_all_errors : exn Tail.t list
    ; mutable has_seen_error : bool
    ; mutable forwarding : Forwarding.t
    }
end =
  Monitor

and Tail : sig
  type 'a t = { mutable next : 'a Stream.next Ivar.t }
end =
  Tail

and Stream : sig
  type 'a t = 'a next Deferred.t

  and 'a next =
    | Nil
    | Cons of 'a * 'a t
end =
  Stream

(* We avoid using [module rec] to define [Bvar], so that [to_repr] and [of_repr] are
   inlined. *)
module Bvar : sig
  type ('a, -'permission) t

  (** [repr] exists so that we may hide the implementation of a [Bvar.t], and then add a
      phantom type to it upstream.  Without this, the phantom type variable would allow
      for anything to be coerced in and out, since it is unused. *)
  type 'a repr =
    { mutable has_any_waiters : bool
    ; mutable ivar : 'a Ivar.t
    }

  val of_repr : 'a repr -> ('a, 'permission) t
  val to_repr : ('a, 'permission) t -> 'a repr
end = struct
  type 'a repr =
    { mutable has_any_waiters : bool
    ; mutable ivar : 'a Ivar.t
    }

  type ('a, 'permission) t = 'a repr

  let to_repr t = t
  let of_repr t = t
end

module rec Event : sig
  module Status : sig
    type t =
      | Fired
      | Happening_periodic_event
      | Scheduled
      | Unscheduled
  end

  module Option : sig
    type t
  end

  type t =
    { mutable alarm : Job_or_event.t Timing_wheel.Alarm.t
    ; mutable at : Time_ns.t
    ; callback : unit -> unit
    ; execution_context : Execution_context.t
    ; mutable interval : Time_ns.Span.t option
    ; mutable next_fired : Option.t
    ; mutable prev_fired : Option.t
    ; mutable status : Status.t
    }
end =
  Event

and External_job : sig
  type t = T : Execution_context.t * ('a -> unit) * 'a -> t
end =
  External_job

and Job : sig
  type slots = (Execution_context.t, Obj.t -> unit, Obj.t) Pool.Slots.t3
  type t = slots Pool.Pointer.t
end =
  Job

and Job_or_event : sig
  type t
end =
  Job_or_event

and Job_pool : sig
  type t = Job.slots Pool.t
end =
  Job_pool

and Job_queue : sig
  type t =
    { mutable num_jobs_run : int
    ; mutable jobs_left_this_cycle : int
    ; mutable jobs : Obj.t Uniform_array.t
    ; mutable mask : int
    ; mutable front : int
    ; mutable length : int
    ; mutable backtrace_of_first_enqueue : Backtrace.t option
    }
end =
  Job_queue

and Jobs : sig
  type t =
    { scheduler : Scheduler.t
    ; mutable job_pool : Job_pool.t
    ; normal : Job_queue.t
    ; low : Job_queue.t
    }
end =
  Jobs

and Scheduler : sig

  type t =
    { mutable check_access : (unit -> unit) option
    ; mutable job_pool : Job_pool.t
    ; normal_priority_jobs : Job_queue.t
    ; low_priority_jobs : Job_queue.t
    ; very_low_priority_workers : Very_low_priority_worker.t Deque.t
    ; mutable main_execution_context : Execution_context.t
    ; mutable current_execution_context : Execution_context.t
    ; mutable uncaught_exn : (Exn.t * Sexp.t) option
    ; mutable cycle_count : int
    ; mutable cycle_start : Time_ns.t
    ; mutable in_cycle : bool
    ; mutable run_every_cycle_start : Cycle_hook.t array
    ; run_every_cycle_start_state : (Cycle_hook_handle.t, Cycle_hook.t) Hashtbl.t
    ; mutable run_every_cycle_end : Cycle_hook.t array
    ; run_every_cycle_end_state : (Cycle_hook_handle.t, Cycle_hook.t) Hashtbl.t
    ; mutable last_cycle_time : Time_ns.Span.t
    ; mutable last_cycle_num_jobs : int
    ; mutable total_cycle_time : Time_ns.Span.t
    ; mutable time_source : read_write Time_source.t1
    ; external_jobs : External_job.t Thread_safe_queue.t
    ; mutable thread_safe_external_job_hook : unit -> unit
    ; mutable job_queued_hook : (Priority.t -> unit) option
    ; mutable event_added_hook : (Time_ns.t -> unit) option
    ; mutable yield : (unit, read_write) Bvar.t
    ; mutable yield_until_no_jobs_remain : (unit, read_write) Bvar.t
    ; mutable check_invariants : bool
    ; mutable max_num_jobs_per_priority_per_cycle : Max_num_jobs_per_priority_per_cycle.t
    ; mutable record_backtraces : bool
    }
end =
  Scheduler

and Cycle_hook : sig
  type t = unit -> unit
end =
  Cycle_hook

and Cycle_hook_handle : Unique_id.Id = Unique_id.Int63 ()
and Time_source_id : Unique_id.Id = Unique_id.Int63 ()

and Time_source : sig
  type -'rw t1 =
    { id : Time_source_id.t
    ; mutable advance_errors : Error.t list
    ; mutable am_advancing : bool
    ; events : Job_or_event.t Timing_wheel.t
    ; mutable fired_events : Event.Option.t
    ; mutable most_recently_fired : Event.Option.t
    ; handle_fired : Job_or_event.t Timing_wheel.Alarm.t -> unit
    ; is_wall_clock : bool
    ; scheduler : Scheduler.t
    }
end =
  Time_source

and Very_low_priority_worker : sig
  module Exec_result : sig
    type t =
      | Finished
      | Not_finished
  end

  type t =
    { execution_context : Execution_context.t
    ; exec : unit -> Exec_result.t
    }
end =
  Very_low_priority_worker