[m-rev.] for review: support STM in low level grades
Julien Fischer
juliensf at csse.unimelb.edu.au
Mon May 4 14:51:49 AEST 2009
On Sun, 3 May 2009, Ben Mellor wrote:
> Index: runtime/mercury_stm.c
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stm.c,v
> retrieving revision 1.6
> diff -u -r1.6 mercury_stm.c
> --- runtime/mercury_stm.c 27 Feb 2008 07:23:57 -0000 1.6
> +++ runtime/mercury_stm.c 3 May 2009 12:23:54 -0000
> @@ -347,14 +347,22 @@
> #endif
> }
>
> +
> +#if defined(MR_HIGHLEVEL_CODE)
> +/*
> +** MR_STM_block_thread is called to block the thread in high level C grades,
> +** using POSIX thread facilities, as there is a POSIX thread for every engine
> +** in these grades.
I suggest:
as there is one POSIX thread for every Mercury thread in these
grades.
(which is indeed what you say in equivalent comment in stm_builtin.m.)
(The high-level C backend does not use engines - except in a very dodgy
fashion for implementing thread local mutables and thread local
trailing.)
> + The low level C grade equivalent of this code is defined
> +** in the stm_builtin library module.
> +*/
> void
> MR_STM_block_thread(MR_STM_TransLog *tlog)
> {
> #if defined(MR_THREAD_SAFE)
> - #if defined(MR_HIGHLEVEL_CODE)
> MR_STM_ConditionVar *thread_condvar;
>
> thread_condvar = MR_GC_NEW(MR_STM_ConditionVar);
> + MR_STM_condvar_init(thread_condvar);
>
> MR_STM_wait(tlog, thread_condvar);
>
> @@ -370,11 +378,37 @@
> MR_STM_unwait(tlog, thread_condvar);
>
> MR_GC_free(thread_condvar);
> - #else
> - MR_fatal_error("Low-Level backend: Not implemented");
> - #endif
> #else
> MR_fatal_error("Blocking thread in non-parallel grade");
> #endif
> +}
> +#endif
> +
> +
> +#if !defined(MR_HIGHLEVEL_CODE)
> +/*
> +** In the low level C grades, the "condition variable" created when an STM
> +** transaction blocks is actually a pointer to the transaction log.
> "Signalling" +** it consists of going through the STM variables listed in the
> log and removing +** the waiters attached to them for the context listed in the
> log. After this, +** the context can be safely rescheduled.
> +*/
> +void
> +MR_STM_condvar_signal(MR_STM_ConditionVar *cvar)
> +{
> + /*
> + ** Calling MR_STM_unwait here should be safe, as this signalling is called
> + ** in response to a commit, while the committing thread holds the global
> + ** STM lock. Note that a MR_STM_ConditionVar IS a MR_STM_TransLog if
> + ** MR_HIGHLEVEL_CODE is not defined, which is why cvar is passed twice.
> + */
> + MR_STM_unwait(cvar, cvar);
> +
> +#if defined(MR_STM_DEBUG)
> + fprintf(stderr, "STM RESCHEDULING: log <0x%.8lx>\n", (MR_Word)cvar);
> +#endif
>
> + MR_schedule_context(MR_STM_context_from_condvar(cvar));
> }
> +
> +#endif
> Index: runtime/mercury_stm.h
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_stm.h,v
> retrieving revision 1.6
> diff -u -r1.6 mercury_stm.h
> --- runtime/mercury_stm.h 27 Feb 2008 07:23:57 -0000 1.6
> +++ runtime/mercury_stm.h 3 May 2009 12:23:54 -0000
> @@ -78,6 +78,7 @@
> #if defined(MR_THREAD_SAFE)
> typedef MercuryCond MR_STM_ConditionVar;
>
> + #define MR_STM_condvar_init(x) pthread_cond_init(x,
> MR_COND_ATTR) #define MR_STM_condvar_wait(x, y) MR_cond_wait(x, y)
> #define MR_STM_condvar_signal(x) MR_cond_signal(x)
> #else
> @@ -86,20 +87,18 @@
> ** Since these grades don't support concurrency, there is no
> ** need to block the thread.
> */
> + #define MR_STM_condvar_init(x)
> #define MR_STM_condvar_wait(x, y)
> #define MR_STM_condvar_signal(x)
> #endif
>
> #else /* !MR_HIGHLEVEL_CODE */
>
> - typedef MR_Context *MR_STM_ConditionVar;
> + typedef MR_STM_TransLog MR_STM_ConditionVar;
>
> - /*
> - ** These are dummy definitions; STM is not yet implemented for low level C
> - ** grades.
> - */
> - #define MR_STM_condvar_wait(x, y)
> - #define MR_STM_condvar_signal(x)
> + extern void MR_STM_condvar_signal(MR_STM_ConditionVar *cvar);
> +
> + #define MR_STM_context_from_condvar(x) (x->MR_STM_tl_thread)
Parenthesize the arguement in the macro body, e.g.
((x)->MR_STM_tl_thread)
> Index: library/stm_builtin.m
> ===================================================================
> RCS file: /home/mercury/mercury1/repository/mercury/library/stm_builtin.m,v
> retrieving revision 1.14
> diff -u -r1.14 stm_builtin.m
> --- library/stm_builtin.m 26 Feb 2009 23:43:08 -0000 1.14
> +++ library/stm_builtin.m 3 May 2009 12:23:54 -0000
> @@ -368,13 +368,100 @@
>
> %-----------------------------------------------------------------------------%
>
> +
> +% In high level C grades, stm_block calls a C procedure in the runtime that
> +% blocks the POSIX thread until signalled, as there is one POSIX thread for
> +% every Mercury thread.
> +% In the low level C grades, this approach cannot be taken, as when the context
> +% blocks the engine running in the POSIX thread needs to be able to look for
> +% other work (there might only be a single engine/POSIX thread).
> +
> :- pragma foreign_proc("C",
> stm_block(STM::ui),
> [will_not_call_mercury, thread_safe],
> "
> +#if defined(MR_HIGHLEVEL_CODE)
> MR_STM_block_thread(STM);
> +#else
> +
> + MR_STM_wait(STM, STM);
> +
> +#if defined(MR_STM_DEBUG)
> + fprintf(stderr, ""STM BLOCKING: log <0x%.8lx>\n"", STM);
> +#endif
> +
> + MR_save_context(MR_ENGINE(MR_eng_this_context));
> +
> + MR_ENGINE(MR_eng_this_context)->MR_ctxt_resume =
> + MR_ENTRY(mercury__stm_builtin__block_thread_resume);
> +
> + MR_ENGINE(MR_eng_this_context) = NULL;
> + MR_UNLOCK(&MR_STM_lock, ""MR_STM_block_thread"");
> + MR_runnext();
> +
> +#endif
> ").
>
> +
> +% block_thread_resume is the piece of code we jump to when a thread suspended
> +% after a failed STM transaction resumes
> +:- pragma foreign_decl("C",
> +"
> +/*
> +INIT mercury_sys_init_stm_builtin_modules
> +*/
> +
> +#if (!defined MR_HIGHLEVEL_CODE)
#if !defined(MR_HIGHLEVEL_CODE)
is the usual way the above is written throughout the rest of the
runtime.
Julien.
--------------------------------------------------------------------------
mercury-reviews mailing list
Post messages to: mercury-reviews at csse.unimelb.edu.au
Administrative Queries: owner-mercury-reviews at csse.unimelb.edu.au
Subscriptions: mercury-reviews-request at csse.unimelb.edu.au
--------------------------------------------------------------------------
More information about the reviews
mailing list