tk*********@gmail.com wrote:
Thanks Michael for the message -
It is actually a SIGBUS.
And I could not quite understand about the alignment and non-alignment
concept that you have written. Can you please elaborate, so that I
could check mNextWriteAdress is an aligned address or no-aligned?
Ok, as an example: lets assume aValue is a double and a double has a
sizeof(double) == 8. Let's assume further the Sparc has an alignment of
4 Bytes (the Sparcs I worked with had an alignment of 4 bytes, could be
different for yours...).
If you take the address of a double like
double d;
double* ptr = &d;
the ptr would (on this theoretical machine) be aligned to an 4 byte
boundary, this means the address must be divideable by 4 without
remainder (assuming this machine is a 32 Bit machine with 32 Bit
pointers and a long is 32 Bits) the following MUST hold:
(reinterpret_cast<unsigned long>(ptr) % 4) == 0
In your example
*reinterpret_cast< ValueType* >( mNextWriteAddress ) = aValue;
mNextWriteAddress could be anything, so the expression
(reinterpret_cast<unsigned long>( mNextWriteAddress) %8) could be != 0
which results in the SIGBUS.
Of course this is machine specific, so your Sparc might have a different
alignment.
You can imagine it like this:
Address Value
0x0000 0x11 0x22 0x33 0x44
0x0004 0x00 0x00 0x00 0x00
at 0x0000 there would be an aligned 32 Bit value 0x11223344 (let's
silently forget the byte order issues) and on 0x004 the value woudl be
0. Both values can be accessed with a normal 32-Bit instruction
In your example this could happen:
0x0000 0x00 0x11 0x22 0x33
0x0004 0x44 0x00 0x00 0x00
So the value 0x11223344 would start on address 0x0001 and not on 0x0000,
but the 32-Bit instruction cannot access 32 Bits from 0x0001.
On Intel machines, this is normally no problem, a Sparc is a little pickier.
The solution would be either use a different design, or make sure, that
mNextWriteAddress is aligned.
For example on a 4-Byte alignment (untested code!):
// convert to some pointer to byte-size
uint8_t* ptr = reinterpret_cast<uint8_t*>(mNextWriteAddress);
// align to 4 byte boundary
ptr += (ptr % 4 ? (4 - ptr % 4) : 0);
// set value
*reinterpret_cast< ValueType* >( ptr ) = aValue;
With this code you have to be sure that reading and writing is
synchronous, so you'll have to do the same on reading. And, since there
will be some bytes skipped, these should be initialised before (with
e.g. 0). And always be aware, that this is machine specific and not
fully portable!
lg,
Michael