diff options
author | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2020-03-31 17:24:39 -0300 |
---|---|---|
committer | Adhemerval Zanella <adhemerval.zanella@linaro.org> | 2021-06-09 15:16:45 -0300 |
commit | 8c1c0aae2079039a629b15098d78f3d11aabefb4 (patch) | |
tree | 72a4a714ee7310810a0d2a5778e6b5c40f18fa85 /nptl/cancellation.c | |
parent | 2b5174253155bdace1262ea2ab53d11347ecdefd (diff) | |
download | glibc-8c1c0aae2079039a629b15098d78f3d11aabefb4.tar.gz glibc-8c1c0aae2079039a629b15098d78f3d11aabefb4.tar.xz glibc-8c1c0aae2079039a629b15098d78f3d11aabefb4.zip |
nptl: Move cancel type out of cancelhandling
Now that the thread cancellation type is not accessed concurrently anymore, it is possible to move it out the cancelhandling. By removing the cancel state out of the internal thread cancel handling state there is no need to check if cancelled bit was set in CAS operation. It allows simplifing the cancellation wrappers and the CANCEL_CANCELED_AND_ASYNCHRONOUS is removed. Checked on x86_64-linux-gnu and aarch64-linux-gnu.
Diffstat (limited to 'nptl/cancellation.c')
-rw-r--r-- | nptl/cancellation.c | 51 |
1 files changed, 12 insertions, 39 deletions
diff --git a/nptl/cancellation.c b/nptl/cancellation.c index ce00603109..05962784d5 100644 --- a/nptl/cancellation.c +++ b/nptl/cancellation.c @@ -31,31 +31,19 @@ int __pthread_enable_asynccancel (void) { struct pthread *self = THREAD_SELF; - int oldval = THREAD_GETMEM (self, cancelhandling); - while (1) - { - int newval = oldval | CANCELTYPE_BITMASK; - - if (newval == oldval) - break; - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, - oldval); - if (__glibc_likely (curval == oldval)) - { - if (self->cancelstate == PTHREAD_CANCEL_ENABLE - && CANCEL_CANCELED_AND_ASYNCHRONOUS (newval)) - { - THREAD_SETMEM (self, result, PTHREAD_CANCELED); - __do_cancel (); - } + int oldval = THREAD_GETMEM (self, canceltype); + THREAD_SETMEM (self, canceltype, PTHREAD_CANCEL_ASYNCHRONOUS); - break; - } + int ch = THREAD_GETMEM (self, cancelhandling); - /* Prepare the next round. */ - oldval = curval; + if (self->cancelstate == PTHREAD_CANCEL_ENABLE + && (ch & CANCELED_BITMASK) + && !(ch & EXITING_BITMASK) + && !(ch & TERMINATED_BITMASK)) + { + THREAD_SETMEM (self, result, PTHREAD_CANCELED); + __do_cancel (); } return oldval; @@ -69,25 +57,10 @@ __pthread_disable_asynccancel (int oldtype) { /* If asynchronous cancellation was enabled before we do not have anything to do. */ - if (oldtype & CANCELTYPE_BITMASK) + if (oldtype == PTHREAD_CANCEL_ASYNCHRONOUS) return; struct pthread *self = THREAD_SELF; - int newval; - - int oldval = THREAD_GETMEM (self, cancelhandling); - - while (1) - { - newval = oldval & ~CANCELTYPE_BITMASK; - - int curval = THREAD_ATOMIC_CMPXCHG_VAL (self, cancelhandling, newval, - oldval); - if (__glibc_likely (curval == oldval)) - break; - - /* Prepare the next round. */ - oldval = curval; - } + self->canceltype = PTHREAD_CANCEL_DEFERRED; } libc_hidden_def (__pthread_disable_asynccancel) |