[m-rev.] For review: ensure proper initialisation of pretty_printer
Ralph Becket
rafe at csse.unimelb.edu.au
Thu Apr 22 22:39:02 AEST 2010
Julien Fischer, Thursday, 22 April 2010:
>
> On Thu, 22 Apr 2010, Ralph Becket wrote:
>
> >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.
>
> IMO, this is hacky way of fixing the problem. A better solution would be to
> ensure that initialisation of any global variables required by the
> pretty-printer is done as part the standard library's initialisation, in
> ML_init_io_state. That is guaranteed to occur before any :- initialise
> directives are processed.
I did start putting code in an initialise directive in library.m, but
that seemed more of a hack. It required:
- giving pretty_printer a special place in the library;
- exporting stuff from library.m;
- hence making library.m an "active" part of the library, rather than a
bookkeeping mechanism.
> >This patch fixes the problem by using C instead of a mutable
> >for the default formatter map variable.
>
> That doesn't seem to be the case -- io_formatter_map is still a mutable
> below.
Ah, that's a leftover I forgot to delete.
> >:- 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;
> >+").
>
> This is wrong, if we end up with references to either variable outside
> of pretty_printer.o then linking will fail.
>
> Either do:
>
> :- pragma foreign_dec("C", "
> extern MR_Bool pretty_printer_is_initialised;
> extern MR_Word pretty_printer_default_formatter_map;
> ").
>
> :- pragma foreign_code("C", "
> MR_Bool pretty_printer_is_initialised = MR_FALSE;
> MR_Word pretty_printer_default_formatter_map = NULL;
> ").
>
> or:
> :- pragma foreign_decl("C", local,
> static MR_Bool pretty_printer_is_initialised = MR_FALSE;
> static MR_Word pretty_printer_default_formatter_map = NULL;
> ").
>
> and then _ensure_ that any foreign procs. in pretty_printer.m cannot be
> inlined in other modules.
>
> I recommend the first; it is less error prone.
Ah, this was nagging me. Thanks (I didn't know about the 'local' option
to foreign_decl - ta for pointing that one out!).
What's your preferred course of action here?
-- Ralph
--------------------------------------------------------------------------
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