So I read that in a 32bit machine, one can use the CAS operation with aligned 64bit blocks.
Similarly, in a 64bit machine, one can use the CAS operation with aligned 128bit blocks.
I’m using a 32bit machine so I tried the following:
// sizeof(long long) is 8 bytes, so 64 bits
long long y = 12;
long long z = 12;
long long x = 99;
__sync_bool_compare_and_swap(&y, z, x);
and the CAS succeeded changing the value of y to 99.
But then I tried using a char array[8];(which size is 64 bits) instead of a long long. And I do:
char full[8] = {'0', '1', '2', '3', '4', '5', '6', '7'};
char full2[8] = {'0', '1', '2', '3', '4', '5', '6', '7'};
char full3[8] = {'5', '8', '9', 'G', 'X', '5', '6', 'U'};
__sync_bool_compare_and_swap(full, full2, full3);
But in this case, the CAS fails although full and full2 have exactly the same data. (I also checked that full and full2 where correctly alligned)
So the first time it seems that a CAS can be used to 64bit, but the second time it seems it can’t. Any ideas why?
EDIT
(How about 64bit machines?)
Ok, so the problem was that I was using char * in my CAS and these were only checked. So the solution was to cast to long long or to uint64_t which are 64bit values.
But what should I do with a 64bit machine when I need to use 128bit value? long long is still 64bit in a 64bit machine and uint128_t doesn’t seem to exist in C. So to which type should I cast? double long seems to be 128bit in my 64bit machine, but when doing the following:
double long y = 32432143243214;
double long z = 32432143243214;
int x = __sync_bool_compare_and_swap(&y, z, 1234321990);
I get this compile error
error: incompatible type for argument 1 of ‘__sync_bool_compare_and_swap’.
Looks like you forgot to deref your pointers and cast.
I tested and this is the only combination that is correct:
You need to cast the first param or it will only swap the first char.
Regarding handling 128-bit double long, this is from the gcc 4.1.2 docs.
So it would seem you cannot use this function to handle that case.