Skip to content

Commit

Permalink
Serialise access to IO in tl_backjump_test.m
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
PaulBone committed Sep 20, 2016
1 parent 6b88f17 commit d66a766
Showing 1 changed file with 41 additions and 27 deletions.
68 changes: 41 additions & 27 deletions tests/hard_coded/tl_backjump_test.m
Original file line number Diff line number Diff line change
Expand Up @@ -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)
)
).

Expand All @@ -104,3 +110,11 @@ impure backjump(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).

0 comments on commit d66a766

Please sign in to comment.