79739438

Date: 2025-08-19 04:16:58
Score: 1
Natty:
Report link

I run the stress test using the implementation of Android Bionic SystemProperties, and the original code did not pass the test.

But after I revise it to something like this:

// The contract with readers is that whenever the dirty bit is set, an undamaged copy
// of the pre-dirty value is available in the dirty backup area. The fence ensures
// that we publish our dirty area update before allowing readers to see a
// dirty serial.
memcpy(pa->dirty_backup_area(), pi->value, old_len + 1);
if (have_override) {
  memcpy(override_pa->dirty_backup_area(), override_pi->value, old_len + 1);
}

atomic_thread_fence(memory_order_release);

serial |= 1;
atomic_store_explicit(&pi->serial, serial, memory_order_relaxed);

atomic_thread_fence(memory_order_release);

strlcpy(pi->value, value, len + 1);
if (have_override) {
  atomic_store_explicit(&override_pi->serial, serial, memory_order_relaxed);
  strlcpy(override_pi->value, value, len + 1);
}

// Now the primary value property area is up-to-date. Let readers know that they should
// look at the property value instead of the backup area.
atomic_thread_fence(memory_order_release);
int new_serial = (len << 24) | ((serial + 1) & 0xffffff);
atomic_store_explicit(&pi->serial, new_serial, memory_order_relaxed);

then it'll pass the stress test, or we could merge the fence and store like @Peter Cordes suggested:

// ...

// Now the primary value property area is up-to-date. Let readers know that they should
// look at the property value instead of the backup area.
int new_serial = (len << 24) | ((serial + 1) & 0xffffff);
atomic_store_explicit(&pi->serial, new_serial, memory_order_release);

it'd also pass the stress test.

Reasons:
  • Long answer (-1):
  • Has code block (-0.5):
  • User mentioned (1): @Peter
  • Self-answer (0.5):
  • Low reputation (1):
Posted by: Kymdon