(* TEST modules = "stubs.c"; no-tsan; (* Takes too much time and memory with tsan *) { bytecode; } { native; } *) external init_skiplist : unit -> unit = "init_skiplist" external hammer_skiplist : int -> unit = "hammer_skiplist" let () = init_skiplist (); let domains_list = List.init 4 (fun i -> Domain.spawn (fun () -> hammer_skiplist i)) in ignore(List.iter Domain.join domains_list) (* Concurrent versions of the memory test in tests.ml, see there first *) external insert_skiplist : int -> int -> int -> unit = "insert_skiplist" external find_skiplist : int -> int -> int -> bool = "find_skiplist" external clean_skiplist : int -> unit = "clean_skiplist" external cardinal_skiplist : unit -> int = "cardinal_skiplist" let () = (* Clean garbage list *) clean_skiplist (-1); (* Check cleaning *) clean_skiplist 0; init_skiplist (); assert (cardinal_skiplist() = 0) ; let nturns = 128 and npar = 4 and nseq = 4 in assert (nturns < 1024); (* See calc_key in stubs.c *) (* Fill skip list and then empty it *) for k = 1 to nseq do let d_list = List.init npar (fun i -> Domain.spawn (fun () -> for k = 1 to nturns do insert_skiplist k npar i done)) in ignore (List.iter Domain.join d_list) ; assert (cardinal_skiplist() = npar*nturns) ; let d_list = List.init npar (fun i -> Domain.spawn (fun () -> for k = 1 to nturns do assert(find_skiplist k npar i) done)) in ignore (List.iter Domain.join d_list) ; assert (cardinal_skiplist() = 0) ; clean_skiplist (npar*nturns) ; done ; (* Fill and empty skiplist concurrently *) for k = 1 to nseq do let d_list = List.init (npar*2) (fun i -> Domain.spawn (fun () -> let j = i/2 in if i mod 2 = 0 then for k = 1 to nturns do insert_skiplist k npar j done else for k = 1 to nturns do while not (find_skiplist k npar j) do Domain.cpu_relax () done done)) in ignore (List.iter Domain.join d_list) ; assert (cardinal_skiplist() = 0) ; clean_skiplist (npar*nturns) ; done ; (* Fill and empty skiplist concurrently, checking list consistency *) for k = 1 to nseq do let d_list = List.init (npar*2) (fun i -> Domain.spawn (fun () -> let j = i/2 in if i mod 2 = 0 then for k = 1 to nturns do insert_skiplist k npar j done else if j mod 2 = 0 then for k = 1 to nturns do while not (find_skiplist k npar j) do Domain.cpu_relax () done done)) in ignore (List.iter Domain.join d_list) ; assert (cardinal_skiplist() = nturns*(npar-(npar+1)/2)) ; clean_skiplist (nturns*((npar+1)/2)) ; let d_list = List.init npar (fun i -> Domain.spawn (fun () -> if i mod 2 = 1 then for k = 1 to nturns do while not (find_skiplist k npar i) do Domain.cpu_relax () done done)) in ignore (List.iter Domain.join d_list) ; assert (cardinal_skiplist() = 0); clean_skiplist (nturns*(npar/2)) ; done ; ()