Merge pull request #23963 from matoro/main

Replace __sync intrinsics with __atomic
This commit is contained in:
Lennart Poettering
2022-07-21 00:10:01 +02:00
committed by GitHub
7 changed files with 99 additions and 45 deletions

View File

@@ -1147,7 +1147,7 @@ void reset_cached_pid(void) {
pid_t getpid_cached(void) {
static bool installed = false;
pid_t current_value;
pid_t current_value = CACHED_PID_UNSET;
/* getpid_cached() is much like getpid(), but caches the value in local memory, to avoid having to invoke a
* system call each time. This restores glibc behaviour from before 2.24, when getpid() was unconditionally
@@ -1158,7 +1158,13 @@ pid_t getpid_cached(void) {
* https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c579f48edba88380635ab98cb612030e3ed8691e
*/
current_value = __sync_val_compare_and_swap(&cached_pid, CACHED_PID_UNSET, CACHED_PID_BUSY);
__atomic_compare_exchange_n(
&cached_pid,
&current_value,
CACHED_PID_BUSY,
false,
__ATOMIC_SEQ_CST,
__ATOMIC_SEQ_CST);
switch (current_value) {

View File

@@ -28,24 +28,31 @@ static void sigbus_push(void *addr) {
assert(addr);
/* Find a free place, increase the number of entries and leave, if we can */
for (size_t u = 0; u < SIGBUS_QUEUE_MAX; u++)
if (__sync_bool_compare_and_swap(&sigbus_queue[u], NULL, addr)) {
__sync_fetch_and_add(&n_sigbus_queue, 1);
for (size_t u = 0; u < SIGBUS_QUEUE_MAX; u++) {
/* OK to initialize this here since we haven't started the atomic ops yet */
void *tmp = NULL;
if (__atomic_compare_exchange_n(&sigbus_queue[u], &tmp, addr, false,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
__atomic_fetch_add(&n_sigbus_queue, 1, __ATOMIC_SEQ_CST);
return;
}
}
/* If we can't, make sure the queue size is out of bounds, to
* mark it as overflow */
for (;;) {
unsigned c;
sig_atomic_t c;
__sync_synchronize();
__atomic_thread_fence(__ATOMIC_SEQ_CST);
c = n_sigbus_queue;
if (c > SIGBUS_QUEUE_MAX) /* already overflow */
return;
if (__sync_bool_compare_and_swap(&n_sigbus_queue, c, c + SIGBUS_QUEUE_MAX))
/* OK if we clobber c here, since we either immediately return
* or it will be immediately reinitialized on next loop */
if (__atomic_compare_exchange_n(&n_sigbus_queue, &c, c + SIGBUS_QUEUE_MAX, false,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST))
return;
}
}
@@ -56,7 +63,7 @@ int sigbus_pop(void **ret) {
for (;;) {
unsigned u, c;
__sync_synchronize();
__atomic_thread_fence(__ATOMIC_SEQ_CST);
c = n_sigbus_queue;
if (_likely_(c == 0))
@@ -72,8 +79,13 @@ int sigbus_pop(void **ret) {
if (!addr)
continue;
if (__sync_bool_compare_and_swap(&sigbus_queue[u], addr, NULL)) {
__sync_fetch_and_sub(&n_sigbus_queue, 1);
/* OK if we clobber addr here, since we either immediately return
* or it will be immediately reinitialized on next loop */
if (__atomic_compare_exchange_n(&sigbus_queue[u], &addr, NULL, false,
__ATOMIC_SEQ_CST, __ATOMIC_SEQ_CST)) {
__atomic_fetch_sub(&n_sigbus_queue, 1, __ATOMIC_SEQ_CST);
/* If we successfully entered this if condition, addr won't
* have been modified since its assignment, so safe to use it */
*ret = addr;
return 1;
}