atomic fields
@mpiechotka
Submitted by Maciej Marcin Piechotka Link to original bug (#622336)
Description
Currently atomic fields are simulated by using volatile + atomic primitives (EDIT - I cannot make volatile working in vala and types are not updated in glib-2.0.vapi). There are 2 problems with this approach:
-
You can easily make error. For example:
volatile int i = 0; int j = i;
does not have to be atomic - on some platforms it needs additional memory barriers. Correct code would be:
volatile int i = 0;
int j = GLib.AtomicInt.get(i);
- volatile does specify (despite what many people think) atomicity. While it is needed in some cases AND atomic variables are volatile it would be good to separate the concepts.
It would be nice to have atomic keywork which would work as:
Vala --> C
atomic int i/atomic type *p/atomic classtype c --> volatile int i/volatile type *p/volatile classtype *c
i = 0 --> g_atomic_int_set(&i, 0)
int j = i --> int j = g_atomic_int_get(&i);
i += 3 --> g_atomic_int_add(&i, 3);
i.cas(0, 1) --> _atomic_int_compare_and_exchange(&i, 0, 1)
i++, ++i --> g_atomic_int_inc(&i) // If result unused
int j = i++ --> j = g_atomic_int_exchange_and_add(&i, 1)
int j = ++i --> j = g_atomic_int_exchange_and_add(&i, 1) + 1
(--i) --> g_atomic_int_dec_and_test(&i)
int j = i-- --> j = g_atomic_int_exchange_and_add(&i, -1)
int j = --j --> j = g_atomic_int_exchange_and_add(&i, 1) - 1
p = &x --> g_atomic_pointer_set(&p, &x);
type *r = p --> type *r = g_atomic_pointer_get(&p)
p.cas(p1, p2) --> g_atomic_pointer_compare_and_exchange(&p, p1, p2);
While not all operations can be rewritten it provides a large shortcut in writing.
Potential problems:
atomic int i = 0;
i = i + 2; // g_atomic_int_set(&i, g_atomic_int_get(&i) + 2);
i += 2; // g_atomic_int_add(&i, 2);
// Completly non-equivalent
However as atomic variables are 'hard' anyway I don't think it would be a great problem.