-
Notifications
You must be signed in to change notification settings - Fork 3.8k
[coop] mono_coop_cond_signal should switch to GC Safe thread state #9347
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
`mono_pmip` calls `get_method_from_ip` which needs to make a string with the name of a method. It used to call `mono_method_full_name` which is a `MONO_API` function and so tries to switch to GC Unsafe mode (which requires the thread to be attached). However `mono_pmip` is often used from GDB/LLDB and it might be invoked by the developer from a stopped thread that isn't currently attached which would assert. Instead call `mono_method_get_name_full` in `get_method_from_ip` which doesn't switch the thread state.
|
Does this fix Alpine and is it a better fix for the thread6/7 hang at shutdown? (see f3319f7) |
mono/utils/mono-coop-mutex.h
Outdated
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Modern style is one space after periods.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
And this seems reasonable even with less commentary -- "external functions can block" -- klnda just a blanket/blind good assumption. But ok.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We ought to know better, but I think there's an assumption that some of these pthread operations are primitive and will behave atomically. But yea we should just assume all external calls can block.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
While it isn't likely, it could be they haven't been called in a while, are paged out, and just calling them requires paging them in. Just crossing from one page of code to another, without even a call, can page fault and be slow. But we can't do much about that, except maybe page-align functions and keep them under page in size, limiting the fault to their start.
I call |
…ch to GC Safe Under Linux/glibc `pthread_cond_signal` and `pthread_cond_broadcast` can block on a futex in `__cond_quiesce_and_switch_g1`, so switch the thread to GC Safe mode around the blocking operation.
|
@lewurm As long as you're calling it from a thread that's attached to the runtime, it's fine. I accidentally called it from some random thread - a GC worker or something libtest.c created. |
|
Oh I guess nevermind, it's a sem_timedwait here: f3319f7#diff-ce0350ac89da817c904c38a837fc7b23L391 This still needs attention but it isn't related to your PR. Maybe the fix is around here, to not skip aborting when abort already requested.. |
…houldn't swith to GC Safe On Win32, still do the thread state change here; on other platforms its handled in the implementation of mono_w32handle_signal_and_wait
|
@monojenkins build failed |
…ono#9347) * [debug] mono_pmip shouldn't assume it's called from an attached thread `mono_pmip` calls `get_method_from_ip` which needs to make a string with the name of a method. It used to call `mono_method_full_name` which is a `MONO_API` function and so tries to switch to GC Unsafe mode (which requires the thread to be attached). However `mono_pmip` is often used from GDB/LLDB and it might be invoked by the developer from a stopped thread that isn't currently attached which would assert. Instead call `mono_method_get_name_full` in `get_method_from_ip` which doesn't switch the thread state. * [coop] mono_coop_cond_signal and mono_coop_cond_broadcast should switch to GC Safe Under Linux/glibc `pthread_cond_signal` and `pthread_cond_broadcast` can block on a futex in `__cond_quiesce_and_switch_g1`, so switch the thread to GC Safe mode around the blocking operation. * [coop] ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal shouldn't swith to GC Safe On Win32, still do the thread state change here; on other platforms its handled in the implementation of mono_w32handle_signal_and_wait
…ono/mono#9347) * [debug] mono_pmip shouldn't assume it's called from an attached thread `mono_pmip` calls `get_method_from_ip` which needs to make a string with the name of a method. It used to call `mono_method_full_name` which is a `MONO_API` function and so tries to switch to GC Unsafe mode (which requires the thread to be attached). However `mono_pmip` is often used from GDB/LLDB and it might be invoked by the developer from a stopped thread that isn't currently attached which would assert. Instead call `mono_method_get_name_full` in `get_method_from_ip` which doesn't switch the thread state. * [coop] mono_coop_cond_signal and mono_coop_cond_broadcast should switch to GC Safe Under Linux/glibc `pthread_cond_signal` and `pthread_cond_broadcast` can block on a futex in `__cond_quiesce_and_switch_g1`, so switch the thread to GC Safe mode around the blocking operation. * [coop] ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal shouldn't swith to GC Safe On Win32, still do the thread state change here; on other platforms its handled in the implementation of mono_w32handle_signal_and_wait Commit migrated from mono/mono@ebc98c0
mono_coop_cond_signalandmono_coop_cond_broadcastbecause at least on Linux/glibc the underlying implementation can block on a futex (specifically in__condvar_quiesce_and_switch_g1inglibc/ntpl/pthread_cond_common.c). If you'd like details:__condvar_quiesce_and_switch_g1(pthread_cond_common.c:341 on sourceware.org) it can block at (pthread_cond_common.c:412 on sourceware.org)mono_pmipwork again under coop and hybrid suspend inside GDB/LLDB (it used to callmono_method_full_namewhich would try to switch GC Unsafe thread state and then assert if the developer unwittingly called it from a thread that isn't currently attached).