atomicity (again)

38 views
Skip to first unread message

sch...@gmail.com

unread,
Nov 20, 2017, 7:26:18 AM11/20/17
to pmem
Dear all,

I wanted to ask about the atomicity of non-flush data. In the following example, the first assignment is flushed. However, there is a power failure before the second flush.

alignas(64) uint64_t foo = std::numeric_limits<uint64_t>::min();
// flush
foo = std::numeric_limits<uint64_t>::max();
// power failure
// flush


Is there a guarantee, that either min() or max() and nothing else was persisted? Is it possible, that a mix of both was persisted, i.e. individual bytes but not the whole 8 bytes made it to the persistence domain?

The real question is about packed structs of size 8 bytes. I want to use the committed flag to indicate that the data fields are valid. With appropriate casting, I can make updates as 8 byte writes. Would this approach work?

struct __attribute__((__packed__)) metadata {
  bool committed:1;
  unsigned data1:32;
  unsigned data2:31;
};

Thanks,
  Thorsten

Andy Rudoff

unread,
Nov 20, 2017, 9:47:18 AM11/20/17
to pmem
Hi Thorsten,

Here's my take:  If the assignments happen as 8-byte aligned stores, like I think you're showing in your example code, then after a reboot in your scenario you'll have either the entire 8-bytes from the first assignment, or the entire 8-bytes from the second assignment, but not a mix.

Of course, if you define the packed struct as you said and do assignments to the individual fields, then a cache eviction could happen between any two assignments and you could get partial results persisted.  But the way you described it where the assignment is a single aligned 8-byte store, you should get the atomicity you're looking for.

-andy

sch...@gmail.com

unread,
Nov 20, 2017, 10:20:23 AM11/20/17
to pmem
Thanks Andy, this helps a lot.

Thorsten
Reply all
Reply to author
Forward
0 new messages