[Gc] Fix for Win32 GC_write

Ivan Maidanski ivmai at mail.ru
Sat Nov 1 00:52:33 PST 2008


Hi!

If we are running parallel markers then GC_write() needs synchronization even if there is no "user" threads (i.e. GC_need_to_lock == FALSE).

This patch does:
- introduce "IF_NEED_TO_LOCK(x)" macro (locally defined for convenience) in "misc.c" and use it in in GC_write() for Enter/LeaveCriticalSection() calling (it is assumed here that my "diff20" is already applied);
- replace GC_ASSERT(const_expr) with GC_STATIC_ASSERT(const_expr) in GC_init_inner() ("misc.c" file) and in "gc_pmark.h", "os_dep.c" files;
- fix a typo in GC_init_inner() ("misc.c" file).

Also, GC_abort() is not defined for SMALL_CONFIG now (since it is unused in this case).

Bye.

-------------- next part --------------
diff -ru bdwgc/include/private/gc_pmark.h updated/bdwgc/include/private/gc_pmark.h
--- bdwgc/include/private/gc_pmark.h	2008-10-25 16:13:41.000000000 +0400
+++ updated/bdwgc/include/private/gc_pmark.h	2008-10-31 22:25:52.000000000 +0300
@@ -342,7 +342,7 @@
 	  GC_ASSERT((ptr_t)(hhdr -> hb_block) < (ptr_t) current); \
 	} else { \
 	  /* Accurate enough if HBLKSIZE <= 2**15.	*/ \
-	  GC_ASSERT(HBLKSIZE <= (1 << 15)); \
+	  GC_STATIC_ASSERT(HBLKSIZE <= (1 << 15)); \
 	  size_t obj_displ = (((low_prod >> 16) + 1) * (hhdr -> hb_sz)) >> 16; \
 	  if (do_offset_check && !GC_valid_offsets[obj_displ]) { \
 	    GC_ADD_TO_BLACK_LIST_NORMAL(current, source); \
diff -ru bdwgc/misc.c updated/bdwgc/misc.c
--- bdwgc/misc.c	2008-10-29 01:05:06.000000000 +0300
+++ updated/bdwgc/misc.c	2008-10-31 22:16:14.000000000 +0300
@@ -654,13 +654,15 @@
         GC_ASSERT((word)(&dummy) >= (word)GC_stackbottom);
 #     endif
 #   endif
-#   if !defined(_AUX_SOURCE) || defined(__GNUC__)
-      GC_ASSERT((word)(-1) > (word)0);
+#   if !defined(_AUX_SOURCE)
+      GC_STATIC_ASSERT((word)(-1) > (word)0);
       /* word should be unsigned */
 #   endif
-    GC_ASSERT((ptr_t)(word)(-1) > (ptr_t)0);
+#   if !defined(__BORLANDC__) /* Workaround for Borland C */
+	GC_STATIC_ASSERT((ptr_t)(word)(-1) > (ptr_t)0);
     	/* Ptr_t comparisons should behave as unsigned comparisons.	*/
-    GC_ASSERT((signed_word)(-1) < (signed_word)0);
+#   endif
+    GC_STATIC_ASSERT((signed_word)(-1) < (signed_word)0);
 #   if !defined(SMALL_CONFIG)
       if (GC_incremental || 0 != GETENV("GC_ENABLE_INCREMENTAL")) {
 	/* This used to test for !GC_no_win32_dlls.  Why? */
@@ -755,7 +757,7 @@
     /* The rest of this again assumes we don't really hold	*/
     /* the allocation lock.					*/
 #   if defined(PARALLEL_MARK) || defined(THREAD_LOCAL_ALLOC)
-	/* Make sure marker threads and started and thread local */
+	/* Make sure marker threads are started and thread local */
 	/* allocation is initialized, in case we didn't get 	 */
 	/* called from GC_init_parallel();			 */
         {
@@ -836,19 +838,25 @@
 #   endif
   }
 
+#ifdef GC_THREADS
+# ifdef PARALLEL_MARK
+#   define IF_NEED_TO_LOCK(x) if (GC_parallel || GC_need_to_lock) x
+# else
+#   define IF_NEED_TO_LOCK(x) if (GC_need_to_lock) x
+# endif
+#else
+# define IF_NEED_TO_LOCK(x)
+#endif
+
   int GC_write(const char *buf, size_t len)
   {
       BOOL tmp;
       DWORD written;
       if (len == 0)
 	  return 0;
-#     ifdef GC_THREADS
-	  if (GC_need_to_lock) EnterCriticalSection(&GC_write_cs);
-#     endif
+      IF_NEED_TO_LOCK(EnterCriticalSection(&GC_write_cs));
       if (GC_stdout == INVALID_HANDLE_VALUE) {
-#	  ifdef GC_THREADS
-	      if (GC_need_to_lock) LeaveCriticalSection(&GC_write_cs);
-#	  endif
+	  IF_NEED_TO_LOCK(LeaveCriticalSection(&GC_write_cs));
 	  return -1;
       } else if (GC_stdout == 0) {
 	char * file_name = GETENV("GC_LOG_FILE");
@@ -876,9 +884,7 @@
 #     if defined(_MSC_VER) && defined(_DEBUG)
 	  _CrtDbgReport(_CRT_WARN, NULL, 0, NULL, "%.*s", len, buf);
 #     endif
-#     ifdef GC_THREADS
-	  if (GC_need_to_lock) LeaveCriticalSection(&GC_write_cs);
-#     endif
+      IF_NEED_TO_LOCK(LeaveCriticalSection(&GC_write_cs));
       return tmp ? (int)written : -1;
   }
 
@@ -1055,7 +1061,7 @@
     return old;
 }
 
-#ifndef PCR
+#if !defined(PCR) && (!defined(SMALL_CONFIG) || defined(DARWIN))
 void GC_abort(const char *msg)
 {
 #   if defined(MSWIN32) && !defined(DONT_USE_USER32_DLL)
diff -ru bdwgc/os_dep.c updated/bdwgc/os_dep.c
--- bdwgc/os_dep.c	2008-10-25 17:20:36.000000000 +0400
+++ updated/bdwgc/os_dep.c	2008-10-31 22:23:44.000000000 +0300
@@ -3997,7 +3997,7 @@
     }
     GC_in_save_callers = TRUE;
 # endif
-  GC_ASSERT(sizeof(struct callinfo) == sizeof(void *));
+  GC_STATIC_ASSERT(sizeof(struct callinfo) == sizeof(void *));
   npcs = backtrace((void **)tmp_info, NFRAMES + IGNORE_FRAMES);
   BCOPY(tmp_info+IGNORE_FRAMES, info, (npcs - IGNORE_FRAMES) * sizeof(void *));
   for (i = npcs - IGNORE_FRAMES; i < NFRAMES; ++i) info[i].ci_pc = 0;


More information about the Gc mailing list