-2011-03-07 Ivan Maidanski
+2011-03-07 Ivan Maidanski <ivmai@mail.ru>
+
+ * dyn_load.c (GC_MUST_RESTORE_REDEFINED_DLOPEN): Test
+ GC_NO_DLOPEN.
+ * gc_dlopen.c: Ditto.
+ * include/gc_pthread_redirects.h (GC_dlopen, dlopen): Ditto.
+ * gc_dlopen.c: Don't include dlfcn.h (as it is included in
+ gc_pthread_redirects.h).
+ * pthread_support.c (pthread_sigmask, GC_pthread_sigmask_t,
+ GC_pthread_sigmask): Test GC_NO_PTHREAD_SIGMASK (instead of
+ GC_DARWIN_THREADS, GC_OPENBSD_THREADS and NACL).
+ * include/gc_pthread_redirects.h (GC_pthread_sigmask,
+ pthread_sigmask): Ditto.
+ * win32_threads.c (pthread_sigmask, GC_pthread_sigmask): Test
+ GC_NO_PTHREAD_SIGMASK (instead of GC_WIN32_PTHREADS); reformat the
+ comment.
+ * pthread_support.c (pthread_create, GC_pthread_create_t,
+ GC_pthread_create): Rename GC_PTHREAD_CONST to
+ GC_PTHREAD_CREATE_CONST.
+ * win32_threads.c (GC_pthread_create): Ditto.
+ * include/gc_pthread_redirects.h: Ditto.
+ * include/gc_pthread_redirects.h (GC_NO_DLOPEN,
+ GC_NO_PTHREAD_SIGMASK): New macro defined.
+ * include/gc_pthread_redirects.h (GC_PTHREAD_CREATE_CONST): Set to
+ empty for NaCl.
+ * include/gc_pthread_redirects.h (GC_PTHREAD_EXIT_ATTRIBUTE): Do
+ not define for Android (as CANCEL_SAFE is not defined).
+
+2011-03-07 Ivan Maidanski <ivmai@mail.ru>
* include/gc.h (GC_ADD_CALLER, GC_RETURN_ADDR,
GC_HAVE_BUILTIN_BACKTRACE, GC_CAN_SAVE_CALL_STACKS): Move
#endif
/* BTL: avoid circular redefinition of dlopen if GC_SOLARIS_THREADS defined */
-# undef GC_MUST_RESTORE_REDEFINED_DLOPEN
-# if (defined(GC_PTHREADS) || defined(GC_SOLARIS_THREADS)) \
- && defined(dlopen) && !defined(GC_USE_LD_WRAP)
- /* To support threads in Solaris, gc.h interposes on dlopen by */
- /* defining "dlopen" to be "GC_dlopen", which is implemented below. */
- /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */
- /* real system dlopen() in their implementation. We first remove */
- /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
-# undef dlopen
-# define GC_MUST_RESTORE_REDEFINED_DLOPEN
-# endif
+#undef GC_MUST_RESTORE_REDEFINED_DLOPEN
+#if defined(GC_PTHREADS) && !defined(GC_NO_DLOPEN) \
+ && !defined(GC_NO_THREAD_REDIRECTS) && !defined(GC_USE_LD_WRAP)
+ /* To support threads in Solaris, gc.h interposes on dlopen by */
+ /* defining "dlopen" to be "GC_dlopen", which is implemented below. */
+ /* However, both GC_FirstDLOpenedLinkMap() and GC_dlopen() use the */
+ /* real system dlopen() in their implementation. We first remove */
+ /* gc.h's dlopen definition and restore it later, after GC_dlopen(). */
+# undef dlopen
+# define GC_MUST_RESTORE_REDEFINED_DLOPEN
+#endif /* !GC_NO_DLOPEN */
/* A user-supplied routine (custom filter) that might be called to */
/* determine whether a DSO really needs to be scanned by the GC. */
/* file to avoid having to link against libdl.{a,so} if the client */
/* doesn't call dlopen. Of course this fails if the collector is in */
/* a dynamic library. -HB */
-
-#if defined(GC_PTHREADS) && !defined(GC_DARWIN_THREADS) \
- && !defined(GC_WIN32_PTHREADS) && !defined(NACL)
+#if defined(GC_PTHREADS) && !defined(GC_NO_DLOPEN)
#undef GC_MUST_RESTORE_REDEFINED_DLOPEN
#if defined(dlopen) && !defined(GC_USE_LD_WRAP)
/* GC_register_dynamic_libraries. Should probably happen for */
/* other operating systems, too. */
-#include <dlfcn.h>
-
/* This is similar to WRAP/REAL_FUNC() in pthread_support.c. */
#ifdef GC_USE_LD_WRAP
# define WRAP_DLFUNC(f) __wrap_##f
# define dlopen GC_dlopen
#endif
-#endif /* GC_PTHREADS */
+#endif /* GC_PTHREADS && !GC_NO_DLOPEN */
#include <pthread.h>
-#if !defined(GC_DARWIN_THREADS) && !defined(GC_WIN32_PTHREADS) \
- && !defined(__native_client__)
-# include <signal.h>
-# include <dlfcn.h>
+#if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
+ || defined(__native_client__)) && !defined(GC_NO_DLOPEN)
+ /* Either there is no dlopen() or we do not need to intercept it. */
+# define GC_NO_DLOPEN
+#endif
-# ifndef GC_OPENBSD_THREADS
- GC_API int GC_pthread_sigmask(int /* how */, const sigset_t *,
- sigset_t * /* oset */);
-# endif
+#if (defined(GC_DARWIN_THREADS) || defined(GC_WIN32_PTHREADS) \
+ || defined(GC_OPENBSD_THREADS) || defined(__native_client__)) \
+ && !defined(GC_NO_PTHREAD_SIGMASK)
+ /* Either there is no pthread_sigmask() or no need to intercept it. */
+# define GC_NO_PTHREAD_SIGMASK
+#endif
+
+#if defined(__native_client__) && !defined(GC_PTHREAD_CREATE_CONST)
+ /* At present, NaCl pthread_create() prototype does not have "const" */
+ /* for "attr" argument. */
+# define GC_PTHREAD_CREATE_CONST /* empty */
+#endif
+
+#ifndef GC_NO_DLOPEN
+# include <dlfcn.h>
GC_API void *GC_dlopen(const char * /* path */, int /* mode */);
-#endif /* !GC_DARWIN_THREADS */
+#endif /* !GC_NO_DLOPEN */
+
+#ifndef GC_NO_PTHREAD_SIGMASK
+# include <signal.h>
+ GC_API int GC_pthread_sigmask(int /* how */, const sigset_t *,
+ sigset_t * /* oset */);
+#endif /* !GC_NO_PTHREAD_SIGMASK */
-#ifndef GC_PTHREAD_CONST
-# define GC_PTHREAD_CONST const
+#ifndef GC_PTHREAD_CREATE_CONST
+ /* This is used for pthread_create() only. */
+# define GC_PTHREAD_CREATE_CONST const
#endif
-GC_API int GC_pthread_create(pthread_t *, GC_PTHREAD_CONST pthread_attr_t *,
+GC_API int GC_pthread_create(pthread_t *,
+ GC_PTHREAD_CREATE_CONST pthread_attr_t *,
void *(*)(void *), void * /* arg */);
GC_API int GC_pthread_join(pthread_t, void ** /* retval */);
GC_API int GC_pthread_detach(pthread_t);
-#if !defined(GC_PTHREAD_EXIT_ATTRIBUTE) \
+#if !defined(GC_PTHREAD_EXIT_ATTRIBUTE) && !defined(PLATFORM_ANDROID) \
&& (defined(GC_LINUX_THREADS) || defined(GC_SOLARIS_THREADS))
/* Intercept pthread_cancel and pthread_exit on Linux and Solaris. */
# if defined(__GNUC__) /* since GCC v2.7 */
# define pthread_join GC_pthread_join
# define pthread_detach GC_pthread_detach
-# if !defined(GC_DARWIN_THREADS) && !defined(GC_WIN32_PTHREADS) \
- && !defined(__native_client__)
-# ifndef GC_OPENBSD_THREADS
-# undef pthread_sigmask
-# define pthread_sigmask GC_pthread_sigmask
-# endif
+# ifndef GC_NO_PTHREAD_SIGMASK
+# undef pthread_sigmask
+# define pthread_sigmask GC_pthread_sigmask
+# endif
+
+# ifndef GC_NO_DLOPEN
# undef dlopen
# define dlopen GC_dlopen
# endif
/* Undefine macros used to redirect pthread primitives. */
# undef pthread_create
-# if !defined(GC_DARWIN_THREADS) && !defined(GC_OPENBSD_THREADS) \
- && !defined(NACL)
+# ifndef GC_NO_PTHREAD_SIGMASK
# undef pthread_sigmask
# endif
# ifdef GC_PTHREAD_EXIT_ATTRIBUTE
# define WRAP_FUNC(f) __wrap_##f
# define REAL_FUNC(f) __real_##f
int REAL_FUNC(pthread_create)(pthread_t *,
- GC_PTHREAD_CONST pthread_attr_t *,
+ GC_PTHREAD_CREATE_CONST pthread_attr_t *,
void *(*start_routine)(void *), void *);
int REAL_FUNC(pthread_join)(pthread_t, void **);
int REAL_FUNC(pthread_detach)(pthread_t);
-# if !defined(GC_DARWIN_THREADS) && !defined(GC_OPENBSD_THREADS) \
- && !defined(NACL)
+# ifndef GC_NO_PTHREAD_SIGMASK
int REAL_FUNC(pthread_sigmask)(int, const sigset_t *, sigset_t *);
# endif
# ifdef GC_PTHREAD_EXIT_ATTRIBUTE
/* included gc.h, wich redefined f to GC_f. */
/* FIXME: Needs work for DARWIN and True64 (OSF1) */
typedef int (* GC_pthread_create_t)(pthread_t *,
- GC_PTHREAD_CONST pthread_attr_t *,
- void * (*)(void *), void *);
+ GC_PTHREAD_CREATE_CONST pthread_attr_t *,
+ void * (*)(void *), void *);
static GC_pthread_create_t REAL_FUNC(pthread_create);
- typedef int (* GC_pthread_sigmask_t)(int, const sigset_t *, sigset_t *);
- static GC_pthread_sigmask_t REAL_FUNC(pthread_sigmask);
+# ifndef GC_NO_PTHREAD_SIGMASK
+ typedef int (* GC_pthread_sigmask_t)(int, const sigset_t *,
+ sigset_t *);
+ static GC_pthread_sigmask_t REAL_FUNC(pthread_sigmask);
+# endif
typedef int (* GC_pthread_join_t)(pthread_t, void **);
static GC_pthread_join_t REAL_FUNC(pthread_join);
typedef int (* GC_pthread_detach_t)(pthread_t);
/* be intercepted. This allows files which include gc.h, and hence */
/* generate references to the GC_ symbols, to see the right symbols. */
GC_API int GC_pthread_create(pthread_t * t,
- GC_PTHREAD_CONST pthread_attr_t * a,
+ GC_PTHREAD_CREATE_CONST pthread_attr_t *a,
void * (* fn)(void *), void * arg)
{
return pthread_create(t, a, fn, arg);
}
- GC_API int GC_pthread_sigmask(int how, const sigset_t *mask,
- sigset_t *old)
- {
+# ifndef GC_NO_PTHREAD_SIGMASK
+ GC_API int GC_pthread_sigmask(int how, const sigset_t *mask,
+ sigset_t *old)
+ {
return pthread_sigmask(how, mask, old);
- }
+ }
+# endif /* !GC_NO_PTHREAD_SIGMASK */
GC_API int GC_pthread_join(pthread_t t, void **res)
{
ABORT("pthread_create not found"
" (probably -lgc is specified after -lpthread)");
# endif
- REAL_FUNC(pthread_sigmask) = (GC_pthread_sigmask_t)
+# ifndef GC_NO_PTHREAD_SIGMASK
+ REAL_FUNC(pthread_sigmask) = (GC_pthread_sigmask_t)
dlsym(dl_handle, "pthread_sigmask");
+# endif
REAL_FUNC(pthread_join) = (GC_pthread_join_t)
dlsym(dl_handle, "pthread_join");
REAL_FUNC(pthread_detach) = (GC_pthread_detach_t)
# endif
}
-#if !defined(GC_DARWIN_THREADS) && !defined(GC_OPENBSD_THREADS) \
- && !defined(NACL)
+#ifndef GC_NO_PTHREAD_SIGMASK
GC_API int WRAP_FUNC(pthread_sigmask)(int how, const sigset_t *set,
sigset_t *oset)
{
}
return(REAL_FUNC(pthread_sigmask)(how, set, oset));
}
-#endif /* !GC_DARWIN_THREADS && !GC_OPENBSD_THREADS && !NACL */
+#endif /* !GC_NO_PTHREAD_SIGMASK */
#if defined(GC_DARWIN_THREADS) && !defined(DARWIN_DONT_PARSE_STACK)
GC_INNER ptr_t GC_FindTopOfStack(unsigned long);
}
GC_API int WRAP_FUNC(pthread_create)(pthread_t *new_thread,
- GC_PTHREAD_CONST pthread_attr_t *attr,
+ GC_PTHREAD_CREATE_CONST pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg)
{
int result;
/* Cygwin-specific forward decls */
# undef pthread_create
-# undef pthread_sigmask
# undef pthread_join
# undef pthread_detach
+# ifndef GC_NO_PTHREAD_SIGMASK
+# undef pthread_sigmask
+# endif
+
# ifdef DEBUG_THREADS
# ifdef CYGWIN32
# define DEBUG_CYGWIN_THREADS 1
/* Cygwin-pthreads calls CreateThread internally, but it's not easily */
/* interceptible by us..., so intercept pthread_create instead. */
GC_API int GC_pthread_create(pthread_t *new_thread,
- GC_PTHREAD_CONST pthread_attr_t *attr,
+ GC_PTHREAD_CREATE_CONST pthread_attr_t *attr,
void *(*start_routine)(void *), void *arg)
{
if (!parallel_initialized) GC_init_parallel();
UNLOCK();
}
-# ifndef GC_WIN32_PTHREADS
- /* win32 pthread does not support sigmask */
- /* nothing required here... */
+# ifndef GC_NO_PTHREAD_SIGMASK
+ /* Win32 pthread does not support sigmask. */
+ /* So, nothing required here... */
GC_API int GC_pthread_sigmask(int how, const sigset_t *set,
sigset_t *oset)
{
if (!parallel_initialized) GC_init_parallel();
return pthread_sigmask(how, set, oset);
}
-# endif
+# endif /* !GC_NO_PTHREAD_SIGMASK */
GC_API int GC_pthread_detach(pthread_t thread)
{