[m-rev.] for review: fix taking label addresses in standard library
Peter Wang
wangp at students.csse.unimelb.edu.au
Tue Feb 6 14:10:29 AEDT 2007
Branches: main
library/thread.m:
library/thread.semaphore.m:
Don't take the addresses of labels in spawn/3, semaphore.signal/3 and
semaphore.wait/3 as that is a gcc extension. This also fixes a crash
in spawn/3 on x86 when the Mercury standard library is dynamically
linked.
library/par_builtin.m:
Rename symbols for module initialisation to be more similar to other
modules.
Index: library/par_builtin.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/par_builtin.m,v
retrieving revision 1.8
diff -u -r1.8 par_builtin.m
--- library/par_builtin.m 3 Nov 2006 08:31:20 -0000 1.8
+++ library/par_builtin.m 5 Feb 2007 05:02:43 -0000
@@ -198,7 +198,7 @@
:- pragma foreign_decl("C",
"
/*
-INIT mercury_par_builtin_wait_resume
+INIT mercury_sys_init_par_builtin_modules
*/
#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
@@ -210,9 +210,10 @@
"
#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
- MR_BEGIN_MODULE(wait_resume_module)
+ MR_BEGIN_MODULE(par_builtin_module)
MR_init_entry_ai(mercury__par_builtin__wait_resume);
MR_BEGIN_CODE
+
MR_define_entry(mercury__par_builtin__wait_resume);
{
MR_Future *Future;
@@ -232,26 +233,26 @@
#endif
/* forward decls to suppress gcc warnings */
- void mercury_par_builtin_wait_resume_init(void);
- void mercury_par_builtin_wait_resume_init_type_tables(void);
+ void mercury_sys_init_par_builtin_modules_init(void);
+ void mercury_sys_init_par_builtin_modules_init_type_tables(void);
#ifdef MR_DEEP_PROFILING
- void mercury_par_builtin_wait_resume_write_out_proc_statics(FILE *fp);
+ void mercury_sys_init_par_builtin_modules_write_out_proc_statics(FILE *fp);
#endif
- void mercury_par_builtin_wait_resume_init(void)
+ void mercury_sys_init_par_builtin_modules_init(void)
{
#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
- wait_resume_module();
+ par_builtin_module();
#endif
}
- void mercury_par_builtin_wait_resume_init_type_tables(void)
+ void mercury_sys_init_par_builtin_modules_init_type_tables(void)
{
/* no types to register */
}
#ifdef MR_DEEP_PROFILING
- void mercury_par_builtin_wait_resume_write_out_proc_statics(FILE *fp)
+ void mercury_sys_init_par_builtin_modules_write_out_proc_statics(FILE *fp)
{
/* no proc_statics to write out */
}
Index: library/thread.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/thread.m,v
retrieving revision 1.3
diff -u -r1.3 thread.m
--- library/thread.m 1 Feb 2007 14:49:54 -0000 1.3
+++ library/thread.m 5 Feb 2007 12:58:28 -0000
@@ -64,7 +64,6 @@
%-----------------------------------------------------------------------------%
-:- pragma no_inline(spawn/3).
:- pragma foreign_proc("C",
spawn(Goal::(pred(di, uo) is cc_multi), IO0::di, IO::uo),
[promise_pure, will_not_call_mercury, thread_safe],
@@ -72,7 +71,8 @@
#if !defined(MR_HIGHLEVEL_CODE)
MR_Context *ctxt;
ctxt = MR_create_context(""spawn"", MR_CONTEXT_SIZE_REGULAR, NULL);
- ctxt->MR_ctxt_resume = &&spawn_call_back_to_mercury_cc_multi;
+ ctxt->MR_ctxt_resume =
+ MR_ENTRY(mercury__thread__spawn_call_back_to_mercury_cc_multi);
/*
** Store the closure on the top of the new context's stack.
@@ -83,17 +83,7 @@
ctxt->MR_ctxt_thread_local_mutables =
MR_clone_thread_local_mutables(MR_THREAD_LOCAL_MUTABLES);
MR_schedule_context(ctxt);
- if (0) {
-spawn_call_back_to_mercury_cc_multi:
- MR_save_registers();
- /*
- ** Get the closure from the top of the stack
- */
- ML_call_back_to_mercury_cc_multi(*((MR_Word *)MR_sp));
- MR_destroy_context(MR_ENGINE(MR_eng_this_context));
- MR_ENGINE(MR_eng_this_context) = NULL;
- MR_runnext();
- }
+
#else /* MR_HIGHLEVEL_CODE */
#if defined(MR_THREAD_SAFE)
@@ -126,18 +116,87 @@
#ifndef MR_HIGHLEVEL_CODE
MR_save_context(MR_ENGINE(MR_eng_this_context));
MR_ENGINE(MR_eng_this_context)->MR_ctxt_resume =
- &&yield_skip_to_the_end;
+ MR_ENTRY(mercury__thread__yield_resume);
MR_schedule_context(MR_ENGINE(MR_eng_this_context));
MR_ENGINE(MR_eng_this_context) = NULL;
MR_runnext();
-yield_skip_to_the_end:
#endif
IO = IO0;
-
").
yield(!IO).
+%-----------------------------------------------------------------------------%
+
+:- pragma foreign_decl("C",
+"
+/*
+INIT mercury_sys_init_thread_modules
+*/
+
+#ifndef MR_HIGHLEVEL_CODE
+ MR_define_extern_entry(
+ mercury__thread__spawn_call_back_to_mercury_cc_multi);
+ MR_define_extern_entry(mercury__thread__yield_resume);
+#endif
+").
+
+:- pragma foreign_code("C",
+"
+#ifndef MR_HIGHLEVEL_CODE
+
+ MR_BEGIN_MODULE(thread_module)
+ MR_init_entry_ai(mercury__thread__spawn_call_back_to_mercury_cc_multi);
+ MR_init_entry_ai(mercury__thread__yield_resume);
+ MR_BEGIN_CODE
+
+ MR_define_entry(mercury__thread__spawn_call_back_to_mercury_cc_multi);
+ {
+ MR_save_registers();
+ /*
+ ** Get the closure from the top of the stack.
+ */
+ ML_call_back_to_mercury_cc_multi(*((MR_Word *)MR_sp));
+ MR_destroy_context(MR_ENGINE(MR_eng_this_context));
+ MR_ENGINE(MR_eng_this_context) = NULL;
+ MR_runnext();
+ }
+
+ MR_define_entry(mercury__thread__yield_resume);
+ {
+ MR_proceed();
+ }
+ MR_END_MODULE
+
+#endif
+
+ /* forward decls to suppress gcc warnings */
+ void mercury_sys_init_thread_modules_init(void);
+ void mercury_sys_init_thread_modules_init_type_tables(void);
+ #ifdef MR_DEEP_PROFILING
+ void mercury_sys_init_thread_modules_write_out_proc_statics(FILE *fp);
+ #endif
+
+ void mercury_sys_init_thread_modules_init(void)
+ {
+ #ifndef MR_HIGHLEVEL_CODE
+ thread_module();
+ #endif
+ }
+
+ void mercury_sys_init_thread_modules_init_type_tables(void)
+ {
+ /* no types to register */
+ }
+
+ #ifdef MR_DEEP_PROFILING
+ void mercury_sys_init_thread_modules_write_out_proc_statics(FILE *fp)
+ {
+ /* no proc_statics to write out */
+ }
+ #endif
+").
+
:- pred call_back_to_mercury(pred(io, io), io, io).
:- mode call_back_to_mercury(pred(di, uo) is cc_multi, di, uo) is cc_multi.
:- pragma foreign_export("C",
@@ -147,6 +206,8 @@
call_back_to_mercury(Goal, !IO) :-
Goal(!IO).
+%-----------------------------------------------------------------------------%
+
:- pragma foreign_decl("C", "
#if defined(MR_HIGHLEVEL_CODE) && defined(MR_THREAD_SAFE)
#include <pthread.h>
@@ -213,6 +274,8 @@
#endif /* MR_HIGHLEVEL_CODE && MR_THREAD_SAFE */
").
+%-----------------------------------------------------------------------------%
+
:- pragma foreign_code("C#", "
public class MercuryThread {
object[] Goal;
Index: library/thread.semaphore.m
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/library/thread.semaphore.m,v
retrieving revision 1.1
diff -u -r1.1 thread.semaphore.m
--- library/thread.semaphore.m 1 Feb 2007 08:08:00 -0000 1.1
+++ library/thread.semaphore.m 5 Feb 2007 12:59:35 -0000
@@ -160,10 +160,10 @@
#endif
").
- % Because semaphore.signal has a local label, we may get
- % C compilation errors if inlining leads to multiple copies
- % of this code.
- %
+ % semaphore.signal causes the calling context to resume in semaphore.nop,
+ % which simply jumps to the succip. That will return control to the caller
+ % of semaphore.signal as intended, but not if this procedure is inlined.
+ %
% XXX get rid of this limitation at some stage.
%
:- pragma no_inline(semaphore.signal/3).
@@ -189,22 +189,20 @@
/* yield() */
MR_save_context(MR_ENGINE(MR_eng_this_context));
MR_ENGINE(MR_eng_this_context)->MR_ctxt_resume =
- &&signal_skip_to_the_end_1;
+ MR_ENTRY(mercury__thread__semaphore__nop);
MR_schedule_context(MR_ENGINE(MR_eng_this_context));
MR_ENGINE(MR_eng_this_context) = NULL;
MR_runnext();
-signal_skip_to_the_end_1: ;
} else {
sem->count++;
MR_UNLOCK(&(sem->lock), ""semaphore__signal"");
/* yield() */
MR_save_context(MR_ENGINE(MR_eng_this_context));
MR_ENGINE(MR_eng_this_context)->MR_ctxt_resume =
- &&signal_skip_to_the_end_2;
+ MR_ENTRY(mercury__thread__semaphore__nop);
MR_schedule_context(MR_ENGINE(MR_eng_this_context));
MR_ENGINE(MR_eng_this_context) = NULL;
MR_runnext();
-signal_skip_to_the_end_2: ;
}
#else
sem->count++;
@@ -225,13 +223,13 @@
System.Threading.Monitor.Exit(Semaphore);
").
- % Because semaphore__wait has a local label, we may get
- % C compilation errors if inlining leads to multiple copies
- % of this code.
- %
+ % semaphore.wait causes the calling context to resume in semaphore.nop,
+ % which simply jumps to the succip. That will return control to the caller
+ % of semaphore.wait as intended, but not if this procedure is inlined.
+ %
% XXX get rid of this limitation at some stage.
%
-:- pragma no_inline(semaphore__wait/3).
+:- pragma no_inline(semaphore.wait/3).
:- pragma foreign_proc("C",
wait(Semaphore::in, IO0::di, IO::uo),
[promise_pure, will_not_call_mercury, thread_safe],
@@ -252,13 +250,12 @@
} else {
MR_save_context(MR_ENGINE(MR_eng_this_context));
MR_ENGINE(MR_eng_this_context)->MR_ctxt_resume =
- &&wait_skip_to_the_end;
+ MR_ENTRY(mercury__thread__semaphore__nop);
MR_ENGINE(MR_eng_this_context)->MR_ctxt_next = sem->suspended;
sem->suspended = MR_ENGINE(MR_eng_this_context);
MR_UNLOCK(&(sem->lock), ""semaphore__wait"");
MR_ENGINE(MR_eng_this_context) = NULL;
MR_runnext();
-wait_skip_to_the_end: ;
}
#else
while (sem->count <= 0) {
@@ -338,4 +335,60 @@
").
%-----------------------------------------------------------------------------%
+
+:- pragma foreign_decl("C",
+"
+/*
+INIT mercury_sys_init_semaphore_modules
+*/
+
+#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
+ MR_define_extern_entry(mercury__thread__semaphore__nop);
+#endif
+").
+
+:- pragma foreign_code("C",
+"
+#if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
+
+ MR_BEGIN_MODULE(semaphores_module)
+ MR_init_entry_ai(mercury__thread__semaphore__nop);
+ MR_BEGIN_CODE
+
+ MR_define_entry(mercury__thread__semaphore__nop);
+ {
+ MR_proceed();
+ }
+ MR_END_MODULE
+
+#endif
+
+ /* forward decls to suppress gcc warnings */
+ void mercury_sys_init_semaphore_modules_init(void);
+ void mercury_sys_init_semaphore_modules_init_type_tables(void);
+ #ifdef MR_DEEP_PROFILING
+ void mercury_sys_init_semaphore_modules_write_out_proc_statics(FILE *fp);
+ #endif
+
+ void mercury_sys_init_semaphore_modules_init(void)
+ {
+ #if (!defined MR_HIGHLEVEL_CODE) && (defined MR_THREAD_SAFE)
+ semaphores_module();
+ #endif
+ }
+
+ void mercury_sys_init_semaphore_modules_init_type_tables(void)
+ {
+ /* no types to register */
+ }
+
+ #ifdef MR_DEEP_PROFILING
+ void mercury_sys_init_semaphore_modules_write_out_proc_statics(FILE *fp)
+ {
+ /* no proc_statics to write out */
+ }
+ #endif
+").
+
+%-----------------------------------------------------------------------------%
%-----------------------------------------------------------------------------%
--------------------------------------------------------------------------
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