guile-devel
[Top][All Lists]
Advanced

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

A solution to pthread_getattr_np on MacOS X and potentially others.


From: Steven Wu
Subject: A solution to pthread_getattr_np on MacOS X and potentially others.
Date: Sat, 24 Feb 2007 14:42:10 -0700

One problem that I see in porting Guile to MacOS X is the function get_thread_stack_base. Since pthread_getattr_np is not portable, we need a better approach. Here is what I did:

I defined a macro PTHREAD_GET_STACKSIZE(size, start, end) and used that in get_thread_stack_base function. I then wrote a test in configure.in to test for pthread_get_stackaddr_np, pthread_get_stacksize_np, which are in the MacOS X, and pthread_attr_getstack, pthread_getattr_np, which are in Linux. I defined the PTHREAD_GET_STACKSIZE based on the test result for of these functions.

I think this is the cleaner way to port this function across different platforms.

Here is the diff for thread.c
===
Index: threads.c
===================================================================
RCS file: /sources/guile/guile/guile-core/libguile/threads.c,v
retrieving revision 1.88
diff -c -r1.88 threads.c
*** threads.c   15 Jan 2007 23:35:34 -0000      1.88
--- threads.c   24 Feb 2007 21:20:29 -0000
***************
*** 19,25 ****
  

  #define _GNU_SOURCE
-
  #include "libguile/_scm.h"

  #if HAVE_UNISTD_H
--- 19,24 ----
***************
*** 49,54 ****
--- 48,97 ----
  #include "libguile/gc.h"
  #include "libguile/init.h"

+
+ #if HAVE_PTHREAD_GET_STACKADDR_NP && HAVE_PTHREAD_GET_STACKSIZE_NP
+ #define PTHREAD_GET_STACKSIZE(size, start, end) \
+ {                                               \
+   pthread_t self_id;                            \
+                                                 \
+   self_id = pthread_self ();                    \
+   start = pthread_get_stackaddr_np (self_id);   \
+   size = pthread_get_stacksize_np (self_id);    \
+   end = (char *)start + size;                   \
+ } while (0)
+ #endif /* HAVE_PTHREAD_GET_STACKADDR_NP && HAVE_PTHREAD_GET_STACKSIZE_N */
+
+
+ #if HAVE_PTHREAD_GETATTR_NP && HAVE_PTHREAD_GET_STACKADDR_NP && HAVE_PTHREAD_GET_STACKSIZE_NP
+
+ /* XXX - pthread_getattr_np from LinuxThreads does not seem to work
+    for the main thread, but we can use scm_get_stack_base in that
+    case.
+ */
+
+ #ifndef PTHREAD_ATTR_GETSTACK_WORKS
+ #define GET_STACK_BASE(attr, start, end)                \
+   {                                                     \
+     if ((void *)&attr < start || (void *)&attr >= end)  \
+       return scm_get_stack_base ();                     \
+   } while (0)
+ #else
+ #define GET_STACK_BASE(attr, start, end)
+ #endif
+
+ #define PTHREAD_GET_STACKSIZE(size, start, end) \
+ {                                               \
+   pthread_attr_t attr;                          \
+                                                 \
+   pthread_getattr_np (pthread_self (), &attr);  \
+   pthread_attr_getstack (&attr, &start, &size); \
+   end = (char *)start + size;                   \
+                                                 \
+   GET_STACK_BASE(attr, start, end);             \
+                                                 \
+ } while (0)
+ #endif /* HAVE_PTHREAD_GETATTR_NP && HAVE_PTHREAD_GET_STACKADDR_NP && HAVE_PTHREAD_GET_STACKSIZE_NP */
+
  #ifdef __MINGW32__
  #ifndef ETIMEDOUT
  # define ETIMEDOUT       WSAETIMEDOUT
***************
*** 594,636 ****
  }

  #if SCM_USE_PTHREAD_THREADS

  #if HAVE_PTHREAD_ATTR_GETSTACK && HAVE_PTHREAD_GETATTR_NP
  /* This method for GNU/Linux and perhaps some other systems.
It's not for MacOS X or Solaris 10, since pthread_getattr_np is not
     available on them.  */
  #define HAVE_GET_THREAD_STACK_BASE

  static SCM_STACKITEM *
  get_thread_stack_base ()
  {
-   pthread_attr_t attr;
    void *start, *end;
    size_t size;

!   pthread_getattr_np (pthread_self (), &attr);
!   pthread_attr_getstack (&attr, &start, &size);
!   end = (char *)start + size;
!
!   /* XXX - pthread_getattr_np from LinuxThreads does not seem to work
!      for the main thread, but we can use scm_get_stack_base in that
!      case.
!   */
!
! #ifndef PTHREAD_ATTR_GETSTACK_WORKS
!   if ((void *)&attr < start || (void *)&attr >= end)
!     return scm_get_stack_base ();
!   else
  #endif
!     {
! #if SCM_STACK_GROWS_UP
        return start;
! #else
        return end;
! #endif
!     }
  }

  #elif HAVE_PTHREAD_GET_STACKADDR_NP
  /* This method for MacOS X.
It'd be nice if there was some documentation on pthread_get_stackaddr_np,
--- 637,677 ----
  }

  #if SCM_USE_PTHREAD_THREADS
+ <<<<<<< threads.c
+
+ /* pthread_getattr_np not available on MacOS X and Solaris 10. */
+ #ifdef HAVE_PTHREAD_GETSTACK_FUNCS
+
+ =======

  #if HAVE_PTHREAD_ATTR_GETSTACK && HAVE_PTHREAD_GETATTR_NP
  /* This method for GNU/Linux and perhaps some other systems.
It's not for MacOS X or Solaris 10, since pthread_getattr_np is not
     available on them.  */
+ >>>>>>> 1.88
  #define HAVE_GET_THREAD_STACK_BASE

  static SCM_STACKITEM *
  get_thread_stack_base ()
  {
    void *start, *end;
    size_t size;

! #ifdef PTHREAD_GET_STACKSIZE
!   PTHREAD_GET_STACKSIZE(size, start, end);
  #endif
!
! #   if SCM_STACK_GROWS_UP
        return start;
! #   else
        return end;
! #   endif
  }

+ <<<<<<< threads.c
+ #endif /* HAVE_PTHREAD_GETSTACK_FUNCS */
+
+ =======
  #elif HAVE_PTHREAD_GET_STACKADDR_NP
  /* This method for MacOS X.
It'd be nice if there was some documentation on pthread_get_stackaddr_np,
***************
*** 655,660 ****
--- 696,702 ----
  }

  #endif /* pthread methods of get_thread_stack_base */
+ >>>>>>> 1.88

  #else /* !SCM_USE_PTHREAD_THREADS */

===
and diff for configure.in
===
Index: configure.in
===================================================================
RCS file: /sources/guile/guile/guile-core/configure.in,v
retrieving revision 1.283
diff -c -r1.283 configure.in
*** configure.in        18 Feb 2007 23:04:35 -0000      1.283
--- configure.in        24 Feb 2007 21:41:08 -0000
***************
*** 1103,1108 ****
--- 1103,1116 ----
      #
AC_CHECK_FUNCS(pthread_attr_getstack pthread_getattr_np pthread_get_stackaddr_np pthread_sigmask)

+     # Reasons for testing:
+     #          pthread_get_stackaddr_np - only present on MacOS X
+     AC_CHECK_FUNCS(pthread_get_stackaddr_np pthread_get_stacksize_np)
+
+ if test "$ac_cv_func_pthread_attr_getstack" == yes || test "$ac_cv_func_pthread_get_stackaddr_np" == yes; then
+         AC_DEFINE(HAVE_PTHREAD_GETSTACK_FUNCS)
+     fi
+
      # On past versions of Solaris, believe 8 through 10 at least, you
      # had to write "pthread_once_t foo = { PTHREAD_ONCE_INIT };".
      # This is contrary to posix:
===



reply via email to

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