Imported Upstream version 5.14.0.78

Former-commit-id: 3494343bcc9ddb42b36b82dd9ae7b69e85e0229f
This commit is contained in:
Xamarin Public Jenkins (auto-signing)
2018-05-10 08:37:03 +00:00
parent 74b74abd9f
commit 19234507ba
1776 changed files with 67755 additions and 31107 deletions

View File

@@ -396,7 +396,8 @@ GC_bool GC_register_main_static_data()
# if (defined(LINUX) || defined (__GLIBC__) || defined(NACL)) /* Are others OK here, too? */ \
&& (__GLIBC__ > 2 || (__GLIBC__ == 2 && __GLIBC_MINOR__ > 2) \
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG)))
|| (__GLIBC__ == 2 && __GLIBC_MINOR__ == 2 && defined(DT_CONFIG))) \
|| defined(OPENBSD)
/* We have the header files for a glibc that includes dl_iterate_phdr. */
/* It may still not be available in the library on the target system. */

View File

@@ -835,6 +835,18 @@ typedef GC_PTR (*GC_fn_type) GC_PROTO((GC_PTR client_data));
GC_API GC_PTR GC_call_with_alloc_lock
GC_PROTO((GC_fn_type fn, GC_PTR client_data));
/*
* These are similar to GC_do_blocking () in upstream bdwgc. The design is
* simpler in that there is no distinction between active and inactive stack
* frames; instead, while a thread is in blocking state, it promises to not
* interact with the GC at all, and to not keep any pointers to GC memory
* around from before entering blocking state. Additionally, these can be
* called unbalanced (they simply set a flag internally).
*/
GC_API void GC_start_blocking GC_PROTO((void));
GC_API void GC_end_blocking GC_PROTO((void));
/* The following routines are primarily intended for use with a */
/* preprocessor which inserts calls to check C pointer arithmetic. */
/* They indicate failure by invoking the corresponding _print_proc. */

View File

@@ -1245,7 +1245,6 @@ void GC_start_blocking(void) {
GC_thread me;
LOCK();
me = GC_lookup_thread(pthread_self());
GC_ASSERT(!(me -> thread_blocked));
# ifdef SPARC
me -> stop_info.stack_ptr = (ptr_t)GC_save_regs_in_stack();
# else
@@ -1273,7 +1272,6 @@ void GC_end_blocking(void) {
GC_thread me;
LOCK(); /* This will block if the world is stopped. */
me = GC_lookup_thread(pthread_self());
GC_ASSERT(me -> thread_blocked);
me -> thread_blocked = FALSE;
UNLOCK();
}

View File

@@ -48,6 +48,7 @@ struct GC_thread_Rep {
/* 0 ==> entry not valid. */
/* !in_use ==> stack_base == 0 */
GC_bool suspended;
GC_bool thread_blocked;
# ifdef CYGWIN32
void *status; /* hold exit value until join in case it's a pointer */
@@ -174,6 +175,7 @@ static GC_thread GC_new_thread(void) {
/* the world, wait here. Hopefully this can't happen on any */
/* systems that don't allow us to block here. */
while (GC_please_stop) Sleep(20);
GC_ASSERT(!thread_table[i]->thread_blocked);
return thread_table + i;
}
@@ -223,7 +225,6 @@ static void GC_delete_thread(DWORD thread_id) {
}
}
#ifdef CYGWIN32
/* Return a GC_thread corresponding to a given pthread_t. */
@@ -245,6 +246,20 @@ static GC_thread GC_lookup_thread(pthread_t id)
return thread_table + i;
}
#else
static GC_thread GC_lookup_thread(DWORD id)
{
int i;
LONG max = GC_get_max_thread_index();
for (i = 0; i <= max; i++)
if (thread_table[i].in_use && thread_table[i].id == id)
return &thread_table[i];
return NULL;
}
#endif /* CYGWIN32 */
void GC_push_thread_structures GC_PROTO((void))
@@ -264,6 +279,35 @@ void GC_push_thread_structures GC_PROTO((void))
# endif
}
/* Wrappers for functions that are likely to block for an appreciable */
/* length of time. Must be called in pairs, if at all. */
/* Nothing much beyond the system call itself should be executed */
/* between these. */
void GC_start_blocking(void) {
GC_thread me;
LOCK();
#ifdef CYGWIN32
me = GC_lookup_thread(pthread_self());
#else
me = GC_lookup_thread(GetCurrentThreadId());
#endif
me->thread_blocked = TRUE;
UNLOCK();
}
void GC_end_blocking(void) {
GC_thread me;
LOCK(); /* This will block if the world is stopped. */
#ifdef CYGWIN32
me = GC_lookup_thread(pthread_self());
#else
me = GC_lookup_thread(GetCurrentThreadId());
#endif
me->thread_blocked = FALSE;
UNLOCK();
}
/* Defined in misc.c */
extern CRITICAL_SECTION GC_write_cs;
@@ -281,6 +325,8 @@ void GC_stop_world()
for (i = 0; i <= GC_get_max_thread_index(); i++)
if (thread_table[i].stack_base != 0
&& thread_table[i].id != thread_id) {
if (thread_table [i].thread_blocked)
continue;
# ifdef MSWINCE
/* SuspendThread will fail if thread is running kernel code */
while (SuspendThread(thread_table[i].handle) == (DWORD)-1)