33 |
33 |
34 fun tracing level msg = |
34 fun tracing level msg = |
35 if level > ! trace then () |
35 if level > ! trace then () |
36 else (TextIO.output (TextIO.stdErr, (">>> " ^ msg () ^ "\n")); TextIO.flushOut TextIO.stdErr) |
36 else (TextIO.output (TextIO.stdErr, (">>> " ^ msg () ^ "\n")); TextIO.flushOut TextIO.stdErr) |
37 handle _ (*sic*) => (); |
37 handle _ (*sic*) => (); |
|
38 |
|
39 fun tracing_time time = |
|
40 tracing |
|
41 (if Time.>= (time, Time.fromMilliseconds 1000) then 1 |
|
42 else if Time.>= (time, Time.fromMilliseconds 100) then 2 |
|
43 else if Time.>= (time, Time.fromMilliseconds 10) then 3 |
|
44 else if Time.>= (time, Time.fromMilliseconds 1) then 4 else 5); |
|
45 |
38 |
46 |
39 val available = true; |
47 val available = true; |
40 |
48 |
41 val max_threads = ref 0; |
49 val max_threads = ref 0; |
42 |
50 |
203 | SOME t => Thread.equal (t, Thread.self ())); |
211 | SOME t => Thread.equal (t, Thread.self ())); |
204 |
212 |
205 fun NAMED_CRITICAL name e = |
213 fun NAMED_CRITICAL name e = |
206 if self_critical () then e () |
214 if self_critical () then e () |
207 else |
215 else |
208 uninterruptible (fn restore_attributes => fn () => |
216 Exn.release (uninterruptible (fn restore_attributes => fn () => |
209 let |
217 let |
210 val name' = ! critical_name; |
218 val name' = ! critical_name; |
211 val _ = |
219 val _ = |
212 if Mutex.trylock critical_lock then () |
220 if Mutex.trylock critical_lock then () |
213 else |
221 else |
214 let |
222 let |
215 val timer = Timer.startRealTimer (); |
223 val timer = Timer.startRealTimer (); |
216 val _ = tracing 4 (fn () => "CRITICAL" ^ show name ^ show' name' ^ ": waiting"); |
224 val _ = tracing 5 (fn () => "CRITICAL" ^ show name ^ show' name' ^ ": waiting"); |
217 val _ = Mutex.lock critical_lock; |
225 val _ = Mutex.lock critical_lock; |
218 val time = Timer.checkRealTimer timer; |
226 val time = Timer.checkRealTimer timer; |
219 val trace_time = |
227 val _ = tracing_time time (fn () => |
220 if Time.>= (time, Time.fromMilliseconds 1000) then 1 |
|
221 else if Time.>= (time, Time.fromMilliseconds 100) then 2 |
|
222 else if Time.>= (time, Time.fromMilliseconds 10) then 3 else 4; |
|
223 val _ = tracing trace_time (fn () => |
|
224 "CRITICAL" ^ show name ^ show' name' ^ ": passed after " ^ Time.toString time); |
228 "CRITICAL" ^ show name ^ show' name' ^ ": passed after " ^ Time.toString time); |
225 in () end; |
229 in () end; |
226 val _ = critical_thread := SOME (Thread.self ()); |
230 val _ = critical_thread := SOME (Thread.self ()); |
227 val _ = critical_name := name; |
231 val _ = critical_name := name; |
228 val result = Exn.capture (restore_attributes e) (); |
232 val result = Exn.capture (restore_attributes e) (); |
229 val _ = critical_name := ""; |
233 val _ = critical_name := ""; |
230 val _ = critical_thread := NONE; |
234 val _ = critical_thread := NONE; |
231 val _ = Mutex.unlock critical_lock; |
235 val _ = Mutex.unlock critical_lock; |
232 in Exn.release result end) (); |
236 in result end) ()); |
233 |
237 |
234 fun CRITICAL e = NAMED_CRITICAL "" e; |
238 fun CRITICAL e = NAMED_CRITICAL "" e; |
235 |
239 |
236 end; |
240 end; |
237 |
241 |