On Sat, Dec 13, 2008 at 1:44 AM, Dave Thompson
<dave.thomp...@princetonpayments.com> 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:   g...@hobbelt.com
mobile: +31-6-11 120 978
--------------------------------------------------
______________________________________________________________________
OpenSSL Project                                 http://www.openssl.org
Development Mailing List                       openssl-dev@openssl.org
Automated List Manager                           majord...@openssl.org

Reply via email to