On Sat, Dec 13, 2008 at 1:44 AM, Dave Thompson
<[email protected]> wrote:
> (getting rather offtopic now, so I've tried to keep it short)
[...]
>> unsigned int shift = wordsize - 1;
>> shift -= ((unsigned int)rawptr) % wordsize;
>>
> Sorry, that's worse. That makes (byte*)rawptr +shift _always_ misaligned.
Sigh. Verily. And truly so.
I should stop working on SQL databases, PHP crud and return to working
with real languages like C/C++ before I become a complete sack of
equine dung.
I'm very glad Vishnu included your fixes in his code.
> No, those are quite different. Assuming (as before) that wordsize
> is a power of two, thus only one bit set in binary, wordsize-1 is
> all the bits below it, and -wordsize is all the bits at and above it.
[...]
> ~wordsize is different, and unuseful here. 2sC -x is ~x PLUS ONE.
You are completely correct in this as well. And, yes, the ~ here is
stupid; am mixed up.
> To be exact, where ptr doesn't fit any (safely) available UNSIGNED integer
> type. That's a good point. Then my method needs to be more like:
> /* assumes common uchar,uint, obvious fixes otherwise */
> void* rawptr = malloc_or_whatever;
> uint good = ((uint)rawptr +wordsize-1) & -/*(uint)*/wordsize ;
> uchar* al_ptr = (uchar*)rawptr + (good -(uint)rawptr);
Okay, last try to make myself look like a total dunce.
What I was trying to attain was a 'correction offset', derived from
the originally unaligned pointer, and add that to the pointer (while
having it cast as a byte* pointer so offsets would be counted as
bytes).
In your code the offset is (good - (uint)rawptr).
I used a (slower) modulo operator, so the signed/unsigned type of the
final offset result isn't important as only the lowest bits will end
up in there due to unsigned intermediates. For power-of-2 wordsize the
modulo wordsize === bitwise-and (wordsize-1)
void* rawptr = malloc_or_whatever;
if (wordsize <= 0) goto err;
/*
uint offset = (((uint)wordsize) - ((uint)rawptr)) % wordsize;
or for power-of-2 wordsizes only:
*/
uint offset = (((uint)wordsize) - ((uint)rawptr)) & (wordsize - 1);
uchar* al_ptr = ((uchar*)rawptr) + offset;
take various unaligned pointer bit patterns and a wordsize of, for
this example, 4, and inspect edge cases to make sure I only screw up
at a grander scale now:
Dave
rawptr: (LSB hex; 64 bit) 0x1 FFFF FFFD
wordsize: 4
uint = 32 bits
good: (0xFFFFFFFD+4-1) & -4
= 0x00000000 & 0xFFFFFFFC
= 0x00000000
al_ptr 0x1FFFFFFFD + (0x00000000 - 0xFFFFFFFD)
= 0x1FFFFFFFD + 3
= 0x200000000
(at 32-bit pointer size, the pointer 'wraps around' to 0, which is,
then, correct)
Dave
rawptr: (LSB hex; 64 bit) 0x1 0000 0005
wordsize: 4
uint = 32 bits
good: (0x00000005+4-1) & -4
= 0x00000008 & 0xFFFFFFFC
= 0x00000008
al_ptr 0x100000005 + (0x00000008 - 0x00000005)
= 0x100000005 + 3
= 0x100000008
Ger (last produce above, after falling off the stairs)
rawptr: (LSB hex; 64 bit) 0x1 FFFF FFFD
wordsize: 4
uint = 32 bits
offset (4 - 0xFFFFFFFD) & (4 - 1)
= 0x00000007 & 0x00000003
= 0x00000003
al_ptr 0x1FFFFFFFD + 3
= 0x200000000
(same 'becomes 0' comment here for 32-bit pointers)
Ger
rawptr: (LSB hex; 64 bit) 0x1 0000 0005
wordsize: 4
uint = 32 bits
offset (4 - 0x00000005) & (4 - 1)
= 0xFFFFFFFF & 0x00000003
= 0x00000003
al_ptr 0x100000005 + 3
= 0x100000008
So both look okay now (instead of just one).
[unsigned] int wrap-around happens at different occasions for Dave's
vs. my code, but can occur in live situations for both.
> I hate ALL mornings. You may notice my posts are late in the day
> (in Eastern US winter = -0500 if that isn't obvious). <G>
And I am reconsidering Dave's comment about mornings - after all,
researchers have already found a few years ago that more intelligent
people get up later in the day and there I was, having quit the habit
of decades of getting up late (and working late), because some
(mentally challenged) people told me showing up early would improve my
work ethic. (read: make me dumb) Saved by the bell; they almost
succeeded. Don't ever try to wake me before 9 again, you <bleepards>.
> The other way that works mathematically (unsigned or 2sC) is:
[...]
> uint good = - (-(uint)rawptr & -uwordsize);
> uchar* al_ptr = (uchar*)rawptr +(good -(uint)rawptr);
> but now it's confusing AND inelegant.
But I kinda like it. It's got an odd sense of humor in it. :-)
Still, it's 6 ops, vs. minimum above 4 operations, with similar
clock-tick count per opcode.
--
Met vriendelijke groeten / Best regards,
Ger Hobbelt
--------------------------------------------------
web: http://www.hobbelt.com/
http://www.hebbut.net/
mail: [email protected]
mobile: +31-6-11 120 978
--------------------------------------------------
______________________________________________________________________
OpenSSL Project http://www.openssl.org
Development Mailing List [email protected]
Automated List Manager [email protected]