@@ -164,37 +164,72 @@ let shutdown copts (vg_name,_) =
164164 lwt_while (fun () -> is_alive pid) (fun () -> Lwt_unix. sleep 1.0 )
165165 in Lwt_main. run t
166166
167- let benchmark copts (vg_name ,_ ) =
167+ let benchmark copts (vg_name ,_ ) volumes threads =
168168 let t =
169169 let creation_host = Unix. gethostname () in
170170 get_vg_info_t copts vg_name >> = fun info ->
171171 set_uri copts info;
172172 let mib = Int64. mul 1048576L 4L in
173- let number = 1000 in
174- let start = Unix. gettimeofday () in
175- let rec fori test_name acc f = function
176- | 0 -> return acc
177- | n ->
178- f n
179- >> = fun () ->
180- ( if ((n * 100 ) / number) <> (((n + 1 ) * 100 ) / number)
181- then stderr " %s %d %% complete\n %!" test_name (100 - (n * 100 ) / number)
182- else return () ) >> = fun () ->
183- fori test_name ((number - n, Unix. gettimeofday () -. start) :: acc) f (n - 1 ) in
184- fori " Creating volumes" [] (fun i -> Client. create ~name: (Printf. sprintf " test-lv-%d" i) ~size: mib ~creation_host ~creation_time: (Unix. gettimeofday () |> Int64. of_float) ~tags: [] ) number
185- >> = fun creates ->
186- let time = Unix. gettimeofday () -. start in
173+
174+ let start = ref (Unix. gettimeofday () ) in
175+ let n_pending = ref volumes in
176+ let m = Lwt_mutex. create () in
177+ let n_complete = ref 0 in
178+ let times = ref [] in
179+ let on_complete () =
180+ incr n_complete;
181+ let n = ! n_complete in
182+ times := (n, Unix. gettimeofday () -. ! start) :: ! times;
183+ if ((n * 100 ) / volumes) <> (((n + 1 ) * 100 ) / volumes)
184+ then stderr " %d %% complete" ((n * 100 ) / volumes)
185+ else return () in
186+ let rec worker f =
187+ Lwt_mutex. with_lock m
188+ (fun () ->
189+ if ! n_pending > 0 then begin
190+ decr n_pending;
191+ return (Some (volumes - ! n_pending))
192+ end else return None )
193+ >> = function
194+ | Some n ->
195+ f n
196+ >> = fun () ->
197+ on_complete ()
198+ >> = fun () ->
199+ worker f
200+ | None ->
201+ return () in
202+
203+ let create n =
204+ Client. create ~name: (Printf. sprintf " test-lv-%d" n) ~size: mib ~creation_host ~creation_time: (Unix. gettimeofday () |> Int64. of_float) ~tags: [] in
205+ let destroy n =
206+ Client. remove ~name: (Printf. sprintf " test-lv-%d" n) in
207+
208+ let rec mkints = function
209+ | 0 -> []
210+ | n -> n :: (mkints (n - 1 )) in
211+ let creators = List. map (fun _ -> worker create) (mkints threads) in
212+ Lwt. join creators
213+ >> = fun () ->
214+
187215 let oc = open_out " benchmark.dat" in
188- List. iter (fun (n , t ) -> Printf. fprintf oc " %d %f\n " n t) (List. rev creates);
189- Printf. fprintf oc " # %d creates in %.1f s\n " number time;
190- Printf. fprintf oc " # Average %.1f /sec\n " (float_of_int number /. time);
191- let start = Unix. gettimeofday () in
192- fori " Removing volumes" [] (fun i -> Client. remove ~name: (Printf. sprintf " test-lv-%d" i)) number
193- >> = fun destroys ->
194- let time = Unix. gettimeofday () -. start in
195- List. iter (fun (n , t ) -> Printf. fprintf oc " %d %f\n " (number + n) t) (List. rev destroys);
196- Printf. fprintf oc " # %d destroys in %.1f s\n " number time;
197- Printf. fprintf oc " # Average %.1f /sec\n " (float_of_int number /. time);
216+ let time = Unix. gettimeofday () -. ! start in
217+ List. iter (fun (n , t ) -> Printf. fprintf oc " %d %f\n " n t) (List. rev ! times);
218+ Printf. fprintf oc " # %d creates in %.1f s\n " volumes time;
219+ Printf. fprintf oc " # Average %.1f /sec\n " (float_of_int volumes /. time);
220+
221+ start := Unix. gettimeofday () ;
222+ n_pending := volumes;
223+ n_complete := 0 ;
224+ times := [] ;
225+
226+ let destroyers = List. map (fun _ -> worker destroy) (mkints threads) in
227+ Lwt. join destroyers
228+ >> = fun () ->
229+ let time = Unix. gettimeofday () -. ! start in
230+ List. iter (fun (n , t ) -> Printf. fprintf oc " %d %f\n " (volumes + n) t) (List. rev ! times);
231+ Printf. fprintf oc " # %d destroys in %.1f s\n " volumes time;
232+ Printf. fprintf oc " # Average %.1f /sec\n " (float_of_int volumes /. time);
198233 return () in
199234 Lwt_main. run t
200235
@@ -315,7 +350,13 @@ let benchmark_cmd =
315350 `S " DESCRIPTION" ;
316351 `P " Perform some microbenchmarks and print the results." ;
317352 ] in
318- Term. (pure benchmark $ copts_t $ name_arg),
353+ let volumes_arg =
354+ let doc = " The number of logical volumes which should be created then destroyed." in
355+ Arg. (value & opt int 10000 & info [ " volumes" ; " v" ] ~docv: " VOLUMES" ~doc ) in
356+ let threads_arg =
357+ let doc = " The number of concurrent worker threads which should create then destroy the volumes." in
358+ Arg. (value & opt int 1 & info [ " threads" ; " t" ] ~docv: " THREADS" ~doc ) in
359+ Term. (pure benchmark $ copts_t $ name_arg $ volumes_arg $ threads_arg),
319360 Term. info " benchmark" ~sdocs: copts_sect ~doc ~man
320361
321362let default_cmd =
0 commit comments