[Gc] Fix for PARALLEL_MARK for cygwin and wn32

Ivan Maidanski ivmai at mail.ru
Wed Nov 12 14:47:30 PST 2008


Hi!

This patch makes GC_register_dynamic_libraries() ignore stack areas of marker threads.

And, this patch also contains some code for windows-ia64 (more IA64-specific code should be really added to get it compile and work on Win64).

In addition, a comment (specific really to x86) for amd64 is removed in libatomics.

PS. One question about PARALLEL_MARK on Win32 remains: Should we undef MPROTECT_VDB even in case of GWW_VDB?

Bye.
-------------- next part --------------
diff -ru bdwgc/include/gc.h updated/bdwgc/include/gc.h
--- bdwgc/include/gc.h	2008-11-11 02:15:32.000000000 +0300
+++ updated/bdwgc/include/gc.h	2008-11-12 20:15:54.000000000 +0300
@@ -875,7 +875,7 @@
 /* platforms this contains just a single address.			*/
 struct GC_stack_base {
 	void * mem_base;	/* Base of memory stack.	*/
-#	if defined(__ia64) || defined(__ia64__)
+#	if defined(__ia64) || defined(__ia64__) || defined(_M_IA64)
 	  void * reg_base;	/* Base of separate register stack.	*/
 #	endif
 };
diff -ru bdwgc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc/x86_64.h updated/bdwgc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc/x86_64.h
--- bdwgc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc/x86_64.h	2008-10-29 23:13:56.000000000 +0300
+++ updated/bdwgc/libatomic_ops-1.2/src/atomic_ops/sysdeps/msftc/x86_64.h	2008-11-12 20:05:58.000000000 +0300
@@ -20,9 +20,6 @@
  * SOFTWARE. 
  */
 
-/* The following really assume we have a 486 or better. */
-/* If ASSUME_WINDOWS98 is defined, we assume Windows 98 or newer.	*/
-
 #include "../all_aligned_atomic_load_store.h"
 
 /* Real X86 implementations, except for some old WinChips, appear	*/
diff -ru bdwgc/win32_threads.c updated/bdwgc/win32_threads.c
--- bdwgc/win32_threads.c	2008-11-12 16:36:58.000000000 +0300
+++ updated/bdwgc/win32_threads.c	2008-11-13 00:35:28.529728500 +0300
@@ -194,6 +194,11 @@
 			/* !in_use ==> stack_base == 0	*/
   ptr_t last_stack_min;	/* Last known minimum (hottest) address */
   			/* in stack or ADDR_LIMIT if unset	*/
+# ifdef IA64
+    ptr_t backing_store_end;
+    ptr_t backing_store_ptr;
+# endif
+
   GC_bool suspended;
 
 # ifdef GC_PTHREADS
@@ -403,6 +408,9 @@
   }
   me -> last_stack_min = ADDR_LIMIT;
   me -> stack_base = sb -> mem_base;
+# ifdef IA64
+      me -> backing_store_end = sb -> reg_base;
+# endif
   /* Up until this point, GC_push_all_stacks considers this thread	*/
   /* invalid.								*/
   /* Up until this point, this entry is viewed as reserved but invalid	*/
@@ -1028,6 +1036,29 @@
     ABORT("Collecting from unknown thread.");
 }
 
+#ifdef PARALLEL_MARK
+
+# ifndef MAX_MARKERS
+#   define MAX_MARKERS 16
+# endif
+
+  extern long GC_markers;	/* Number of mark threads we would	*/
+				/* like to have.  Includes the 		*/
+				/* initiating thread.			*/
+
+  STATIC ptr_t marker_sp[MAX_MARKERS - 1]; /* The cold end of the stack	*/
+					   /* for markers.		*/
+# ifdef IA64
+    STATIC ptr_t marker_bsp[MAX_MARKERS - 1];
+# endif
+
+  STATIC ptr_t marker_last_stack_min[MAX_MARKERS - 1];
+				/* Last known minimum (hottest) address */
+    				/* in stack (or ADDR_LIMIT if unset)	*/
+    				/* for markers.				*/
+
+#endif
+
 /* Find stack with the lowest address which overlaps the 	*/
 /* interval [start, limit).					*/
 /* Return stack bounds in *lo and *hi.  If no such stack	*/
@@ -1049,7 +1080,7 @@
         for (i = 0; i <= my_max; i++) {
      	  ptr_t s = (ptr_t)(dll_thread_table[i].stack_base);
 
-	  if (0 != s && s > start && s < current_min) {
+	  if (s > start && s < current_min) {
 	    /* Update address of last_stack_min. */
 	    plast_stack_min = (ptr_t * /* no volatile */)
 	    			&dll_thread_table[i].last_stack_min;
@@ -1063,7 +1094,7 @@
           for (t = GC_threads[i]; t != 0; t = t -> next) {
 	    ptr_t s = t -> stack_base;
 
-	    if (0 != s && s > start && s < current_min) {
+	    if (s > start && s < current_min) {
 	      /* Update address of last_stack_min. */
 	      plast_stack_min = &t -> last_stack_min;
 	      current_min = s;
@@ -1071,7 +1102,17 @@
           }
         }
 #	ifdef PARALLEL_MARK
-	  /* FIXME: Should we scan marker threads here too? */
+	  for (i = 0; i < GC_markers - 1; ++i) {
+	    ptr_t s = marker_sp[i];
+#	    ifdef IA64
+		/* FIXME: not implemented */
+#	    endif
+	    if (s > start && s < current_min) {
+	      GC_ASSERT(marker_last_stack_min[i] != NULL);
+	      plast_stack_min = &marker_last_stack_min[i];
+	      current_min = s;
+	    }
+	  }
 #	endif
       }
 
@@ -1113,12 +1154,7 @@
 
 #ifdef PARALLEL_MARK
 
-# ifndef MAX_MARKERS
-#   define MAX_MARKERS 16
-# endif
-
   /* GC_mark_thread() is the same as in pthread_support.c	*/
-  /* except for unused marker_[b]sp.				*/
 #ifdef GC_PTHREADS
   STATIC void * GC_mark_thread(void * id)
 #else
@@ -1127,6 +1163,11 @@
 {
   word my_mark_no = 0;
 
+  marker_sp[(word)id] = GC_approx_sp();
+# ifdef IA64
+    marker_bsp[(word)id] = GC_save_regs_in_stack();
+# endif
+
   if ((word)id == (word)-1) return 0; /* to make compiler happy */
 
   for (;; ++my_mark_no) {
@@ -1143,10 +1184,6 @@
   }
 }
 
-extern long GC_markers;		/* Number of mark threads we would	*/
-				/* like to have.  Includes the 		*/
-				/* initiating thread.			*/
-
 #ifdef GC_ASSERTIONS
   unsigned long GC_mark_lock_holder = NO_THREAD;
 #endif
@@ -1172,6 +1209,7 @@
 	ABORT("pthread_attr_setdetachstate failed");
 
     for (i = 0; i < GC_markers - 1; ++i) {
+      marker_last_stack_min[i] = ADDR_LIMIT;
       if (0 != pthread_create(&new_thread, &attr,
 			      GC_mark_thread, (void *)(word)i)) {
 	WARN("Marker thread creation failed, errno = %ld.\n",
@@ -1288,6 +1326,7 @@
       unsigned thread_id;
 
       for (i = 0; i < GC_markers - 1; ++i) {
+	marker_last_stack_min[i] = ADDR_LIMIT;
 	handle = _beginthreadex(NULL /* security_attr */, 0 /* stack_size */,
 			GC_mark_thread, (void *)(word)i, 0 /* flags */,
 			&thread_id);


More information about the Gc mailing list