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