src/Pure/Concurrent/timeout.ML
author wenzelm
Wed, 10 Jan 2024 13:10:20 +0100
changeset 79463 7d10708bbc32
parent 78787 a7e4b412cc7c
permissions -rw-r--r--
clarified signature;
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
     1
(*  Title:      Pure/Concurrent/timeout.ML
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
     2
    Author:     Makarius
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
     3
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
     4
Execution with relative timeout:
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
     5
  - timeout specification < 1ms means no timeout
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
     6
  - actual timeout is subject to system option "timeout_scale"
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
     7
*)
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
     8
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
     9
signature TIMEOUT =
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    10
sig
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
    11
  exception TIMEOUT of Time.time
73388
a40e69fde2b4 clarified smt: support Timeout.ignored and Timeout.scale_time;
wenzelm
parents: 73387
diff changeset
    12
  val ignored: Time.time -> bool
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    13
  val scale: unit -> real
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    14
  val scale_time: Time.time -> Time.time
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    15
  val end_time: Time.time -> Time.time
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
    16
  val apply: Time.time -> ('a -> 'b) -> 'a -> 'b
74870
d54b3c96ee50 more robust physical timeout (despite 1bea05713dde), especially relevant for quickcheck where large unary numerals may cause excessive heap allocations and resulting GC is better included in the timing;
wenzelm
parents: 73388
diff changeset
    17
  val apply_physical: Time.time -> ('a -> 'b) -> 'a -> 'b
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
    18
  val print: Time.time -> string
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    19
end;
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    20
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
    21
structure Timeout: TIMEOUT =
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    22
struct
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    23
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
    24
exception TIMEOUT of Time.time;
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    25
73388
a40e69fde2b4 clarified smt: support Timeout.ignored and Timeout.scale_time;
wenzelm
parents: 73387
diff changeset
    26
fun ignored timeout = timeout < Time.fromMilliseconds 1;
a40e69fde2b4 clarified smt: support Timeout.ignored and Timeout.scale_time;
wenzelm
parents: 73387
diff changeset
    27
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    28
fun scale () = Options.default_real "timeout_scale";
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    29
fun scale_time t = Time.scale (scale ()) t;
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    30
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    31
fun end_time timeout = Time.now () + scale_time timeout;
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    32
74870
d54b3c96ee50 more robust physical timeout (despite 1bea05713dde), especially relevant for quickcheck where large unary numerals may cause excessive heap allocations and resulting GC is better included in the timing;
wenzelm
parents: 73388
diff changeset
    33
fun apply' {physical, timeout} f x =
73388
a40e69fde2b4 clarified smt: support Timeout.ignored and Timeout.scale_time;
wenzelm
parents: 73387
diff changeset
    34
  if ignored timeout then f x
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    35
  else
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    36
    Thread_Attributes.with_attributes Thread_Attributes.no_interrupts (fn orig_atts =>
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    37
      let
78648
852ec09aef13 more explicit type Isabelle_Thread.T;
wenzelm
parents: 74870
diff changeset
    38
        val self = Isabelle_Thread.self ();
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    39
        val start = Time.now ();
52051
9362fcd0318c modernized TimeLimit.timeLimit using Event_Timer service -- based on more elementary version 11ae688e4e30;
wenzelm
parents: 44112
diff changeset
    40
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    41
        val request =
74870
d54b3c96ee50 more robust physical timeout (despite 1bea05713dde), especially relevant for quickcheck where large unary numerals may cause excessive heap allocations and resulting GC is better included in the timing;
wenzelm
parents: 73388
diff changeset
    42
          Event_Timer.request {physical = physical} (start + scale_time timeout)
78787
a7e4b412cc7c tuned signature, following Isabelle/Scala;
wenzelm
parents: 78766
diff changeset
    43
            (fn () => Isabelle_Thread.interrupt_thread self);
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    44
        val result =
78757
a094bf81a496 clarified signature;
wenzelm
parents: 78714
diff changeset
    45
          Exn.capture_body (fn () => Thread_Attributes.with_attributes orig_atts (fn _ => f x));
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    46
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    47
        val stop = Time.now ();
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    48
        val was_timeout = not (Event_Timer.cancel request);
78714
eb2255d241da clarified signature;
wenzelm
parents: 78713
diff changeset
    49
        val test = Isabelle_Thread.expose_interrupt_result ();
78766
5578341489cb further clarification of Exn.is_interrupt_proper vs. overall Exn.is_interrupt;
wenzelm
parents: 78757
diff changeset
    50
        val was_interrupt =
5578341489cb further clarification of Exn.is_interrupt_proper vs. overall Exn.is_interrupt;
wenzelm
parents: 78757
diff changeset
    51
          Exn.is_interrupt_proper_exn result orelse
5578341489cb further clarification of Exn.is_interrupt_proper vs. overall Exn.is_interrupt;
wenzelm
parents: 78757
diff changeset
    52
          Exn.is_interrupt_proper_exn test;
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    53
      in
78766
5578341489cb further clarification of Exn.is_interrupt_proper vs. overall Exn.is_interrupt;
wenzelm
parents: 78757
diff changeset
    54
        if was_timeout andalso was_interrupt
73387
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    55
        then raise TIMEOUT (stop - start)
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    56
        else (Exn.release test; Exn.release result)
3b5196dac4c8 clarified timeouts in Isabelle/ML;
wenzelm
parents: 71692
diff changeset
    57
      end);
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    58
74870
d54b3c96ee50 more robust physical timeout (despite 1bea05713dde), especially relevant for quickcheck where large unary numerals may cause excessive heap allocations and resulting GC is better included in the timing;
wenzelm
parents: 73388
diff changeset
    59
fun apply timeout f x = apply' {physical = false, timeout = timeout} f x;
d54b3c96ee50 more robust physical timeout (despite 1bea05713dde), especially relevant for quickcheck where large unary numerals may cause excessive heap allocations and resulting GC is better included in the timing;
wenzelm
parents: 73388
diff changeset
    60
fun apply_physical timeout f x = apply' {physical = true, timeout = timeout} f x;
d54b3c96ee50 more robust physical timeout (despite 1bea05713dde), especially relevant for quickcheck where large unary numerals may cause excessive heap allocations and resulting GC is better included in the timing;
wenzelm
parents: 73388
diff changeset
    61
67000
1698e9ccef2d more portable print_time, notably for occasional negative (!) elapsed time of theory_timing;
wenzelm
parents: 62924
diff changeset
    62
fun print t = "Timeout after " ^ Value.print_time t ^ "s";
62519
a564458f94db tuned signature -- clarified modules;
wenzelm
parents: 61556
diff changeset
    63
41710
11ae688e4e30 clarified bootstrapping of structure TimeLimit;
wenzelm
parents:
diff changeset
    64
end;