Mercury currently allows for two positive leap seconds per minute, presumably
following earlier versions of the C standard (e.g. C90). This is based on
an erroneous understanding of how UTC is defined and was corrected in C99.
(UTC allows a maximum of one leap second, positive or negative, per minute.)
library/calendar.m:
library/time.m:
Allow only a single positive leap second per minute.
NEWS.md:
Announce the above change.
tests/hard_coded/calendar_date_time.conv.{m,exp}:
Update this test.
Previously, we created _detached_ threads to run work-stealing engines.
The only reason for using detached threads instead of joinable threads
was because the code for thread creation was originally designed for
creating Mercury threads (the interface exported by the thread.m module
expects detached threads).
When the program is about to end, the main thread notifies the engines
to shut down, then waits on a semaphore that is incremented when an
engine is shut down. But an engine can only increment the semaphore
BEFORE its thread terminates. That is, while the semaphore indicates
that the engine has shut down (no longer responding), the thread that
it was running on may continue for an indeterminate amount of time
before it is terminated. The main thread may think that it is safe
to proceed, even while some of the engine threads are still running.
I found that that on a Linux/glibc system, with a statically linked
binary, this setup could sometimes cause an "Aborted" error message
at program exit (after Mercury main/2). From backtraces, I believe the
problem is as described: the main thread is already in a exit() call
while engine threads are still performing their own cleanup, leading to
an abort() call.
The solution is to do what we should have done to begin with: run
work-stealing engines in non-detached threads, and call pthread_join()
to wait for engine threads to terminate before allowing the main thread
to continue with program termination.
runtime/mercury_context.c:
Delete references to shutdown_ws_semaphore.
runtime/mercury_thread.c:
runtime/mercury_thread.h:
Make MR_create_worksteal_thread create a non-detached thread.
runtime/mercury_wrapper.c:
In mercury_runtime_init, record the IDs of the threads created for
running work-stealing engines in an array.
In mercury_runtime_terminate, after notifying each work-stealing
engine to shut down, wait for the engine threads to terminate
by calling pthread_join().
Sample backtrace:
Thread 1 (Thread 0x7f6dcafb46c0 (LWP 11122) (Exiting)):
#0 0x000000000093c40c in pthread_kill ()
#1 0x00000000009219ce in raise ()
#2 0x00000000004013b2 in abort ()
#3 0x0000000000401bd4 in uw_init_context_1[cold] ()
#4 0x00000000009cebda in _Unwind_ForcedUnwind ()
#5 0x0000000000940044 in __pthread_unwind ()
#6 0x000000000093b9e0 in pthread_exit ()
#7 0x00000000009022ad in GC_pthread_exit ()
#8 0x00000000008bd062 in action_shutdown_ws_engine ()
#9 0x00000000008be0ea in scheduler_module_idle_sleep ()
#10 0x00000000008ca58d in MR_call_engine ()
#11 0x00000000008e5d05 in MR_init_thread_inner ()
#12 0x00000000008e5e8c in MR_create_worksteal_thread_2 ()
#13 0x00000000009048d9 in GC_inner_start_routine ()
#14 0x00000000008f46fe in GC_call_with_stack_base ()
#15 0x000000000093a85c in start_thread ()
#16 0x000000000096875c in clone3 ()
Thread 2 (Thread 0x1c533c0 (LWP 11092)):
#0 0x000000000096656d in write ()
#1 0x0000000000933f35 in _IO_new_file_write ()
#2 0x00000000009321c1 in _IO_new_do_write ()
#3 0x0000000000936906 in _IO_flush_all ()
#4 0x0000000000936f2d in _IO_cleanup ()
#5 0x000000000092236e in __run_exit_handlers ()
#6 0x00000000009223be in exit ()
#7 0x0000000000917d0f in __libc_start_call_main ()
#8 0x0000000000919ed0 in __libc_start_main_impl ()
#9 0x0000000000401d85 in _start ()
Thread 3 (Thread 0x7f6dd97d16c0 (LWP 11093) (Exiting)):
#0 0x0000000000941d19 in alloc_new_heap ()
#1 0x00000000009421f2 in arena_get2.part ()
#2 0x0000000000943fb9 in tcache_init.part ()
#3 0x00000000009448c4 in malloc ()
#4 0x00000000009d2141 in _Unwind_Find_FDE ()
#5 0x00000000009cda7d in uw_frame_state_for ()
#6 0x00000000009ce0d3 in uw_init_context_1 ()
#7 0x00000000009cebda in _Unwind_ForcedUnwind ()
#8 0x0000000000940044 in __pthread_unwind ()
#9 0x000000000093b9e0 in pthread_exit ()
#10 0x00000000009022ad in GC_pthread_exit ()
#11 0x00000000008bd062 in action_shutdown_ws_engine ()
#12 0x00000000008be0ea in scheduler_module_idle_sleep ()
#13 0x00000000008ca58d in MR_call_engine ()
#14 0x00000000008e5d05 in MR_init_thread_inner ()
#15 0x00000000008e5e8c in MR_create_worksteal_thread_2 ()
#16 0x00000000009048d9 in GC_inner_start_routine ()
#17 0x00000000008f46fe in GC_call_with_stack_base ()
#18 0x000000000093a85c in start_thread ()
#19 0x000000000096875c in clone3 ()
doc/mercury_reference_manual.texi:
Fix grammar in a number of spots.
Fix errors in some examples.
Fix the table mapping Mercury to CLI and C# types.
There is no System.{Int8,UInt8} in the CLI; they should be
System.SByte and System.Byte respectively.
Add more systematic tests of conversion of durations to and from strings.
Fix two bugs in duration_from_string/2 identified as a result of the new
tests. The first is that the duration string "P" was incorrectly accepted as
the zero duration; the second is that a fractional seconds component with no
whole number part (e.g. "PT.5S"), was incorrectly accepted.
library/calendar.m:
Fix the two bugs above.
tests/hard_coded/Mmakefile:
tests/hard_coded/calendar_duration_conv.{m,exp}:
Add the new test.
tests/hard_coded/fold_days.m:
Add some addition tests of foldl_days.
Add a test for each of foldl2_days and foldl3_days.
tests/hard_coded/fold_days.exp:
Conform to the above additions.
Currently, testing of conversion of date_times to and from strings is only done
by the hard_coded/calendar_test test case. This testing is only done indirectly
as part of testing other functionality and, in particular, does *not* cover the
failure paths of the string to date_time conversion. Add a new test case that
tests the date_time conversions more thoroughly.
tests/hard_coded/Mmakefile:
tests/hard_coded/calendar_date_time_conv.{m,exp}:
Add the new test case.
compiler/error_spec.m:
Delete the function symbol of the error_msg_component type
that allowed the inclusion of help text *if* an option had a given value.
This functionality has been unused since we made all warning and
informational error_specs conditional on an option.
Delete the subtype whose only job was to rule out the now-deleted
function symbol.
Add a comment about a possible solution of a have-your-cake-AND-eat-it
problem.
compiler/error_sort.m:
compiler/error_util.m:
compiler/write_error_spec.m:
Conform to the change in error_spec.m.
This is another move towards making it impossible for the compiler
to stop due to the presence of an error *without* printing a diagnostic
about that error.
compiler/grab_modules.m:
Some of the errors that this module are intended to block the compiler
from continuing on to semantic analysis, and some are not. We used
to make the distinction by returning a flag saying "some of these
are blocking errors", but the list of diagnostics that contained
these blocking errors
- contained a list of error_specs reporting *both* kinds of errors, and
- was not returned alongside the flag, but instead hidden inside
the module baggage, making it hard to find, and easy to ignore.
Change this to computing two lists of error_specs: one for blocking errors,
and one for nonblocking ones. Return the former explicitly, keeping the
latter in the baggage. This design lets the code that stops execution
before semantic analysis to test for the list of blocking errors
being non-empty, which makes printing them the easy thing to do.
Delete the code that, with --very-verbose, wrote out any error_specs
we generated during the processing of a .opt or .trans_opt file
immediately after that processing. The reason is that
- if we print those error_specs out and then do not return them
to mercury_compile_make_hlds.m, then mercury_compile_make_hlds.m
will be making decisions on incomplete and therefore incorrect data,
while
- if we print those error_specs out and *also* return them, then
- either those diagnostics will be printed twice, or
- we need to implement a new system whereby write_error_spec.m
keeps a database of the diagnostics it has already printed,
and simply skips printing any repeats.
Neither of those alternative is palatable, and since in several
decades, I have never needed such immediate printing of diagnostics,
losing that capability is not really an issue.
Fix some relics of the era when the data structures that were
module_baggage's predecessors could not distinguish between fatal
and nonfatal errors.
compiler/mercury_compile_make_hlds.m:
For now, make the new code in grab_modules.m work with the existing
decision making code. Changing that is future work, since it requires
changes to other compiler components as well.
compiler/mercury_compile_args.m:
Instead of writing out any error messages (and setting the exit status)
in different ways in different circumstances, return all error messages
to our caller, as error_specs, and the option_table needed to print
those error_specs out.
Simplify the code that actually does the expansion of @file arguments,
both by invoking higher level primitives than were available when
the original code was written, and by avoiding repeatedly putting
arguments info ok/1 wrappers and taking them out again.
Change the argument list of setup_all_args to delete the ErrorStream
argument and pass only ProgressStream, because its only caller always
passes the *same* stream as both arguments.
compiler/mercury_compile_main.m:
Print the error messages that mercury_compile_args.m now returns.
Standardize on printing "mmc:" before those messages to identify
the program reporting those errors. (The old code could print any
one of "mercury_compile:", "mmc:", the name of the executable,
or nothing.)
compiler/file_util.m:
Add two utility functions for the new code in mercury_compile_args.m.
compiler/handle_options.m:
Add an XXX.
tests/invalid/invalid_mllibs.err_exp:
tests/invalid_make_int/bad_color.int_err_exp:
tests/invalid_options_file/inf_incl_direct.err_exp:
tests/invalid_options_file/inf_incl_indirect.err_exp:
tests/invalid_options_file/no_assign.err_exp:
tests/invalid_options_file/no_var.err_exp:
tests/invalid_options_file/nonexistent_file.err_exp:
tests/invalid_options_file/undefined_var.err_exp:
tests/invalid_options_file/unterminated_string.err_exp:
tests/invalid_options_file/unterminated_var.err_exp:
Consistently expect the "mmc:" prefix before the error messages
now printed by mercury_compile_main.m.
... by removing four more modules from that set.
compiler/make.module_dep_file.m:
compiler/mercury_compile_front_end.m:
compiler/mercury_compile_middle_passes.m:
Replace bespoke error reporting code with invocations of standardized
error reporting predicates.
compiler/source_file_map.m:
Delete an unused predicate.
... by removing globals.m, handle_options.m recompilation.used_file.m
from that set.
compiler/globals.m:
compiler/recompilation.used_file.m:
Replace bespoke error reporting code with invocations of standardized
error reporting predicates.
compiler/handle_options.m:
Generate error_specs instead of writing out warnings directly.
... by removing export.m and options_file.m from that set.
compiler/export.m:
compiler/options_file.m:
Replace bespoke error reporting code with invocations of standardized
error reporting predicates.
compiler/file_util.m:
Add versions of existing error reporting predicates and functions that
work without access to a globals structure, for use by options_file.m.
... by removing compiler_util.m from that set.
compiler/tupling.m:
Replace the only two calls to report_warning with code to return
error_specs.
compiler/mercury_compile_middle_passes.m:
Accumulate the resulting error_specs.
compiler/write_error_spec.m:
Inline the only call to record_warning_opt_table.
compiler/compiler_util.m:
Delete report_warning and record_warning_opt_table, which now have
no callers, and record_warning, which had no callers to begin with.
samples/c_interface/short_example.m:
Do not output two trailing newlines.
samples/concurrency/midimon/concurrent_stream.m:
Module qualify some calls.
samples/java_interface/short_example.m:
s/JAva/Java/
samples/muz/muz.m:
Fix some spelling errors.
samples/calculator2.m:
Do not output error messages that begin with "unexpected unexpected".
samples/sort.m:
Fix inadvertently escaped newline in usage message.
samples/ultra_sub.m:
Fix inverted arguments in usage message.
C99 introduced additional conversion specifiers for use with the printf and
scanf family of functions. Specifically, the 'z' size specifier for size_t
values and the 't' size specifier for ptrdiff_t values. Historically, we have
not used them because the C99 support in a certain C compiler was lacking.
Since this is no longer the case, use them. This removes the need of a bunch
of casts, some of which were incorrect on 64-bit Windows.
runtime/mercury_accurate_gc.c:
runtime/mercury_memory_zones.c:
runtime/mercury_stacks.c:
runtime/mercury_wrapper.c:
As above.