[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