[m-rev.] For review: ensure proper initialisation of pretty_printer
Ralph Becket
rafe at csse.unimelb.edu.au
Thu Apr 22 15:46:50 AEST 2010
If this could be reviewed quickly, that would be great. I'm using
this patch to track down a problem in the G12 IC solver.
Estimated hours taken: 2
Branches: main
There is a race condition between the initialisation of modules
and mutables, mainly because there is no guaranteed order of
initialisation. This is a problem for pretty_printer.m since
we would like other modules to be able to register formatters
for types they define via an ':- initialise' directive.
This patch fixes the problem by using C instead of a mutable
for the default formatter map variable.
Index: library/pretty_printer.m
===================================================================
RCS file: /home/mercury1/repository/mercury/library/pretty_printer.m,v
retrieving revision 1.9
diff -u -r1.9 pretty_printer.m
--- library/pretty_printer.m 18 May 2009 05:55:13 -0000 1.9
+++ library/pretty_printer.m 22 Apr 2010 05:39:14 -0000
@@ -884,7 +884,7 @@
%-----------------------------------------------------------------------------%
% Convenience predicates.
-:- mutable(io_formatter_map, formatter_map, initial_formatter_map, ground,
+:- mutable(io_formatter_map, formatter_map, new_formatter_map, ground,
[attach_to_io_state, untrailed, thread_local]).
:- mutable(io_pp_params, pp_params, pp_params(78, 100, triangular(100)),
@@ -892,16 +892,76 @@
%-----------------------------------------------------------------------------%
+ % Because there is no guaranteed order of module initialisation, we need
+ % to ensure that we do the right thing if other modules try to update the
+ % default formatter_map before this module has been initialised.
+ %
+ % All of this machinery is needed to avoid a race condition between
+ % initialise directives and initialisation of mutables.
+ %
+:- pragma foreign_decl("C",
+"
+ static MR_Bool pretty_printer_is_initialised = MR_FALSE;
+ static MR_Word pretty_printer_default_formatter_map = NULL;
+").
+
+%-----------------------------------------------------------------------------%
+
+:- pred pretty_printer_is_initialised(bool::out, io::di, io::uo)
+ is det.
+
+:- pragma foreign_proc("C",
+ pretty_printer_is_initialised(Okay::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+ Okay = pretty_printer_is_initialised;
+").
+
+%-----------------------------------------------------------------------------%
+
+ % This predicate must not be called unless pretty_printer_is_initialised ==
+ % MR_TRUE, which occurs when set_default_formatter_map has been called at
+ % least once.
+ %
+:- pred unsafe_get_default_formatter_map(formatter_map::out, io::di, io::uo)
+ is det.
+
+:- pragma foreign_proc("C",
+ unsafe_get_default_formatter_map(FMap::out, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury, thread_safe],
+"
+ FMap = pretty_printer_default_formatter_map;
+").
+
+%-----------------------------------------------------------------------------%
+
get_default_formatter_map(FMap, !IO) :-
- get_io_formatter_map(FMap, !IO).
+ pretty_printer_is_initialised(Okay, !IO),
+ (
+ Okay = no,
+ FMap = initial_formatter_map,
+ set_default_formatter_map(FMap, !IO)
+ ;
+ Okay = yes,
+ unsafe_get_default_formatter_map(FMap, !IO)
+ ).
-set_default_formatter_map(FMap, !IO) :-
- set_io_formatter_map(FMap, !IO).
+%-----------------------------------------------------------------------------%
+
+:- pragma foreign_proc("C",
+ set_default_formatter_map(FMap::in, _IO0::di, _IO::uo),
+ [promise_pure, will_not_call_mercury],
+"
+ pretty_printer_default_formatter_map = FMap;
+ pretty_printer_is_initialised = MR_TRUE;
+").
+
+%-----------------------------------------------------------------------------%
set_default_formatter(ModuleName, TypeName, Arity, Formatter, !IO) :-
- get_io_formatter_map(FMap0, !IO),
+ get_default_formatter_map(FMap0, !IO),
FMap = set_formatter(ModuleName, TypeName, Arity, Formatter, FMap0),
- set_io_formatter_map(FMap, !IO).
+ set_default_formatter_map(FMap, !IO).
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list