Skip to content

Commit

Permalink
[runtime] Get rid of SuspendThread()/ResumeThread(), integrate its fu…
Browse files Browse the repository at this point in the history
…nctionality into mono-thread-info.c.
  • Loading branch information
vargaz committed Jan 15, 2014
1 parent f18648d commit 791387f
Show file tree
Hide file tree
Showing 9 changed files with 56 additions and 100 deletions.
1 change: 0 additions & 1 deletion mono/io-layer/thread-private.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,6 @@ struct _WapiHandle_thread
* This also acts as a reference for the handle.
*/
gpointer wait_handle;
MonoSemType suspend_sem;
guint32 (*start_routine)(gpointer arg);
gpointer start_arg;
};
Expand Down
3 changes: 0 additions & 3 deletions mono/io-layer/threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,8 +45,6 @@ extern void ExitThread(guint32 exitcode) G_GNUC_NORETURN;
extern gboolean GetExitCodeThread(gpointer handle, guint32 *exitcode);
extern gsize GetCurrentThreadId(void); /* NB return is 32bit in MS API */
extern gpointer GetCurrentThread(void);
extern guint32 ResumeThread(gpointer handle);
extern guint32 SuspendThread(gpointer handle);
extern void Sleep(guint32 ms);
extern guint32 SleepEx(guint32 ms, gboolean alertable);
extern guint32 QueueUserAPC (WapiApcProc apc_callback, gpointer thread_handle,
Expand All @@ -70,7 +68,6 @@ void wapi_finish_interrupt_thread (gpointer wait_handle);
char* wapi_current_thread_desc (void);

gpointer wapi_create_thread_handle (void);
void wapi_thread_suspend (gpointer handle);
void wapi_thread_set_exit_code (guint32 exitstatus, gpointer handle);

G_END_DECLS
Expand Down
77 changes: 0 additions & 77 deletions mono/io-layer/wthreads.c
Original file line number Diff line number Diff line change
Expand Up @@ -165,7 +165,6 @@ void _wapi_thread_set_termination_details (gpointer handle,

thread_handle->exitstatus = exitstatus;
thread_handle->state = THREAD_STATE_EXITED;
MONO_SEM_DESTROY (&thread_handle->suspend_sem);
g_ptr_array_free (thread_handle->owned_mutexes, TRUE);

_wapi_handle_set_signal_state (handle, TRUE, TRUE);
Expand Down Expand Up @@ -241,32 +240,6 @@ static void thread_hash_init(void)
g_assert (thr_ret == 0);
}

static void _wapi_thread_suspend (struct _WapiHandle_thread *thread)
{
g_assert (pthread_equal (thread->id, pthread_self ()));

while (MONO_SEM_WAIT (&thread->suspend_sem) != 0 &&
errno == EINTR);
}

static void _wapi_thread_resume (struct _WapiHandle_thread *thread)
{
MONO_SEM_POST (&thread->suspend_sem);
}

void
wapi_thread_suspend (gpointer handle)
{
struct _WapiHandle_thread *thread;
int res;

res = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
(gpointer *)&thread);
g_assert (res);

_wapi_thread_suspend (thread);
}

/*
* wapi_create_thread_handle:
*
Expand Down Expand Up @@ -297,7 +270,6 @@ wapi_create_thread_handle (void)
(gpointer *)&thread);
g_assert (res);

MONO_SEM_INIT (&thread->suspend_sem, 0);
thread->handle = handle;

res = pthread_setspecific (thread_hash_key, handle);
Expand Down Expand Up @@ -536,10 +508,6 @@ static gpointer thread_attach(gsize *tid)
*/
_wapi_handle_ref (handle);

/* suspend_sem is not used for attached threads, but
* thread_exit() might try to destroy it
*/
MONO_SEM_INIT (&thread_handle_p->suspend_sem, 0);
thread_handle_p->handle = handle;
thread_handle_p->id = pthread_self ();

Expand Down Expand Up @@ -608,51 +576,6 @@ gpointer GetCurrentThread(void)
return(_WAPI_THREAD_CURRENT);
}

/**
* ResumeThread:
* @handle: the thread handle to resume
*
* Decrements the suspend count of thread @handle. A thread can only
* run if its suspend count is zero.
*
* Return value: the previous suspend count, or 0xFFFFFFFF on error.
*/
guint32 ResumeThread(gpointer handle)
{
struct _WapiHandle_thread *thread_handle;
gboolean ok;

ok = _wapi_lookup_handle (handle, WAPI_HANDLE_THREAD,
(gpointer *)&thread_handle);
if (ok == FALSE) {
g_warning ("%s: error looking up thread handle %p", __func__,
handle);

return (0xFFFFFFFF);
}

/* This is still a kludge that only copes with starting a
* thread that was suspended on create, so don't bother with
* the suspend count crap yet
*/
_wapi_thread_resume (thread_handle);
return(0xFFFFFFFF);
}

/**
* SuspendThread:
* @handle: the thread handle to suspend
*
* Increments the suspend count of thread @handle. A thread can only
* run if its suspend count is zero.
*
* Return value: the previous suspend count, or 0xFFFFFFFF on error.
*/
guint32 SuspendThread(gpointer handle)
{
return(0xFFFFFFFF);
}

/**
* SleepEx:
* @ms: The time in milliseconds to suspend for
Expand Down
17 changes: 4 additions & 13 deletions mono/metadata/appdomain.c
Original file line number Diff line number Diff line change
Expand Up @@ -2387,6 +2387,7 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
MonoAppDomainState prev_state;
MonoMethod *method;
unload_data *thread_data;
MonoNativeThreadId tid;
MonoDomain *caller_domain = mono_domain_get ();

/* printf ("UNLOAD STARTING FOR %s (%p) IN THREAD 0x%x.\n", domain->friendly_name, domain, GetCurrentThreadId ()); */
Expand Down Expand Up @@ -2436,20 +2437,10 @@ mono_domain_try_unload (MonoDomain *domain, MonoObject **exc)
* First we create a separate thread for unloading, since
* we might have to abort some threads, including the current one.
*/
/*
* If we create a non-suspended thread, the runtime will hang.
* See:
* http://bugzilla.ximian.com/show_bug.cgi?id=27663
*/
#if 0
thread_handle = mono_threads_create_thread (unload_thread_main, thread_data, 0, 0, NULL);
#else
thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, 0, CREATE_SUSPENDED, NULL);
if (thread_handle == NULL) {
thread_handle = mono_threads_create_thread ((LPTHREAD_START_ROUTINE)unload_thread_main, thread_data, 0, CREATE_SUSPENDED, &tid);
if (thread_handle == NULL)
return;
}
ResumeThread (thread_handle);
#endif
mono_thread_info_resume (tid);

/* Wait for the thread */
while (!thread_data->done && WaitForSingleObjectEx (thread_handle, INFINITE, TRUE) == WAIT_IO_COMPLETION) {
Expand Down
2 changes: 1 addition & 1 deletion mono/metadata/threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -757,7 +757,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, StartInfo *star
if (!handle_store (thread, FALSE))
return FALSE;

ResumeThread (internal->handle);
mono_thread_info_resume (tid);

if (internal->start_notify) {
/*
Expand Down
23 changes: 21 additions & 2 deletions mono/utils/mono-threads-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -66,13 +66,21 @@ inner_start_thread (void *arg)
info = mono_thread_info_attach (&result);
info->runtime_thread = TRUE;

if (flags & CREATE_SUSPENDED) {
info->create_suspended = TRUE;
MONO_SEM_INIT (&info->create_suspended_sem, 0);
}

/* start_info is not valid after this */
res = MONO_SEM_POST (&(start_info->registered));
g_assert (!res);
start_info = NULL;

if (flags & CREATE_SUSPENDED)
wapi_thread_suspend (handle);
if (flags & CREATE_SUSPENDED) {
while (MONO_SEM_WAIT (&info->create_suspended_sem) != 0 &&
errno == EINTR);
MONO_SEM_DESTROY (&info->create_suspended_sem);
}

/* Run the actual main function of the thread */
result = start_func (t_arg);
Expand Down Expand Up @@ -152,6 +160,17 @@ mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start_routine, gpointer
return start_info.handle;
}

/*
* mono_threads_core_resume_created:
*
* Resume a newly created thread created using CREATE_SUSPENDED.
*/
void
mono_threads_core_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid)
{
MONO_SEM_POST (&info->create_suspended_sem);
}

#if !defined (__MACH__)

#if !defined(__native_client__)
Expand Down
19 changes: 16 additions & 3 deletions mono/utils/mono-threads-windows.c
Original file line number Diff line number Diff line change
Expand Up @@ -82,14 +82,16 @@ inner_start_thread (LPVOID arg)
DWORD result;
gboolean suspend = start_info->suspend;
HANDLE suspend_event = start_info->suspend_event;
MonoThreadInfo *info;

mono_thread_info_attach (&result)->runtime_thread = TRUE;
info = mono_thread_info_attach (&result);
info->runtime_thread = TRUE;
info->create_suspended = suspend;

post_result = MONO_SEM_POST (&(start_info->registered));
g_assert (!post_result);

if (suspend)
{
if (suspend) {
WaitForSingleObject (suspend_event, INFINITE); /* caller will suspend the thread before setting the event. */
CloseHandle (suspend_event);
}
Expand Down Expand Up @@ -162,4 +164,15 @@ mono_native_thread_create (MonoNativeThreadId *tid, gpointer func, gpointer arg)
return CreateThread (NULL, 0, (func), (arg), 0, (tid)) != NULL;
}

void
mono_threads_core_resume_created (MonoThreadInfo *info, MonoNativeThreadId tid)
{
HANDLE handle;

handle = OpenThread (THREAD_ALL_ACCESS, TRUE, tid);
g_assert (handle);
ResumeThread (handle);
CloseHandle (handle);
}

#endif
8 changes: 8 additions & 0 deletions mono/utils/mono-threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -447,9 +447,17 @@ mono_thread_info_resume (MonoNativeThreadId tid)
gboolean result = TRUE;
MonoThreadHazardPointers *hp = mono_hazard_pointer_get ();
MonoThreadInfo *info = mono_thread_info_lookup (tid); /*info on HP1*/

if (!info)
return FALSE;

if (info->create_suspended) {
/* Have to special case this, as the normal suspend/resume pair are racy, they don't work if he resume is received before the suspend */
info->create_suspended = FALSE;
mono_threads_core_resume_created (info, tid);
return TRUE;
}

MONO_SEM_WAIT_UNITERRUPTIBLE (&info->suspend_semaphore);

THREADS_DEBUG ("resume %x IN COUNT %d\n",tid, info->suspend_count);
Expand Down
6 changes: 6 additions & 0 deletions mono/utils/mono-threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,11 @@ typedef struct {
* operations like locking without having to pass an 'async' parameter around.
*/
gboolean is_async_context;

gboolean create_suspended;

/* Semaphore used to implement CREATE_SUSPENDED */
MonoSemType create_suspended_sem;
} MonoThreadInfo;

typedef struct {
Expand Down Expand Up @@ -284,6 +289,7 @@ void mono_threads_core_interrupt (THREAD_INFO_TYPE *info) MONO_INTERNAL;
void mono_threads_core_abort_syscall (THREAD_INFO_TYPE *info) MONO_INTERNAL;
gboolean mono_threads_core_needs_abort_syscall (void) MONO_INTERNAL;
HANDLE mono_threads_core_create_thread (LPTHREAD_START_ROUTINE start, gpointer arg, guint32 stack_size, guint32 creation_flags, MonoNativeThreadId *out_tid) MONO_INTERNAL;
void mono_threads_core_resume_created (THREAD_INFO_TYPE *info, MonoNativeThreadId tid) MONO_INTERNAL;

MonoNativeThreadId mono_native_thread_id_get (void) MONO_INTERNAL;

Expand Down

0 comments on commit 791387f

Please sign in to comment.