[m-dev.] response to fjh's review of the parallelism changes
Fergus Henderson
fjh at cs.mu.OZ.AU
Mon Jun 1 14:17:51 AEST 1998
On 01-Jun-1998, Thomas Charles CONWAY <conway at cs.mu.OZ.AU> wrote:
> Fergus Henderson, you write:
> > > +/*
> > > +** We use our own version of memcpy because gcc recognises calls to the
> > > +** standard memcpy and generates inline code for them. Unfortunately this
> > > +** causes it to abort because it tries to use a register that we're already
> > > +** reserved.
> > > +*/
> > > +void MR_memcpy(char *dest, const char *src, size_t nbytes);
> >
> > Which version of gcc, on which architecture?
> > Doesn't compiling with -fno-builtin avoid this?
> > Don't we compile with -fno-builtin by default?
>
> Sparc (toaster et al), gcc 2.7.2
>
> -fno-builtin doesn't occur in mgnuc (nor anywhere else in
> the runtime or scripts. It does occur in the configure script though.
Ah yes. Currently we use -fno-builtin only for x86.
> > > - MR_engine_base = *eng;
> > > + MR_memcpy(&MR_engine_base, eng, sizeof(MercuryEngine));
> > > restore_registers();
> >
> > Ah, I see. This is where MR_memcpy() is used.
> > Did you try using memcpy() here?
>
> No - when we discovered this was causing the gcc abort, you
> thought (at the time) that memcpy wouldn't help (unless we
> included -fno-builtin, I suppose - perhaps we should).
Yes. If memcpy() doesn't work, then that is a problem -- for
example, users may include calls to memcpy() in `pragma c_code'
declarations.
However, this should not be a high priority -- don't worry
about it for this change, but please just include your
answers here in the documentation.
mercury/runtime/mercury_conf.h.in:
> /*
> ** Multithreaded execution support.
> */
> #undef MR_DIGITAL_UNIX_PTHREADS
The comment here doesn't quite match the #undef.
Various places, e.g. mercury_spinlock.[ch], still use #ifdef PARALLEL.
Some other places use MR_THREAD_SAFE.
All these macros should be documented in either mercury_conf.h.in or
mercury_conf_param.h. Currently neither PARALLEL nor MR_THREAD_SAFE
is documented there.
The thread_safe variable should be set in init_grade_options.sh-subr
only -- there's no need to also set it in mgnuc.in and ml.in,
since those file #include init_grade_options.sh-subr.
There should be an option for parallel or thread safe operation, not just
a grade modifier (`.par'), because every grade modifier should have a
corresponding option. Oh, I see you already have a `--parallel option'
supported by compiler/options.m. But parse_grade_options.sh-subr should
support this option too.
> +++ mercury/runtime/mercury_engine.c Mon Jun 1 11:21:06 1998
> @@ -94,9 +94,14 @@
> +/*
> +** finalize_engine should release any resources used withing the
> +** engine structure (but not the engine structure itself).
> +** Currently, it doesn't need to realase any.
> +*/
s/withing/within/
s/realase/release/
> +/*
> +** The following two macros are used as the argument to
> +** init_thread.
> +** MR_USE_NOW should be passed to init_thread to indicate that
> +** it has been called in a context in which it should initialize
> +** the current thread's environment and return.
> +** MR_USE_LATER should be passed to indicate that the thread should
> +** be initialized, then suspend waiting for work to appear in the
> +** runqueue.
> +*/
> +#define MR_USE_NOW ((void *) 1)
> +#define MR_USE_LATER ((void *) 0)
Ah, you still didn't document why the (void *) casts are needed,
but I understand it now. They're needed because the
pthreads interface uses `void *' as generic type -- specifically,
pthread_init() takes as arguments a `void * f(void *)' function
and a `void *' data to pass to that function.
It would be cleaner to use an enum instead of #defines, and to put the
casts to void * at the call to pthread_init() and the cast from void *
at the top of the init_thread() function whose address you pass to
pthread_create(). In fact, you could define the interface of
init_thread() in a clean manner
typedef enum { MR_use_now, MR_use_later } MR_when_to_use;
void init_thread(MR_when_to_use);
and then use casts and a seperate function with the interface that
pthread_create() wants only at the place where pthread_create()
is actually called:
static void *
call_init_thread(void *arg)
{
init_thread((MR_when_to_use) arg);
return NULL;
}
MercuryThread *
create_thread(MR_when_to_use when)
{
...
err = pthread_create(thread, &attrs, call_init_thread,
(void *) when);
...
}
> diff -u -r bak/mercury/runtime/mercury_wrapper.c mercury/runtime/mercury_wrapper.c
> --- bak/mercury/runtime/mercury_wrapper.c Fri May 22 10:01:32 1998
> +++ mercury/runtime/mercury_wrapper.c Mon Jun 1 11:35:16 1998
> @@ -225,15 +225,15 @@
>
> /* start up the Mercury engine */
> #ifndef MR_THREAD_SAFE
> - init_thread((void *) 1);
> + init_thread((void *) MR_USE_NOW);
> #else
> {
> int i;
> init_thread_stuff();
> - init_thread((void *)1);
> + init_thread((void *) MR_USE_NOW);
It seems like overkill to cast to `void *' twice,
once in the definition of MR_USE_NOW and once when you use it.
In fact for calls such as these which do not go via pthread_create(),
you can avoid the need for any cast at all, as I explained above.
--------------------
I think we still need another round of reviewing.
Can you please send another relative diff next time?
Thanks,
Fergus.
--
Fergus Henderson <fjh at cs.mu.oz.au> | "I have always known that the pursuit
WWW: <http://www.cs.mu.oz.au/~fjh> | of excellence is a lethal habit"
PGP: finger fjh at 128.250.37.3 | -- the last words of T. S. Garp.
More information about the developers
mailing list