guile-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Thread support plan with initial patch


From: NIIBE Yutaka
Subject: Thread support plan with initial patch
Date: Mon, 2 Apr 2001 14:17:20 +0900 (JST)

I have been not active those days.  Anyway, new fiscal year starts,
here in Japan.  So, things changed.

Here's my plan of introducing POSIX thread support:
-------------------------- plan-threads.txt
(1) Use giant recursive lock (GRL) for critical sections
   (recursive lock: the owner of the lock can acquire the lock
   multiple times)

(1-1) Remove SCM_THREAD_DEFER/ALLOW, use 
      SCM_THREAD_CRITICAL_SECTION_START/END instead.

Basically, all the critical sections are protected with this.
There may be the code where multiple threads are not assumed and cause
troubles.

Therefore:

(1-2) Protect (missing) critical sections where needed, with
SCM_THREAD_CRITICAL_SECTION_START/END.

(2) Introduse POSIX threads support
    Implement SCM_THREAD_CRITICAL_SECTION_START/END as recursive mutex
    at this time.

(3) Introduce fine-grain lock for each critical sections

(3-1) Examine all SCM_DEFER_INTS/SCM_ALLOW_INTS,
                  SCM_REDEFER_INTS/SCM_REALLOW_INTS.
      Introduce fine-grain lock where applicable, such as:
      SCM_ENTER_A_SECTION/SCM_EXIT_A_SECTION

(3-1-1) Just remove it, if it's actually not needed to be protected

        Note that we're not interrupted asynchronously by signal any more, 
        all the signals are handled synchronously.

        Remove DEFER.
        Replace ALLOW with THREAD_SWITCHING_CODE, if needed, 
        so that cooperative thread implementation can get the opportunities
        to change the context.

(3-1-2) Replace DEFER/ALLOW with local LOCK/UNLOCK with mutex, if it's
        really needed to be protected.

(3-2) Examine all SCM_ENTER_A_SECTION/SCM_EXIT_A_SECTION, and change
      it's implementation note with GRL.  Watch out for GC.
      Double check all the relevant code are using
      SCM_ENTER_A_SECTION/SCM_EXIT_A_SECTION.

(3-3) Examine all occurrence of SCM_THREAD_CRITICAL_SECTION_START/END
      Introduce fine-grain lock (mutex) where applicable.


(4) Others

(4-1) Fix bugs where we should use REDEFER/REALLOW instead of DEFER/ALLOW

(4-2) Nuke REDEFER/REALLOW and use DEFER/ALLOW instead, and make
      GRL non-recursive (for performance reason)

(4-3) Introduce LEAVE_GUILE/BACKTO_GUILE (for GC cooperation)

(4-4) Introduce SCM_CHECK_INTS to get interrupted
      Perhaps replace SCM_ALLOW_INTS with 
      CHECK_INTS+THREAD_SWITCHING_CODE
--------------------------

And the initial patch which does (1-1) in the text above.


2001-04-02  NIIBE Yutaka  <address@hidden>

        * srcprop.c (scm_make_srcprops): Added SCM_ALLOW_INTS which
        matches SCM_DEFER_INTS at the beginning of the function.

        * mallocs.c (scm_malloc_obj): Remove un-matched SCM_ALLOW_INTS.

        * gc.c (scm_igc): Unconditionally call
        SCM_THREAD_CRITICAL_SECTION_START/END.

        * fluids.c (next_fluid_num): Unconditionally call
        SCM_THREAD_CRITICAL_SECTION_START/END.
        (s_scm_make_fluid): Remove un-matched SCM_DEFER_INTS.

        * coop-defs.h (SCM_THREAD_DEFER, SCM_THREAD_ALLOW,
        SCM_THREAD_REDEFER, SCM_THREAD_REALLOW_1, SCM_THREAD_REALLOW_2):
        Removed.

        * __scm.h (SCM_THREAD_CRITICAL_SECTION_START,
        SCM_THREAD_CRITICAL_SECTION_END): Defined as nothing
        for the case of !defined(USE_THREADS).
        (SCM_THREAD_DEFER, SCM_THREAD_ALLOW, SCM_THREAD_REDEFER): Removed.
        (<stdio.h>): Include when defined(SCM_CAREFUL_INTS).
        (SCM_CHECK_NOT_DISABLED, SCM_CHECK_NOT_ENABLED): Print FILE and
        LINE.
        (SCM_DEFER_INTS, SCM_ALLOW_INTS_ONLY, SCM_ALLOW_INTS, 
        SCM_REDEFER_INTS, SCM_REALLOW_INTS): Don't use
        SCM_THREAD_DEFER/SCM_THREAD_ALLOW.  Instead, use
        SCM_THREAD_CRITICAL_SECTION_START/END.
        (SCM_TICK): Don't use SCM_DEFER_INTS/SCM_ALLOW_INTS.  Instead, 
        use SCM_THREAD_SWITCHING_CODE directly.
        (SCM_ENTER_A_SECTION): Unconditionally use 
        SCM_THREAD_CRITICAL_SECTION_START/END.
        (was: SCM_DEFER_INTS/SCM_ALLOW_INTS when SCM_POSIX_THREADS defined).

Index: libguile/__scm.h
===================================================================
RCS file: /cvs/guile/guile-core/libguile/__scm.h,v
retrieving revision 1.65
diff -u -r1.65 __scm.h
--- libguile/__scm.h    2001/03/17 13:34:21     1.65
+++ libguile/__scm.h    2001/04/02 04:04:14
@@ -319,9 +319,8 @@
 
 
 #ifndef USE_THREADS
-#define SCM_THREAD_DEFER
-#define SCM_THREAD_ALLOW
-#define SCM_THREAD_REDEFER
+#define SCM_THREAD_CRITICAL_SECTION_START 
+#define SCM_THREAD_CRITICAL_SECTION_END 
 #define SCM_THREAD_SWITCHING_CODE
 #endif
 
@@ -344,13 +343,18 @@
 #endif
 
 #ifdef SCM_CAREFUL_INTS
+#include <stdio.h>
 #define SCM_CHECK_NOT_DISABLED \
+do { \
   if (scm_ints_disabled) \
-    fputs("ints already disabled\n", stderr); \
+    fprintf(stderr, "ints already disabled (at %s:%d)\n", __FILE__, __LINE__); 
\
+} while (0)
 
 #define SCM_CHECK_NOT_ENABLED \
+do { \
   if (!scm_ints_disabled) \
-    fputs("ints already enabled\n", stderr); \
+    fprintf(stderr, "ints already enabled (at %s:%d)\n", __FILE__, __LINE__); \
+} while (0)
 
 #else
 #define SCM_CHECK_NOT_DISABLED
@@ -383,7 +387,7 @@
 do { \
   SCM_FENCE; \
   SCM_CHECK_NOT_DISABLED; \
-  SCM_THREAD_DEFER; \
+  SCM_THREAD_CRITICAL_SECTION_START; \
   SCM_FENCE; \
   scm_ints_disabled = 1; \
   SCM_FENCE; \
@@ -392,7 +396,7 @@
 
 #define SCM_ALLOW_INTS_ONLY \
 do { \
-  SCM_THREAD_ALLOW; \
+  SCM_THREAD_CRITICAL_SECTION_END; \
   scm_ints_disabled = 0; \
 } while (0)
 
@@ -401,11 +405,11 @@
 do { \
   SCM_FENCE; \
   SCM_CHECK_NOT_ENABLED; \
-  SCM_THREAD_SWITCHING_CODE; \
+  SCM_THREAD_CRITICAL_SECTION_END; \
   SCM_FENCE; \
   scm_ints_disabled = 0; \
   SCM_FENCE; \
-  SCM_THREAD_ALLOW; \
+  SCM_THREAD_SWITCHING_CODE; \
   SCM_FENCE; \
 } while (0)
 
@@ -413,7 +417,7 @@
 #define SCM_REDEFER_INTS  \
 do { \
   SCM_FENCE; \
-  SCM_THREAD_REDEFER; \
+  SCM_THREAD_CRITICAL_SECTION_START; \
   ++scm_ints_disabled; \
   SCM_FENCE; \
 } while (0)
@@ -422,18 +426,19 @@
 #define SCM_REALLOW_INTS \
 do { \
   SCM_FENCE; \
-  SCM_THREAD_SWITCHING_CODE; \
+  SCM_THREAD_CRITICAL_SECTION_END; \
   SCM_FENCE; \
   --scm_ints_disabled; \
   SCM_FENCE; \
+  SCM_THREAD_SWITCHING_CODE; \
+  SCM_FENCE; \
 } while (0)
 
 
 #define SCM_TICK \
 do { \
-  SCM_DEFER_INTS; \
-  SCM_ALLOW_INTS; \
   SCM_ASYNC_TICK; \
+  SCM_THREAD_SWITCHING_CODE; \
 } while (0)
 
 
@@ -466,13 +471,8 @@
  * at all times.
  */
 
-#ifdef SCM_POSIX_THREADS
-#define SCM_ENTER_A_SECTION
-#define SCM_EXIT_A_SECTION
-#else
-#define SCM_ENTER_A_SECTION SCM_DEFER_INTS
-#define SCM_EXIT_A_SECTION SCM_ALLOW_INTS
-#endif
+#define SCM_ENTER_A_SECTION SCM_THREAD_CRITICAL_SECTION_START
+#define SCM_EXIT_A_SECTION SCM_THREAD_CRITICAL_SECTION_END
 
 
 
Index: libguile/coop-defs.h
===================================================================
RCS file: /cvs/guile/guile-core/libguile/coop-defs.h,v
retrieving revision 1.18
diff -u -r1.18 coop-defs.h
--- libguile/coop-defs.h        2000/10/02 21:32:57     1.18
+++ libguile/coop-defs.h        2001/04/02 04:04:14
@@ -245,12 +245,6 @@
 
 
 
-#define SCM_THREAD_DEFER
-#define SCM_THREAD_ALLOW
-#define SCM_THREAD_REDEFER
-#define SCM_THREAD_REALLOW_1
-#define SCM_THREAD_REALLOW_2
-
 #if 0
 #define SCM_THREAD_SWITCHING_CODE \
 do { \
Index: libguile/fluids.c
===================================================================
RCS file: /cvs/guile/guile-core/libguile/fluids.c,v
retrieving revision 1.31
diff -u -r1.31 fluids.c
--- libguile/fluids.c   2001/03/30 15:03:22     1.31
+++ libguile/fluids.c   2001/04/02 04:04:14
@@ -107,13 +107,9 @@
 next_fluid_num ()
 {
   int n;
-#ifdef USE_THREADS
   SCM_THREAD_CRITICAL_SECTION_START;
-#endif
   n = n_fluids++;
-#ifdef USE_THREADS
   SCM_THREAD_CRITICAL_SECTION_END;
-#endif
   return n;
 }
 
@@ -130,7 +126,6 @@
 {
   int n;
 
-  SCM_DEFER_INTS;
   n = next_fluid_num ();
   SCM_RETURN_NEWSMOB (scm_tc16_fluid, n);
 }
Index: libguile/gc.c
===================================================================
RCS file: /cvs/guile/guile-core/libguile/gc.c,v
retrieving revision 1.190
diff -u -r1.190 gc.c
--- libguile/gc.c       2001/03/31 22:55:27     1.190
+++ libguile/gc.c       2001/04/02 04:04:15
@@ -1000,10 +1000,8 @@
           ? "*"
           : (SCM_NULLP (scm_freelist2) ? "o" : "m"));
 #endif
-#ifdef USE_THREADS
   /* During the critical section, only the current thread may run. */
   SCM_THREAD_CRITICAL_SECTION_START;
-#endif
 
   /* fprintf (stderr, "gc: %s\n", what); */
 
@@ -1101,9 +1099,7 @@
   --scm_gc_heap_lock;
   gc_end_stats ();
 
-#ifdef USE_THREADS
   SCM_THREAD_CRITICAL_SECTION_END;
-#endif
   scm_c_hook_run (&scm_after_gc_c_hook, 0);
   --scm_gc_running_p;
 }
Index: libguile/mallocs.c
===================================================================
RCS file: /cvs/guile/guile-core/libguile/mallocs.c,v
retrieving revision 1.22
diff -u -r1.22 mallocs.c
--- libguile/mallocs.c  2001/03/09 23:33:40     1.22
+++ libguile/mallocs.c  2001/04/02 04:04:15
@@ -64,10 +64,7 @@
 {
   scm_bits_t mem = n ? (scm_bits_t) malloc (n) : 0;
   if (n && !mem)
-    {
-      SCM_ALLOW_INTS;
-      return SCM_BOOL_F;
-    }
+    return SCM_BOOL_F;
   SCM_RETURN_NEWSMOB (scm_tc16_malloc, mem);
 }
 
Index: libguile/srcprop.c
===================================================================
RCS file: /cvs/guile/guile-core/libguile/srcprop.c,v
retrieving revision 1.45
diff -u -r1.45 srcprop.c
--- libguile/srcprop.c  2001/03/10 16:56:07     1.45
+++ libguile/srcprop.c  2001/04/02 04:04:15
@@ -148,6 +148,7 @@
   ptr->fname = filename;
   ptr->copy = copy;
   ptr->plist = plist;
+  SCM_ALLOW_INTS;
   SCM_RETURN_NEWSMOB (scm_tc16_srcprops, ptr);
 }
 
-- 



reply via email to

[Prev in Thread] Current Thread [Next in Thread]