Skip to content

Commit f659636

Browse files
authored
Merge pull request #5682 from GabrielBuica/private/dbuica/CP-49129
CP-49129: Drop global lock around sexpr parsing
2 parents da49add + d6d5c4d commit f659636

File tree

9 files changed

+126
-10
lines changed

9 files changed

+126
-10
lines changed

dune-project

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
(lang dune 3.0)
22
(formatting (enabled_for ocaml))
3+
(using menhir 2.0)
34

45
(generate_opam_files true)
56

ocaml/database/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
(ocamllex db_filter_lex)
22

3-
(ocamlyacc db_filter_parse)
3+
(menhir (modules db_filter_parse))
44

55
(library
66
(name xapi_schema)

ocaml/libs/sexpr/dune

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(ocamlyacc sExprParser)
1+
(menhir (modules sExprParser))
22

33
(ocamllex sExprLexer)
44

@@ -17,9 +17,10 @@
1717
(executable
1818
(modes exe)
1919
(name sexprpp)
20+
(public_name sexprpp)
21+
(package sexpr)
2022
(modules sexprpp)
2123
(libraries
2224
sexpr
2325
)
2426
)
25-

ocaml/libs/sexpr/sExpr_TS.ml

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,6 @@
1212
* GNU Lesser General Public License for more details.
1313
*)
1414

15-
let lock = Mutex.create ()
16-
17-
let of_string s =
18-
Xapi_stdext_threads.Threadext.Mutex.execute lock (fun () ->
19-
SExprParser.expr SExprLexer.token (Lexing.from_string s)
20-
)
15+
let of_string s = SExprParser.expr SExprLexer.token (Lexing.from_string s)
2116

2217
let string_of = SExpr.string_of

ocaml/libs/sexpr/test/dune

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
(test
2+
(name test_sexpr)
3+
(modules test_sexpr)
4+
(libraries sexpr astring rresult qcheck alcotest threads))

ocaml/libs/sexpr/test/test_sexpr.ml

Lines changed: 103 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,103 @@
1+
(*
2+
* Copyright (C) 2024 Cloud Software Group
3+
*
4+
* This program is free software; you can redistribute it and/or modify
5+
* it under the terms of the GNU Lesser General Public License as published
6+
* by the Free Software Foundation; version 2.1 only. with the special
7+
* exception on linking described in file LICENSE.
8+
*
9+
* This program is distributed in the hope that it will be useful,
10+
* but WITHOUT ANY WARRANTY; without even the implied warranty of
11+
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12+
* GNU Lesser General Public License for more details.
13+
*)
14+
15+
module Tree = struct
16+
type 'a t = Node of 'a * 'a t list
17+
18+
let rec show pv = function
19+
| Node (l, []) ->
20+
pv l
21+
| Node (l, xs) ->
22+
let xs = String.concat " " List.(map (show pv) xs) in
23+
Printf.sprintf "(%s %s)" (pv l) xs
24+
end
25+
26+
module Test = struct
27+
let labels = [|"foo"; "bar"; "baz"|]
28+
29+
let label_gen =
30+
QCheck.Gen.(map (Array.get labels) (int_bound (Array.length labels - 1)))
31+
32+
let tree_gen =
33+
(*Alternatively, this can use QCheck.Gen.fix.*)
34+
let open QCheck.Gen in
35+
let node l xs = Tree.Node (l, xs) in
36+
let lo, hi = (2, 6) in
37+
let go recur = function
38+
| 0 ->
39+
map2 node label_gen (return [])
40+
| depth ->
41+
let xs_gen = list_size (int_range 2 4) (recur (depth - 1)) in
42+
map2 node label_gen xs_gen
43+
in
44+
sized_size (int_range lo hi) (fix go)
45+
46+
type 'a outcome =
47+
| Unfinished
48+
| Finished of 'a
49+
| Excepted of exn * Printexc.raw_backtrace
50+
51+
let is_exceptional = function Excepted _ -> true | _ -> false
52+
53+
let assert_exceptional outcomes =
54+
outcomes
55+
|> Array.iter (fun outcome ->
56+
let exceptional = is_exceptional outcome in
57+
let msg =
58+
match (exceptional, outcome) with
59+
| true, Excepted (_, trace) ->
60+
Printf.sprintf "Exception found when parsing Sexpr: %s"
61+
(Printexc.raw_backtrace_to_string trace)
62+
| _ ->
63+
""
64+
in
65+
Alcotest.(check bool) msg false exceptional
66+
)
67+
68+
let go n =
69+
Printexc.record_backtrace true ;
70+
let outcomes = Array.init n (Fun.const Unfinished) in
71+
let trees = QCheck.Gen.generate ~n tree_gen in
72+
let parse (i, input) =
73+
(* Continually parse input until ~200ms has elapsed. *)
74+
let go () =
75+
let start = Unix.gettimeofday () in
76+
while Unix.gettimeofday () -. start < 0.2 do
77+
ignore (SExpr_TS.of_string input)
78+
done
79+
in
80+
(* Trap any exception and populate outcomes with it. *)
81+
let open Rresult.R in
82+
match trap_exn go () with
83+
| Ok () ->
84+
outcomes.(i) <- Finished ()
85+
| Error (`Exn_trap (exn, trace)) ->
86+
outcomes.(i) <- Excepted (exn, trace)
87+
in
88+
let tids =
89+
let launch (tids, i) tree =
90+
let tid = Thread.create parse (i, Tree.show Fun.id tree) in
91+
(tid :: tids, i + 1)
92+
in
93+
fst (List.fold_left launch ([], 0) trees)
94+
in
95+
List.iter Thread.join tids ;
96+
assert_exceptional outcomes
97+
end
98+
99+
let test_parsing () = Test.go 10
100+
101+
let test = [("Parallel Parsing", `Quick, test_parsing)]
102+
103+
let () = Alcotest.run "Sexpr parser" [("parallel parsing", test)]

ocaml/libs/sexpr/test/test_sexpr.mli

Whitespace-only changes.

ocaml/xenopsd/cli/dune

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
(ocamlyacc xn_cfg_parser)
1+
(menhir (modules xn_cfg_parser))
22
(ocamllex xn_cfg_lexer)
33

44
(executable

quality-gate.sh

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -82,10 +82,22 @@ vtpm-fields () {
8282
esac
8383
}
8484

85+
ocamlyacc () {
86+
N=0
87+
OCAMLYACC=$(git grep -r -o --count "ocamlyacc" '**/dune' | wc -l)
88+
if [ "$OCAMLYACC" -eq "$N" ]; then
89+
echo "OK found $OCAMLYACC usages of ocamlyacc usages in dune files."
90+
else
91+
echo "ERROR expected $N usages of ocamlyacc in dune files, got $OCAMLYACC." 1>&2
92+
exit 1
93+
fi
94+
}
95+
8596
list-hd
8697
verify-cert
8798
mli-files
8899
structural-equality
89100
vtpm-unimplemented
90101
vtpm-fields
102+
ocamlyacc
91103

0 commit comments

Comments
 (0)