unofficial mirror of guile-devel@gnu.org 
 help / color / mirror / Atom feed
* A solution to pthread_getattr_np on MacOS X and potentially others.
@ 2007-02-24 21:42 Steven Wu
  2007-02-25 22:48 ` Kevin Ryde
  0 siblings, 1 reply; 2+ messages in thread
From: Steven Wu @ 2007-02-24 21:42 UTC (permalink / raw)
  To: guile-devel

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 ****
   \f

   #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:
===

_______________________________________________
Guile-devel mailing list
Guile-devel@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-devel


^ permalink raw reply	[flat|nested] 2+ messages in thread

end of thread, other threads:[~2007-02-25 22:48 UTC | newest]

Thread overview: 2+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2007-02-24 21:42 A solution to pthread_getattr_np on MacOS X and potentially others Steven Wu
2007-02-25 22:48 ` Kevin Ryde

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).