From 5f61ff41948d23b3c4f4c6194120fc659bb1d0af Mon Sep 17 00:00:00 2001 From: ivmai Date: Fri, 16 Apr 2010 10:36:59 +0000 Subject: [PATCH] 2010-04-16 Ivan Maidanski (mostly really Louis Zhuang) * os_dep.c (GC_get_stack_base, GC_get_main_stack_base): New Solaris-specific implementation (based on thr_stksegment). * os_dep.c (stackbase_main_self, stackbase_main_ss_sp): New static variable used by the Solaris-specific GC_get_stack_base(). --- ChangeLog | 7 ++++++ os_dep.c | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++- 2 files changed, 72 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index ed86a501..486c32fa 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,10 @@ +2010-04-16 Ivan Maidanski (mostly really Louis Zhuang) + + * os_dep.c (GC_get_stack_base, GC_get_main_stack_base): New + Solaris-specific implementation (based on thr_stksegment). + * os_dep.c (stackbase_main_self, stackbase_main_ss_sp): New static + variable used by the Solaris-specific GC_get_stack_base(). + 2010-04-16 Ivan Maidanski (mostly really NIIBE Yutaka) * pthread_support.c (GC_mark_thread_local_free_lists, diff --git a/os_dep.c b/os_dep.c index 5b2e8139..7ad5cf20 100644 --- a/os_dep.c +++ b/os_dep.c @@ -1140,7 +1140,8 @@ ptr_t GC_get_main_stack_base(void) #if !defined(BEOS) && !defined(AMIGA) && !defined(MSWIN32) \ && !defined(MSWINCE) && !defined(OS2) && !defined(NOSYS) && !defined(ECOS) \ - && !defined(CYGWIN32) && !defined(GC_OPENBSD_THREADS) + && !defined(CYGWIN32) && !defined(GC_OPENBSD_THREADS) \ + && (!defined(GC_SOLARIS_THREADS) || defined(_STRICT_STDC)) ptr_t GC_get_main_stack_base(void) { @@ -1306,6 +1307,69 @@ GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *b) #endif /* GC_OPENBSD_THREADS */ +#if defined(GC_SOLARIS_THREADS) && !defined(_STRICT_STDC) + +# include +# include +# include + + /* These variables are used to cache ss_sp value for the primordial */ + /* thread (it's better not to call thr_stksegment() twice for this */ + /* thread - see JDK bug #4352906). */ + static pthread_t stackbase_main_self = 0; + /* 0 means stackbase_main_ss_sp value is unset. */ + static void *stackbase_main_ss_sp = NULL; + + GC_API int GC_CALL GC_get_stack_base(struct GC_stack_base *b) + { + stack_t s; + pthread_t self = pthread_self(); + if (self == stackbase_main_self) + { + /* If the client calls GC_get_stack_base() from the main thread */ + /* then just return the cached value. */ + b -> mem_base = stackbase_main_ss_sp; + GC_ASSERT(b -> mem_base != NULL); + return GC_SUCCESS; + } + + if (thr_stksegment(&s)) { + /* According to the manual, the only failure error code returned */ + /* is EAGAIN meaning "the information is not available due to the */ + /* thread is not yet completely initialized or it is an internal */ + /* thread" - this shouldn't happen here. */ + ABORT("thr_stksegment failed"); + } + /* s.ss_sp holds the pointer to the stack bottom. */ + GC_ASSERT((void *)&s HOTTER_THAN s.ss_sp); + + if (!stackbase_main_self) + { + /* Cache the stack base value for the primordial thread (this */ + /* is done during GC_init, so there is no race). */ + stackbase_main_ss_sp = s.ss_sp; + stackbase_main_self = self; + } + + b -> mem_base = s.ss_sp; + return GC_SUCCESS; + } + +# define HAVE_GET_STACK_BASE + + /* This is always called from the main thread. The above */ + /* implementation of GC_get_stack_base() requires the latter to be */ + /* first called from GC_get_main_stack_base() (to cache the proper */ + /* ss_sp value). */ + ptr_t GC_get_main_stack_base(void) + { + struct GC_stack_base sb; + GC_get_stack_base(&sb); + return (ptr_t)sb.mem_base; + } + +#endif /* GC_SOLARIS_THREADS */ + #ifndef HAVE_GET_STACK_BASE /* Retrieve stack base. */ /* Using the GC_find_limit version is risky. */ -- 2.40.0