Skip to content

Commit

Permalink
Avoid code duplication between pthread_support.c and win32_threads.c
Browse files Browse the repository at this point in the history
(refactoring)

* CMakeLists.txt [CMAKE_USE_PTHREADS_INIT
|| CMAKE_USE_WIN32_THREADS_INIT] (SRC): Include pthread_start.c and
pthread_support.c for Win32 platform.
* Makefile.am [THREADS] (libgc_la_SOURCES): Likewise.
* NT_MAKEFILE [ENABLE_STATIC] (OBJS): Add pthread_start.obj,
pthread_support.obj.
* include/private/gc_locks.h [LINT2 || GC_WIN32_THREADS]
(NO_PTHREAD_TRYLOCK): Do not define if already defined; add comment.
* include/private/gcconfig.h [GC_PTHREADS && !GC_PTHREADS_PARAMARK
&& !__MINGW32__] (GC_PTHREADS_PARAMARK): Do not define unless
PARALLEL_MARK.
* include/private/pthread_support.h (thread_id_self, THREAD_ID_EQUAL,
ADDR_LIMIT, MAX_MARKERS, GC_PTHREAD_PTRVAL): Define macro.
* include/private/pthread_support.h (GC_win32_dll_threads,
GC_available_markers_m1, GC_required_markers_cnt, GC_marker_sp,
GC_marker_last_stack_min, GC_marker_Id): Declare global variable.
* include/private/pthread_support.h (GC_init_win32_thread_naming,
GC_mark_thread, GC_new_thread, GC_record_stack_base,
GC_register_my_thread_inner, GC_lookup_by_pthread, GC_setup_atfork,
GC_win32_cache_self_pthread, GC_delete_gc_thread_no_free,
GC_win32_dll_lookup_thread, GC_delete_thread,
GC_win32_unprotect_thread, GC_wait_for_gc_completion): Declare.
* include/private/pthread_support.h [GC_PTHREADS]
(GC_pthread_start_inner, GC_start_rtn_prepare_thread): Declare even for
GC_WIN32_THREADS.
* misc.c [!THREADS] (GC_call_with_gc_active, GC_do_blocking_inner):
Update comment to refer to pthread_support.c.
* pthread_start.c [GC_PTHREADS] (GC_pthread_start_inner): Define even
for GC_WIN32_THREADS.
* pthread_support.c: Do not skip this file for GC_WIN32_THREADS;
adjust includes for Win32.
* pthread_support.c (GC_INNER_WIN32THREAD): New macro.
* pthread_support.c (GC_init_win32_thread_naming,
GC_win32_unprotect_thread): New function.
* pthread_support.c (setThreadDescription_fn, set_marker_thread_name):
Move from win32_threads.c.
* pthread_support.c (available_markers_m1): Rename to
GC_available_markers_m1.
* win32_threads.c (available_markers_m1): Likewise.
* pthread_support.c (required_markers_cnt): Rename to
GC_required_markers_cnt.
* win32_threads.c (required_markers_cnt): Likewise.
* pthread_support.c (GC_mark_thread, GC_start_mark_threads_inner,
GC_push_thread_structures, GC_count_threads, GC_new_thread,
GC_delete_thread, GC_delete_gc_thread_no_free, GC_lookup_thread,
GC_reset_finalizer_nested, GC_check_finalizer_nested,
GC_is_thread_tsd_valid, GC_thread_is_registered, GC_register_altstack,
GC_segment_is_thread_stack, GC_wait_for_gc_completion,
GC_remove_all_threads_but_me, fork_child_proc, GC_record_stack_base,
GC_init_parallel, GC_pthread_sigmask, GC_set_stackbottom,
GC_get_my_stackbottom, GC_call_with_gc_active, GC_unregister_my_thread,
GC_unregister_my_thread_inner, GC_thread_exit_proc, GC_pthread_join,
GC_pthread_detach, GC_pthread_sigmask, GC_pthread_create): Adjust
function for Win32.
* win32_threads.c (GC_lock_holder, GC_win32_dll_threads, IE_t,
GC_thr_initialized, GC_need_to_lock, ADDR_LIMIT, GC_thread,
GC_vthread, GC_threads, first_thread, GC_new_thread,
GC_in_thread_creation, GC_record_stack_base, GC_lookup_thread,
CHECK_LOOKUP_MY_THREAD, GC_reset_finalizer_nested,
GC_check_finalizer_nested, GC_is_thread_tsd_valid,
GC_thread_is_registered, GC_register_altstack, UNPROTECT_THREAD,
GC_PTHREAD_PTRVAL, GC_delete_gc_thread_no_free, GC_delete_thread,
GC_allow_register_threads, GC_register_my_thread, GC_set_stackbottom,
GC_wait_for_gc_completion, GC_unregister_my_thread,
GC_do_blocking_inner, GC_call_with_gc_active, GC_get_my_stackbottom,
GC_remove_all_threads_but_me, fork_prepare_proc, fork_parent_proc,
fork_child_proc, GC_atfork_prepare, GC_atfork_parent, GC_atfork_child,
GC_setup_atfork, GC_push_thread_structures, marker_sp,
set_marker_thread_name, setThreadDescription_fn, GC_mark_thread,
required_markers_cnt, GC_set_markers_count, START_MARK_THREADS,
start_info, GC_pthread_join, GC_pthread_create, GC_pthread_start_inner,
GC_pthread_start, GC_thread_exit_proc, GC_pthread_detach, GC_check_tls,
GC_init_parallel, GC_lock, GC_mark_thread_local_free_lists): Remove.
* win32_threads.c [GC_PTHREADS_PARAMARK] (mark_cv,
GC_start_mark_threads_inner, GC_mark_lock_holder, SET_MARK_LOCK_HOLDER,
UNSET_MARK_LOCK_HOLDER, mark_mutex, builder_cv, GC_acquire_mark_lock,
GC_release_mark_lock, GC_wait_builder, GC_wait_for_reclaim,
GC_notify_all_builder, GC_wait_marker, GC_notify_all_marker,
* win32_threads.c [GC_PTHREADS] (pthread_create, pthread_join,
pthread_detach, pthread_sigmask): Do not undefine.
* win32_threads.c [CAN_CALL_ATFORK]: Do not include unistd.h.
* win32_threads.c (GC_register_my_thread_inner): Change type of me
local variable from GC_vthread to GC_thread.
* win32_threads.c (GC_win32_dll_lookup_thread,
GC_win32_cache_self_pthread): New GC_INNER function.
* win32_threads.c (GC_suspend, GC_start_world, GC_push_stack_for): Use
GC_win32_unprotect_thread() instead of UNPROTECT_THREAD().
* win32_threads.c (marker_last_stack_min): Rename to
GC_marker_last_stack_min.
* win32_threads.c (GC_thr_init): Call GC_init_win32_thread_naming().
  • Loading branch information
ivmai committed Dec 6, 2022
1 parent 92ba441 commit bc1866b
Show file tree
Hide file tree
Showing 10 changed files with 1,281 additions and 2,192 deletions.
6 changes: 3 additions & 3 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -217,11 +217,10 @@ endif(enable_threads)

# Thread support detection.
if (CMAKE_USE_PTHREADS_INIT)
set(SRC ${SRC} gc_dlopen.c)
set(SRC ${SRC} gc_dlopen.c pthread_start.c pthread_support.c)
if (CYGWIN OR MSYS)
set(SRC ${SRC} win32_threads.c)
else()
set(SRC ${SRC} pthread_start.c pthread_support.c)
if (APPLE)
set(SRC ${SRC} darwin_stop_world.c)
else()
Expand Down Expand Up @@ -274,7 +273,8 @@ elseif (CMAKE_USE_WIN32_THREADS_INIT)
set(SRC ${SRC} thread_local_alloc.c)
endif()
add_definitions("-DEMPTY_GETENV_RESULTS")
set(SRC ${SRC} win32_threads.c)
set(SRC ${SRC} pthread_start.c) # in case client defines GC_WIN32_PTHREADS
set(SRC ${SRC} pthread_support.c win32_threads.c)
elseif (CMAKE_HP_PTHREADS_INIT OR CMAKE_USE_SPROC_INIT)
message(FATAL_ERROR "Unsupported thread package")
endif()
Expand Down
14 changes: 8 additions & 6 deletions Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -70,22 +70,24 @@ libgc_la_SOURCES = \
# C Library: Architecture Dependent
# ---------------------------------

if THREADS

libgc_la_SOURCES += pthread_start.c pthread_support.c

if THREAD_LOCAL_ALLOC
libgc_la_SOURCES += thread_local_alloc.c
endif

if WIN32_THREADS
libgc_la_SOURCES += win32_threads.c
else
if PTHREADS
# Not Cygwin or MinGW.
libgc_la_SOURCES += pthread_start.c pthread_support.c
if DARWIN_THREADS
libgc_la_SOURCES += darwin_stop_world.c
else
libgc_la_SOURCES += pthread_stop_world.c
endif
endif
endif

if THREAD_LOCAL_ALLOC
libgc_la_SOURCES += thread_local_alloc.c
endif

if MAKE_BACK_GRAPH
Expand Down
3 changes: 2 additions & 1 deletion NT_MAKEFILE
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,8 @@ AO_SRC_DIR=libatomic_ops/src
AO_INCLUDE_DIR=$(AO_SRC_DIR)

!IFDEF ENABLE_STATIC
OBJS= misc.obj win32_threads.obj alloc.obj reclaim.obj allchblk.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj fnlz_mlc.obj malloc.obj dyn_load.obj typd_mlc.obj ptr_chck.obj gcj_mlc.obj mallocx.obj extra\msvc_dbg.obj thread_local_alloc.obj
# pthread_start.obj is needed just in case client defines GC_WIN32_PTHREADS.
OBJS= misc.obj win32_threads.obj alloc.obj reclaim.obj allchblk.obj mach_dep.obj os_dep.obj mark_rts.obj headers.obj mark.obj obj_map.obj blacklst.obj finalize.obj new_hblk.obj dbg_mlc.obj fnlz_mlc.obj malloc.obj dyn_load.obj typd_mlc.obj ptr_chck.obj gcj_mlc.obj mallocx.obj extra\msvc_dbg.obj pthread_start.obj pthread_support.obj thread_local_alloc.obj
!ELSE
OBJS= extra\gc.obj extra\msvc_dbg.obj
!ENDIF
Expand Down
5 changes: 4 additions & 1 deletion include/private/gc_locks.h
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,10 @@
|| defined(LINT2)) && defined(GC_PTHREADS)
# define USE_PTHREAD_LOCKS
# undef USE_SPIN_LOCK
# if defined(LINT2) && !defined(NO_PTHREAD_TRYLOCK)
# if (defined(LINT2) || defined(GC_WIN32_THREADS)) \
&& !defined(NO_PTHREAD_TRYLOCK)
/* pthread_mutex_trylock may not win in GC_lock on Win32, */
/* due to builtin support for spinning first? */
# define NO_PTHREAD_TRYLOCK
# endif
# endif
Expand Down
6 changes: 4 additions & 2 deletions include/private/gcconfig.h
Original file line number Diff line number Diff line change
Expand Up @@ -2927,12 +2927,14 @@ EXTERN_C_BEGIN
# endif
#endif /* GC_WIN32_THREADS */

#if defined(GC_PTHREADS) && !defined(GC_PTHREADS_PARAMARK) \
&& !defined(__MINGW32__)
#if defined(PARALLEL_MARK) && defined(GC_PTHREADS) \
&& !defined(GC_PTHREADS_PARAMARK) && !defined(__MINGW32__)
/* Use pthread-based parallel mark implementation. */
/* Except for MinGW 32/64 to workaround a deadlock in */
/* winpthreads-3.0b internals. */
# define GC_PTHREADS_PARAMARK
#else
# undef GC_PTHREADS_PARAMARK /* just in case defined by client */
#endif

#ifndef GC_NO_THREADS_DISCOVERY
Expand Down
100 changes: 94 additions & 6 deletions include/private/pthread_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,12 @@ EXTERN_C_BEGIN

#ifdef GC_WIN32_THREADS
typedef DWORD thread_id_t;
# define thread_id_self() GetCurrentThreadId()
# define THREAD_ID_EQUAL(id1, id2) ((id1) == (id2))
#else
typedef pthread_t thread_id_t;
# define thread_id_self() pthread_self()
# define THREAD_ID_EQUAL(id1, id2) THREAD_EQUAL(id1, id2)
#endif

/* We use the allocation lock to protect thread-related data structures. */
Expand Down Expand Up @@ -106,6 +110,9 @@ typedef struct GC_Thread_Rep {
# endif
# ifndef GC_WIN32_THREADS
# define MAIN_THREAD 0x4 /* True for the original thread only. */
# endif
# if (defined(GC_HAVE_PTHREAD_EXIT) || !defined(GC_NO_PTHREAD_CANCEL)) \
&& defined(GC_PTHREADS)
# define DISABLED_GC 0x10 /* Collections are disabled while the */
/* thread is exiting. */
# endif
Expand Down Expand Up @@ -140,6 +147,7 @@ typedef struct GC_Thread_Rep {
ptr_t stack_ptr; /* Valid only in some platform-specific states. */

# ifdef GC_WIN32_THREADS
# define ADDR_LIMIT ((ptr_t)GC_WORD_MAX)
ptr_t last_stack_min; /* Last known minimum (hottest) address */
/* in stack or ADDR_LIMIT if unset. */
# ifdef I386
Expand Down Expand Up @@ -274,11 +282,95 @@ typedef struct GC_Thread_Rep {

GC_EXTERN GC_thread GC_threads[THREAD_TABLE_SZ];

#ifndef MAX_MARKERS
# define MAX_MARKERS 16
#endif

#ifdef GC_ASSERTIONS
GC_EXTERN GC_bool GC_thr_initialized;
#endif

#ifdef GC_WIN32_THREADS

# ifdef GC_NO_THREADS_DISCOVERY
# define GC_win32_dll_threads FALSE
# elif defined(GC_DISCOVER_TASK_THREADS)
# define GC_win32_dll_threads TRUE
# else
GC_EXTERN GC_bool GC_win32_dll_threads;
# endif

GC_EXTERN int GC_available_markers_m1;

# ifdef PARALLEL_MARK
GC_EXTERN unsigned GC_required_markers_cnt;
GC_EXTERN ptr_t GC_marker_sp[MAX_MARKERS - 1];
GC_EXTERN ptr_t GC_marker_last_stack_min[MAX_MARKERS - 1];
# ifndef GC_PTHREADS_PARAMARK
GC_EXTERN thread_id_t GC_marker_Id[MAX_MARKERS - 1];
# endif
# if !defined(HAVE_PTHREAD_SETNAME_NP_WITH_TID) && !defined(MSWINCE)
GC_INNER void GC_init_win32_thread_naming(HMODULE hK32);
# endif
# ifdef GC_PTHREADS_PARAMARK
GC_INNER void *GC_mark_thread(void *);
# elif defined(MSWINCE)
GC_INNER DWORD WINAPI GC_mark_thread(LPVOID);
# else
GC_INNER unsigned __stdcall GC_mark_thread(void *);
# endif
# endif /* PARALLEL_MARK */

GC_INNER GC_thread GC_new_thread(thread_id_t);
GC_INNER void GC_record_stack_base(GC_thread me,
const struct GC_stack_base *sb);
GC_INNER GC_thread GC_register_my_thread_inner(
const struct GC_stack_base *sb,
thread_id_t self_id);

# ifdef GC_PTHREADS
GC_INNER GC_thread GC_lookup_by_pthread(pthread_t);
GC_INNER void GC_win32_cache_self_pthread(thread_id_t);
# else
GC_INNER void GC_delete_gc_thread_no_free(GC_thread);
# endif

# ifdef CAN_HANDLE_FORK
GC_INNER void GC_setup_atfork(void);
# endif

# ifndef GC_NO_THREADS_DISCOVERY
GC_INNER GC_thread GC_win32_dll_lookup_thread(thread_id_t);
GC_INNER void GC_delete_thread(thread_id_t);
# endif

# ifdef MPROTECT_VDB
/* Make sure given thread descriptor is not protected by the VDB */
/* implementation. Used to prevent write faults when the world */
/* is (partially) stopped, since it may have been stopped with */
/* a system lock held, and that lock may be required for fault */
/* handling. */
GC_INNER void GC_win32_unprotect_thread(GC_thread);
# else
# define GC_win32_unprotect_thread(t) (void)(t)
# endif /* !MPROTECT_VDB */

#else
# define GC_win32_dll_threads FALSE
#endif /* !GC_WIN32_THREADS */

#ifdef GC_PTHREADS
# if defined(GC_WIN32_THREADS) && !defined(CYGWIN32) \
&& (defined(GC_WIN32_PTHREADS) || defined(GC_PTHREADS_PARAMARK)) \
&& !defined(__WINPTHREADS_VERSION_MAJOR)
# define GC_PTHREAD_PTRVAL(pthread_id) pthread_id.p
# else
# define GC_PTHREAD_PTRVAL(pthread_id) pthread_id
# endif
#endif /* GC_PTHREADS */

GC_INNER GC_thread GC_lookup_thread(thread_id_t);
GC_INNER void GC_wait_for_gc_completion(GC_bool);

#ifdef NACL
GC_EXTERN __thread GC_thread GC_nacl_gc_thread_self;
Expand Down Expand Up @@ -306,17 +398,13 @@ GC_INNER GC_thread GC_lookup_thread(thread_id_t);
# define GC_INNER_PTHRSTART GC_INNER
# endif

# ifndef GC_WIN32_THREADS
GC_INNER_PTHRSTART void *GC_CALLBACK GC_pthread_start_inner(
GC_INNER_PTHRSTART void *GC_CALLBACK GC_pthread_start_inner(
struct GC_stack_base *sb, void *arg);
GC_INNER_PTHRSTART GC_thread GC_start_rtn_prepare_thread(
GC_INNER_PTHRSTART GC_thread GC_start_rtn_prepare_thread(
void *(**pstart)(void *),
void **pstart_arg,
struct GC_stack_base *sb, void *arg);
# endif

GC_INNER_PTHRSTART void GC_thread_exit_proc(void *);

#endif /* GC_PTHREADS */

#ifdef GC_DARWIN_THREADS
Expand Down
4 changes: 2 additions & 2 deletions misc.c
Original file line number Diff line number Diff line change
Expand Up @@ -2199,7 +2199,7 @@ GC_INNER ptr_t GC_blocked_sp = NULL;

GC_INNER struct GC_traced_stack_sect_s *GC_traced_stack_sect = NULL;

/* This is nearly the same as in win32_threads.c */
/* This is nearly the same as in pthread_support.c. */
GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn,
void * client_data)
{
Expand Down Expand Up @@ -2250,7 +2250,7 @@ GC_API void * GC_CALL GC_call_with_gc_active(GC_fn_type fn,
return client_data; /* result */
}

/* This is nearly the same as in win32_threads.c */
/* This is nearly the same as in pthread_support.c. */
STATIC void GC_do_blocking_inner(ptr_t data, void *context)
{
struct blocking_data * d = (struct blocking_data *)data;
Expand Down
7 changes: 4 additions & 3 deletions pthread_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@

#include "private/pthread_support.h"

#if defined(GC_PTHREADS) && !defined(GC_WIN32_THREADS) \
#if defined(GC_PTHREADS) \
&& !defined(SN_TARGET_ORBIS) && !defined(SN_TARGET_PSP2)

/* Invoked from GC_pthread_start. */
Expand All @@ -50,11 +50,12 @@ GC_INNER_PTHRSTART void *GC_CALLBACK GC_pthread_start_inner(
GC_start_rtn_prepare_thread(&start, &start_arg, sb, arg);

# ifndef NACL
pthread_cleanup_push(GC_thread_exit_proc, me);
pthread_cleanup_push(GC_thread_exit_proc, (void *)me);
# endif
result = (*start)(start_arg);
# if defined(DEBUG_THREADS) && !defined(GC_PTHREAD_START_STANDALONE)
GC_log_printf("Finishing thread %p\n", (void *)pthread_self());
GC_log_printf("Finishing thread %p\n",
(void *)GC_PTHREAD_PTRVAL(pthread_self()));
# endif
me -> status = result;
GC_end_stubborn_change(me); /* cannot use GC_dirty */
Expand Down
Loading

0 comments on commit bc1866b

Please sign in to comment.