[m-rev.] diff: Serialise access to IO in tl_backjump_test.m

Paul Bone paul at bone.id.au
Tue Sep 20 13:53:38 AEST 2016


After upgrading the collector this test started to fail, but probably not
because of the collector (AFAIK).  I've fixed it by serialising the logging,
so that whole messages are written out and not broken up.

tests/hard_coded/tl_backjump_test.m:
    As above.
---
 tests/hard_coded/tl_backjump_test.m | 68 ++++++++++++++++++++++---------------
 1 file changed, 41 insertions(+), 27 deletions(-)

diff --git a/tests/hard_coded/tl_backjump_test.m b/tests/hard_coded/tl_backjump_test.m
index 8cde2ca..4d3aa01 100644
--- a/tests/hard_coded/tl_backjump_test.m
+++ b/tests/hard_coded/tl_backjump_test.m
@@ -20,75 +20,81 @@
 :- import_module solutions.
 :- import_module string.
 :- import_module thread.
+:- import_module thread.semaphore.
 
 main(!IO) :-
     ( can_spawn ->
-        thread.spawn(run_problem(2), !IO),
-        thread.spawn(run_problem(3), !IO)
+        semaphore.init(1, Sem, !IO),
+        thread.spawn(run_problem(Sem, 2), !IO),
+        thread.spawn(run_problem(Sem, 3), !IO)
     ;
         io.write_string("spawn/3 not supported in this grade", !IO)
     ).
 
 :- type thread_id == int.
 
-:- pred run_problem(thread_id::in, io::di, io::uo) is cc_multi.
+:- pred run_problem(semaphore::in, thread_id::in, io::di, io::uo) is cc_multi.
 
-run_problem(TId0, !IO) :-
+run_problem(Sem, TId0, !IO) :-
     cc_multi_equal(TId0, TId),  % Make sure we are cc_multi.
-    solutions(problem(TId), Sols),
+    solutions(problem(Sem, TId), Sols),
     (
         Sols = [],
-        io.format("(TID: #%d) No solutions!\n",
-            [i(TId)], !IO)
+        locked_write_string(Sem,
+            format("(TID: #%d) No solutions!\n", [i(TId)]),
+            !IO)
     ;
         Sols = [_ | _],
+        wait(Sem, !IO),
         io.format("(TID: #%d) Solutions:\n", [i(TId)], !IO),
         WriteSoln = (pred(Sol::in, !.IO::di, !:IO::uo) is det :-
             io.format("(TID: #%d) ", [i(TId)], !IO),
             io.write(Sol, !IO)
         ),
         io.write_list(Sols, ",\n", WriteSoln, !IO),
-        io.nl(!IO)
+        io.nl(!IO),
+        signal(Sem, !IO)
     ).
 
-:- pred problem(thread_id::in, {int, int, int}::out) is nondet.
+:- pred problem(semaphore::in, thread_id::in, {int, int, int}::out) is nondet.
 
-problem(TId, {A, B, C}) :-
+problem(Sem, TId, {A, B, C}) :-
     promise_pure (
-        impure label(TId, "A", [1, 2], A, PA),
-        impure label(TId, "B", [1, 2], B, PB),
-        impure label(TId, "C", [1, 2, 3], C, PC),
-        impure check(TId, A, B, C, PA, PB, PC)
+        impure label(Sem, TId, "A", [1, 2], A, PA),
+        impure label(Sem, TId, "B", [1, 2], B, PB),
+        impure label(Sem, TId, "C", [1, 2, 3], C, PC),
+        impure check(Sem, TId, A, B, C, PA, PB, PC)
     ).
 
-:- impure pred label(thread_id::in, string::in, list(int)::in, int::out,
-    choice_id::out) is nondet.
+:- impure pred label(semaphore::in, thread_id::in, string::in,
+    list(int)::in, int::out, choice_id::out) is nondet.
 
-label(TId, Name, [N | _], N, P) :-
+label(Sem, TId, Name, [N | _], N, P) :-
     impure get_choice_id(P),
     trace [io(!IO)] (
-        io.format("(TID: #%d) label %s = %d, (%d)\n",
-            [i(TId), s(Name), i(N), i(to_int(P))], !IO),
+        locked_write_string(Sem, format("(TID: #%d) label %s = %d, (%d)\n",
+            [i(TId), s(Name), i(N), i(to_int(P))]), !IO),
         true
     ).
-label(TId, Name, [_ | Ns], N, P) :-
-    impure label(TId, Name, Ns, N, P).
+label(Sem, TId, Name, [_ | Ns], N, P) :-
+    impure label(Sem, TId, Name, Ns, N, P).
 
-:- impure pred check(thread_id::in, int::in, int::in, int::in, choice_id::in,
-    choice_id::in, choice_id::in) is semidet.
+:- impure pred check(semaphore::in, thread_id::in, int::in, int::in, int::in,
+    choice_id::in, choice_id::in, choice_id::in) is semidet.
 
-check(TId, A, B, C, PA, PB, PC) :-
+check(Sem, TId, A, B, C, PA, PB, PC) :-
     ( is_nogood(A, B, C, PA, PB, PC, P) ->
         trace [io(!IO)] (
-            io.format("(TID: #%d) backjump (%d)\n", [i(TId), i(to_int(P))],
+            locked_write_string(Sem,
+                format("(TID: #%d) backjump (%d)\n", [i(TId), i(to_int(P))]),
                 !IO)
         ),
         impure backjump(P)
     ;
         is_solution(A, B, C),
         trace [io(!IO)] (
-            io.format("(TID: #%d) solution %d, %d, %d\n",
-                [i(TId), i(A), i(B), i(C)], !IO)
+            locked_write_string(Sem, format("(TID: #%d) solution %d, %d, %d\n",
+                [i(TId), i(A), i(B), i(C)]), !IO)
         )
     ).
 
@@ -104,3 +110,11 @@ is_nogood(2, 1, 2, _, P, _, P).
 is_solution(1, 1, 3).
 is_solution(2, 1, 1).
 is_solution(2, 2, 2).
+
+:- pred locked_write_string(semaphore::in, string::in, io::di, io::uo) is det.
+
+locked_write_string(Sem, String, !IO) :-
+    wait(Sem, !IO),
+    write_string(String, !IO),
+    signal(Sem, !IO).
+
-- 
2.7.4



More information about the reviews mailing list