1
0
mirror of https://git.FreeBSD.org/src.git synced 2024-12-19 10:53:58 +00:00

Do not leak THR_FLAGS_SUSPENDED from the previous suspend/resume

cycle.  The flag currently is cleared by the resumed thread.  If next
suspend request comes before the thread was able to clean the flag, in
which case suspender skip the thread.

Instead, clear the THR_FLAGS_SUSPEND flag in resume_common(), we do
not care how much code was executed in the resumed thread when the
pthread_resume_*np(s) functions returned.

PR:	209233
Reported by:	Lawrence Esswood <le277@cam.ac.uk>
MFC after:	1 week
This commit is contained in:
Konstantin Belousov 2016-05-05 10:20:22 +00:00
parent 8a0fd1a7cd
commit 321e2a0090
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/head/; revision=299114
2 changed files with 2 additions and 4 deletions

View File

@ -91,7 +91,7 @@ static void
resume_common(struct pthread *thread)
{
/* Clear the suspend flag: */
thread->flags &= ~THR_FLAGS_NEED_SUSPEND;
thread->flags &= ~(THR_FLAGS_NEED_SUSPEND | THR_FLAGS_SUSPENDED);
thread->cycle++;
_thr_umtx_wake(&thread->cycle, 1, 0);
}

View File

@ -374,8 +374,7 @@ check_suspend(struct pthread *curthread)
*/
curthread->critical_count++;
THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
while ((curthread->flags & (THR_FLAGS_NEED_SUSPEND |
THR_FLAGS_SUSPENDED)) == THR_FLAGS_NEED_SUSPEND) {
while ((curthread->flags & THR_FLAGS_NEED_SUSPEND) != 0) {
curthread->cycle++;
cycle = curthread->cycle;
@ -392,7 +391,6 @@ check_suspend(struct pthread *curthread)
THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
_thr_umtx_wait_uint(&curthread->cycle, cycle, NULL, 0);
THR_UMUTEX_LOCK(curthread, &(curthread)->lock);
curthread->flags &= ~THR_FLAGS_SUSPENDED;
}
THR_UMUTEX_UNLOCK(curthread, &(curthread)->lock);
curthread->critical_count--;