[m-rev.] for review: support pthreads-win32 on mingw

Julien Fischer juliensf at csse.unimelb.edu.au
Mon Dec 13 02:08:47 AEDT 2010


Branches: main, 10.04

Support the use of the pthreads-win32 library on MinGW systems.
(This is based on the patch provided by Sergey Khorev.)
The main change is to remove the assumption in the runtime code
that POSIX thread handles are integers; in the pthreads-win32 library
they are not.

With this change the hlc.par.gc grade will work on Windows / MinGW.
(The low-level C parallel grades will require further work.)

configure.in:
 	Configure the Boehm GC to use pthreads-win32 if that is being used
 	to provide threads for the runtime on MinGW.

 	Delete the --with-pthreads-win32 option; it is no longer needed.

 	Add a new option --with-gc-pthreads-win32 that forces the Boehm GC
 	to use pthreads-win32.  This is the default for MinGW anyway, the option
 	is intended for use by developers using pthreads-win32 in other ways,
 	e.g. with MSVC.

runtime/mercury_thread.h:
 	Add a new macro / function (depending on the implementation of pthreads)
 	that returns the "null" thread.

 	Add a new macro MR_thread_equal() that tests two thread handles
 	for equality.

runtime/mercury_thread.c:
 	Provide implementations of MR_null_thread().

 	Add a macro, for use within this module, that returns the id
 	of a thread in a form suitable for use in debugging messages.

runtime/mercury_engine.c:
runtime/mercury_context.c:
runtime/mercury_wrapper.c:
runtime/mercury_thread.c:
 	Use MR_null_thread() instead of NULL or 0.

 	Use MR_thread_equal() instead of directly comparing thread handles.

Julien.

Index: configure.in
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/configure.in,v
retrieving revision 1.571
diff -u -r1.571 configure.in
--- configure.in	9 Dec 2010 06:14:14 -0000	1.571
+++ configure.in	12 Dec 2010 15:02:56 -0000
@@ -1223,19 +1223,6 @@
      MERCURY_CHECK_FOR_HEADERS(sys/ucontext.h)
  fi

-if test "$MR_HAVE_PTHREAD_H" = 1
-then
-    case "$host" in
-        *mingw*)
-            MERCURY_HAVE_PTHREADS_WIN32
-            if test $mercury_cv_have_pthreads_win32 = "yes"
-            then
-                AC_DEFINE([MR_PTHREADS_WIN32])
-            fi 
-        ;;
-    esac
-fi
-
  #-----------------------------------------------------------------------------#
  #
  # Check whether we can set the FP rounding mode
@@ -2856,29 +2843,49 @@

  #-----------------------------------------------------------------------------#

-# Allow the use of pthreads-win32 instead of native Win32 threads on Windows.
-# XXX it should also be possible to use pthreads-win32 with MSVC.
+# Check if we are using the pthreads-win32 library.
+# NOTE: we currently only support this on MinGW.
+
+if test "$MR_HAVE_PTHREAD_H" = 1
+then
+    case "$host" in
+        *mingw*)
+            MERCURY_HAVE_PTHREADS_WIN32
+            if test $mercury_cv_have_pthreads_win32 = "yes"
+            then
+                AC_DEFINE([MR_PTHREADS_WIN32])
+                WIN32_GC_THREADLIB="-DGC_WIN32_PTHREADS"
+            else
+                WIN32_GC_THREADLIB="-DGC_WIN32_THREADS"
+            fi 
+        ;;
+
+        *)
+            WIN32_GC_THREADLIB="-DGC_WIN32_THREADS"
+        ;;
+    esac
+else
+    WIN32_GC_THREADLIB="-DGC_WIN32_THREADS"
+fi

-AC_ARG_WITH([pthreads-win32],
-   AC_HELP_STRING([--with-pthreads-win32]
-      [use the pthreads-win32 library instead of Win32 threads (GCC only)]
-   ),
-   [with_pthreads_win32="$withval"],[with_pthreads_win32="no"])
+AC_ARG_WITH([gc-pthreads-win32],
+   AC_HELP_STRING([--with-gc-pthreads-win32]
+          [Force the use of the pthreads-win32 library with the Boehm GC.
+           This is the default for MinGW]),
+   [with_gc_pthreads_win32="$withval"],[with_gc_pthreads_win32="no"])

-case "$with_pthreads_win32" in
+case "$with_gc_pthreads_win32" in

      yes)
-        # Use the pthreads-win32 library.
+        # Force the use of the pthreads-win32 library with the Boehm GC.
          WIN32_GC_THREADLIB="-DGC_WIN32_PTHREADS"
      ;;

-    no)
-        # Use native Win32 threads.
-        WIN32_GC_THREADLIB="-DGC_WIN32_THREADS"
+    no)
      ;;

      *)
-        AC_MSG_ERROR([unexpected argument to --with-pthreads-win32])
+        AC_MSG_ERROR([unexpected argument to --with-gc-pthreads-win32])
      ;;
  esac

@@ -2963,7 +2970,9 @@
                  LD_LIBFLAGS_FOR_THREADS="/MD"
                  ;;
              *)
-                CFLAGS_FOR_THREADS="$WIN32_GC_THREADLIB -DMR_THREAD_SAFE" ;;
+                CFLAGS_FOR_THREADS="-DMR_THREAD_SAFE $WIN32_GC_THREADLIB"
+                THREAD_LIBS="-lpthread"
+                ;;
          esac
          ;;

Index: runtime/mercury_context.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_context.c,v
retrieving revision 1.83
diff -u -r1.83 mercury_context.c
--- runtime/mercury_context.c	1 Nov 2010 05:01:14 -0000	1.83
+++ runtime/mercury_context.c	12 Dec 2010 15:02:56 -0000
@@ -491,7 +491,7 @@
      c->MR_ctxt_next = NULL;
      c->MR_ctxt_resume = NULL;
  #ifdef  MR_THREAD_SAFE
-    c->MR_ctxt_resume_owner_thread = (MercuryThread) NULL;
+    c->MR_ctxt_resume_owner_thread = MR_null_thread();
      c->MR_ctxt_resume_c_depth = 0;
      c->MR_ctxt_saved_owners = NULL;
  #endif
@@ -852,15 +852,15 @@
      /* XXX check pending io */
      prev = NULL;
      while (cur != NULL) {
-        if (cur->MR_ctxt_resume_owner_thread == thd &&
+        if (MR_thread_equal(cur->MR_ctxt_resume_owner_thread, thd) &&
              cur->MR_ctxt_resume_c_depth == depth)
          {
-            cur->MR_ctxt_resume_owner_thread = (MercuryThread) NULL;
+            cur->MR_ctxt_resume_owner_thread = MR_null_thread();
              cur->MR_ctxt_resume_c_depth = 0;
              break;
          }

-        if (cur->MR_ctxt_resume_owner_thread == (MercuryThread) NULL) {
+        if (MR_thread_equal(cur->MR_ctxt_resume_owner_thread, MR_null_thread())) {
              break;
          }

@@ -1108,7 +1108,7 @@
      ** possibility that a woken thread might not accept this context then
      ** we wake up all the waiting threads.
      */
-    if (ctxt->MR_ctxt_resume_owner_thread == (MercuryThread) NULL) {
+    if (MR_thread_equal(ctxt->MR_ctxt_resume_owner_thread, MR_null_thread())) {
          MR_SIGNAL(&MR_runqueue_cond, "schedule_context");
      } else {
          MR_BROADCAST(&MR_runqueue_cond, "schedule_context");
@@ -1173,7 +1173,7 @@
              ** The primordial thread has the responsibility of cleaning
              ** up the Mercury runtime. It cannot exit by this route.
              */
-            assert(thd != MR_primordial_thread);
+            assert(!MR_thread_equal(thd, MR_primordial_thread));
              MR_destroy_thread(MR_cur_engine());
              MR_num_exited_engines++;
              MR_UNLOCK(&MR_runqueue_lock, "MR_do_runnext (ii)");
Index: runtime/mercury_engine.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_engine.c,v
retrieving revision 1.62
diff -u -r1.62 mercury_engine.c
--- runtime/mercury_engine.c	31 May 2010 09:41:47 -0000	1.62
+++ runtime/mercury_engine.c	12 Dec 2010 15:02:56 -0000
@@ -525,7 +525,7 @@
          owner = this_ctxt->MR_ctxt_saved_owners;
          this_ctxt->MR_ctxt_saved_owners = owner->MR_saved_owner_next;

-        if (owner->MR_saved_owner_thread == MR_ENGINE(MR_eng_owner_thread) &&
+        if (MR_thread_equal(owner->MR_saved_owner_thread, MR_ENGINE(MR_eng_owner_thread)) &&
              owner->MR_saved_owner_c_depth == MR_ENGINE(MR_eng_c_depth))
          {
              MR_GC_free(owner);
Index: runtime/mercury_thread.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_thread.c,v
retrieving revision 1.44
diff -u -r1.44 mercury_thread.c
--- runtime/mercury_thread.c	6 Dec 2010 14:41:34 -0000	1.44
+++ runtime/mercury_thread.c	12 Dec 2010 15:02:56 -0000
@@ -51,6 +51,12 @@

  #ifdef MR_THREAD_SAFE

+  #if defined(MR_PTHREADS_WIN32)
+    #define SELF_THREAD_ID ((long) pthread_self().p)
+  #else
+    #define SELF_THREAD_ID ((long) pthread_self())
+  #endif
+
  static void *
  MR_create_thread_2(void *goal);

@@ -61,7 +67,7 @@
      pthread_attr_t  attrs;
      int             err;

-    assert(MR_primordial_thread != (MercuryThread) 0);
+    assert(!MR_thread_equal(MR_primordial_thread, MR_null_thread()));

      /*
      ** Create threads in the detached state so that resources will be
@@ -238,7 +244,7 @@
      int err;

      fprintf(stderr, "%ld locking on %p (%s)\n",
-        (long) pthread_self(), lock, from);
+        SELF_THREAD_ID, lock, from);
      err = pthread_mutex_lock(lock);
      assert(err == 0);
      return err;
@@ -250,7 +256,7 @@
      int err;

      fprintf(stderr, "%ld unlocking on %p (%s)\n",
-        (long) pthread_self(), lock, from);
+        SELF_THREAD_ID, lock, from);
      err = pthread_mutex_unlock(lock);
      assert(err == 0);
      return err;
@@ -262,7 +268,7 @@
      int err;

      fprintf(stderr, "%ld signaling %p (%s)\n", 
-        (long) pthread_self(), cond, from);
+        SELF_THREAD_ID, cond, from);
      err = pthread_cond_signal(cond);
      assert(err == 0);
      return err;
@@ -274,7 +280,7 @@
      int err;

      fprintf(stderr, "%ld broadcasting %p (%s)\n", 
-        (long) pthread_self(), cond, from);
+        SELF_THREAD_ID, cond, from);
      err = pthread_cond_broadcast(cond);
      assert(err == 0);
      return err;
@@ -286,7 +292,7 @@
      int err;

      fprintf(stderr, "%ld waiting on cond: %p lock: %p (%s)\n", 
-        (long) pthread_self(), cond, lock, from);
+        SELF_THREAD_ID, cond, lock, from);
      err = pthread_cond_wait(cond, lock);
      assert(err == 0);
      return err;
@@ -299,13 +305,22 @@
      int err;

      fprintf(stderr, "%ld timed-waiting on cond: %p lock: %p (%s)\n",
-        (long)pthread_self(), cond, lock, from);
+        SELF_THREAD_ID, cond, lock, from);
      err = pthread_cond_timedwait(cond, lock, abstime);
      fprintf(stderr, "%ld timed-wait returned %d\n",
-        (long)pthread_self(), err);
+        SELF_THREAD_ID, err);
      return err;
  }

+#if defined(MR_PTHREADS_WIN32)
+MercuryThread
+MR_null_thread(void)
+{
+    const MercuryThread null_thread = {NULL, 0};
+    return null_thread;
+}
+#endif /* MR_PTHREADS_WIN32 */
+
  #endif  /* MR_THREAD_SAFE */

  MR_Unsigned
Index: runtime/mercury_thread.h
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_thread.h,v
retrieving revision 1.32
diff -u -r1.32 mercury_thread.h
--- runtime/mercury_thread.h	6 Dec 2010 14:41:34 -0000	1.32
+++ runtime/mercury_thread.h	12 Dec 2010 15:02:56 -0000
@@ -45,6 +45,15 @@
  MR_cond_timed_wait(MercuryCond *cond, MercuryLock *lock,
      const struct timespec *abstime, const char *from);

+   #if defined(MR_PTHREADS_WIN32)
+extern MercuryThread
+MR_null_thread(void);
+  #else
+    #define MR_null_thread() ((MercuryThread) 0)
+  #endif
+
+  #define MR_thread_equal(a, b)       pthread_equal((a), (b))
+
    extern MR_bool    MR_debug_threads;

    #ifndef MR_DEBUG_THREADS
Index: runtime/mercury_wrapper.c
===================================================================
RCS file: /home/mercury/mercury1/repository/mercury/runtime/mercury_wrapper.c,v
retrieving revision 1.212
diff -u -r1.212 mercury_wrapper.c
--- runtime/mercury_wrapper.c	13 Nov 2010 17:39:07 -0000	1.212
+++ runtime/mercury_wrapper.c	12 Dec 2010 15:02:56 -0000
@@ -2758,7 +2758,7 @@
      }

    #if defined(MR_HIGHLEVEL_CODE) && defined(MR_THREAD_SAFE)
-    assert(pthread_self() == MR_primordial_thread);
+    assert(MR_thread_equal(pthread_self(), MR_primordial_thread));
      MR_LOCK(&MR_thread_barrier_lock, "MR_do_interpreter");
      while (MR_thread_barrier_count > 0) {
          while (MR_WAIT(&MR_thread_barrier_cond, &MR_thread_barrier_lock,
@@ -3035,8 +3035,8 @@
      MR_finalize_threadscope();
  #endif

-    assert(MR_primordial_thread == pthread_self());
-    MR_primordial_thread = (MercuryThread) 0;
+    assert(MR_thread_equal(MR_primordial_thread, pthread_self()));
+    MR_primordial_thread = MR_null_thread();

      MR_finalize_thread_stuff();
  #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