Commit Graph

76 Commits

Author SHA1 Message Date
Julien Fischer
7c2cf9e946 Rationalise foreign_proc attributes in stdlib.
library/*.m:
    Remove tabled_for_io attributes from C# and Java foreign_procs.
    I/O tabling is not supported by those backends.

    Remove will_not_modify_trail attributes from C# and Java foreign_procs,
    and from predicates that do I/O. They have no effect in the former and
    cannot affect anything with the latter.

    Fix a spot a where will_not_modify_trail was given, but
    will_not_call_mercury was meant.
2026-02-20 19:19:26 +11:00
Julien Fischer
b85f11b41d Fix library documentation errors.
library/*.m:
    As above.

library/getopt.m:
    Regenerate this file.
2026-01-22 21:22:38 +11:00
Julien Fischer
b7685aae5f Disable concurrency in non .par LLDS grades.
The non .par LLDS grades currently "support" concurrency. However, this support
is really only usable with a small few benchmark programs, due to the inability
of the implementation to switch threads if the executing thread blocks. Disable
this capability by causing spawn/3 to abort if used in non .par LLDS grades.

library/thread.m:
    Make the above change to spawn/3.

compiler/globals.m:
    Update the code that checks if the current grade supports concurrency.

compiler/options.m:
    Adjust documentation for the --parallel option.

tests/warnings/help_text.err_exp:
    Conform to the above change.
2025-08-21 22:08:48 +10:00
Julien Fischer
86f39dc421 Implement num_processors/4 for C#.
library/thread.m:
    As above.

    Delete some unnecessary foreign code attributes.
2025-08-15 18:32:47 +10:00
Zoltan Somogyi
34e64a623b Replace "iff" with "if-and-only-if" in the library. 2025-06-08 10:33:56 +10:00
Zoltan Somogyi
a19bcaaed5 Updates to programming style in the library.
library/bt_array.m:
    Reorder the arguments of the resize and shrink predicates
    to make them easier to use with state variables.

tests/general/array_test.m:
    Update the test calls to these two predicates.

library/version_array2d.m:
    Rewrite part of this module using a programming style that includes
    variable names that are longer than one character :-(. In the absence
    of comprehensive, or even basic, test cases, leave the rest using
    the old style.

    Add a non-field-syntax lookup operation.

    Mark the site of a probable bug.

library/version_bitmap.m:
    Add non-field-syntax versions of the get_bit and set_bit operations.

NEWS.md:
    Announce the reordering and the new predicates above.

library/getopt.m:
library/getopt_io.m:
    Apply to getopt_io.m an update that was previously applied to getopt.m,
    even though getopt.m is now computed from getopt_io.m.

library/array2d.m:
library/bit_buffer.m:
library/bit_buffer.read.m:
library/bit_buffer.write.m:
library/bitmap.m:
library/cord.m:
library/edit_distance.m:
library/edit_seq.m:
library/fat_sparse_bitset.m:
library/fatter_sparse_bitset.m:
library/list.m:
library/one_or_more.m:
library/pair.m:
library/ra_list.m:
library/rbtree.m:
library/set_bbbtree.m:
library/set_ctree234.m:
library/set_ordlist.m:
library/set_tree234.m:
library/set_unordlist.m:
library/solutions.m:
library/sparse_bitset.m:
library/test_bitset.m:
library/thread.barrier.m:
library/thread.m:
library/thread.semaphore.m:
library/time.m:
library/tree_bitset.m:
library/version_array.m:
library/version_hash_table.m:
library/version_store.m:
    General updates to style, the main ones being the following.

    Using standard names for type variables:

    - K and V for key and value types in map-like structures
    - A to F for types of accumulators
    - T for most everything else, possibly with a numeric suffix
      to distinguish two separate types that nevertheless play
      similar roles.

    (I left descriptive type var names such as Stream and Store unchanged.)

    Adding or expanding descriptions of exported predicates and functions.

    Declaring and defining field syntax getters and setters without using ^,
    while keeping the use of field syntax, including ^, in the operations'
    descriptions.

    Defining field syntax operations operations in terms of the
    non-field-syntax versions, not vice versa.

    Defining function versions of operations in terms of the predicate
    versions, not vice versa.
2024-12-29 20:09:09 +11:00
Peter Wang
6ecbd12b1d Fix compilation of thread.m with tabling.
The tabling transform aborted on a predicate in thread.m because
an argument has mode 'unused':

Software Error: predicate `transform_hlds.table_gen.get_input_output_vars'/7:
Unexpected: bad var

library/thread.m:
    Change the mode of the argument from 'unused' to 'in'.
2024-02-27 11:10:08 +11:00
Peter Wang
4dd926b54d Support joinable threads in C# and Java backends.
library/thread.m:
    Implement spawn_native_joinable and join_thread for C# and Java.

    Rename the existing Java helper class RunGoal to RunGoalDetached.
    Add RunGoalJoinable.

    Rename the C# helper MercuryThread to RunGoalDetached, to match the
    Java backend. Add RunGoalJoinable.

java/runtime/MercuryThreadPool.java:
    Replace submitExclusiveThread() method with createExclusiveThread(),
    which returns the newly created thread, without starting it.
2024-02-26 13:18:45 +11:00
Peter Wang
4ea65113d8 Add interface for joinable threads.
It is often necessary to be certain that a thread has terminated before
the rest of the program can continue. In some cases, signalling that a
thread is ABOUT to terminate (using any synchronisation device)
is insufficient: even after the last piece of Mercury code has run,
the thread still has additional cleanup code to run, which might include
arbitrary code in thread-specific data destructors, etc.

Introduce a predicate to create a joinable native thread,
and a predicate to wait for that thread to terminate (joining).

Joinable threads are only implemented for C backends for now.

library/thread.m:
    Add new predicates spawn_native_joinable and join_thread.

    Add a internal type thread_handle.

    Rename the internal type thread_id type to thread_desc,
    as thread_id is too similar to thread_handle.

tests/hard_coded/Mmakefile:
tests/hard_coded/spawn_native_joinable.exp:
tests/hard_coded/spawn_native_joinable.exp2:
tests/hard_coded/spawn_native_joinable.m:
    Add test case.

NEWS.md:
    Announce changes.
2024-02-26 13:18:45 +11:00
Zoltan Somogyi
efafcdd0c1 Stop using higher order insts as modes ...
... in the fourth and final batch of library modules.

Set -no-allow-ho-insts-as-modes as the default for this directory
from now on.
2023-07-26 23:55:07 +02:00
Zoltan Somogyi
daba30c48e Stop using higher order insts as modes ...
... in a third batch of library modules.
2023-07-26 22:26:51 +02:00
Zoltan Somogyi
219a387602 Stop using higher order insts as modes ...
... in a first batch of library modules.
2023-07-26 16:22:04 +02:00
Julien Fischer
e7d28ff90f Update copyright notices in stdlib.
library/*.m:
    As above.
2022-06-07 21:51:03 +10:00
Zoltan Somogyi
8ff61f8a4b Delete quotes from `VarNames' in stdlib comments.
In the Mercury standard library, every exported predicate or function
has (or at least *should* have) a comment that documents it, including
the meanings of its arguments. About 35-40% of these modules put `'s
(left and right quotes) around the names of the variable representing
those arguments. Some tried to do it consistently (though there were spots
with unquoted or half quoted names), while some did it only a few places.
This is inconsistent: we should either do it everywhere, or nowhere.
This diff makes it nowhere, because

- this is what the majority of the standard library modules do;
- this is what virtually all of the modules in the compiler, profiler,
  deep_profiler etc directories do;
- typing all those quotes when adding new predicates in modules that
  follow this convention is a pain in the ass; and because
- on many modern terminals, `' looks non-symmetrical and weird.

Likewise, the comment explaining a predicate often started with

    % `predname(arguments)' returns ...

This diff deletes these quotes as well, since they add nothing useful.

This diff does leave in place quotes around code fragments, both terms
and goals, where this helps delineate the boundaries of that fragment.
2022-03-07 11:49:00 +11:00
Peter Wang
ca488701c0 Add thread.spawn_native/5 with minimum stack size option.
library/thread.m:
    Add thread_options type, and a variant of the spawn_native predicate
    that takes a thread_options argument.

    The only thread option supported so far is to request a minimum
    stack size for the newly created thread. This is only implemented
    for POSIX threads so far.

NEWS:
    Announce changes.
2021-10-27 14:59:25 +11:00
Zoltan Somogyi
0d7c8a7654 Specify pred or func for all pragmas.
*/*.m:
    As above.

configure.ac:
    Require the installed compiler to support this capability.
2021-06-16 15:23:58 +10:00
Peter Wang
dae414d920 Add closeable channels to the standard library.
library/thread.closeable_channel.m
    Add the new module. It omits two operations from thread.channel.m:
    - untake, because it is deprecated
    - duplicate, because I'm not sure what it's useful for in practice

library/MODULES_DOC:
library/library.m
library/thread.m:
NEWS:
    Mention the new module.
2020-02-17 14:36:31 +11:00
Zoltan Somogyi
95f8f56716 Delete unneeded $module args from calls to expect/unexpected. 2019-07-03 22:37:19 +02:00
Zoltan Somogyi
c7f8ebbe2f Avoid warnings from --warn-non-contiguous-{clauses,foreign-procs}.
browser/collect_lib.m:
browser/declarative_execution.m:
browser/dl.m:
browser/io_action.m:
compiler/make.util.m:
compiler/pickle.m:
compiler/process_util.m:
compiler/prog_event.m:
library/array.m:
library/benchmarking.m:
library/bit_buffer.m:
library/builtin.m:
library/char.m:
library/deconstruct.m:
library/dir.m:
library/erlang_rtti_implementation.m:
library/int.m:
library/int16.m:
library/int32.m:
library/int64.m:
library/int8.m:
library/io.m:
library/math.m:
library/mutvar.m:
library/private_builtin.m:
library/profiling_builtin.m:
library/rtti_implementation.m:
library/store.m:
library/string.format.m:
library/string.m:
library/table_builtin.m:
library/term_size_prof_builtin.m:
library/thread.m:
library/time.m:
library/type_desc.m:
library/uint16.m:
library/uint32.m:
library/uint64.m:
library/uint8.m:
ssdb/ssdb.m:
    As above. This mostly involved two things.

    The first was grouping foreign_procs by predicate instead of by language.
    In a few cases, this revealed that some predicates *had* no foreign_proc
    for a language, while related predicates did have one that just aborted
    if called. This diff adds similar aborting foreign_procs to predicate/
    language combinations that were missing them, when this seemed obviously
    the right thing to do.

    The second was moving pragmas about a predicate from the middle of the
    block of clauses of that predicate to the start of that block.
2018-10-19 11:01:33 +11:00
Peter Wang
72f174b4e2 Don't print value of errno in MR_fatal_error.
The majority of calls to MR_fatal_error do not follow an operation that
sets errno, so printing out an error message unrelated to the reason for
the fatal error will lead to confusion. It can also cause test failures
if errno happens to be set to non-zero some time prior to an expected
call to MR_fatal_error. Fixes bug #464.

runtime/mercury_misc.c:
    Don't print value of errno in MR_fatal_error.

runtime/mercury_context.c:
runtime/mercury_thread.c:
    Pass strerror strings to MR_fatal_error where appropriate.

runtime/mercury_memory_zones.c:
runtime/mercury_memory_zones.h:
    Pass strerror strings to MR_fatal_error following failures of
    MR_protect_pages. Document that this assumes MR_protect_pages sets
    errno on error.

    Skip unnecessary call to sprintf before MR_fatal_error.

runtime/mercury_deep_profiling.c:
    Skip unnecessary call to sprintf before MR_fatal_error.

    Reduce size of some buffers.

runtime/mercury_overflow.c:
runtime/mercury_stack_trace.c:
    Pass a fixed format string to MR_fatal_error just in case
    the message string may contain percentage signs.

runtime/mercury_tabling.c:
    Skip unnecessary call to sprintf before MR_fatal_error.

deep_profiler/timeout.m:
library/thread.m:
mdbcomp/shared_utilities.m:
    Pass strerror strings to MR_fatal_error where appropriate.

trace/mercury_trace.c:
    Skip unnecessary call to sprintf before MR_fatal_error.

trace/mercury_trace_external.c:
    Pass a fixed format string to MR_fatal_error just in case.
2018-08-19 12:19:19 +10:00
Zoltan Somogyi
a12692a0de Replace /* */ comments with // in the library.
Keep the old style comments where they do not go to the end of the line,
or where it is important that the comment line not have a // on it.
2018-06-21 18:55:08 +02:00
Mark Brown
d465fa53cb Update the COPYING.LIB file and references to it.
Discussion of these changes can be found on the Mercury developers
mailing list archives from June 2018.

COPYING.LIB:
    Add a special linking exception to the LGPL.

*:
    Update references to COPYING.LIB.

    Clean up some minor errors that have accumulated in copyright
    messages.
2018-06-09 17:43:12 +10:00
Peter Wang
4af9648908 Defer CPU detection in high-level C grades, and related cleanups.
library/thread.m:
    Make num_processors/3 call a function in the runtime instead of
    reading a global variable, so we can defer initialisation of the
    variable.

    Return `no' if unable to determine the number of CPUs instead of
    defaulting to 1.

runtime/mercury_context.c:
runtime/mercury_context.h:
    Add a function MR_get_num_processors().

    Hide MR_num_processors_detected variable.

    Rename MR_detect_num_processors() to
    MR_init_available_cpus_and_detect_num_processors()
    to reflect what it does.

    Add a function MR_free_available_cpus(), currently only implemented
    for the Linux CPU affinity API path.

    Call MR_init_available_cpus_and_detect_num_processors() at startup
    only in low-level C grades. The only reason to call it in high-level
    C grades was to set MR_num_processors_detected. It will now be set
    at the first call to MR_get_num_processors().

    Free the available CPU data structures as soon as we have
    MR_num_processors_detected, unless required for thread pinning.

    Rename MR_setup_num_threads to MR_setup_num_ws_engines.
    Pass the number of processors detected as an argument to make
    the dependency explicit.

    Make MR_pin_primordial_thread return a CPU number as its comment
    suggests.

    Delete the global variable MR_primordial_thread_cpu as it is
    currently unused.

    Add a function MR_done_thread_pinning().

runtime/mercury_wrapper.c:
    Call MR_done_thread_pinning() to free up available CPU data
    structures after thread pinning is done with them.

    Add an unrelated XXX.
2018-05-23 17:52:39 +10:00
Peter Wang
fb682d9d71 Fix use of Linux CPU affinity API.
The main fix is to retry the sched_getaffinity() call in
MR_reset_available_cpus(). If that call failed because we provided a
cpuset that is too small for the kernel, MR_reset_available_cpus() would
set MR_available_cpus to NULL but leave MR_cpuset_size non-zero,
leading to a null pointer dereference soon after.

runtime/mercury_context.c:
runtime/mercury_context.h:
    Use a macro MR_HAVE_LINUX_CPU_AFFINITY_API if we have all the pieces
    we need for that API.

    Rename MR_num_processors to MR_num_processors_detected for clarity.

    Add a global variable MR_cpuset_num_cpus to record the size of the
    cpuset that we allocated.

    Change MR_cpuset_size to size_t to match the type in the underlying
    interface.

    Rename MR_available_cpus to MR_cpuset_available to clarify the
    relationship with MR_cpuset_size and MR_cpuset_num_cpus.

    In MR_reset_available_cpus(), retry sched_getaffinity() if it fails
    with EINVAL. It may fail because the kernel uses a larger CPU
    affinity mask than the cpuset we provided; then we must retry the
    call with a larger cpuset.

    Ensure MR_reset_available_cpus() does not leave MR_cpuset_*
    variables in an inconsistent state.

    Make MR_detect_num_processors() set MR_num_processors to 1 if the
    MR_cpuset_available set is somehow empty after
    MR_reset_available_cpus(). It should not happen, but the program
    should be able to continue anyway.

    In MR_pin_thread_no_locking(), loop over the entire
    MR_cpuset_available set to find a target CPU to pin to.
    The CPUs available to the thread are not necessarily numbered
    consecutively from the initial CPU onwards mod MR_num_processors.

    Fix cpuset allocation in MR_do_pin_thread to not assume that CPUs
    are numbered from 0 to MR_num_processors-1. Fix a memory leak.

    Clean up MR_current_cpu().
    Prevent a null pointer dereference in the hwloc path:
    hwloc_get_pu_obj_by_os_index always returns NULL on my system.

    Change some types from 'unsigned' to 'int' to match underlying APIs.

library/thread.m:
    Conform to variable renaming.

checkout sysconf(_SC_NPROCESSORS_ONLN); error
2018-05-23 17:52:21 +10:00
Peter Wang
938d9af9cd Report more specific error messages when thread.spawn_native fails.
library/thread.m:
    Return error message for errno when pthread_create() fails
    in thread.spawn_native.

    Return the exception message when thread creation fails in C#.
    Catch System.SystemException as that is seen in practice with mono
    (might not be documented).

    Return the exception message when thread creation fails in Java.
    Catch SecurityException (as documented) and OutOfMemoryError
    (seen in practice).
2018-04-24 15:18:02 +10:00
Julien Fischer
97721a4d3e Update configure script for C# grade.
Implement thread.yield/2 for the C# grade.

m4/mercury.m4:
    Update the C# compiler check to not try the old aliases for the
    Mono C# compiler; do not try the DotGNU (which is no longer a going
    concern) C# compiler either.

    Update the copyright notice for this file.

library/thread.m:
    Uncomment and correct the C# implementation of thread.yield/2.
2018-01-04 01:49:31 -05:00
Zoltan Somogyi
74a7a8345c Fix too-long lines. 2017-12-30 19:59:59 +11:00
Peter Wang
0f46cce052 Keep two C functions local to thread module.
library/thread.m:
    As above.
2017-07-13 11:25:07 +10:00
Peter Wang
0856389da8 Avoid sem_post/sem_wait race in glibc.
glibc prior to 2.21 is susceptible to a race between sem_post/sem_wait
https://sourceware.org/bugzilla/show_bug.cgi?id=12674

(I have not personally encountered this bug, and I hope never to.)

library/thread.m:
    Use a pthread mutex and condition variable instead of a pthread
    semaphore to synchronise the newly spawned thread with its parent in
    ML_create_exclusive_thread.
2017-07-12 13:55:13 +10:00
Peter Wang
9424a6fe7e Handle sem_wait, sem_timedwait being interrupted by signal handlers.
sem_wait or sem_timedwait may be interrupted by signal handlers and
return an error. We must retry the call if errno is set to EINTR.

library/thread.m:
    Retry MR_SEM_WAIT if interrupted by a signal handler in
    ML_create_exclusive_thread.

    Call MR_fatal_error if MR_SEM_WAIT fails for any other reason.
    The only other documented error code is EINVAL if the semaphore is
    invalid; that should not happen.

runtime/mercury_context.c:
    Retry MR_SEM_WAIT if interrupted by a signal handler in
    MR_shutdown_ws_engines.

runtime/mercury_thread.h:
    Add the macro MR_SEM_IS_EINTR for checking if errno == EINTR
    after calling MR_SEM_WAIT or MR_SEM_TIMED_WAIT.
2017-07-10 10:38:49 +10:00
Julien Fischer
4966332290 Rename the macros for condition variables.
runtime/mercury_thread.h:
   Rename MR_WAIT to MR_COND_WAIT etc.

runtime/mercury_wrapper.c:
library/thread.m:
library/thread.semaphore.m:
    Conform to the above change.
2016-10-05 13:13:07 +11:00
Julien Fischer
74dfaa5953 Isolate all dependencies on POSIX unnamed semaphores.
Isolate all dependencies on POSIX unnamed semaphores to the runtime's
mercury_thread module.  This is a step towards fixing bug #357.

runtime/mercury_thread.{h,c}:
    Provide wrappers for the functions sem_destroy and sem_timedwait.
    The latter does not exist on OS X, so (for now) just abort if it
    is called.

runtime/mercury_context.c:
library/thread.m:
     Use the above wrappers instead of calling the sem_* functions
     directly.
2016-09-29 14:06:04 +10:00
Paul Bone
0bd301b59e Add thread.num_processors/3
Add a predicate that retrieves the number of processors available to this
process if known.

library/thread.m:
    As above.

runtime/mercury_context.c:
    The existing code that determines the number of processors was only used
    on thread safe low-level C grades.  Make it also available for thread
    safe high-level C grades.

    Add a fall back (less accurate) method of determining the number of
    processors.

    Remove an out-of-date comment.

runtime/mercury_context.h:
    Export the number of available processors.

scripts/ml.in:
    Link to libhwloc (if configured) on thread safe high and low-level C
    grades.

NEWS:
    Announce new predicate.

configure.ac:
    Update a --help message.
2016-05-13 16:17:52 +10:00
Paul Bone
5f0eb0a2c6 Fix spawn_context bug
In low-level C grades spawn_context attempts to use the stack of the new
context to pass the closure and thread ID to the new context once it starts
running.  The first stack slot used has a 0 offset from the stack pointer,
but the second used has a -1 offset.  If the stack pointer is at the
beginning of the memory zone (which happens sometimes but not usually, see
MR_next_offset()) then this can create an invalid memory access.  This
raises a segfault with the new version of Boehm GC.

Create a stack frame for the closure and thread ID in spawn_context.

library/thread.m:
    As above.
2015-09-25 17:34:10 +10:00
Zoltan Somogyi
62ec97d443 Report imports shadowed by other imports.
If a module has two or more import_module or use_module declarations
for the same module, (typically, but not always, one being in its interface
and one in its implementation), generate an informational message about
each redundant declaration if --warn-unused-imports is enabled.

compiler/hlds_module.m:
    We used to record the set of imported/used modules, and the set of
    modules imported/used in the interface of the current module. However,
    these sets

    - did not record the distinction between imports and uses;
    - did not allow distinction between single and multiple imports/uses;
    - did not record the locations of the imports/uses.

    The first distinction was needed only by module_qual.m, which *did*
    pay attention to it; the other two were not needed at all.

    To generate messages for imports/uses shadowing other imports/uses,
    we need all three, so change the data structure storing such information
    for *direct* imports to one that records all three of the above kinds
    of information. (For imports made by read-in interface and optimization
    files, the old set of modules approach is fine, and this diff leaves
    the set of thus *indirectly* imported module names alone.)

compiler/unused_imports.m:
    Use the extra information now available to generate a
    severity_informational message about any import or use that is made
    redundant by an earlier, more general import or use.

    Fix two bugs in the code that generated warnings for just plain unused
    modules.

    (1) It did not consider that a use of the builtin type char justified
    an import of char.m, but without that import, the type is not visible.

    (2) It scanned cons_ids in goals in procedure bodies, but did not scan
    cons_ids that have been put into the const_struct_db. (I did not update
    the code here when I added the const_struct_db.)

    Also, add a (hopefully temporary) workaround for a bug in
    make_hlds_passes.m, which is noted below.

    However, there are at least three problems that prevent us from enabling
    --warn-unused-imports by default.

    (1) In some places, the import of a module is used only by clauses for
    a predicate that also has foreign procs. When compiled in a grade that
    selects one of those foreign_procs as the implementation of the predicate,
    the clauses are discarded *without* being added to the HLDS at all.
    This leads unused_imports.m to generate an uncalled-for warning in such
    cases. To fix this, we would need to preserve the Mercury clauses for
    *all* predicates, even those with foreign procs, and do all the semantic
    checks on them before throwing them away. (I tried to do this once, and
    failed, but the task should be easier after the item list change.)

    (2) We have two pieces of code to generate import warnings. The one in
    unused_imports.m operates on the HLDS after type and mode checking,
    while module_qual.m operates on the parse tree before the creation of
    the HLDS. The former is more powerful, since it knows e.g. what types and
    modes are used in the bodies of predicates, and hence can generate warnings
    about an import being unused *anywhere* in a module, as opposed to just
    unused in its interface.

    If --warn-unused-imports is enabled, we will get two separate set of
    reports about an interface import being unused in the interface,
    *unless* we get a type or mode error, in which case unused_imports.m
    won't be invoked. But in case we do get such errors, we don't want to
    throw away the warnings from module_qual.m. We could store them and
    throw them away only after we know we won't need them, or just get
    the two modules to generate identical error_specs for each warning,
    so that the sort_and_remove_dups of the error specs will do the
    throwing away for us for free, if we get that far.

    (3) The valid/bug100.m test case was added as a regression test for a bug
    that was fixed in module_qual.m. However the bug is still present in
    unused_imports.m.

compiler/make_hlds_passes.m:
    Give hlds_module.m the extra information it now needs for each item_avail.

    Add an XXX for a bug that cannot be fixed right now: the setting of
    the status of abstract instances to abstract_imported. (The "abstract"
    part is correct; the "imported" part may not be.)

compiler/intermod.m:
compiler/try_expand.m:
compiler/xml_documentation.m:
    Conform to the change in hlds_module.m.

compiler/module_qual.m:
    Update the documentation of the relationship of this module
    with unused_imports.m.

compiler/hlds_data.m:
    Document a problem with the status of instance definitions.

compiler/hlds_out_module.m:
    Update the code that prints out the module_info to conform to the change
    to hlds_module.m.

    Print status information about instances, which was needed to diagnose
    one of the bugs in unused_imports.m. Format the output for instances
    nicer.

compiler/prog_item.m:
    Add a convenience predicate.

compiler/prog_data.m:
    Remove a type synonym that makes things harder to understand, not easier.

compiler/modules.m:
    Delete an XXX that asks for the feature this diff implements.
    Add another XXX about how that feature could be improved.

compiler/Mercury.options.m:
    Add some more modules to the list of modules on which the compiler
    should be invoked with --no-warn-unused-imports.

compiler/*.m:
library/*.m:
mdbcomp/*.m:
browser/*.m:
deep_profiler/*.m:
mfilterjavac/*.m:
    Delete unneeded imports. Many of these shadow other imports, and some
    are just plain unneeded, as shown by --warn-unused-imports. In a few
    modules, there were a *lot* of unneeded imports, but most had just
    one or two.

    In a few cases, removing an import from a module, because it *itself*
    does not need it, required adding that same import to those of its
    submodules which *do* need it.

    In a few cases, conform to other changes above.

tests/invalid/Mercury.options:
    Test the generation of messages about import shadowing on the existing
    import_in_parent.m test case (although it was also tested very thoroughly
    when giving me the information needed for the deletion of all the
    unneeded imports above).

tests/*/*.{m,*exp}:
    Delete unneeded imports, and update any expected error messages
    to expect the now-smaller line numbers.
2015-08-25 00:38:49 +10:00
Zoltan Somogyi
572c1040ad Start using `:- pragma external_pred'.
configure.ac:
    Check whether the installed compiler supports `:- pragma external_pred'.

library/backjump.m:
library/builtin.m:
library/exception.m:
library/par_builtin.m:
library/profiling_builtin.m:
library/table_builtin.m:
library/thread.m:
    Replace `:- external' with `:- pragma external_pred'.

    Replace (C->T;E) with (if C then T else E).

    Fix indentation and white space.
2015-08-21 16:05:50 +10:00
Julien Fischer
c580a95c99 Fix whitespace problems in stdlib.
library/backjump.m:
library/benchmarking.m:
library/calendar.m:
library/gc.m:
library/store.m:
library/term_io.m:
library/thread.m:
library/time.m:
	Expand tabs and deleting trailing whitespace as necessary.
2015-08-18 22:54:32 +10:00
Zoltan Somogyi
7f9791aa26 Standardize divider line lengths in the library.
library/*.m:
    As above.

tool/stdlines:
    A new shell script to do the job.
2014-11-23 22:05:34 +11:00
Paul Bone
e3c2dfa344 Add a future data type for concurrent and parallel programming
library/library.m:
library/thread.future.m:
library/thread.m:
    Add new future standard library module.

NEWS:
    Announce the new addition.

library/thread.semaphore.m:
    Add an impure interface to thread.semaphore.m.  Semaphores are used to
    implement our other concurrency primitives and an impure interface can
    often be useful to implement things such as futures, which don't require
    IO state threading.  The impure interface predicate names are prefixed
    with "impure_".

library/thread.semaphore.m:
NEWS:
    Deprecate the impure init/1 function.

library/thread.mvar.m:
    Conform to changes in semaphore.m.

benchmarks/progs/mandelbrot/mandelbrot.m:
    Add future example to mandelbrot benchmark.
2014-10-10 00:57:36 +11:00
Paul Bone
a2879c6837 Make MercuryThreadPool (java) notice when a thread blocks on a semaphore.
If threads are blocked while there is work in the queue extra threads may be
spawned to keep the processors busy.

Beginning now, tasks created with thread.spawn are use the thread pool.
(thread.spawn_native does not use the thread pool.)

java/runtime/Semaphore.java:
    Wrap Java's Semaphore class which call the current thread's blocked()
    and running() methods when a thread blocks and then runs after being
    blocked.

library/thread.semaphore.m:
    Use our own Semaphore class.

java/runtime/MercuryThread.java:
java/runtime/MercuryWorkerThread.java:
    Define blocked() and running() on our threads.

java/runtime/NativeThread.java:
    This class is used by spawn_native/4 and is required to define blocked()
    and running(), however it implements them as no-ops as it isn't included
    in the thread pool.

java/runtime/ThreadStatus.java:
    Define the BLOCKED status.

java/runtime/MercuryThreadPool.java:
    Count blocked threads seperatly and allow the creation of new threads
    when existing threads become blocked.

    Add some tracing code to help debug the thread management code.  This is
    disabled by default.

library/thread.m:
    Implement spawn for Java using the thread pool.  This was not enabled
    earlier because without using java/runtime/Semaphore.java it was
    possible to deadlock the system.

java/runtime/Task.java:
    Add some tracing code to debug thread state changes, this is disabled by
    default.
2014-10-03 19:22:32 +10:00
Julien Fischer
cf9dad309e Add missing local to foreign_decl pragma.
library/thread.m:
	The C functions ML_{incr,decr}_thread_barrier_count are declared
	with static linkage; their containing foreign_decl pragma should
	be marked as local.
2014-09-19 09:50:08 +10:00
Paul Bone
496952e5ab Use a thread pool to manage threads on the Java backend
Thread pools are often used to reduce poor performance on embarrassingly
parallel work loads.  This isn't immediately necessary on the Java backend
however I've implemented it because:
    + It will be required when we implement parallel conjunctions for the
      Java backend.
    + I want to implement parallel profiling on the Java backend and don't
      want to have to implement this once now, and then re-implement it after
      introducing thread pools later.

We want the thread pool to generally restrict the number of threads that are
in use, this reduces overheads.  However, when one or more tasks become
blocked then it can be desirable to create extra threads, this helps ensure
that all processors are kept busy and that thread pooling doesn't contribute
to any deadlocks itself.  The implementation is a work in prograss and
currently does not implement this second feature.

Java's API provides several different thread pools, see
java.util.concurrent.Executors, none of which are suitable.  Specifically
the fixed thread pool is unsuitable as we want to be able to temporarily
exceed the normal number of threads as explained above; and the cached
thread pools, which are also very similar to the ThreadPoolExecutor class,
do not implement the correct algorithm for determining when a new thread
should be created (they can still perform poorly for embarassingly parallel
workloads).  Additionally we cannot instrument this code as easily for
parallel profiling.

These changes alter the behaviour of Mercury threads on the Java backend in
two ways, they now behave more correctly and more like threads on the C
backends.
    + If a thread throws an exception it is now reported and the program is
      aborted.  Previously it was ignored and let pass to the Java runtime
      where I assume it was reported.
    + The program now exits only after all threads have exited.

The ThreadPool will automatically detect the number of threads to use, or if
the -P flag is given in the MERCURY_OPTIONS environment variable it will
honor that.

java/runtime/MercuryThread.java:
java/runtime/MercuryThreadPool.java:
java/runtime/MercuryWorkerThread.java:
java/runtime/Task.java:
java/runtime/ThreadStatus.java:
    These new classes make up the thread pool.  A MercuryThread is an
    abstract class for Mercury threads, MercuryWorkerThread is a concrete
    subclass of MercuryThread which includes the worker thread behaviour.
    A Task is a computation/closure that has not yet been started, it
    provides some methods not available in Java's generic Runnable and
    Callable classes.  The others should be self-explanatory and all files
    contain documentation.

java/runtime/Getopt.java:
java/runtime/MercuryOptions.java:
    Parse the MERCURY_OPTIONS environment variable for the -P flag.

java/runtime/JavaInternal.java:
    Add support for handling Mercury exceptions, this is used in case a
    worker thread's task (a Mercury thread) throws an exception.

compiler/mlds_to_java.m:
    The main method of the main Java class of an application now starts and
    uses the thread pool to execute main/2.

library/exception.m:
    Export exception reporting code to the Java runtime system.

library/thread.m:
    Use the thread pool for thread.spawn.
2014-08-01 12:32:51 +10:00
Peter Wang
7688546d03 Add thread_safe and not_thread_safe attributes.
library/benchmarking.m:
library/bit_buffer.m:
library/exception.m:
library/gc.m:
library/io.m:
library/library.m:
library/thread.m:
library/time.m:
	Add `thread_safe' or `not_thread_safe' to foreign procs
	where it is clear which is correct.
2014-07-25 17:45:33 +10:00
Peter Wang
c631dc4379 Simplify workaround for Erlang backend.
The bug avoided by the preceding commit is that the Erlang backend can
produce code for cc_multi_equal(!IO) which refers to a non-existent
dummy IO variable.

library/thread.m:
	Replace `cc_multi_equal' by a disjunction to convince the
	compiler that `spawn_context_2' is non-deterministic.

	Delete the Erlang foreign proc.
2014-07-17 10:33:14 +10:00
Julien Fischer
0997b1317f Fix standard library compilation in erlang grade.
library/thread.m:
	Workaround a problem that was preventing this module from compiling
	successfully in the erlang grade.
2014-07-16 17:48:28 +10:00
Peter Wang
56cebb3114 Add thread.spawn_native/4 and thread.spawn/4.
Most backends already mapped Mercury threads to "native" threads in spawn/3,
but it was and remains an implementation detail.  spawn_native provides
that behaviour as a documented feature for programs which require it,
including for the low-level C backend.

While we are at it, add a `thread' handle type.  It currently holds a
thread identifier (not yet formally exported), but it may also have
other uses such as a handle for a `thread.join' predicate, or a place to
hold result values or uncaught exceptions.

library/thread.m:
	Add abstract type `thread'.

	Add can_spawn_native.

	Add spawn_native/4.  It can report failure to start a thread,
	which was missing from the spawn/3 interface.

	Add spawn/4 to match spawn_native/4, without the native thread
	requirement.

	Make ML_create_exclusive_thread wait for a success code from
	the new thread before continuing.

	Reduce accessibility levels in C# and Java helper classes.

runtime/mercury_thread.c:
	Make MR_init_thread_inner and MR_setup_engine_for_threads
	return errors instead of aborting on failure.

tests/hard_coded/Mercury.options:
tests/hard_coded/Mmakefile:
tests/hard_coded/spawn_native.exp2:
tests/hard_coded/spawn_native.exp:
tests/hard_coded/spawn_native.m:
	Add test case.

NEWS:
	Announce change.
2014-07-10 14:58:14 +10:00
Peter Wang
29f2dcf213 Support dynamic creation of Mercury engines in low-level C parallel grades.
This change allows Mercury engines (each in a separate OS thread) to be
created and destroyed dynamically in low-level C grades.

We divide Mercury engines into two types:

    "Shared" engines may execute code from any Mercury thread.
    Shared engines may steal work from other shared engines, so are also
    called work-stealing engines; we do not have shared engines that
    refrain from work-stealing.

    "Exclusive" engines execute code only for a single Mercury thread.

Only exclusive engines may be created and destroyed dynamically so far.
This assumption could be lifted when and if the need should arise.

Exclusive engines are a means for the user to map a Mercury thread directly
to an OS thread.  Calls to blocking procedures on that thread will not block
progress in arbitrary other Mercury threads.  Foreign code which depends on
the OS thread-local state is usable when called from that thread.

We do not yet allow shared engines to steal parallel work from exclusive
engines.

runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
	Rename MR_num_threads to MR_num_ws_engines.  It counts only
	work-stealing engines.  Move comment to the header file.

	Add MR_max_engines.  The default value is arbitrary.

	Add MERCURY_OPTIONS `--max-engines' option.

	Define MR_num_ws_engines and MR_max_engines only with
	MR_LL_PARALLEL_CONJ.

runtime/mercury_context.c:
runtime/mercury_context.h:
	Rename MR_num_idle_engines to MR_num_idle_ws_engines.
	It only counts idle work-stealing engines.

	Extend MR_spark_deques to MR_max_engines length.

	Extend engine_sleep_sync_data to MR_max_engines length.

	Add function to index engine_sleep_sync_data with optional bounds
	checking.

	Replace instances of MR_num_threads by MR_num_ws_engines or
	MR_max_engines as appropriate.

	Add MR_ctxt_exclusive_engine field.

	Rename existing MR_Context fields to remove the implication that the
	engine "owns" the context.  The new exclusive_engine field does
	imply a kind of ownership, hence potential confusion.

	Rename MR_SavedOwner, too.

	Make MR_find_ready_context respect MR_ctxt_exclusive_engine.

	Make MR_schedule_context respect MR_ctxt_exclusive_engine.

	Rename MR_try_wake_an_engine to MR_try_wake_ws_engine
	and restrict it to work-stealing engines.

	Rename MR_shutdown_all_engines to MR_shutdown_ws_engines
	and restrict it to work-stealing engines.

	Make try_wake_engine and try_notify_engine decrement
	MR_num_idle_ws_engines only for shared engines.

	In MR_do_idle, make exclusive engines bypass work-stealing
	and skip to the sleep state.

	In MR_do_sleep, make exclusive engines ignore work-stealing advice
	and abort the program if told to shut down.

	Assert that a context with an exclusive_engine really is only loaded
	by that engine.

	In MR_fork_new_child, make exclusive engines not attempt to wake
	work-stealing engines.  Its sparks cannot be stolen anyway.

	Make do_work_steal fail the attempt for exclusive engines.
	There is one call where this might happen.

	Add notes to MR_attempt_steal_spark.  Its behaviour is unchanged.

	Replace a call to MR_destroy_thread by MR_finalize_thread_engine.

	Delete MR_num_exited_engines.  It was unused.

runtime/mercury_thread.c:
runtime/mercury_thread.h:
	Delete MR_next_engine_id and MR_next_engine_id_lock.  We can no longer
	allocate engine ids by incrementing a counter.  Engine ids need to be
	reused as they act as indices into fixed-sized arrays.

	Extend MR_all_engine_bases to MR_max_engines entries.

	Add MR_all_engine_bases_lock to protect MR_all_engine_bases.

	Add MR_highest_engine_id.

	Add MR_EngineType with the two options described.

	Split the main part of MR_init_engine into a new function which
	accepts an engine type.  MR_init_engine is used by generated code so
	maintain the interface.

	Factor out setup/shutdown for thread support.

	Make MR_finalize_thread_engine call the shutdown function.

	Specialise MR_create_thread into MR_create_worksteal_thread.
	The generic form was unused.

	Move thread pinning into MR_create_worksteal_thread as other threads
	do not require it.

	Delete MR_destroy_thread.  Its one caller can use
	MR_finalize_thread_engine.

	Delete declaration for non-existent variable
	MR_init_engine_array_lock.

runtime/mercury_engine.c:
runtime/mercury_engine.h:
	Add MR_eng_type field.

	Make MR_eng_spark_deque a pointer to separately-allocated memory.
	The reason is given in MR_attempt_steal_spark.

	Add MR_ENGINE_ID_NONE, a dummy value for MR_ctxt_exclusive_engine.

	Delete MR_eng_owner_thread which was obsoleted by engine ids
	before.

	Delete misplaced declaration of MR_all_engine_bases.

runtime/mercury_memory_zones.c:
	Replace MR_num_threads by appropriate counters (I hope).

runtime/mercury_memory_handlers.c:
runtime/mercury_par_builtin.h:
	Conform to changes.

runtime/mercury_threadscope.c:
	Conform to renaming (but it might be wrong).

library/thread.m:
	Add hidden predicate `spawn_native' for testing.
	The interface is subject to change.

	Share much of the code with the high-level C backend.

library/par_builtin.m:
	Delete `num_os_threads' as it is unused.

doc/user_guide.texi:
	Document MERCURY_OPTIONS `--max-engines' option.
2014-07-10 14:57:48 +10:00
Paul Bone
8ad499c685 Add barriers (for concurrency) to the standard library
Mission Critical IT has maintained a library of code for concurrent
programming.  We're happy to contribute this upstream to the Mercury
project starting with this module implementing barriers.

library/thread.barrier.m:
    Add the new module implementing barriers.

library/thread.m:
library/library.m:
    Add new module.

NEWS:
    Announce the new module.

library/thread.semaphore.m:
    Add a comment.
2014-05-16 20:15:32 +10:00
Paul Bone
79c5b951fb Modify how an idle engine with a dirty context gets new work.
These changes fix a couple of performance bugs and also modify the
algorithms in the RTS so that they match the ones in my thesis.

runtime/mercury_context.[ch]:
    An engine with a dirty context will no-longer check for a runnable
    context first.  It first checks for a local spark, if the spark is not
    compatible it puts the spark back on the local spark stack.  Then it
    saves the dirty context and jumps to MR_idle - the entry point for
    engines with no contexts.

    Remove the MR_MAYBE_TRAMPOLINE macro and expand out any case where it
    was previously used.

    We no longer execute a spark when an engine has a dirty incompatible
    context.  (previously we saved the old context then allocated a new
    one).  Therefore prepare_engine_for_spark() no-longer needs the
    join_label parameter (which was used when saving a dirty context).
    Consequently, the same parameter has been removed from
    MR_do_steal_spark.

    If a work stealing thief looses a race then it retries until it wins or
    there is no work.

    Use a mutex rather than a (binary) semaphore to protect the engine sleep
    sync structure.  This more directly reflects the intentions plus POSIX
    mutexes don't always make kernel calls but semaphores do.

    The MR_num_idle_engines global was not being updated correctly, in
    particular it showed that there were idle engines even when there
    weren't.  This caused an engine creating a spark to always attempt to
    notify other engines of the spark.  Fixing the use of
    MR_num_idle_engines improves performance by over a factor of 2x in the
    naive fibs micro benchmark.

    Refactor MR_join_and_continue to match the simplier structure in my
    thesis.

    Rename MR_destroy_context to MR_release_context, which gives a more
    accurate impression.

    Update some MR_assert calls that where incorrect.

runtime/mercury_engine.c:
runtime/mercury_par_builtin.c:
    Conform to MR_release_context.

library/thread.m:
    Conform to MR_release_context.

    Add a missing MR_save_context.
2012-08-06 02:11:24 +00:00
Peter Wang
e6cfcc53fc Fix a memory leak in thread.spawn in high-level C grades.
Branches: main

Fix a memory leak in thread.spawn in high-level C grades.

library/thread.m:
	Call MR_finalize_thread_engine after finishing the thread goal in
	ML_thread_wrapper.

runtime/mercury_thread.c:
	Call MR_destroy_engine in MR_finalize_thread_engine.
	(The XXX is from year 2000 -- a lot of things have changed since then.
	If the problem is still present, we should fix it.)
2011-11-28 05:14:26 +00:00