Skip to content

Commit

Permalink
Fix cast of struct-based pthread_t to void pointer on Win32
Browse files Browse the repository at this point in the history
`THREAD_ID_TO_VPTR()` should be applied only to values of `thread_id_t`
type.  Another macro (`PTHREAD_TO_VPTR()`) should be defined and used
for 'pthread_t' values (this matters only Win32 platform when
`pthreads-win32` library is used).

* include/private/pthread_support.h (THREAD_ID_TO_VPTR): Move
definition upper to be near definition of `thread_id_self()`.
* include/private/pthread_support.h [GC_WIN32_THREADS]
(THREAD_ID_TO_VPTR): Define to `CAST_THRU_UINTPTR(void*,id)` regardless
of `CYGWIN32`, `GC_WIN32_PTHREADS`, `GC_PTHREADS_PARAMARK` and
`__WINPTHREADS_VERSION_MAJOR`.
* include/private/pthread_support.h [!GC_WIN32_THREADS]
(THREAD_ID_TO_VPTR): Redirect to `PTHREAD_TO_VPTR()`.
* include/private/pthread_support.h [GC_PTHREADS
|| GC_PTHREADS_PARAMARK] (PTHREAD_TO_VPTR): Define (similarly as
`THREAD_ID_TO_VPTR()` was defined previously); add comment.
* pthread_start.c [GC_PTHREADS && !PLATFORM_THREADS && !SN_TARGET_PSP2
&& DEBUG_THREADS && !GC_PTHREAD_START_STANDALONE]
(GC_pthread_start_inner): Use `PTHREAD_TO_VPTR()` instead of
`THREAD_ID_TO_VPTR()` (for a value of `pthread_t`).
* pthread_support.c [GC_PTHREADS && !PLATFORM_THREADS
&& !SN_TARGET_PSP2 && DEBUG_THREADS] (GC_wrap_pthread_join,
GC_start_rtn_prepare_thread, GC_wrap_pthread_create): Likewise.
* pthread_support.c [GC_PTHREADS_PARAMARK && GC_ASSERTIONS
&& GC_WIN32_THREADS && !USE_PTHREAD_LOCKS] (NUMERIC_THREAD_ID):
Likewise.
* win32_threads.c [STACKPTR_CORRECTOR_AVAILABLE && GC_PTHREADS]
(GC_push_stack_for): Likewise.
* win32_threads.c [STACKPTR_CORRECTOR_AVAILABLE] (GC_push_stack_for):
Check `GC_PTHREADS`.
  • Loading branch information
ivmai committed Dec 26, 2024
1 parent 5e023e9 commit d8fccec
Show file tree
Hide file tree
Showing 4 changed files with 22 additions and 18 deletions.
23 changes: 14 additions & 9 deletions include/private/pthread_support.h
Original file line number Diff line number Diff line change
Expand Up @@ -139,10 +139,15 @@ typedef struct GC_StackContext_Rep {
typedef DWORD thread_id_t;
# define thread_id_self() GetCurrentThreadId()
# define THREAD_ID_EQUAL(id1, id2) ((id1) == (id2))
/* Convert a platform-specific thread id (of thread_id_t type) to */
/* some pointer identifying the thread. This is used mostly for */
/* a debugging purpose when printing thread id. */
# define THREAD_ID_TO_VPTR(id) CAST_THRU_UINTPTR(void *, id)
# else
typedef pthread_t thread_id_t;
# define thread_id_self() pthread_self()
# define THREAD_ID_EQUAL(id1, id2) THREAD_EQUAL(id1, id2)
# define THREAD_ID_TO_VPTR(id) PTHREAD_TO_VPTR(id)
# endif

typedef struct GC_Thread_Rep {
Expand Down Expand Up @@ -275,17 +280,17 @@ typedef struct GC_Thread_Rep {
# endif
} * GC_thread;

/* Convert a platform-specific thread id (of thread_id_t type) to */
/* some pointer identifying the thread. This is used mostly for */
/* a debugging purpose when printing thread id. */
# if defined(GC_WIN32_THREADS) && !defined(CYGWIN32) \
&& (defined(GC_WIN32_PTHREADS) || defined(GC_PTHREADS_PARAMARK)) \
&& !defined(__WINPTHREADS_VERSION_MAJOR)
# if defined(GC_PTHREADS) || defined(GC_PTHREADS_PARAMARK)
/* Convert an opaque pthread_t value to a pointer identifying the thread. */
# if defined(GC_WIN32_THREADS) && !defined(CYGWIN32) \
&& (defined(GC_WIN32_PTHREADS) || defined(GC_PTHREADS_PARAMARK)) \
&& !defined(__WINPTHREADS_VERSION_MAJOR)
/* Using documented internal details of pthreads-win32 library. */
/* pthread_t is a struct. */
# define THREAD_ID_TO_VPTR(id) ((void *)(id).p)
# else
# define THREAD_ID_TO_VPTR(id) CAST_THRU_UINTPTR(void *, id)
# define PTHREAD_TO_VPTR(id) ((void *)(id).p)
# else
# define PTHREAD_TO_VPTR(id) CAST_THRU_UINTPTR(void *, id)
# endif
# endif

# ifndef THREAD_TABLE_SZ
Expand Down
2 changes: 1 addition & 1 deletion pthread_start.c
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ GC_pthread_start_inner(struct GC_stack_base *sb, void *arg)
# endif
result = (*start)(start_arg);
# if defined(DEBUG_THREADS) && !defined(GC_PTHREAD_START_STANDALONE)
GC_log_printf("Finishing thread %p\n", THREAD_ID_TO_VPTR(pthread_self()));
GC_log_printf("Finishing thread %p\n", PTHREAD_TO_VPTR(pthread_self()));
# endif
me->status = result;
/* Note: we cannot use GC_dirty() instead. */
Expand Down
11 changes: 5 additions & 6 deletions pthread_support.c
Original file line number Diff line number Diff line change
Expand Up @@ -2532,7 +2532,7 @@ GC_wrap_pthread_join(pthread_t thread, void **retval)
INIT_REAL_SYMS();
# ifdef DEBUG_THREADS
GC_log_printf("thread %p is joining thread %p\n",
THREAD_ID_TO_VPTR(pthread_self()), THREAD_ID_TO_VPTR(thread));
PTHREAD_TO_VPTR(pthread_self()), PTHREAD_TO_VPTR(thread));
# endif

/* After the join, thread id may have been recycled. */
Expand Down Expand Up @@ -2570,7 +2570,7 @@ GC_wrap_pthread_join(pthread_t thread, void **retval)

# ifdef DEBUG_THREADS
GC_log_printf("thread %p join with thread %p %s\n",
THREAD_ID_TO_VPTR(pthread_self()), THREAD_ID_TO_VPTR(thread),
PTHREAD_TO_VPTR(pthread_self()), PTHREAD_TO_VPTR(thread),
result != 0 ? "failed" : "succeeded");
# endif
return result;
Expand Down Expand Up @@ -2624,7 +2624,7 @@ GC_start_rtn_prepare_thread(void *(**pstart)(void *), void **pstart_arg,

# ifdef DEBUG_THREADS
GC_log_printf("Starting thread %p, sp= %p\n",
THREAD_ID_TO_VPTR(pthread_self()), (void *)GC_approx_sp());
PTHREAD_TO_VPTR(pthread_self()), (void *)GC_approx_sp());
# endif
/* If a GC occurs before the thread is registered, that GC will */
/* ignore this thread. That's fine, since it will block trying to */
Expand Down Expand Up @@ -2749,7 +2749,7 @@ GC_wrap_pthread_create(pthread_t *new_thread,
# endif
# ifdef DEBUG_THREADS
GC_log_printf("About to start new thread from thread %p\n",
THREAD_ID_TO_VPTR(pthread_self()));
PTHREAD_TO_VPTR(pthread_self()));
# endif
set_need_to_lock();
result = REAL_FUNC(pthread_create)(new_thread, attr, GC_pthread_start, &si);
Expand Down Expand Up @@ -3004,8 +3004,7 @@ GC_lock(void)
# if defined(GC_ASSERTIONS) && defined(GC_WIN32_THREADS) \
&& !defined(USE_PTHREAD_LOCKS)
/* Note: result is not guaranteed to be unique. */
# define NUMERIC_THREAD_ID(id) \
((unsigned long)ADDR(THREAD_ID_TO_VPTR(id)))
# define NUMERIC_THREAD_ID(id) ((unsigned long)ADDR(PTHREAD_TO_VPTR(id)))
# endif

# ifdef GC_ASSERTIONS
Expand Down
4 changes: 2 additions & 2 deletions win32_threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -908,9 +908,9 @@ GC_push_stack_for(GC_thread thread, thread_id_t self_id, GC_bool *pfound_me)
}
# endif /* WOW64_THREAD_CONTEXT_WORKAROUND */
}
# ifdef STACKPTR_CORRECTOR_AVAILABLE
# if defined(STACKPTR_CORRECTOR_AVAILABLE) && defined(GC_PTHREADS)
if (GC_sp_corrector != 0)
GC_sp_corrector((void **)&sp, (void *)thread->pthread_id);
GC_sp_corrector((void **)&sp, PTHREAD_TO_VPTR(thread->pthread_id));
# endif

/* Set stack_min to the lowest address in the thread stack, */
Expand Down

0 comments on commit d8fccec

Please sign in to comment.