I am writing this post in reference to Atomic store. Structures
@Peter Cordes said:
What does it mean to lock? Especially, I know that lock is a prefix that ensures about atomicity of "prefixed" instruction.
Lock as in spinlock / mutex, not lock prefix. The lock prefix only ever works on read-modify-write instructions; there is no lock mov [mem], eax to do an atomic unaligned store or something. locked bus cycles are always read-modify-write, as documented by Intel in the docs for cmpxchg. So a lock mov store would also generate a load, which has different semantics if you use it on memory-mapped I/O. (A read can trigger side effects).
Ok, so I understand well. But, I cannot understand why it is copied ( stored) atomically. It could be a spinlock insted of a mutex but the situation is the same. A critical section is safe, I agree. But there is no certainty about atomic execution of that.
I add an example to explain what I mean:
struct S{
public:
int a, b, c, d, e;
};
std::mutex mut; // global
S s = {0}; // global
//From what I understand atomic store could looks like
//something similar to:
store(const S& src){
mut.lock();
S* dst = this->getPointerOfRawStructure(); // pseudocode
dst->a = src.a;
dst->b = src.b;
dst->c = src.c;
dst->d = src.d;
dst->e = src.e;
// I know that we can copy it in better ( faster ) way.
mut.unlock();
});
And now, let thread1 do:
std::atomic<S> as;
as.store(s);
Now, mutex is free, so thread1 succesfully call store.
Let thread2 do something like;
S* ptr = &s; // addres of global variable s declared before.
int ee = s->e;
And, let assume that `thread1` executed
dst->a = src.a;
dst->b = src.b;
dst->c = src.c;
And now thread2 executed: int ee = s->e; Thread2 sees old value of s->e though as.store() was started firstly and it should be executed in atomical way. ( The another thread cannot see a half-written variable, actually it sees).
So, I don't still understand how atomicity is ensured with lock ( spinlocks/mutex).
Aucun commentaire:
Enregistrer un commentaire