diff --git a/compiler/compile_target_code.m b/compiler/compile_target_code.m index 720b83c18..dfe5a2866 100644 --- a/compiler/compile_target_code.m +++ b/compiler/compile_target_code.m @@ -1,7 +1,7 @@ %-----------------------------------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %-----------------------------------------------------------------------------% -% Copyright (C) 2002-2009 The University of Melbourne. +% Copyright (C) 2002-2010 The University of Melbourne. % This file may only be copied under the terms of the GNU General % Public License - see the file COPYING in the Mercury distribution. %-----------------------------------------------------------------------------% @@ -496,6 +496,14 @@ gather_c_compiler_flags(Globals, PIC, AllCFlags) :- Parallel = no, CFLAGS_FOR_THREADS = "" ), + globals.lookup_bool_option(Globals, threadscope, Threadscope), + ( + Threadscope = yes, + ThreadscopeOpt = "-DMR_THREADSCOPE " + ; + Threadscope = no, + ThreadscopeOpt = "" + ), globals.get_gc_method(Globals, GC_Method), BoehmGC_Opt = "-DMR_CONSERVATIVE_GC -DMR_BOEHM_GC ", ( @@ -861,6 +869,7 @@ gather_c_compiler_flags(Globals, PIC, AllCFlags) :- RegOpt, GotoOpt, AsmOpt, CFLAGS_FOR_REGS, " ", CFLAGS_FOR_GOTOS, " ", CFLAGS_FOR_THREADS, " ", CFLAGS_FOR_PIC, " ", + ThreadscopeOpt, GC_Opt, ProfileCallsOpt, ProfileTimeOpt, ProfileMemoryOpt, ProfileDeepOpt, diff --git a/compiler/handle_options.m b/compiler/handle_options.m index 471b26853..85c109368 100644 --- a/compiler/handle_options.m +++ b/compiler/handle_options.m @@ -554,6 +554,18 @@ convert_options_to_globals(OptionTable0, Target, GC_Method, TagsMethod0, ; TagsMethod = TagsMethod0 ), + + globals.lookup_bool_option(!.Globals, parallel, Parallel), + globals.lookup_bool_option(!.Globals, threadscope, Threadscope), + ( + Parallel = no, + Threadscope = yes + -> + add_error("'threadscope' grade component requires a parallel grade", + !Errors) + ; + true + ), % Implicit parallelism requires feedback information, however this % error should only be shown in a parallel grade, otherwise implicit @@ -562,7 +574,6 @@ convert_options_to_globals(OptionTable0, Target, GC_Method, TagsMethod0, ImplicitParallelism), ( ImplicitParallelism = yes, - globals.lookup_bool_option(!.Globals, parallel, Parallel), ( Parallel = yes, globals.lookup_string_option(!.Globals, feedback_file, @@ -2476,10 +2487,8 @@ grade_string_to_comp_strings(GradeString, MaybeGrade, !Errors) :- %-----------------------------------------------------------------------------% - % IMPORTANT: any changes here may require similar changes to - % runtime/mercury_grade.h - % scripts/parse_grade_options.sh-subr - % scripts/canonical_grade.sh-subr + % IMPORTANT: any changes here may require similar changes to other files, + % see the list of files at the top of runtime/mercury_grade.h % % The grade_component type should have one constructor for each % dimension of the grade. It is used when converting the components @@ -2493,16 +2502,19 @@ grade_string_to_comp_strings(GradeString, MaybeGrade, !Errors) :- % The value to which a grade option should be reset should be given % in the grade_start_values table below. % - % The ordering of the components here is the same as the order - % used in scripts/ml.in, and any change here will require a - % corresponding change there. The only place where the ordering - % actually matters is for constructing the pathname for the - % grade of the library, etc for linking (and installation). + % The ordering of the components here is the same as the order used in + % scripts/canonical_grand.sh-subr, and any change here will require a + % corresponding change there. The only place where the ordering actually + % matters is for constructing the pathname for the grade of the library, + % etc for linking (and installation). % :- type grade_component ---> comp_gcc_ext % gcc extensions etc. -- see % grade_component_table ; comp_par % parallelism / multithreading + ; comp_par_threadscope + % Whether to support theadscope profiling of + % parallel grades. ; comp_gc % the kind of GC to use ; comp_prof % what profiling options to use ; comp_term_size % whether or not to record term sizes @@ -2754,6 +2766,10 @@ grade_component_table("erlang", comp_gcc_ext, [], % Parallelism/multithreading components. grade_component_table("par", comp_par, [parallel - bool(yes)], no, yes). + % Threadscope profiling in parallel grades. +grade_component_table("threadscope", comp_par_threadscope, + [threadscope - bool(yes)], no, yes). + % GC components. grade_component_table("gc", comp_gc, [gc - string("boehm")], no, yes). grade_component_table("gcd", comp_gc, [gc - string("boehm_debug")], no, yes). @@ -2866,7 +2882,7 @@ grade_component_table("rbmmp", comp_regions, grade_component_table("rbmmdp", comp_regions, [use_regions - bool(yes), use_regions_debug - bool(yes), use_regions_profiling - bool(yes)], - no, yes). + no, yes). :- pred reset_grade_options(option_table::in, option_table::out) is det. @@ -2886,6 +2902,7 @@ grade_start_values(highlevel_code - bool(no)). grade_start_values(highlevel_data - bool(no)). grade_start_values(gcc_nested_functions - bool(no)). grade_start_values(parallel - bool(no)). +grade_start_values(threadscope - bool(no)). grade_start_values(gc - string("none")). grade_start_values(profile_deep - bool(no)). grade_start_values(profile_time - bool(no)). diff --git a/compiler/options.m b/compiler/options.m index 06e405d9e..a025e3bae 100644 --- a/compiler/options.m +++ b/compiler/options.m @@ -1,7 +1,7 @@ %-----------------------------------------------------------------------------% % vim: ft=mercury ts=4 sw=4 et %-----------------------------------------------------------------------------% -% Copyright (C) 1994-2009 The University of Melbourne. +% Copyright (C) 1994-2010 The University of Melbourne. % This file may only be copied under the terms of the GNU General % Public License - see the file COPYING in the Mercury distribution. %-----------------------------------------------------------------------------% @@ -361,6 +361,7 @@ % (c) Miscellaneous ; gc ; parallel + ; threadscope ; use_trail ; trail_segments ; use_minimal_model_stack_copy @@ -1245,6 +1246,7 @@ option_defaults_2(compilation_model_option, [ % (c) Miscellaneous optional features gc - string("boehm"), parallel - bool(no), + threadscope - bool(no), use_trail - bool(no), trail_segments - bool(no), maybe_thread_safe_opt - string("no"), diff --git a/doc/user_guide.texi b/doc/user_guide.texi index ee0f0e953..8645164ee 100644 --- a/doc/user_guide.texi +++ b/doc/user_guide.texi @@ -73,6 +73,7 @@ into another language, under the above conditions for modified versions. @author Tyson Dowd @author Mark Brown @author Ian MacLarty +@author Paul Bone @page @vskip 0pt plus 1filll Copyright @copyright{} 1995--2010 The University of Melbourne. @@ -7307,6 +7308,7 @@ The set of aspects and their alternatives are: @cindex .decldebug (grade modifier) @c @cindex .ssdebug (grade modifier) @cindex .par (grade modifier) +@c @cindex .threadscope (grade modifier) @cindex prof (grade modifier) @cindex memprof (grade modifier) @cindex profdeep (grade modifier) @@ -7319,6 +7321,7 @@ The set of aspects and their alternatives are: @cindex decldebug (grade modifier) @c @cindex ssdebug (grade modifier) @cindex par (grade modifier) +@c @cindex threadscope (grade modifier) @table @asis @item What target language to use, what data representation to use, and (for C) what combination of GNU C extensions to use: @samp{none}, @samp{reg}, @samp{jump}, @samp{asm_jump}, @@ -7351,6 +7354,12 @@ small segments: @samp{stseg} (the default is to used fixed size stacks) @item Whether to use a thread-safe version of the runtime environment: @samp{par} (the default is a non-thread-safe environment). +@c @item Whether to include support for profile the execution of parallel +@c programs: +@c @samp{threadscope} (the default is no support for profiling parallel +@c execution). +@c See also the @samp{--profile-parallel-execution} runtime option. + @end table The default grade is system-dependent; it is chosen at installation time @@ -9730,9 +9739,8 @@ grade. @c @findex --profile-parallel-execution @c Tells the runtime to collect and write out parallel execution profiling @c information to a file named @file{parallel_execution_profile.txt}. -@c This only has an effect if the executable was built in a parallel grade -@c and the @samp{MR_PROFILE_PARALLEL_EXECUTION_SUPPORT} C macro was -@c defined when the runtime system was compiled. +@c This only has an effect if the executable was built in a low level c, +@c parallel, threadscope grade. @sp 1 @item --thread-pinning diff --git a/runtime/mercury_atomic_ops.c b/runtime/mercury_atomic_ops.c index 27c1b9268..7bbcd9d7e 100644 --- a/runtime/mercury_atomic_ops.c +++ b/runtime/mercury_atomic_ops.c @@ -2,7 +2,7 @@ ** vim:ts=4 sw=4 expandtab */ /* -** Copyright (C) 2007, 2009 The University of Melbourne. +** Copyright (C) 2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -81,7 +81,7 @@ MR_OUTLINE_DEFN( /*---------------------------------------------------------------------------*/ -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#if defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) /* ** Profiling of the parallel runtime. @@ -501,5 +501,5 @@ MR_rdtsc(MR_uint_least64_t *tsc) { #endif /* __GNUC__ && (__i386__ || __x86_64__) */ -#endif /* MR_THREAD_SAFE && MR_PROFILE_PARALLEL_EXECUTION_SUPPORT */ +#endif /* MR_PROFILE_PARALLEL_EXECUTION_SUPPORT */ diff --git a/runtime/mercury_atomic_ops.h b/runtime/mercury_atomic_ops.h index c9e86c7cc..a13425512 100644 --- a/runtime/mercury_atomic_ops.h +++ b/runtime/mercury_atomic_ops.h @@ -2,7 +2,7 @@ ** vim:ts=4 sw=4 expandtab */ /* -** Copyright (C) 2007, 2009 The University of Melbourne. +** Copyright (C) 2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -481,7 +481,7 @@ typedef MR_Unsigned MR_Us_Cond; /*---------------------------------------------------------------------------*/ -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#if defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) /* ** Declarations for profiling the parallel runtime. @@ -544,7 +544,7 @@ MR_profiling_stop_timer(MR_Timer *timer, MR_Stats *stats); extern MR_uint_least64_t MR_read_cpu_tsc(void); -#endif /* MR_THREAD_SAFE && MR_PROFILE_PARALLEL_EXECUTION_SUPPORT */ +#endif /* MR_PROFILE_PARALLEL_EXECUTION_SUPPORT */ /*---------------------------------------------------------------------------*/ diff --git a/runtime/mercury_conf_param.h b/runtime/mercury_conf_param.h index 616c8c1ae..814d6cf5c 100644 --- a/runtime/mercury_conf_param.h +++ b/runtime/mercury_conf_param.h @@ -1,5 +1,5 @@ /* -** Copyright (C) 1997-2007, 2009 The University of Melbourne. +** Copyright (C) 1997-2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -113,10 +113,15 @@ ** MR_THREAD_SAFE ** Enable support for parallelism. ** +** MR_THREADSCOPE +** Enable support for parallelism profiling, aka 'threadscope'. This is a +** grade component. This works only with the low level C parallel grades. +** ** MR_PROFILE_PARALLEL_EXECUTION_SUPPORT -** Enable support for profiling parallel execution. This only has an -** effect of MR_THREAD_SAFE is also defined. This must also be enabled -** with the --profile-parallel-execution runtime option. +** Enable support for profiling the parallel runtime system. This collects +** counts and timings of certain runtime events. It is implied by +** MR_THREADSCOPE and must be enabled at runtime with the +** --profile-parallel-execution runtime option. ** ** MR_NO_BACKWARDS_COMPAT ** Disable backwards compatibility with C code using obsolete low-level @@ -728,10 +733,28 @@ ** Whether we are in a grade which supports the low-level parallel ** conjunction execution mechanism. */ +#ifdef MR_LL_PARALLEL_CONJ + #error "MR_LL_PARALLEL_CONJ may not be defined on the command line" +#endif #if !defined(MR_HIGHLEVEL_CODE) && defined(MR_THREAD_SAFE) #define MR_LL_PARALLEL_CONJ #endif +/* +** Check that MR_THREADSCOPE is used correctly. +*/ +#if defined(MR_THREADSCOPE) && !defined(MR_THREAD_SAFE) + #error "The threadscope grade component may only be used with " \ + "parallel grades" +#endif + +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT + #error "MR_PROFILE_PARALLEL_EXECUTION_SUPPORT may only be implied by MR_THREADSCOPE" +#endif +#ifdef MR_THREADSCOPE + #define MR_PROFILE_PARALLEL_EXECUTION_SUPPORT +#endif + /* XXX document MR_BYTECODE_CALLABLE */ /* diff --git a/runtime/mercury_context.c b/runtime/mercury_context.c index d3fbd88b5..fe5130ec1 100644 --- a/runtime/mercury_context.c +++ b/runtime/mercury_context.c @@ -6,7 +6,7 @@ INIT mercury_sys_init_scheduler_wrapper ENDINIT */ /* -** Copyright (C) 1995-2007, 2009 The University of Melbourne. +** Copyright (C) 1995-2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -27,7 +27,7 @@ ENDINIT #include /* for select() on OS X */ #endif #endif -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT #include /* for sqrt and pow */ #endif @@ -45,7 +45,7 @@ ENDINIT #include "mercury_threadscope.h" /* for data types and posting events */ #include "mercury_reg_workarounds.h" /* for `MR_fd*' stuff */ -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT #define MR_PROFILE_PARALLEL_EXECUTION_FILENAME "parallel_execution_profile.txt" #endif @@ -82,9 +82,10 @@ MR_PendingContext *MR_pending_contexts; MercuryLock MR_pending_contexts_lock; #endif -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT MR_bool MR_profile_parallel_execution = MR_FALSE; +#ifndef MR_HIGHLEVEL_CODE static MR_Stats MR_profile_parallel_executed_global_sparks = { 0, 0, 0, 0 }; static MR_Stats MR_profile_parallel_executed_contexts = { 0, 0, 0, 0 }; @@ -102,13 +103,13 @@ static MR_Integer MR_profile_parallel_small_context_reused = 0; static MR_Integer MR_profile_parallel_regular_context_reused = 0; static MR_Integer MR_profile_parallel_small_context_kept = 0; static MR_Integer MR_profile_parallel_regular_context_kept = 0; -#endif +#endif /* ! MR_HIGHLEVEL_CODE */ +#endif /* MR_PROFILE_PARALLEL_EXECUTION_SUPPORT */ /* ** Local variables for thread pinning. */ -#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) +#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) static MercuryLock MR_next_cpu_lock; MR_bool MR_thread_pinning = MR_FALSE; static MR_Unsigned MR_next_cpu = 0; @@ -163,8 +164,7 @@ MR_init_context_maybe_generator(MR_Context *c, const char *id, static void MR_write_out_profiling_parallel_execution(void); -#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) +#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) static void MR_do_pin_thread(int cpu); #endif @@ -248,8 +248,7 @@ MR_init_thread_stuff(void) void MR_pin_primordial_thread(void) { -#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) +#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) #ifdef MR_HAVE_SCHED_GETCPU /* ** We don't need locking to pin the primordial thread as it is called @@ -270,15 +269,14 @@ MR_pin_primordial_thread(void) #else MR_pin_thread(); #endif -#endif /* defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) */ +#endif /* defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) + */ } void MR_pin_thread(void) { -#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) +#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) MR_LOCK(&MR_next_cpu_lock, "MR_pin_thread"); if (MR_thread_pinning) { #if defined(MR_HAVE_SCHED_GETCPU) @@ -290,12 +288,11 @@ MR_pin_thread(void) MR_next_cpu++; } MR_UNLOCK(&MR_next_cpu_lock, "MR_pin_thread"); -#endif /* defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) */ +#endif /* defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) + */ } -#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) +#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) static void MR_do_pin_thread(int cpu) { @@ -318,8 +315,8 @@ MR_do_pin_thread(int cpu) MR_thread_pinning = MR_FALSE; } } -#endif /* defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_HAVE_SCHED_SETAFFINITY) */ +#endif /* defined(MR_LL_PARALLEL_CONJ) && defined(MR_HAVE_SCHED_SETAFFINITY) + */ void MR_finalize_thread_stuff(void) @@ -334,14 +331,14 @@ MR_finalize_thread_stuff(void) pthread_mutex_destroy(&spark_deques_lock); #endif -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT if (MR_profile_parallel_execution) { MR_write_out_profiling_parallel_execution(); } #endif } -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT static int fprint_stats(FILE *stream, const char *message, MR_Stats *stats); @@ -464,7 +461,7 @@ fprint_stats(FILE *stream, const char *message, MR_Stats *stats) { } }; -#endif /* defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) */ +#endif /* MR_PROFILE_PARALLEL_EXECUTION_SUPPORT */ static void MR_init_context_maybe_generator(MR_Context *c, const char *id, @@ -647,7 +644,7 @@ MR_Context * MR_create_context(const char *id, MR_ContextSize ctxt_size, MR_Generator *gen) { MR_Context *c; -#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#if MR_THREADSCOPE MR_Unsigned context_id; #endif @@ -666,7 +663,7 @@ MR_create_context(const char *id, MR_ContextSize ctxt_size, MR_Generator *gen) if (ctxt_size == MR_CONTEXT_SIZE_SMALL && free_small_context_list) { c = free_small_context_list; free_small_context_list = c->MR_ctxt_next; -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT if (MR_profile_parallel_execution) { MR_profile_parallel_small_context_reused++; } @@ -674,7 +671,7 @@ MR_create_context(const char *id, MR_ContextSize ctxt_size, MR_Generator *gen) } else if (free_context_list != NULL) { c = free_context_list; free_context_list = c->MR_ctxt_next; -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT if (MR_profile_parallel_execution) { MR_profile_parallel_regular_context_reused++; } @@ -682,7 +679,7 @@ MR_create_context(const char *id, MR_ContextSize ctxt_size, MR_Generator *gen) } else { c = NULL; } -#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#if MR_THREADSCOPE context_id = MR_next_context_id++; #endif MR_UNLOCK(&free_context_list_lock, "create_context i"); @@ -701,7 +698,7 @@ MR_create_context(const char *id, MR_ContextSize ctxt_size, MR_Generator *gen) c->MR_ctxt_trail_zone = NULL; #endif } -#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE c->MR_ctxt_num_id = context_id; #endif @@ -738,7 +735,7 @@ MR_destroy_context(MR_Context *c) case MR_CONTEXT_SIZE_REGULAR: c->MR_ctxt_next = free_context_list; free_context_list = c; -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT if (MR_profile_parallel_execution) { MR_profile_parallel_regular_context_kept++; } @@ -747,7 +744,7 @@ MR_destroy_context(MR_Context *c) case MR_CONTEXT_SIZE_SMALL: c->MR_ctxt_next = free_small_context_list; free_small_context_list = c; -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT if (MR_profile_parallel_execution) { MR_profile_parallel_small_context_kept++; } @@ -1055,7 +1052,7 @@ MR_check_pending_contexts(MR_bool block) void MR_schedule_context(MR_Context *ctxt) { -#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT MR_threadscope_post_context_runnable(ctxt); #endif MR_LOCK(&MR_runqueue_lock, "schedule_context"); @@ -1223,8 +1220,10 @@ MR_define_entry(MR_do_runnext); if (MR_ENGINE(MR_eng_this_context) == NULL) { MR_ENGINE(MR_eng_this_context) = MR_create_context("from spark", MR_CONTEXT_SIZE_SMALL, NULL); -#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT +#ifdef MR_THREADSCOPE MR_threadscope_post_create_context_for_spark(MR_ENGINE(MR_eng_this_context)); +#endif +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT if (MR_profile_parallel_execution) { MR_atomic_inc_int( &MR_profile_parallel_contexts_created_for_sparks); @@ -1232,7 +1231,7 @@ MR_define_entry(MR_do_runnext); #endif MR_load_context(MR_ENGINE(MR_eng_this_context)); } else { -#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE MR_threadscope_post_run_context(); #endif } @@ -1298,14 +1297,14 @@ MR_do_join_and_continue(MR_SyncTerm *jnc_st, MR_Code *join_label) if (jnc_last) { if (this_context == jnc_st->MR_st_orig_context) { - /* - ** It has finished executing and we're the originating context. Jump - ** to the join label. - */ - return join_label; - } else { -#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT - MR_threadscope_post_stop_context(MR_TS_STOP_REASON_FINISHED); + /* + ** This context originated this parallel conjunction and all the + ** branches have finished so jump to the join label. + */ + return join_label; + } else { +#ifdef MR_THREADSCOPE + MR_threadscope_post_stop_context(MR_TS_STOP_REASON_FINISHED); #endif /* ** This context didn't originate this parallel conjunction and @@ -1322,46 +1321,48 @@ MR_do_join_and_continue(MR_SyncTerm *jnc_st, MR_Code *join_label) MR_ATOMIC_PAUSE; } MR_schedule_context(jnc_st->MR_st_orig_context); - return MR_ENTRY(MR_do_runnext); - } - } else { + return MR_ENTRY(MR_do_runnext); + } + } else { MR_bool popped; MR_Code *spark_resume; - /* + /* * The parallel conjunction it is not yet finished. Try to work on a * spark from our local stack. The sparks on our stack are likely to * cause this conjunction to be complete. - */ - popped = MR_wsdeque_pop_bottom(&this_context->MR_ctxt_spark_deque, &spark_resume); + */ + popped = MR_wsdeque_pop_bottom(&this_context->MR_ctxt_spark_deque, + &spark_resume); if (popped) { - MR_atomic_dec_int(&MR_num_outstanding_contexts_and_all_sparks); + MR_atomic_dec_int(&MR_num_outstanding_contexts_and_all_sparks); return spark_resume; - } else { - /* - ** If this context originated the parallel conjunction we've been - ** executing, suspend this context such that it will be resumed - ** at the join label once the parallel conjunction is completed. - ** + } else { + /* + ** If this context originated the parallel conjunction that we've + ** been executing, suspend this context so that it will be + ** resumed at the join label once the parallel conjunction is + ** completed. + ** ** Otherwise we can reuse this context for the next piece of work. - */ + */ if (this_context == jnc_st->MR_st_orig_context) { -#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT - MR_threadscope_post_stop_context(MR_TS_STOP_REASON_BLOCKED); +#ifdef MR_THREADSCOPE + MR_threadscope_post_stop_context(MR_TS_STOP_REASON_BLOCKED); #endif MR_save_context(this_context); /* XXX: Make sure the context gets saved before we set the join * label, use a memory barrier.*/ this_context->MR_ctxt_resume = (join_label); - MR_ENGINE(MR_eng_this_context) = NULL; - } else { -#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT - MR_threadscope_post_stop_context(MR_TS_STOP_REASON_FINISHED); + MR_ENGINE(MR_eng_this_context) = NULL; + } else { +#ifdef MR_THREADSCOPE + MR_threadscope_post_stop_context(MR_TS_STOP_REASON_FINISHED); #endif - } - return MR_ENTRY(MR_do_runnext); } + return MR_ENTRY(MR_do_runnext); } + } } #endif diff --git a/runtime/mercury_context.h b/runtime/mercury_context.h index 602365d27..00f7093b8 100644 --- a/runtime/mercury_context.h +++ b/runtime/mercury_context.h @@ -2,7 +2,7 @@ ** vim:ts=4 sw=4 expandtab */ /* -** Copyright (C) 1997-2007, 2009 The University of Melbourne. +** Copyright (C) 1997-2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -248,7 +248,7 @@ struct MR_SparkDeque_Struct { struct MR_Context_Struct { const char *MR_ctxt_id; -#if defined(MR_LL_PARALLEL_CONJ) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE MR_Unsigned MR_ctxt_num_id; #endif MR_ContextSize MR_ctxt_size; @@ -343,7 +343,7 @@ extern MR_Context *MR_runqueue_tail; extern MR_bool MR_thread_pinning; #endif -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT extern MR_bool MR_profile_parallel_execution; /* XXX: This is currently unused, we plan to use it in the future. -pbone */ @@ -577,11 +577,10 @@ extern void MR_schedule_context(MR_Context *ctxt); #define MR_IF_NOT_HIGHLEVEL_CODE(x) #endif -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) - #define MR_IF_LL_PAR_CONJ_AND_PROF_PAR_EXEC(x) x +#ifdef MR_THREADSCOPE + #define MR_IF_THREADSCOPE(x) x #else - #define MR_IF_LL_PAR_CONJ_AND_PROF_PAR_EXEC(x) + #define MR_IF_THREADSCOPE(x) #endif #define MR_load_context(cptr) \ @@ -648,7 +647,7 @@ extern void MR_schedule_context(MR_Context *ctxt); ) \ ) \ MR_set_min_heap_reclamation_point(load_context_c); \ - MR_IF_LL_PAR_CONJ_AND_PROF_PAR_EXEC( \ + MR_IF_THREADSCOPE( \ MR_threadscope_post_run_context(); \ ) \ } while (0) diff --git a/runtime/mercury_engine.c b/runtime/mercury_engine.c index 5738c7313..6c4289a50 100644 --- a/runtime/mercury_engine.c +++ b/runtime/mercury_engine.c @@ -6,7 +6,7 @@ INIT mercury_sys_init_engine ENDINIT */ /* -** Copyright (C) 1993-2001, 2003-2007, 2009 The University of Melbourne. +** Copyright (C) 1993-2001, 2003-2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -149,8 +149,7 @@ MR_init_engine(MercuryEngine *eng) eng->MR_eng_c_depth = 0; #endif -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE MR_threadscope_setup_engine(eng); #endif @@ -172,8 +171,7 @@ void MR_finalize_engine(MercuryEngine *eng) MR_destroy_context(eng->MR_eng_this_context); } -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#if MR_THREADSCOPE if (eng->MR_eng_ts_buffer) { MR_threadscope_finalize_engine(eng); } @@ -527,7 +525,7 @@ MR_define_label(engine_done); MR_GOTO_LABEL(engine_done_2); } -#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT +#ifdef MR_THREADSCOPE MR_threadscope_post_stop_context(MR_TS_STOP_REASON_YIELDING); #endif MR_save_context(this_ctxt); diff --git a/runtime/mercury_engine.h b/runtime/mercury_engine.h index 3cd5f5532..66ee77f15 100644 --- a/runtime/mercury_engine.h +++ b/runtime/mercury_engine.h @@ -2,7 +2,7 @@ ** vim: ts=4 sw=4 expandtab */ /* -** Copyright (C) 1994-2007, 2009 The University of Melbourne. +** Copyright (C) 1994-2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -392,7 +392,7 @@ typedef struct MR_mercury_engine_struct { #ifdef MR_THREAD_SAFE MercuryThread MR_eng_owner_thread; MR_Unsigned MR_eng_c_depth; - #if defined(MR_LL_PARALLEL_CONJ) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) + #ifdef MR_THREADSCOPE /* ** For each profiling event add this offset to the time so that events on ** different engines that occur at the same time have the same time in diff --git a/runtime/mercury_grade.h b/runtime/mercury_grade.h index 8129fa8d2..dcddc59a0 100644 --- a/runtime/mercury_grade.h +++ b/runtime/mercury_grade.h @@ -2,7 +2,7 @@ ** vim:ts=4 sw=4 expandtab */ /* -** Copyright (C) 1997-2009 The University of Melbourne. +** Copyright (C) 1997-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -447,8 +447,16 @@ #define MR_GRADE_OPT_PART_17 MR_GRADE_OPT_PART_16 #endif -#define MR_GRADE MR_GRADE_PART_17 -#define MR_GRADE_OPT MR_GRADE_OPT_PART_17 +#if defined(MR_THREADSCOPE) + #define MR_GRADE_PART_18 MR_PASTE2(MR_GRADE_PART_17, _threadscope) + #define MR_GRADE_OPT_PART_18 MR_GRADE_OPT_PART_17 ".threadscope" +#else + #define MR_GRADE_PART_18 MR_GRADE_PART_17 + #define MR_GRADE_OPT_PART_18 MR_GRADE_OPT_PART_17 +#endif + +#define MR_GRADE MR_GRADE_PART_18 +#define MR_GRADE_OPT MR_GRADE_OPT_PART_18 #define MR_GRADE_VAR MR_PASTE2(MR_grade_,MR_GRADE) #define MR_GRADE_STRING MR_STRINGIFY(MR_GRADE) diff --git a/runtime/mercury_thread.c b/runtime/mercury_thread.c index b7045a337..4cef111b8 100644 --- a/runtime/mercury_thread.c +++ b/runtime/mercury_thread.c @@ -2,7 +2,7 @@ ** vim: ts=4 sw=4 expandtab */ /* -** Copyright (C) 1997-2001, 2003, 2005-2007, 2009 The University of Melbourne. +** Copyright (C) 1997-2001, 2003, 2005-2007, 2009-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -131,8 +131,7 @@ MR_init_thread(MR_when_to_use when_to_use) #ifdef MR_THREAD_SAFE MR_ENGINE(MR_eng_owner_thread) = pthread_self(); - #if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) + #ifdef MR_THREADSCOPE /* ** TSC Synchronization is not used, support is commented out. See ** runtime/mercury_threadscope.h for an explanation. @@ -166,8 +165,7 @@ MR_init_thread(MR_when_to_use when_to_use) MR_ENGINE(MR_eng_this_context) = MR_create_context("init_thread", MR_CONTEXT_SIZE_REGULAR, NULL); -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE MR_threadscope_post_create_context(MR_ENGINE(MR_eng_this_context)); #endif } diff --git a/runtime/mercury_threadscope.c b/runtime/mercury_threadscope.c index 3fe5af349..ab59984c0 100644 --- a/runtime/mercury_threadscope.c +++ b/runtime/mercury_threadscope.c @@ -6,7 +6,7 @@ INIT mercury_sys_init_threadscope ENDINIT */ /* -** Copyright (C) 2009 The University of Melbourne. +** Copyright (C) 2009-2010 The University of Melbourne. ** Copyright (C) 2008-2009 The GHC Team. ** ** This file may only be copied under the terms of the GNU Library General @@ -85,8 +85,7 @@ ENDINIT #include #include -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE /***************************************************************************/ @@ -1171,8 +1170,7 @@ get_current_time_nanosecs(void) /***************************************************************************/ -#endif /* defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) */ +#endif /* MR_THREADSCOPE */ /* forward decls to suppress gcc warnings */ void mercury_sys_init_threadscope_init(void); diff --git a/runtime/mercury_threadscope.h b/runtime/mercury_threadscope.h index 6171b8860..d5212306f 100644 --- a/runtime/mercury_threadscope.h +++ b/runtime/mercury_threadscope.h @@ -2,7 +2,7 @@ ** vim:ts=4 sw=4 expandtab */ /* -** Copyright (C) 2009 The University of Melbourne. +** Copyright (C) 2009-2010 The University of Melbourne. ** ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. @@ -22,8 +22,7 @@ #include "mercury_engine.h" #include "mercury_context.h" -#if defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE /* ** Reasons why a context has been stopped, not all of these apply to Mercury, @@ -128,7 +127,6 @@ MR_threadscope_post_stop_context(MR_ContextStopReason reason); extern void MR_threadscope_post_calling_main(void); -#endif /* defined(MR_THREAD_SAFE) && defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) */ +#endif /* MR_THREADSCOPE */ #endif /* not MERCURY_THREADSCOPE_H */ diff --git a/runtime/mercury_wrapper.c b/runtime/mercury_wrapper.c index 9806662e1..ceae73a33 100644 --- a/runtime/mercury_wrapper.c +++ b/runtime/mercury_wrapper.c @@ -6,7 +6,7 @@ INIT mercury_sys_init_wrapper ENDINIT */ /* -** Copyright (C) 1994-2009 The University of Melbourne. +** Copyright (C) 1994-2010 The University of Melbourne. ** This file may only be copied under the terms of the GNU Library General ** Public License - see the file COPYING.LIB in the Mercury distribution. */ @@ -539,7 +539,7 @@ mercury_runtime_init(int argc, char **argv) } #endif -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#if defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) /* ** Setup support for reading the CPU's TSC and detect the clock speed of the ** processor. This is currently used by profiling of the parallelism @@ -630,7 +630,7 @@ mercury_runtime_init(int argc, char **argv) #if defined(MR_LL_PARALLEL_CONJ) MR_pin_primordial_thread(); - #if defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) + #if defined(MR_THREADSCOPE) /* ** We must setup threadscope before we setup the first engine. ** Pin the primordial thread, if thread pinning is configured. @@ -656,7 +656,7 @@ mercury_runtime_init(int argc, char **argv) for (i = 1; i < MR_num_threads; i++) { MR_create_thread(NULL); } - #ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT + #ifdef MR_THREADSCOPE /* ** TSC Synchronization is not used, support is commented out. See ** runtime/mercury_threadscope.h for an explanation. @@ -1794,7 +1794,7 @@ MR_process_options(int argc, char **argv) break; case MR_PROFILE_PARALLEL_EXECUTION: -#if defined(MR_THREAD_SAFE) && defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_PROFILE_PARALLEL_EXECUTION_SUPPORT MR_profile_parallel_execution = MR_TRUE; #endif break; @@ -2468,8 +2468,7 @@ mercury_runtime_main(void) MR_setup_callback(MR_program_entry_point); #endif -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE MR_threadscope_post_calling_main(); @@ -2483,8 +2482,7 @@ mercury_runtime_main(void) MR_debugmsg0("Returning from MR_call_engine()\n"); #endif -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE MR_threadscope_post_stop_context(MR_TS_STOP_REASON_FINISHED); @@ -2999,8 +2997,7 @@ mercury_runtime_terminate(void) MR_ATOMIC_PAUSE; } -#if defined(MR_LL_PARALLEL_CONJ) && \ - defined(MR_PROFILE_PARALLEL_EXECUTION_SUPPORT) +#ifdef MR_THREADSCOPE if (MR_ENGINE(MR_eng_ts_buffer)) { MR_threadscope_finalize_engine(MR_thread_engine_base); } diff --git a/scripts/canonical_grade.sh-subr b/scripts/canonical_grade.sh-subr index 8eb03d422..48b7e0e40 100644 --- a/scripts/canonical_grade.sh-subr +++ b/scripts/canonical_grade.sh-subr @@ -1,7 +1,7 @@ #---------------------------------------------------------------------------# # vim: ft=sh #---------------------------------------------------------------------------# -# Copyright (C) 2000-2007 The University of Melbourne. +# Copyright (C) 2000-2007, 2010 The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# @@ -81,9 +81,15 @@ case $gcc_nested_functions,$highlevel_code in *) ;; esac -case $thread_safe in - true) GRADE="$GRADE.par" ;; - false) ;; +case $thread_safe,$threadscope in + true,false) GRADE="$GRADE.par" ;; + true,true) GRADE="$GRADE.par.threadscope" ;; + false,false) ;; + *) + echo "$progname: error: The 'threadscope' grade component may only be" 1>&2 + echo "$progname: error: used in parallel grades" + exit 1 + ;; esac case $gc_method in diff --git a/scripts/final_grade_options.sh-subr b/scripts/final_grade_options.sh-subr index 30a1cb89d..5d00ee538 100644 --- a/scripts/final_grade_options.sh-subr +++ b/scripts/final_grade_options.sh-subr @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------# -# Copyright (C) 1998-2002, 2004-2007, 2009 The University of Melbourne. +# Copyright (C) 1998-2002, 2004-2007, 2009-2010 The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# @@ -97,4 +97,12 @@ case $use_regions in false) ;; esac +# +# threadscope doesn't make sense in non-parallel grades. +# +case $thread_safe in false) + threadscope=false + ;; +esac + #---------------------------------------------------------------------------# diff --git a/scripts/init_grade_options.sh-subr b/scripts/init_grade_options.sh-subr index c092a8e2d..c20bd48ec 100644 --- a/scripts/init_grade_options.sh-subr +++ b/scripts/init_grade_options.sh-subr @@ -1,5 +1,5 @@ #---------------------------------------------------------------------------# -# Copyright (C) 1997-2007 The University of Melbourne. +# Copyright (C) 1997-2007, 2010 The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# @@ -72,6 +72,7 @@ asm_labels=true non_local_gotos=true global_regs=true thread_safe=false +threadscope=false gc_method=boehm profile_time=false profile_calls=false diff --git a/scripts/mgnuc.in b/scripts/mgnuc.in index 13a779d74..12fcb571c 100644 --- a/scripts/mgnuc.in +++ b/scripts/mgnuc.in @@ -2,7 +2,7 @@ # vim: ts=4 sw=4 et # @configure_input@ #---------------------------------------------------------------------------# -# Copyright (C) 1995-2007 The University of Melbourne. +# Copyright (C) 1995-2007, 2010 The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# @@ -286,6 +286,11 @@ case $thread_safe in false) THREAD_OPTS="" ;; esac +case $threadscope in + true) THREADSCOPE_OPTS="-DMR_THREADSCOPE" ;; + false) THREADSCOPE_OPTS="" ;; +esac + # Set the correct flags if we're to use the MS Visual C runtime. use_msvcrt=@USE_MSVCRT@ if test $use_msvcrt = "yes"; then @@ -648,6 +653,7 @@ ALL_CC_OPTS="$MERC_ALL_C_INCL_DIRS\ $SINGLE_PREC_FLOAT_OPTS\ $SPLIT_OPTS\ $THREAD_OPTS\ + $THREADSCOPE_OPTS\ $REGION_OPTS\ $PICREG_OPTS\ $ARCH_OPTS\ diff --git a/scripts/parse_grade_options.sh-subr b/scripts/parse_grade_options.sh-subr index db8c1a820..80b3d622a 100644 --- a/scripts/parse_grade_options.sh-subr +++ b/scripts/parse_grade_options.sh-subr @@ -1,7 +1,7 @@ #---------------------------------------------------------------------------# # vim: ts=4 sw=4 expandtab #---------------------------------------------------------------------------# -# Copyright (C) 1997-2007 The University of Melbourne. +# Copyright (C) 1997-2007, 2010 The University of Melbourne. # This file may only be copied under the terms of the GNU General # Public License - see the file COPYING in the Mercury distribution. #---------------------------------------------------------------------------# @@ -392,6 +392,10 @@ thread_safe=true ;; + threadscope) + threadscope=true + ;; + agc) gc_method=accurate ;;