-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Implement the OS.Time module together with support for blocking the k…
…ernel. Set the kernel thread stack size to 40 pages to avoid fatal double faults for some larger recursions, e.g. the one in perf/thread_lat. Improve OS.Main.run along the lines of OS.Time so as the example application.
- Loading branch information
Showing
12 changed files
with
293 additions
and
16 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,3 @@ | ||
<lib/*>: for-pack(OS), use_syntax, use_custom_stdlib | ||
<lib/*>: for-pack(OS), use_syntax, use_custom_stdlib, use_lwt_syntax | ||
<syntax/*>: build_syntax | ||
true: camlp4of |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,4 @@ | ||
Main | ||
Console | ||
Clock | ||
Time |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,105 @@ | ||
(* Lightweight thread library for Objective Caml | ||
* http://www.ocsigen.org/lwt | ||
* Module Lwt_mirage, based on Lwt_unix | ||
* Copyright (C) 2005-2008 Jérôme Vouillon | ||
* Laboratoire PPS - CNRS Université Paris Diderot | ||
* 2009 Jérémie Dimino | ||
* Copyright (C) 2010 Anil Madhavapeddy | ||
* Copyright (C) 2012 Gabor Pali | ||
* | ||
* This program is free software; you can redistribute it and/or modify | ||
* it under the terms of the GNU Lesser General Public License as | ||
* published by the Free Software Foundation, with linking exceptions; | ||
* either version 2.1 of the License, or (at your option) any later | ||
* version. See COPYING file for details. | ||
* | ||
* This program is distributed in the hope that it will be useful, but | ||
* WITHOUT ANY WARRANTY; without even the implied warranty of | ||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU | ||
* Lesser General Public License for more details. | ||
* | ||
* You should have received a copy of the GNU Lesser General Public | ||
* License along with this program; if not, write to the Free Software | ||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA | ||
* 02111-1307, USA. | ||
*) | ||
|
||
open Lwt | ||
|
||
type sleep = { | ||
time : int; | ||
mutable canceled : bool; | ||
thread : unit Lwt.u; | ||
} | ||
|
||
module SleepQueue = | ||
Lwt_pqueue.Make (struct | ||
type t = sleep | ||
let compare { time = t1 } { time = t2 } = compare t1 t2 | ||
end) | ||
|
||
let sleep_queue = ref SleepQueue.empty | ||
|
||
let new_sleeps = ref [] | ||
|
||
let sleep d = | ||
let (res, w) = Lwt.task () in | ||
let t = if d <= 0 then 0 else Clock.time () + d in | ||
let sleeper = { time = t; canceled = false; thread = w } in | ||
new_sleeps := sleeper :: !new_sleeps; | ||
Lwt.on_cancel res (fun _ -> sleeper.canceled <- true); | ||
res | ||
|
||
let yield () = sleep 0 | ||
|
||
let auto_yield timeout = | ||
let limit = ref (Clock.time () + timeout) in | ||
fun () -> | ||
let current = Clock.time () in | ||
if current >= !limit then begin | ||
limit := current + timeout; | ||
yield (); | ||
end else | ||
return () | ||
|
||
exception Timeout | ||
|
||
let timeout d = sleep d >> Lwt.fail Timeout | ||
|
||
let with_timeout d f = Lwt.pick [timeout d; Lwt.apply f ()] | ||
|
||
let in_the_past now t = | ||
t = 0 || t <= now () | ||
|
||
let rec restart_threads now = | ||
match SleepQueue.lookup_min !sleep_queue with | ||
| Some{ canceled = true } -> | ||
sleep_queue := SleepQueue.remove_min !sleep_queue; | ||
restart_threads now | ||
| Some{ time = time; thread = thread } when in_the_past now time -> | ||
sleep_queue := SleepQueue.remove_min !sleep_queue; | ||
Lwt.wakeup thread (); | ||
restart_threads now | ||
| _ -> () | ||
|
||
let min_timeout a b = match a, b with | ||
| None, b -> b | ||
| a, None -> a | ||
| Some a, Some b -> Some(min a b) | ||
|
||
let rec get_next_timeout now = | ||
match SleepQueue.lookup_min !sleep_queue with | ||
| Some{ canceled = true } -> | ||
sleep_queue := SleepQueue.remove_min !sleep_queue; | ||
get_next_timeout now | ||
| Some{ time = time } -> | ||
Some (if time = 0 then 0 else max 0 (time - (now ()))) | ||
| None -> | ||
None | ||
|
||
let select_next now = | ||
sleep_queue := | ||
List.fold_left | ||
(fun q e -> SleepQueue.add e q) !sleep_queue !new_sleeps; | ||
new_sleeps := []; | ||
get_next_timeout now |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,23 @@ | ||
(* | ||
* Copyright (c) 2010 Anil Madhavapeddy <anil@recoil.org> | ||
* Copyright (c) 2012 Gabor Pali | ||
* | ||
* Permission to use, copy, modify, and distribute this software for any | ||
* purpose with or without fee is hereby granted, provided that the above | ||
* copyright notice and this permission notice appear in all copies. | ||
* | ||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES | ||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF | ||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR | ||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES | ||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN | ||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF | ||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. | ||
*) | ||
|
||
val restart_threads: (unit -> int) -> unit | ||
val select_next : (unit -> int) -> int option | ||
val sleep : int -> unit Lwt.t | ||
|
||
exception Timeout | ||
val with_timeout : int -> (unit -> 'a Lwt.t) -> 'a Lwt.t |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
open Printf | ||
open Lwt | ||
|
||
let with_time i fn = | ||
let t1 = OS.Clock.time () in | ||
fn (); | ||
let t2 = OS.Clock.time () in | ||
let passed = (t2 - t1) / 1000 in | ||
printf "%s %d %d ms\n%!" (Sys.os_type) i passed; | ||
() | ||
|
||
let main () = | ||
let rec loop_s = | ||
function | ||
| 0 -> return () | ||
| n -> let _ = OS.Time.sleep 1000 in loop_s (n - 1) | ||
in | ||
|
||
for_lwt i = 1 to 20 do | ||
let sz = i * 100000 in | ||
Gc.compact (); | ||
with_time sz (fun () -> | ||
let _ = loop_s sz in () | ||
); | ||
OS.Time.sleep 10000 | ||
done >> | ||
OS.Time.sleep 1000000 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,65 @@ | ||
open Printf | ||
open Lwt | ||
|
||
(* Create a thread that records the OS time at point of creation, | ||
* and at the point it wakes up, and measures the jitter. | ||
*) | ||
let jitter_t t = | ||
let duration = (Random.int 2000000) + 1000000 in | ||
(* Wait for the passed in thread to wake as a sync point *) | ||
lwt () = t in | ||
let t1 = OS.Clock.time () in | ||
lwt () = OS.Time.sleep duration in | ||
let t2 = OS.Clock.time () in | ||
return (t2 - t1 - duration) | ||
|
||
(* Cumulative distribution function of results list *) | ||
let maxt = 2000 | ||
let mint = 0 | ||
let diff = maxt - mint | ||
let buckets = 50 | ||
let quant = diff / buckets | ||
let b = Array.create (buckets + 1) 0 | ||
|
||
let cdf res = | ||
(* Put each result in a bucket *) | ||
List.iter (fun j -> | ||
let bucket = ((j - mint) / quant) in | ||
let bucket = if bucket >= buckets then | ||
((buckets - 1)) else bucket in | ||
b.(bucket) <- b.(bucket) + 1 | ||
) res; | ||
return () | ||
|
||
let cdf_show () = | ||
Array.iteri (fun i x -> printf "%s %d %d %d\n%!" Sys.os_type (mint + (i * quant)) i x) b; | ||
return () | ||
|
||
let main () = | ||
(* Construction X parallel threads and measure each of their | ||
* jitters | ||
*) | ||
let make_threads num = | ||
let t,u = Lwt.task () in | ||
let rec loop acc = | ||
function | ||
|0 -> acc | ||
|n -> | ||
let th = jitter_t t in | ||
loop (th::acc) (n-1) | ||
in | ||
(loop [] num), u | ||
in | ||
for_lwt i = 0 to 5 do | ||
let reps = 1000 in | ||
(* Make threads and launch the parallel map *) | ||
let ths, u = make_threads reps in | ||
let result_t = Lwt_list.map_p (fun x -> x) ths in | ||
(* Settle the GC *) | ||
Gc.compact (); | ||
(* Launch them! *) | ||
Lwt.wakeup u (); | ||
lwt results = result_t in | ||
cdf results | ||
done >> | ||
cdf_show () |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters