mirror of
https://github.com/c-cube/ocaml-containers.git
synced 2025-12-06 11:15:31 -05:00
finish removing threads
This commit is contained in:
parent
bf2375f042
commit
33053a1f96
10 changed files with 4 additions and 555 deletions
2
Makefile
2
Makefile
|
|
@ -1,4 +1,4 @@
|
||||||
PACKAGES=containers,containers-data,containers-thread
|
PACKAGES=containers,containers-data
|
||||||
|
|
||||||
all: build test
|
all: build test
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -39,13 +39,12 @@ Containers is:
|
||||||
data structures that don't have an equivalent in the standard library,
|
data structures that don't have an equivalent in the standard library,
|
||||||
typically not as thoroughly maintained. This is now in its own package
|
typically not as thoroughly maintained. This is now in its own package
|
||||||
since 3.0.
|
since 3.0.
|
||||||
- A separate library for threaded programming in `containers-thread`,
|
|
||||||
including a blocking queue, semaphores, an extension of `Mutex`, and
|
|
||||||
thread-pool based futures. This is in its own package since 3.0.
|
|
||||||
|
|
||||||
Some of the modules have been moved to their own repository (e.g. `sequence` (now `iter`),
|
Some of the modules have been moved to their own repository (e.g. `sequence` (now `iter`),
|
||||||
`gen`, `qcheck`) and are on opam for great fun and profit.
|
`gen`, `qcheck`) and are on opam for great fun and profit.
|
||||||
|
|
||||||
|
Containers-thread has been removed in favor of [Moonpool](https://github.com/c-cube/moonpool/).
|
||||||
|
|
||||||
## Migration Guide
|
## Migration Guide
|
||||||
|
|
||||||
### To 3.0
|
### To 3.0
|
||||||
|
|
@ -54,7 +53,7 @@ The [changelog's breaking section](CHANGELOG.md) contains a list of the breaking
|
||||||
changes in this release.
|
changes in this release.
|
||||||
|
|
||||||
1. The biggest change is that some sub-libraries have been either turned into
|
1. The biggest change is that some sub-libraries have been either turned into
|
||||||
their own packages (`containers-thread`, `containers-data`),
|
their own packages (`containers-data`),
|
||||||
deleted (`containers.iter`),or merged elsewhere (`containers.sexp`).
|
deleted (`containers.iter`),or merged elsewhere (`containers.sexp`).
|
||||||
This means that if use these libraries you will have to edit your
|
This means that if use these libraries you will have to edit your
|
||||||
`dune`/`_oasis`/`opam` files.
|
`dune`/`_oasis`/`opam` files.
|
||||||
|
|
|
||||||
|
|
@ -1,6 +0,0 @@
|
||||||
(test
|
|
||||||
(name t)
|
|
||||||
(flags :standard -strict-sequence -warn-error -a+8)
|
|
||||||
(modes (best exe))
|
|
||||||
(package containers-thread)
|
|
||||||
(libraries containers containers-thread containers_testlib iter threads))
|
|
||||||
|
|
@ -1,9 +0,0 @@
|
||||||
Containers_testlib.run_all ~descr:"containers-thread"
|
|
||||||
[
|
|
||||||
T_bq.Test.get ();
|
|
||||||
T_lock.Test.get ();
|
|
||||||
T_pool.Test.get ();
|
|
||||||
T_semaphore.Test.get ();
|
|
||||||
T_thread.Test.get ();
|
|
||||||
T_timer.Test.get ();
|
|
||||||
]
|
|
||||||
|
|
@ -1,64 +0,0 @@
|
||||||
module Test = (val Containers_testlib.make ~__FILE__ ())
|
|
||||||
open Test
|
|
||||||
open CCBlockingQueue;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let q = create 1 in
|
|
||||||
let t1 =
|
|
||||||
CCThread.spawn (fun () ->
|
|
||||||
push q 1;
|
|
||||||
push q 2)
|
|
||||||
in
|
|
||||||
let t2 =
|
|
||||||
CCThread.spawn (fun () ->
|
|
||||||
push q 3;
|
|
||||||
push q 4)
|
|
||||||
in
|
|
||||||
let l = CCLock.create [] in
|
|
||||||
let t3 =
|
|
||||||
CCThread.spawn (fun () ->
|
|
||||||
for _i = 1 to 4 do
|
|
||||||
let x = take q in
|
|
||||||
CCLock.update l (fun l -> x :: l)
|
|
||||||
done)
|
|
||||||
in
|
|
||||||
Thread.join t1;
|
|
||||||
Thread.join t2;
|
|
||||||
Thread.join t3;
|
|
||||||
assert_equal [ 1; 2; 3; 4 ] (List.sort Stdlib.compare (CCLock.get l));
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let n = 1000 in
|
|
||||||
let lists =
|
|
||||||
[|
|
|
||||||
CCList.(1 -- n); CCList.(n + 1 -- (2 * n)); CCList.((2 * n) + 1 -- (3 * n));
|
|
||||||
|]
|
|
||||||
in
|
|
||||||
let q = create 2 in
|
|
||||||
let senders =
|
|
||||||
CCThread.Arr.spawn 3 (fun i ->
|
|
||||||
if i = 1 then
|
|
||||||
push_list q lists.(i)
|
|
||||||
(* test push_list *)
|
|
||||||
else
|
|
||||||
List.iter (push q) lists.(i))
|
|
||||||
in
|
|
||||||
let res = CCLock.create [] in
|
|
||||||
let receivers =
|
|
||||||
CCThread.Arr.spawn 3 (fun i ->
|
|
||||||
if i = 1 then (
|
|
||||||
let l = take_list q n in
|
|
||||||
CCLock.update res (fun acc -> l @ acc)
|
|
||||||
) else
|
|
||||||
for _j = 1 to n do
|
|
||||||
let x = take q in
|
|
||||||
CCLock.update res (fun acc -> x :: acc)
|
|
||||||
done)
|
|
||||||
in
|
|
||||||
CCThread.Arr.join senders;
|
|
||||||
CCThread.Arr.join receivers;
|
|
||||||
let l = CCLock.get res |> List.sort Stdlib.compare in
|
|
||||||
assert_equal CCList.(1 -- (3 * n)) l;
|
|
||||||
true
|
|
||||||
|
|
@ -1,101 +0,0 @@
|
||||||
module Test = (val Containers_testlib.make ~__FILE__ ())
|
|
||||||
open Test
|
|
||||||
open CCLock;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
let try_incr l =
|
|
||||||
update l (fun x ->
|
|
||||||
Thread.yield ();
|
|
||||||
x + 1)
|
|
||||||
in
|
|
||||||
for _i = 1 to 10 do
|
|
||||||
ignore (Thread.create try_incr l)
|
|
||||||
done;
|
|
||||||
Thread.delay 0.10;
|
|
||||||
assert_equal 10 (get l);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
let test_it l =
|
|
||||||
with_lock_as_ref l ~f:(fun r ->
|
|
||||||
(* increment and decrement *)
|
|
||||||
for j = 0 to 100 do
|
|
||||||
let x = LockRef.get r in
|
|
||||||
LockRef.set r (x + 10);
|
|
||||||
if j mod 5 = 0 then Thread.yield ();
|
|
||||||
let y = LockRef.get r in
|
|
||||||
LockRef.set r (y - 10)
|
|
||||||
done)
|
|
||||||
in
|
|
||||||
for _i = 1 to 100 do
|
|
||||||
ignore (Thread.create test_it l)
|
|
||||||
done;
|
|
||||||
Thread.delay 0.10;
|
|
||||||
0 = get l
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 5 in
|
|
||||||
update l (fun x -> x + 1);
|
|
||||||
get l = 6
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 5 in
|
|
||||||
update_map l (fun x -> x + 1, string_of_int x) = "5" && get l = 6
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
set l 4;
|
|
||||||
get l = 4
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
set l 4;
|
|
||||||
set l 5;
|
|
||||||
get l = 5
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
let a = Array.init 100 (fun _ -> Thread.create (fun _ -> incr l) ()) in
|
|
||||||
Array.iter Thread.join a;
|
|
||||||
assert_equal ~printer:CCInt.to_string 100 (get l);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
incr l;
|
|
||||||
get l = 1
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
decr l;
|
|
||||||
get l = ~-1
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
1 = incr_then_get l && 1 = get l
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 0 in
|
|
||||||
0 = get_then_incr l && 1 = get l
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 10 in
|
|
||||||
9 = decr_then_get l && 9 = get l
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = create 10 in
|
|
||||||
10 = get_then_decr l && 9 = get l
|
|
||||||
|
|
@ -1,220 +0,0 @@
|
||||||
module Test = (val Containers_testlib.make ~__FILE__ ())
|
|
||||||
open Test
|
|
||||||
open CCPool
|
|
||||||
|
|
||||||
module P = Make (struct
|
|
||||||
let max_size = 30
|
|
||||||
end)
|
|
||||||
|
|
||||||
module P2 = Make (struct
|
|
||||||
let max_size = 15
|
|
||||||
end)
|
|
||||||
|
|
||||||
module Fut = P.Fut
|
|
||||||
module Fut2 = P2.Fut;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
List.iter
|
|
||||||
(fun n ->
|
|
||||||
let l = Iter.(1 -- n) |> Iter.to_list in
|
|
||||||
let l =
|
|
||||||
List.rev_map
|
|
||||||
(fun _i ->
|
|
||||||
Fut.make (fun () ->
|
|
||||||
Thread.delay 0.01;
|
|
||||||
1))
|
|
||||||
l
|
|
||||||
in
|
|
||||||
let l' = List.map Fut.get l in
|
|
||||||
assert_equal n (List.fold_left ( + ) 0 l'))
|
|
||||||
[ 10; 300 ];
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
List.iter
|
|
||||||
(fun n ->
|
|
||||||
let l = Iter.(1 -- n) |> Iter.to_list in
|
|
||||||
let l =
|
|
||||||
List.rev_map
|
|
||||||
(fun _i ->
|
|
||||||
Fut2.make (fun () ->
|
|
||||||
Thread.delay 0.01;
|
|
||||||
1))
|
|
||||||
l
|
|
||||||
in
|
|
||||||
let l' = List.map Fut2.get l in
|
|
||||||
assert_equal n (List.fold_left ( + ) 0 l'))
|
|
||||||
[ 10; 300 ];
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let a = Fut.make (fun () -> 1) in
|
|
||||||
let b = Fut.return 42 in
|
|
||||||
let c = Fut.monoid_product CCPair.make a b in
|
|
||||||
assert_equal (1, 42) (Fut.get c);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let a = Fut.make (fun () -> 1) in
|
|
||||||
let b = Fut.make (fun () -> 42) in
|
|
||||||
let c = Fut.monoid_product CCPair.make a b in
|
|
||||||
assert_equal (1, 42) (Fut.get c);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let a = Fut.make (fun () -> 1) in
|
|
||||||
let b = Fut.map succ @@ Fut.make (fun () -> 41) in
|
|
||||||
let c = Fut.monoid_product CCPair.make a b in
|
|
||||||
assert_equal (1, 42) (Fut.get c);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
eq [ 2; 3 ] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x + 1)) [ 1; 2 ]);;
|
|
||||||
eq [] (Fut.get @@ Fut.map_l (fun x -> Fut.return (x + 1)) []);;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = CCList.(1 -- 50) in
|
|
||||||
let l' =
|
|
||||||
l
|
|
||||||
|> List.map (fun x ->
|
|
||||||
Fut.make (fun () ->
|
|
||||||
Thread.delay 0.1;
|
|
||||||
x * 10))
|
|
||||||
|> Fut.sequence_l
|
|
||||||
|> Fut.map (List.fold_left ( + ) 0)
|
|
||||||
in
|
|
||||||
let expected = List.fold_left (fun acc x -> acc + (10 * x)) 0 l in
|
|
||||||
assert_equal expected (Fut.get l');
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = CCList.(1 -- 100_000) in
|
|
||||||
let l' =
|
|
||||||
l
|
|
||||||
|> CCList.map (fun _x -> Fut.make (fun () -> 1))
|
|
||||||
|> Fut.sequence_l
|
|
||||||
|> Fut.map (List.fold_left ( + ) 0)
|
|
||||||
in
|
|
||||||
let expected = 100_000 in
|
|
||||||
assert_equal expected (Fut.get l');
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = CCList.(1 -- 50) in
|
|
||||||
let l' =
|
|
||||||
l
|
|
||||||
|> List.map (fun x ->
|
|
||||||
Fut.make (fun () ->
|
|
||||||
Thread.delay 0.1;
|
|
||||||
if x = 5 then raise Exit;
|
|
||||||
x))
|
|
||||||
|> Fut.sequence_l
|
|
||||||
|> Fut.map (List.fold_left ( + ) 0)
|
|
||||||
in
|
|
||||||
assert_raises (( = ) Exit) (fun () -> Fut.get l');
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let rec fib x =
|
|
||||||
if x < 2 then
|
|
||||||
1
|
|
||||||
else
|
|
||||||
fib (x - 1) + fib (x - 2)
|
|
||||||
in
|
|
||||||
let l =
|
|
||||||
CCList.(1 -- 10_000)
|
|
||||||
|> List.rev_map (fun x ->
|
|
||||||
Fut.make (fun () ->
|
|
||||||
Thread.yield ();
|
|
||||||
fib (x mod 20)))
|
|
||||||
|> Fut.(map_l (fun x -> x >|= fun x -> x + 1))
|
|
||||||
in
|
|
||||||
assert (Fut.state l = Waiting);
|
|
||||||
let l' = Fut.get l in
|
|
||||||
assert_equal 10_000 (List.length l');
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = CCList.(1 -- 50) in
|
|
||||||
let l' =
|
|
||||||
l
|
|
||||||
|> List.map (fun x ->
|
|
||||||
Fut2.make (fun () ->
|
|
||||||
Thread.delay 0.1;
|
|
||||||
x * 10))
|
|
||||||
|> Fut2.sequence_l
|
|
||||||
|> Fut2.map (List.fold_left ( + ) 0)
|
|
||||||
in
|
|
||||||
let expected = List.fold_left (fun acc x -> acc + (10 * x)) 0 l in
|
|
||||||
assert_equal expected (Fut2.get l');
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = CCList.(1 -- 50) in
|
|
||||||
let l' =
|
|
||||||
l
|
|
||||||
|> List.map (fun x ->
|
|
||||||
Fut2.make (fun () ->
|
|
||||||
Thread.delay 0.1;
|
|
||||||
if x = 5 then raise Exit;
|
|
||||||
x))
|
|
||||||
|> Fut2.sequence_l
|
|
||||||
|> Fut2.map (List.fold_left ( + ) 0)
|
|
||||||
in
|
|
||||||
assert_raises (( = ) Exit) (fun () -> Fut2.get l');
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let rec fib x =
|
|
||||||
if x < 2 then
|
|
||||||
1
|
|
||||||
else
|
|
||||||
fib (x - 1) + fib (x - 2)
|
|
||||||
in
|
|
||||||
let l =
|
|
||||||
CCList.(1 -- 10_000)
|
|
||||||
|> List.rev_map (fun x ->
|
|
||||||
Fut2.make (fun () ->
|
|
||||||
Thread.yield ();
|
|
||||||
fib (x mod 20)))
|
|
||||||
|> Fut2.(map_l (fun x -> x >|= fun x -> x + 1))
|
|
||||||
in
|
|
||||||
assert (Fut2.state l = Waiting);
|
|
||||||
let l' = Fut2.get l in
|
|
||||||
assert_equal 10_000 (List.length l');
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let start = Unix.gettimeofday () in
|
|
||||||
let pause = 0.2 and n = 10 in
|
|
||||||
let l =
|
|
||||||
CCList.(1 -- n) |> List.map (fun _ -> Fut.make (fun () -> Thread.delay pause))
|
|
||||||
in
|
|
||||||
List.iter Fut.get l;
|
|
||||||
let stop = Unix.gettimeofday () in
|
|
||||||
assert (stop -. start < float_of_int n *. pause);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let start = Unix.gettimeofday () in
|
|
||||||
let pause = 0.2 and n = 10 in
|
|
||||||
let l =
|
|
||||||
CCList.(1 -- n)
|
|
||||||
|> List.map (fun _ -> Fut2.make (fun () -> Thread.delay pause))
|
|
||||||
in
|
|
||||||
List.iter Fut2.get l;
|
|
||||||
let stop = Unix.gettimeofday () in
|
|
||||||
assert (stop -. start < float_of_int n *. pause);
|
|
||||||
true
|
|
||||||
|
|
@ -1,75 +0,0 @@
|
||||||
module Test = (val Containers_testlib.make ~__FILE__ ())
|
|
||||||
open Test
|
|
||||||
open CCSemaphore;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let s = create 1 in
|
|
||||||
let r = CCLock.create false in
|
|
||||||
let _ =
|
|
||||||
Thread.create
|
|
||||||
(fun s ->
|
|
||||||
acquire 5 s;
|
|
||||||
CCLock.set r true)
|
|
||||||
s
|
|
||||||
in
|
|
||||||
Thread.yield ();
|
|
||||||
assert_equal false (CCLock.get r);
|
|
||||||
release 4 s;
|
|
||||||
Thread.delay 0.2;
|
|
||||||
assert_equal true (CCLock.get r);
|
|
||||||
assert_equal 0 (get s);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let s = create 5 in
|
|
||||||
let n = CCLock.create 0 in
|
|
||||||
let a =
|
|
||||||
Array.init 100 (fun i ->
|
|
||||||
Thread.create
|
|
||||||
(fun _ ->
|
|
||||||
for _i = 1 to 100 do
|
|
||||||
with_acquire
|
|
||||||
~n:(1 + (i mod 5))
|
|
||||||
s
|
|
||||||
~f:(fun () ->
|
|
||||||
Thread.yield ();
|
|
||||||
CCLock.incr n)
|
|
||||||
done)
|
|
||||||
())
|
|
||||||
in
|
|
||||||
Array.iter Thread.join a;
|
|
||||||
assert_equal ~printer:CCInt.to_string 5 (get s);
|
|
||||||
assert_equal ~printer:CCInt.to_string 10_000 (CCLock.get n);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let output _s = () in
|
|
||||||
let s = create 2 in
|
|
||||||
let res = CCLock.create false in
|
|
||||||
let id =
|
|
||||||
Thread.create
|
|
||||||
(fun () ->
|
|
||||||
output "start";
|
|
||||||
wait_until_at_least ~n:5 s ~f:(fun () ->
|
|
||||||
assert (get s >= 5);
|
|
||||||
output "modify now";
|
|
||||||
CCLock.set res true))
|
|
||||||
()
|
|
||||||
in
|
|
||||||
output "launched thread";
|
|
||||||
Thread.yield ();
|
|
||||||
assert (not (CCLock.get res));
|
|
||||||
output "release 2";
|
|
||||||
release 2 s;
|
|
||||||
Thread.yield ();
|
|
||||||
assert (not (CCLock.get res));
|
|
||||||
output "release 1";
|
|
||||||
release 1 s;
|
|
||||||
(* should work now *)
|
|
||||||
Thread.delay 0.2;
|
|
||||||
Thread.join id;
|
|
||||||
output "check";
|
|
||||||
assert (CCLock.get res);
|
|
||||||
true
|
|
||||||
|
|
@ -1,32 +0,0 @@
|
||||||
module Test = (val Containers_testlib.make ~__FILE__ ())
|
|
||||||
open Test
|
|
||||||
open CCThread;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let l = CCLock.create 0 in
|
|
||||||
let a = Arr.spawn 101 (fun i -> CCLock.update l (( + ) i)) in
|
|
||||||
Arr.join a;
|
|
||||||
let n = Iter.(1 -- 100 |> fold ( + ) 0) in
|
|
||||||
assert_equal ~printer:CCInt.to_string n (CCLock.get l);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let b = Barrier.create () in
|
|
||||||
let res = CCLock.create 0 in
|
|
||||||
let t1 =
|
|
||||||
spawn (fun _ ->
|
|
||||||
Barrier.wait b;
|
|
||||||
CCLock.incr res)
|
|
||||||
and t2 =
|
|
||||||
spawn (fun _ ->
|
|
||||||
Barrier.wait b;
|
|
||||||
CCLock.incr res)
|
|
||||||
in
|
|
||||||
Thread.delay 0.2;
|
|
||||||
assert_equal 0 (CCLock.get res);
|
|
||||||
Barrier.activate b;
|
|
||||||
Thread.join t1;
|
|
||||||
Thread.join t2;
|
|
||||||
assert_equal 2 (CCLock.get res);
|
|
||||||
true
|
|
||||||
|
|
@ -1,43 +0,0 @@
|
||||||
module Test = (val Containers_testlib.make ~__FILE__ ())
|
|
||||||
open Test
|
|
||||||
open CCTimer;;
|
|
||||||
|
|
||||||
(* NOTE: could be tighter bounds, but travis' mac OS seems to be dog slow. *)
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
let start = Unix.gettimeofday () in
|
|
||||||
let timer = create () in
|
|
||||||
let res = CCLock.create 0 in
|
|
||||||
let sem = CCSemaphore.create 1 in
|
|
||||||
CCSemaphore.acquire 1 sem;
|
|
||||||
let stop = ref 0. in
|
|
||||||
every timer 0.1 ~f:(fun () ->
|
|
||||||
if CCLock.incr_then_get res > 5 then (
|
|
||||||
stop := Unix.gettimeofday ();
|
|
||||||
CCSemaphore.release 1 sem;
|
|
||||||
raise ExitEvery
|
|
||||||
));
|
|
||||||
CCSemaphore.acquire 1 sem;
|
|
||||||
(* wait *)
|
|
||||||
assert_equal ~printer:CCInt.to_string 6 (CCLock.get res);
|
|
||||||
assert (!stop -. start >= 0.49999);
|
|
||||||
assert (!stop -. start < 2.);
|
|
||||||
true
|
|
||||||
;;
|
|
||||||
|
|
||||||
t @@ fun () ->
|
|
||||||
(* scenario: n := 1; n := n*4 ; n := n+2; res := n *)
|
|
||||||
let timer = create () in
|
|
||||||
let n = CCLock.create 1 in
|
|
||||||
let res = CCLock.create 0 in
|
|
||||||
after timer 0.3 ~f:(fun () -> CCLock.update n (fun x -> x + 2));
|
|
||||||
ignore
|
|
||||||
(Thread.create
|
|
||||||
(fun _ ->
|
|
||||||
Thread.delay 0.4;
|
|
||||||
CCLock.set res (CCLock.get n))
|
|
||||||
());
|
|
||||||
after timer 0.1 ~f:(fun () -> CCLock.update n (fun x -> x * 4));
|
|
||||||
Thread.delay 0.6;
|
|
||||||
assert_equal ~printer:Q.Print.int 6 (CCLock.get res);
|
|
||||||
true
|
|
||||||
Loading…
Add table
Reference in a new issue