Corruption
Irrespective of the system [concurrent or truly parallel] the state of the memory depends on implementation of the memory device. Generally speaking, memory reads and writes are not atomic, which means it is possible that multiple concurrent accesses to the same memory address may return inconsistent results [ie data corruption].
Imagine two concurrent requests, 1 write, 1 read, of a simple integer value. Let's say an integer is 4 bytes. Let us also say, a read takes 2ns to execute, and a write takes 4ns to execute
- t0, Initial value of underlying 4 byte tuple, [0, 0, 0, 0]
- t1, Write op begins, write first byte [255, 0, 0, 0]
- t2, Write op continues, write second byte [255, 255, 0, 0]
- t2, Read op begins, reads first 2 bytes [255, 255, -, -]
- t3, Write op continues, write third byte [255, 255, 255, 0]
- t3, Read op ends, reads last 2 bytes [255, 255, 255, 0]
- t4, Write op ends, write fourth byte [255, 255, 255, 255]
The value returned by the read is neither the original nor the new value. The value is completely corrupted.
And what it means to you!
Admittedly, that is an incredibly simplified and contrived example, but what possible effect could this have in your scenario? In my opinion, the most vulnerable piece of your diagnostics system is the list of diagnostics data.
If your list is of fixed size, say an array of references to objects, at best you may lose whole objects as array elements are overwritten by competing threads, at worst you seg fault if the element contains a corrupted object reference [a la corruption scenario above].
If your list is dynamic, then it is possible underlying data structure becomes corrupted [if an array as in .Net List<>
when it is re-allocated, or if a linked list your next\prev references become lost or corrupted].
As an aside
Why isn't memory access atomic? For the same reason base collection implementations are not atomic - it would be too restrictive and introduce overhead, effectively penalizing simple scenarios. Therefore it is left to the consumer [us!] to synchronize our own memory accesses.