Commit Graph

29 Commits

Author SHA1 Message Date
Julien Fischer
26e542a6d4 Use __sync_synchronize() as a fallback memory barrier with clang.
runtime/mercury_atomic_ops.h:
    clang provides the GCC builtin function __sync_synchronize(); use that
    as a fallback memory barrier.

    Avoid unreadable #error directive output from clang.

    Add an XXX about C11 atomic ops.
2021-04-13 11:28:18 +10:00
Julien Fischer
2c0b268c1f Replace erroneous pragma with #error directive.
runtime/mercury_atomic_ops.h:
    As above; on aarch64-apple-darwin we were *not* getting the error about
    memory fence operations not being defined when using clang as the C
    compiler; compilation was instead aborting later due to MR_SFENCE
    not being defined.
2021-04-12 12:45:03 +10: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
Zoltan Somogyi
53b573692a Convert C code to use // style comments.
runtime/*.[ch]:
trace/*.[chyl]:
    As above. In some places, improve comments, e.g. by expanding contractions
    such as "we've". Add #ifndef guards against double inclusion around
    the trace/*.h files that did not already have them.

tools/*:
    Make the corresponding changes in shell scripts that generate .[ch] files
    in the runtime.

tests/*:
    Conform to a slight change in the text of a message.
2016-07-14 13:57:35 +02:00
Zoltan Somogyi
67326f16e4 Fix style issues in the runtime.
Move all .h and .c files to four-space indentation without tabs,
if they weren't there already.

Use the same vim line for all .h and .c files.

Align all backslashes at the ends of lines in macro definitions.
Align close comment signs.

In some places, fix inconsistent indentation.

Fix a bunch of comments. Add XXXs to a few of them.
2016-07-09 12:14:00 +02:00
Paul Bone
a9f82d004b On some systems the CPU's time stamp counter (TSC) cannot reliabily be
used.  Mercury's ThreadScope support will now use gettimeofday() by
default, but use of the TSC may be enabled.

Note that in Linux, gettimeofday() does not always make a system call.

runtime/mercury_threadscope.[ch]:
    Add support for measuring time with gettimeofday().

    Use gettimeofday() to measure time by default.

runtime/mercury_atomic_ops.[ch]
    Add a new function MR_tsc_is_sensible(), It returns true if the TSC can
    (as far as the RTS can detect) be used.

    Fix trailing whitespace.

runtime/mercury_wrapper.c:
    Add a new runtime option --threadscope-use-tsc.
    When specified this option allows threadscope to use the CPU's TSC to
    measure time.

doc/userguide.texi:
    Document the --threadscope-use-tsc option.  This documentation is
    commented out.
2012-06-20 13:13:34 +00:00
Zoltan Somogyi
742800c5da Post-commit review of Paul's change introducing the loop control primitives.
Estimated hours taken: 1
Branches: main

Post-commit review of Paul's change introducing the loop control primitives.
It also updates some documentation Paul's update did not touch.

library/par_buildin.m:
runtime/mercury_atomic_ops.h:
runtime/mercury_context.h:
	Fix formatting and grammar.

runtime/mercury_par_builtin.[ch]:
	Use a variable length array in the loop control struct to store
	the loop control slots. This setup needs one load to access a slot,
	compared to two with the previous arrangement.

	Fix formatting and grammar.

	Add XXXs where relevant.
2011-09-12 08:09:24 +00:00
Julien Fischer
b31ff32593 Support more of the handwritten atomic ops with clang.
Branches: main, 11.07

runtime/mercury_atomic_ops.h:
	Support more of the handwritten atomic ops with clang.
2011-08-26 14:10:04 +00:00
Julien Fischer
9033da0777 Fix some dodgy spacing.
Branches: main, 11.07

runtime/mercury_atomic_ops.h:
	Fix some dodgy spacing.
2011-08-26 11:09:33 +00:00
Julien Fischer
4486c39aeb Make none.par.gc bootstrap with clang (2.8.0) on Linux.
Branches: main, 11.07

Make none.par.gc bootstrap with clang (2.8.0) on Linux.

runtime/mercury_atomic_ops.h:
	Define MR_ATOMIC_DEC_INT_BODY and MR_ATOMIC_DEC_AND_IS_ZERO_WORD_BODY
	for clang - we use the same inline assembler definitions that are used
	for GCC.
2011-08-26 08:02:05 +00:00
Julien Fischer
870f70a1c3 Make hlc.par.gc bootstrap with clang on Linux.
Branches: main, 11.07

Make hlc.par.gc bootstrap with clang on Linux.

runtime/mercury_atomic_ops.h:
	Use the GCC definitions of MR_COMPARE_AND_SWAP_WORD_BODY and
	MR_CPU_SFENCE with clang.
2011-08-26 06:19:34 +00:00
Julien Fischer
8af00f7a2a Avoid using the __GNUC__ macro in the runtime as a test for the presence of
Branches: main, 11.07

Avoid using the __GNUC__ macro in the runtime as a test for the presence of
gcc, since clang also defines that macro.  Since clang doesn't support all
of the GNU C extensions, we can't actually use __GNUC__ without also checking
whether we are actually using clang.

runtime/mercury_conf_param.h:
	Add three new macros, MR_CLANG, MR_GNUC and MR_MSVC that are defined
	only when the C compiler is clang, gcc, or Visual C respectively.
	(In particular, MR_GNUC will _not_ be defined when the C compiler
	is clang.)

runtime/mercury.c:
runtime/mercury.h:
runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h
runtime/mercury_bitmap.h:
runtime/mercury_float.h:
runtime/mercury_getopt.c:
runtime/mercury_goto.h:
runtime/mercury_heap.h:
runtime/mercury_std.h:
	Replace uses of the __GNUC__ and __clang__ macros with the above.

runtime/mercury_regs.h:
	As above, also #include mercury_conf_param.h directly since
	this file is #included by some of the tests in the configure
	script.
2011-08-01 07:06:21 +00:00
Paul Bone
ca7878f01a Make improvements to stack segments code.
The main benefits of these changes are:

    Stack segments (and other memory zones) are cached when they are released
    and can be re-used.

    Some thread safety-fixes have been added.

    All stack segments on all stacks are now the same size:
        Small contexts (which had small stacks) aren't used with stack
        segments.

        The first segment on any stack is the same size as any other segment.

    The first segment on any stack no-longer has a redzone.

    Hard zones on all memory zones have been set to the minimum of one page
    rather than one MR_unit which is usually two pages.

The caching of stack segments results in the following benchmark results.  The
benefit is negligible under normal circumstances, but becomes important when
small segment sizes are used.  Small segment sizes are common in
asm_fast.gc.par.stseg configurations as they reduce the memory required for
suspended contexts.

Non-segmented stack (32MB)
    asm_fast.gc                      average of 5 with ignore=1     18.16 (1.00)

With 512KB (normal) segments:
    asm_fast.gc.stseg and NO caching average of 5 with ignore=1     19.20 (1.06)
    asm_fast.gc.stseg WITH caching   average of 5 with ignore=1     19.16 (1.06)

With 4KB segments:
    asm_fast.gc.stseg and NO caching average of 5 with ignore=1     20.66 (1.14)
    asm_fast.gc.stseg WITH caching   average of 5 with ignore=1     19.66 (1.08)

Other changes include corrections in code comments, clearer function names and
a documentation fix.

runtime/mercury_memory_zones.h:
runtime/mercury_memory_zones.c:
    Re-write a lot of the code that managed the zone lists.  The old code did
    not re-use previously allocated but saved zones.  The changes ensure that
    MR_create_or_reuse_zone (formerly MR_create_zone) checks for a free zone
    of at least the required size before allocating a new one.  When zones are
    released they are put on the free list.

    As above MR_create_zone is now MR_create_or_reuse_zone,

    MR_unget_zone is now MR_release_zone.

    MR_construct_zone has been removed, it was only ever called by
    MR_create_or_reuse_zone.  MR_create_or_reuse_zone now contains the code for
    MR_construct_zone.

    To avoid an unnecessary sychronisation in parallel code some zones are not
    added to the used list.  The only zones put on the used list are those that
    are useful to have on the used list because they have a non-default signal
    handler or a redzone.

    Updates to used_memory_zones now use a pthread mutex so that only one
    thread may be updating the list at once.  This lock is shared with the
    free_memory_zones structure.

    Updates to used_memory_zones now use memory barriers to guarantee that
    concurrent reads always read a consistent, but possibly incomplete,
    data-structure.  This is necessary because it is read from a signal handler
    which cannot call pthread_mutex().

    Rename MR_get_used_memory_zones() to MR_get_used_memory_zones_readonly()
    and document that the zone lists may be incomplete.

    Make the MR_zone_next field of the MR_MemoryZone_Struct structure volatile.

    Remove MAX_ZONES, it wasn't being used anywhere.

    Insert some calls to MR_debug_log_message to help with debugging.

    Use the correct printf integer length modifier for MR_Unsigned values.

    Rename MR_context_id_counter to zone_id_counter, protect it with a lock in
    HLC thread safe grades and use atomic operations in LLC thread-safe
    grades..

    The offset at which we start using a memory zone is allocated in sequence
    from a table.  This table was protected by Mercury's global lock, this is
    now a CAS operation which prevents deadlocks when using trail segment,
    parallel grades.

runtime/mercury_stacks.c:
    Conform to changes in mercury_memory_zones.c.

    Use MR_debug_log_message for printf-style debugging rather than printf.

runtime/mercury_wrapper.h:
runtime/mercury_wrapper.c:
    Remove support for the smaller sized stacks in grades with stack segments.

    Disable redzones when using stack segments.  The MR_(non)detstack_zone_size
    variables affect the first segment on every stack.  Regardless of the type
    of contaxt that owns that stack.

    Conform to changes in runtime/mercury_memory_zones.h.

runtime/mercury_context.h:
runtime/mercury_context.c:
    Removed an extra declaration for MR_init_context_maybe_generator

    Small contexts are problematic since it's unclear to the programmer which
    computations will be executed on smaller contexts and therefore whether
    their stacks would overflow.

    Conform to changes in runtime/mercury_memory_zones.h.
    Conform to changes in runtime/mercury_wrapper.h.

runtime/mercury_memory.c:
    Adjust the definition of MR_unit.  It is now guaranteed to be a multiple of
    the page size which is required by its use in mercury_memory_zones.c

    Conform to changes in mercury_wrapper.h.

runtime/mercury_engine.c:
runtime/mercury_memory_handlers.c:
runtime/mercury_trail.c:
    Conform to changes in runtime/mercury_memory_zones.h.

runtime/mercury_memory_handlers.c:
    Use the correct printf integer length modifier for MR_Unsigned values.

runtime/mercury_misc.c:
    Print out the meaning of errno if it is nonzero in MR_fatal_error.

    Use the correct printf integer length modifier for MR_Unsigned values.

runtime/mercury_atomic_ops.h:
    Define MR_THREADSAFE_VOLATILE to expand to volatile when MR_THREADSAFE is
    defined.  Otherwise it expands to nothing.

    Make memory fences macros and atomic operations available in all thread safe
    grades, not just low level C grades.

doc/user_guide.texi:
    Corrected the default detstack size.
2011-04-05 10:27:26 +00:00
Paul Bone
0c06eae74d Add a comment warning programmers against using the atomic functions with C's
native integers.

runtime/mercury_atomic_ops.h:
    As above.
2010-06-21 23:52:27 +00:00
Paul Bone
edc230406e Fix a number of errors and warnings in the runtime picked up by GCC 4.x in
parallel and threadscope grades.

We had been using types with the wrong signedness well calling atomic operations.
GCC 4.x also picked up an error where #elif was used instead of #else.

While testing these changes on a 32bit system more bugs where found on the i386
architecture and on AMD brand processors.

runtime/mercury_atomic_ops.h:
runtime/mercury_atomic_ops.c:
    Add unsigned variants of the following atomic operations:
        increment,
        add,
        add_and_fetch,
        dec_and_is_zero,

    Add a signed variant for compare and swap.

    Rename the MR_atomic_dec_<type>_and_is_zero operation to move the type to
    the end of the name.

    Use volatile storage in the MR_Stats structure.

    A 32bit machine cannot do atomic operations on 64bit values and MR_Stats
    must use 64bit values.  Therefore 64bit values in the MR_Stats structure
    are now protected by a lock on 32bit machines.

runtime/mercury_atomic_ops.h:
    Fix a typeo in the i386 version of MR_atomic_dec_and_is_zero_uint().

runtime/mercury_atomic_ops.c:
    AMD CPUs do not conform to Intel's specification for being able to
    extract the CPU clock speed from the brand string.  When we cannot
    determine the CPU's clock speed then we write out threadscope
    timestamps in raw clock cycles rather than nanoseconds.

    On i386 machines the ebx register is used to implement PIC code,
    however the CPUID instruction uses it to output information.  Save
    this register on C's stack while we issue CPUID and retrieve the
    result in ebx.

    We now pass native machine sized values to the inline assembler code
    that implements RDTSC and RDTSCP.

    Fix commenting style in some places.

runtime/mercury_atomic_ops.c:
    Fix some incorrect C preprocessor code for conditional compilation.

runtime/mercury_grade.h:
    Increment binary compatibility number.  This should have been done in a
    prior change when the MR_runnext macro changed which broke binary
    compatibility in the parallel low-level C grades.

runtime/mercury_context.h:
    In MR_SyncTerm_Struct use an unsigned value for the number of conjuncts
    remaining before the conjunction is complete.

runtime/mercury_threadscope.c:
    Record raw cpu clock ticks rather than milliseconds when we don't
    know the processor's clock speed.

runtime/mercury_context.c:
runtime/mercury_wsdeque.h:
runtime/mercury_wsdeque.c:
    Conform to changes in mercury_atomic_ops.h
2010-03-20 10:15:51 +00:00
Paul Bone
cb244110e9 Delete some text that was accidentally committed in my last change.
runtime/mercury_atomic_ops.h:
    As above.
2010-02-17 02:46:17 +00:00
Paul Bone
6b2bc6a66a When an engine steals a spark and executes it using the context it is
currently holding it did not allocate a new context ID.  A user looking at
this behaviour from threadscope would see thread 27 (for instance) finish, and
then immediately begin executing again.  Therefore we now allocates a new
context ID when a context is reused making the context look different from
threadscope's point of view.  New context IDs are already allocated to
contexts that are allocated from the free context lists.

runtime/mercury_context.c:
    As above.

    The next context id variable is now accessed atomically rather than being
    protected by the free context list lock.

runtime/mercury_atomic_ops.h:
runtime/mercury_atomic_ops.c:
    Implement a new atomic operation, MR_atomic_add_and_fetch_int, this is
    used to allocate context ids.

    Reimplement MR_atomic_add_int in terms of MR_atomic_add_and_fetch_int when
    handwritten assembler support is not available.

runtime/mercury_atomic_ops.c:
    Re-order atomic operations to match the order in the header file.

runtime/mercury_atomic_ops.h:
    Place the definition of the MR_ATOMIC_PAUSE macro before the other atomic
    operations since MR_atomic_add_and_fetch_int depends on it.  This also
    conforms with the coding standard.

runtime/mercury_threadscope.h:
    Make the Context ID type a MR_Integer to match the argument size on the
    available atomic operations.
2010-02-17 02:37:45 +00:00
Paul Bone
8db94039a6 Address review comments on the introduction of macros to control alternative
code selection.

runtime/mercury_atomic_ops.h:
runtime/mercury_conf_param.h:
    Updated contents and prose used in comments to make them more clear.

    Updated formatting of comments.
2010-02-16 22:55:39 +00:00
Paul Bone
e13234f35c Fix atomic_ops bug on PowerPC on Linux as reported by Keri Harris.
This change introduces three new C preprocessor macros that can be used to
override which code is used to implement atomic operations.  This allows us to
test more portable but less efficient code on platforms that support the
efficient code.

runtime/mercury_atomic_ops.h:
    Fix the bug.

    Introduce extra declarations that control which implementation of atomic
    operations is selected.

    Re-order code, so that all the declarations occur before any definitions.
    This fixes another bug that was uncovered by the new macros.

runtime/mercury_conf_param.h:
    Document the new macros.
2010-02-16 05:51:14 +00:00
Paul Bone
83a6f14708 Create a threadscope grade component.
Threadscope grades are enabled by using the grade component 'threadscope'.
They are supported only with low-lavel C parallel grades.  Support for
threadscope in high level C grades is intended in the future but does not work
now.

runtime/mercury_conf_param.h:
    Create the MR_THREADSCOPE macro that is defined if the grade is a
    threadscope grade.

    Define MR_PROFILE_FOR_PARALLEL_EXECUTION if MR_THREADSCOPE is defined.

    Emit an error if MR_LL_PARALLEL_CONJ is defined before it is implied by
    MR_THREADSAFE and ! MR_HIGHLEVEL_CODE

runtime/mercury_grade.h
    Update the grade symbol for the threadscope grade component.

runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
runtime/mercury_context.c:
runtime/mercury_context.h:
runtime/mercury_engine.c:
runtime/mercury_engine.h:
runtime/mercury_thread.c:
runtime/mercury_threadscope.c:
runtime/mercury_threadscope.h:
runtime/mercury_wrapper.c:
    Now that MR_PROFILE_FOR_IMPLICIT_PARALLELISM is implied by MR_THREADSAFE we
    don't need to test for MR_THREADSAFE when we test for
    MR_PROFILE_FOR_IMPLICIT_PARALLELISM.  The same is true for
    MR_LL_PARALLEL_CONJ which is implied by MR_THREADSAFE &&
    !MR_HIGHLEVEL_CODE.

    Replace some occurances of MR_PROFILE_FOR_IMPLICIT_PARALLELISM with
    MR_THREADSCOPE where the conditionally compiled code is used to support
    threadscope profiling.

scripts/init_grade_options.sh-subr:
scripts/canonical_grade.sh-subr:
scripts/parse_grade_options.sh-subr:
scripts/final_grade_options.sh-subr:
scripts/mgnuc.in:
compiler/handle_options.m:
compiler/options.m:
compiler/compile_target_code.m:
configure.in:
    Add support for the new grade component.

    Pass -DMR_THREADSCOPE to the C compiler when using a threadscope grade.

    Add assertions to ensure that the 'threadscope' grade component is used
    only with the 'par' grade component.

doc/user_guide.texi:
    Added commented-out documentation for the threadscope greate component.

    Adjusted documentation of the --profile-parallel-execution runtime option
    to describe the correct prerequisite compile time options.

    Added my name to the authors list.

runtime/mercury_context.c:
    Corrected grammar and prose in comments in the MR_do_join_and_continue code.
2010-01-10 04:53:40 +00:00
Paul Bone
5cfd73644a Implement work stealing.
This patch is heavily based on earlier, uncommitted work by Peter Wang.  It
has been updated so that it applies against the current version of the source.
A number of other changes have been made.  Peter's original ChangeLog
follows:

	Implement work stealing for parallel conjunctions.  This builds on an
	older patch which introduced work-stealing deques to the runtime but
	didn't perform work stealing.

	Previously when we came across a parallel conjunct, we would place a spark
	into either the _global spark queue_ or the _local spark stack_ of the
	Mercury context.  A spark on the global spark queue may be picked up for
	parallel execution by an idle Mercury engine, whereas a spark on a local
	spark stack is confined to execution in the context that originated it.

	The problem is that we have to decide, ahead of time, where to put a
	spark.  Ideally, we should have just enough sparks in the global queue to
	keep the available Mercury engines busy, and leave the rest of the sparks
	to execute in their original contexts since that is more efficient.  But
	we can't predict the future so have to make do with guesses using simple
	heuristics.  A bad decision, once made, cannot be reversed.  An engine may
	sit idle due to an empty global spark queue, even while there are sparks
	available in some local spark stacks.

	In the work stealing scheme, sparks are always placed into each context's
	_local spark deque_.  Idle engines actively try to steal sparks from
	random spark deques.  We don't need to make irreversible and potentially
	suboptimal decisions about where to put sparks.  Making a spark available
	for parallel execution is cheap and happens by default because of the
	work-stealing deques; putting a spark on a global queue implies
	synchronisation with other threads.  The downside is that idle engines
	need to expend more time and effort to find the work from multiple places
	instead of just one place.

	Practically, the new scheme seems to work as well as the old scheme and
	vice versa, except that the old scheme often required
	`--max-context-per-threads' to be set "correctly" to get good results.

	Only tested on x86-64, which has a relatively constrained memory model.

My modifications include:

	The difference between 'shared' and 'private' synchronisation terms has
	been removed.  All sync terms are assumed to be shared and thread-safe
	operations are used everywhere.  This allows us to remove complicated code
	used when a private synchronisation term became shared.  This may change
	the performance of thread stealing, in particular it may become slower due
	to the assumption that all sync terms are shared and therefore atomic
	operations must always be used when decrementing their count field.

	I've re-factored MR_do_join_and_continue, It is now much simpler as the
	conditional code in it enumerates the possible cases clearly.

This change bootchecks and successfully runs the test suite in asm_fast.gc
asm_fast.gc.par hlc.gc and hlc.par, no other grades where tested.  I have not
yet tested performance.

runtime/mercury_context.c:
runtime/mercury_context.h:
	Keep pointers to all spark deques in a flat array, so we have access
    to them for stealing.

	Added functions to manage the global array of spark deques.

	Modify MR_do_run_next, it now attempts to steal work from other context's
	spark queues.  Threads sleeping on the condition variable in
	MR_do_run_next now use a timed wait so they can wakeup and try to steal
	sparks.

	Re-factored MR_do_join_and_continue.

	MR_num_idle_engines is used by atomic operations, it has been made an
	MR_Integer so that it's size matches the expectations of the atomic
	operations we have defined.

	Modified the MR_SyncTerm and MR_Spark structures.  Sparks now point to
	their sync terms.  The perant stack pointer has been moved into the
	SyncTerm structure.  The MR_st_is_shared field in the MR_SyncTerm
	structure has been removed.

runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
	Implement a new atomic operation: decrement integer and is zero.  On the
	x86/x86_64 one can't atomically decrement an integer and fetch the result
	in a single instruction, a loop with a 'compare and exchange' instruction
	is necessary.  However since we only want to test if the value has become
	zero after the decrement we can use the processor's flags.  This can be
	done in two instructions, but more importantly a loop is not required and
	only one instruction is atomic.

runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
	Added runtime tunable options for work stealing.  These control the number
	of attempts an idle engine will make when looking for work, and the
	duration to sleep after failing to find any work.

runtime/mercury_thread.c:
runtime/mercury_thread.h:
	Added MR_COND_TIMED_WAIT, which waits on condition variables like
	MR_COND_WAIT except that it may time out.

runtime/mercury_wsdeque.h:
runtime/mercury_wsdeque.c:
	MR_wsdeque_pop_bottom now uses it's second argument to return the code
	address to jump to rather the whole spark.

runtime/mercury_conf.h.in:
configure.in:
	Test for sched_yield()

	Change the synchronisation term structure.

doc/user_guide.texi:
    Add commented out documentation for two new tunable parameters,
    `--worksteal-max-attempts' and `--worksteal-sleep-msecs'.
    Implementors may want to experiment with different values but end
    users shouldn't need to know about them.
2009-12-15 02:29:07 +00:00
Paul Bone
92afa23af5 Support for threadscope profiling of the parallel runtime.
This change adds support for threadscope profiling of the parallel runtime in
low level C grades.  It can be enabled by compiling _all_ code with the
MR_PROFILE_PARALLEL_EXECUTION_SUPPORT C macro defined.  The runtime, libraries
and applications must all have this flag defined as it alters the MercuryEngine
and MR_Context structures.

See Don Jones Jr, Simon Marlow, Satnam Singh - Parallel Performance Tuning for
Haskell.

This change also includes:

    Smarter thread pinning (the primordial thread is pinned to the thread that
    it is currently running on).

    The addition of callbacks from the Boehm GC to notify the runtime of
    stop the world garbage collections.

    Implement some userspace spin loops and conditions.  These are cheaper than
    their POSIX equivalents, do not support sleeping, and are signal handler
    safe.

boehm_gc/alloc.h:
boehm_gc/alloc.c:
    Declare and define the new callback functions.

boehm_gc/alloc.c:
    Call the start and stop collect callbacks when we start and stop a
    stop-the-world collection.

    Correct how we record the time spent collecting, it now includes
    collections that stop prematurely.

boehm_gc/pthread_stop_world.c:
    Call the pause and resume thread callbacks in each thread where the GC
    arranges for that thread to be stopped during a stop-the-world collection.

runtime/mercury_threadscope.c:
runtime/mercury_threadscope.h:
    New files implementing the threadscope support.

runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
    Rename MR_configure_profiling_timers to MR_do_cpu_feature_detection.

    Add a new function MR_read_cpu_tsc() to read the TSC register from the CPU,
    this simply abstracts the static MR_rdtsc function.

runtime/mercury_atomic_ops.h:
    Modify the C inline assembler to ensure we tell the C compiler that the
    value in the register mapped to the 'old' parameter is also an output from
    the instructions.  That is, the C compiler must not depend on the value of
    'old' being the same before and after the instruction is executed.  This
    has never been a problem in practice though.

    Implement some cheap userspace mutual exclusion locks and condition
    variables.  These will be faster than pthread's mutexes when critical
    sections are short and threads are pinned to separate CPUs.

runtime/mercury_context.c:
runtime/mercury_context.h:
    Add a new function for pinning the primordial thread.  If the OS supports
    sched_getcpu we use it to determine which CPU the primordial thread should
    use.  No other thread will be pinned to this CPU.

    Add a numeric id field to each context, this id is uniquely assigned and
    identifies each context for threadscope.

    MR_schedule_context posts the 'context runnable' threadscope event.

    MR_do_runnext has been modified to destroy engines differently, it ensures
    they cleanup properly so that their threadscope events are flushed properly
    and then calls pthread_exit(0)

    MR_do_runnext posts events for threadscope.

    MR_do_join_and_continue posts events for threadscope.

runtime/mercury_engine.h:
    Add new fields to the MercuryEngine structure including a buffer of
    threadscope events, a clock offset (used to synchronize the TSC clocks) and
    a unique identifier for the engine,

runtime/mercury_engine.c:
    Call MR_threadscope_setup_engine() and MR_threadscope_finalize_engine for
    newly created and about-to-be-destroyed engines.

    When the main context finishes on a thread that's not the primordial thread
    post a 'context is yielding' message before re-scheduling the context on
    the primordial thread.

runtime/mercury_thread.c:
    Added an XXX comment about a potential problem, it's only relevant for
    programs using thread.spawn.

    Added calls to the TSC synchronisation code used for threadscope profiling.
    It appears that this is not necessary on modern x86 machines, it has been
    commented out.

    Post a threadscope event when we create a new context.

    Don't call pthread_exit in MR_destroy_thread, we now do this in
    MR_do_runnext so that we can unlock the runqueue mutex after cleaning up.

runtime/mercury_wrapper.c:
    Conform to changes in mercury_atomic_ops.[ch]

    Post an event immediately before calling main to mark the beginning of the
    program in the threadscope profile.

    Post a "context finished" event at the end of the program.

    Wait until all engines have exited before cleaning up global data, this is
    important for finishing writing the threadscope data file.

configure.in:
runtime/mercury_conf.h.in:
    Test for the sched_getcpu C function and utmpx.h header file, these are
    used for thread pinning.

runtime/Mmakefile:
    Include the mercury_threadscope.[hc] files in the list of runtime headers
    and sources respectively.
2009-12-03 05:28:00 +00:00
Paul Bone
3e75c9bd61 Print the CPU's clock speed in the profiling data for the parallelism runtime.
While the CPU's clock speed is not always the speed that the CPU operates at,
it is the number of TSC units per second when the CPU supports the constant TSC
feature (see /proc/cpuinfo / CPUID).  This change set is used in preparation for
upcoming work on exporting ThreadScope profiling data, see "Parallel
Performance Tuning for Haskell" - Don Jones Jr, Simon Marlow and Satnam Singh.

runtime/mercury_atomic_ops.c:
    Retrieve the CPU frequency from the CPUID instruction and store it in
    MR_cpu_cycles_per_sec

runtime/mercury_atomic_ops.h:
    Export MR_cpu_cycles_per_sec

runtime/mercury_context.c:
    Print the number of cycles per second in the parallel profiling data file
    if we where able to detect it.
2009-11-06 05:40:24 +00:00
Paul Bone
db9a526d6b Corrections in response to review comments on recent parallel runtime changes.
Made thread pinning off by default, the operating system should handle this
unless we have a good reason to.

configure.in:
    Removed newly added declaration checking code.

doc/user_guide.texi:
    Documentation corrections.
    Adjusted the --pin-threads runtime option default.

runtime/mercury_atomic_ops.c
runtime/mercury_atomic_ops.h
    Use __x86_64__ instead of __amd64__
    Altered comments at the beginning of sections of the file to better
    describe the contents of that section.
    Placed comments at the end of long conditional compilation blocks that
    match the condition at the beginning of the block.

runtime/mercury_conf.h.in:
    Added editor hint for vim at the top of the file.
    Remove newly added declarations section.

runtime/mercury_context.c:
    Adjusted default behaviour of --pin-threads
    Fixed some style issues.

runtime/mercury_context.h:
    Fixed grammatical error.

runtime/mercury_wrapper.c:
    Fixed grammatical error.
    Fixed a missing break statement in a switch statement.
2009-11-05 05:47:40 +00:00
Paul Bone
b04af52232 Fix some overlong lines and other formatting issues in my previous patch.
runtime/mercury_context.c:
runtime/mercury_context.h:
runtime/mercury_atomic_ops.h:
    As above.
2009-08-16 10:47:55 +00:00
Paul Bone
4f1bfc2ebc Parallel runtime profiling improvements.
Improve the profiling of the parallel runtime code in two main ways:
	+ Record data for more events.
	+ Record high-precision timing data on x86 machines via the TSC where
	  access to the TSC is available.

Access to the TSC is available via two machine instructions.  RDTSC - read
TSC. and RDTSCP - read TSC and processor ID.  We prefer the latter as a
process migrated between two calls to RDTSC may cause an incorrect time
duration to be calculated (since TSC counts are seldom synchronized).  We
fall back to RDTSC when RDTSCP is not available and gracefully record no
timing information when neither is available.  Availability is detected via
the CPUID instruction, see MR_configure_profiling_timers().

runtime/mercury_context.c:
runtime/mercury_context.h:
	Runtime profiling changes as above.

runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
	Add runtime profiling timing code.
	Add new add and subtract atomic operations.

runtime/mercury_wrapper.c:
	Call the new MR_configure_profiling_timers() procedure to detect the CPU
	and configure access to the TSC.

Mmakefile:
runtime/Mmakefile:
	'mmake tags' at the top level now builds the tags file for the runtime
	directory.
	The tags target in the runtime directory is now marked as PHONY so it is
	generated even if it already exists.
2009-08-16 10:18:36 +00:00
Paul Bone
4d41cf6c23 Rename the runtime granularity control macros, variables and predicates.
Estimated hours taken: 3
Branches: main

Rename the runtime granularity control macros, variables and predicates.

Names of the runtime granularity control macros, variables and predicates are
now more descriptive and more consistent.

An alternative runtime granularity control predicate and macro is now
available, it considers the number of contexts and all sparks whereas the
original predicate and macro considers only the number of contexts and sparks
on the global queue.

A new predicate has been added to determine the number of worker threads that
the mercury runtime is configured to use.


library/par_builtin.m:
	Renamed predicates.
	Conform to changes in runtime/mercury_thread.h
	Added the new predicates.
	Removed some old foreign procedure attributes.
	Addressed an XXX comment left by Zoltan.

runtime/mercury_context.c:
runtime/mercury_context.h:
	Rename existing runtime granularity control variables and macros.
	Add new runtime granularity control variable and macro.

runtime/mercury_wrapper.c:
runtime/mercury_wrapper.h:
	Export MR_num_threads variable.
	Make this variable an MR_Unsigned.

runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
	Introduce new atomic increment and decrement instructions.  These are used
	to count the number of local sparks created which is done outside of a
	critical section.

library/Mmakefile:
	Rebuild the par_builtin module when either runtime/mercury_context.h or
	runtime/mercury_thread.h change.

compiler/granularity.m:
	Conform to changes in runtime/mercury_context.h
2009-06-17 03:26:00 +00:00
Julien Fischer
cd849f451a Avoid problems with some versions of gcc when compiling the runtime atomic_ops
Estimated hours taken: 0.2
Branches: main

Avoid problems with some versions of gcc when compiling the runtime atomic_ops
module at -O0 in non low-level .par grades.

runtime/mercury_atomic_ops.[hc]:
	Implement MR_compare_and_swap_word using the builtin gcc compare
	and swap if it is available.  (In particular prefer this to the
	handcoded assembler versions on x86 and x86_64.)

	Only include the code in these modules if MR_LL_PARALLEL_CONJ
	is defined.  This helps to avoid problems with gcc in grades
	where atomic operations are not used.
2007-10-24 05:28:52 +00:00
Peter Wang
cb8459d517 Make the parallel conjunction execution mechanism more efficient.
Branches: main

Make the parallel conjunction execution mechanism more efficient.

1. Don't allocate sync terms on the heap.  Sync terms are now allocated in
the stack frame of the procedure call which originates a parallel
conjunction.

2. Don't allocate individual sparks on the heap.  Sparks are now stored in
preallocated, growing arrays using an algorithm that doesn't use locks.

3. Don't have one mutex per sync term.  Just use one mutex to protect
concurrent accesses to all sync terms (it's is rarely needed anyway).  This
makes sync terms smaller and saves initialising a mutex for each parallel
conjunction encountered.

4. We don't bother to acquire the global sync term lock if we know a parallel
conjunction couldn't be executing in parallel.  In a highly parallel program,
the majority of parallel conjunctions will be executed sequentially so
protecting the sync terms from concurrent accesses is unnecessary.


par_fib(39) is ~8.4 times faster (user time) on my laptop (Linux 2.6, x86_64),
which is ~3.5 as slow as sequential execution.


configure.in:
	Update the configuration for a changed MR_SyncTerm structure.

compiler/llds.m:
	Make the fork instruction take a second argument, which is the base
	stack slot of the sync term.

	Rename it to fork_new_child to match the macro name in the runtime.

compiler/par_conj_gen.m:
	Change the generated code for parallel conjunctions to allocate sync
	terms on the stack and to pass the sync term to fork_new_child.

compiler/dupelim.m:
compiler/dupproc.m:
compiler/exprn_aux.m:
compiler/global_data.m:
compiler/jumpopt.m:
compiler/livemap.m:
compiler/llds_out.m:
compiler/llds_to_x86_64.m:
compiler/middle_rec.m:
compiler/opt_debug.m:
compiler/opt_util.m:
compiler/reassign.m:
compiler/use_local_vars.m:
	Conform to the change in the fork instruction.

compiler/liveness.m:
compiler/proc_gen.m:
	Disable use of the parallel conjunction operator in the compiler as
	older versions of the compiler will generate code incompatible with
	the new runtime.

runtime/mercury_context.c:
runtime/mercury_context.h:
	Remove the next pointer field from MR_Spark as it's no longer needed.

	Remove the mutex from MR_SyncTerm.  Add a field to record if a spark
	belonging to the sync term was scheduled globally, i.e. if the
	parallel conjunction might be executed in parallel.

	Define MR_SparkDeque and MR_SparkArray.

	Use MR_SparkDeques to hold per-context sparks and global sparks.

	Change the abstract machine instructions MR_init_sync_term,
	MR_fork_new_child, MR_join_and_continue as per the main change log.

	Use a preprocessor macro MR_LL_PARALLEL_CONJ as a shorthand for
	!MR_HIGHLEVEL_CODE && MR_THREAD_SAFE.

	Take the opportunity to clean things up a bit.

runtime/mercury_wsdeque.c:
runtime/mercury_wsdeque.h:
	New files containing an implementation of work-stealing deques.  We
	don't do work stealing yet but we use the underlying data structure.

runtime/mercury_atomic_ops.c:
runtime/mercury_atomic_ops.h:
	New files to contain atomic operations.  Currently it just contains
	compare-and-swap for gcc/x86_64, gcc/x86 and gcc-4.1.

runtime/Mmakefile:
	Add the new files.

runtime/mercury_engine.h:
runtime/mercury_mm_own_stacks.c:
runtime/mercury_wrapper.c:
	Conform to runtime changes.

runtime/mercury_conf_param.h:
	Update an outdated comment.
2007-10-11 12:18:03 +00:00