--- old-ounit/src/oUnitCore.ml	2013-03-03 13:11:07.534395994 +0100
+++ new-ounit/src/oUnitCore.ml	2013-03-03 13:11:07.534395994 +0100
@@ -51,6 +51,12 @@
 
 let global_chooser = ref OUnitChooser.simple
 
+
+let thread_pool_threshold = 10
+(** Under this limit, create exactly one thread by test *)
+let thread_pool_size = 15
+(** Should be adjusted but depends of too many parameters, make you own tests *)
+
 (* Events which can happen during testing *)
 
 
@@ -128,6 +134,78 @@
                     state.tests_planned
               }
   in
+
+  (* threading stuff *)
+
+  (* perform_test.run_test_case equivalent *)
+  let thread_run test_fun = try
+    test_fun (); RSuccess
+    with e -> (* No backtraces because I suspect them to not be thread-safe *)
+    match e with
+    | Failure s -> RFailure (s, None)
+    | Skip s -> RSkip s
+    | Todo s -> RTodo s 
+    | s -> RError (Printexc.to_string s, None)
+  in
+
+  (* thread-wide synchronization *)
+  let thread_main (wait_chan, result_chan) =
+    while true do
+      let event = Event.receive wait_chan in
+      let (test_path, test_fun) = Event.sync event in
+      report test_path EStart; (* FIXME *)
+      (* seems a very bad idea as report is NOT thread safe, broking lines in *)
+      (* the log file, maybe more one day. Find an other solution of patch*)
+      (* report *)
+      let test_res = thread_run test_fun in
+      Event.sync (Event.send result_chan (test_path, test_res))
+    done
+  in
+
+  (* application-wide synchronization, end of perfom_test.runner equivalent *)
+  let synchronizer_main (test_number, result_chan, suite_result_chan) =
+    let i = ref test_number and l = ref [] in
+    while !i > 0 do
+      let (path, res) = Event.sync (Event.receive result_chan) in
+      report path (EResult res);
+      report path EEnd;
+      l := (path, res, None)::!l;
+      decr i
+    done;
+    Event.sync (Event.send suite_result_chan !l)
+  in
+
+ (* beginning of preform_test.runn equivalent, wait results from synchronizer *)
+  let rec schedule wait_chan suite_result_chan = function
+    | [] -> Event.sync (Event.receive suite_result_chan)
+    | test::tests_planned ->
+        Event.sync (Event.send wait_chan test);
+        schedule wait_chan suite_result_chan tests_planned
+  in
+
+  (* end of thread stuff *)
+
+  if true (* FIXME use a parameter in the function to switch *)
+  then
+    (* init channels to pass values with easy synchronization *)
+    let len = List.length test_cases
+    and wait_chan = Event.new_channel () (* threads will get tests by there *)
+    and result_chan = Event.new_channel () (* and send test result here *)
+    and suite_result_chan = Event.new_channel () (* theses result will be
+                                                  * aggregated here
+                                                  *)
+    in
+    (* then init our threads: a pool, a scheduler that dispatches tests,*)
+    (* and a synchronizer that aggregates result and call the logger    *)
+    let pool_size = if len < thread_pool_threshold
+                    then len else thread_pool_size
+    in
+    Thread.create synchronizer_main (len, result_chan, suite_result_chan);
+    for i = 0 to pool_size do
+      Thread.create thread_main (wait_chan, result_chan)
+    done;
+    schedule wait_chan suite_result_chan test_cases
+  else
     iter {results = []; tests_planned = test_cases}
 
 (* A simple (currently too simple) text based test runner *)
@@ -164,7 +242,7 @@
   (* Now start the test *)
   let running_time, test_results = 
     time_fun 
-      perform_test 
+      perform_test
       logger
       test 
   in
