Portable (??) pointer alignment

J

James Kuyper

On 04/20/2012 04:33 AM, Noob wrote:
....
malloc works within the framework of the /abstract/ machine. But there
is /real/ hardware behind this abstraction. (I did state I was leaving
the realm of standard C in the paragraph you snipped.)

To name a few reasons for "stricter" alignment than what malloc provides,
consider aligning on a cache line boundary for performance, or aligning
on a page boundary in virtual memory code, or satisfying the requirements
of the USB protocol in driver code.

If you need to address issues like that, portability is no longer an
option. The best you can do is choose a target set of platforms and
write code that works on all of the platforms in that set, but might not
work on platforms outside that set.
On the plus side, this gives you the freedom to use features that are
only available on those platforms, so long as those features are
available on all of the target platforms. The best place to get advice
about such things is a forum specific to those platforms; this is not
such a forum. In such a forum, you might learn that someone has already
addressed the issue you're dealing with.
 
E

Eric Sosman

Eric said:
Noob wrote:
[...]
An acceptable solution might be to provide
void *aligned_malloc(size_t boundary, size_t size)
{
assert(boundary> sizeof(void *));
assert((boundary& (boundary - 1)) == 0);
return aligned_malloc(boundary, size);

I hope you've got lots of stack space ...

I cannot understand why you would say that. An additional function
call within a short-lived call chain has no impact on the stack space
requirement. What am I missing?

recursion, n: see recursion.
Sir, my irony detector is at the repair shop this week, and I'm just
not getting what you wrote. Can you spell it out?

Time to send my reading comprehension to the same repair shop
as your irony detector. (Somehow I misread "C99" as "C90", a two-
bit error that made my response worth even less than two bits.)
 
N

Noob

Eric said:
recursion, n: see recursion.

Doh! I dropped a prefix along the way.
What I meant to write was:

void *safe_aligned_malloc(size_t boundary, size_t size)
{
assert(boundary > sizeof(void *));
assert((boundary & (boundary - 1)) == 0);
return aligned_malloc(boundary, size);
}

Although I'm not sure "safe" is the appropriate word.
 
E

Eric Sosman

I think this works:

x + ((x ^ (x-1))>> 1) + 1

Maps 5 => 6, 9 => 10, 10 => 12, 11 => 12, ...

Also maps 4 => 8, 8 => 16, ..., which satisfies "next power of 2"
but may not be what the O.P. desires.
 
J

Joe keane

What's the point of newp, especially since you never return the int you
declared? Why create a temporary variable when "old" is passed by value
and can be locally modified? Shouldn't those ints be unsigned?
Finally, why not let the compiler figure out if the 32-bit shift is
needed on the current implementation?

questions!

I don't really want a 'roundup' function.

Presumably that code is part of some bigger function which does a bunch
of other things, allocate memory, initialize data, and whatever. The
round up is a small detail. I just threw some crap around it so it's a
real function.

In fact i would write a macro:

#define ROUNDUP(OLD, NEW, T) \
((T) = (OLD) - 1, (T) |= (T) >> 1, (T) |= (T) >> 2, \
(T) |= (T) >> 4, (T) |= (T) >> 8, (T) |= (T) >> 16, \
(T) |= (T) >> 32, (NEW) = (T) + 1)

This is a cool 'template function' since it works for different types,
'short', 'size_t', 'unsigned long', or whatever. This also makes your
code clearer.

At first it seems like we don't have to worry if the size is less than
intended implied by the biggest shift; the extra steps are harmless and
will do nothing. I guess it's not legal. So really we have to make it
more complicated, unless we're just 'it works on -my- machine'.
 
R

Richard Damon

Maps 5 => 6, 9 => 10, 10 => 12, 11 => 12, ...

Also maps 4 => 8, 8 => 16, ..., which satisfies "next power of 2"
but may not be what the O.P. desires.

Yep, messed up my thinking, that formula finds the BOTTOM bit and moves
it up, need to think of how to get the TOP bit in the number.
 
T

Tim Rentsch

Gareth Owen said:
Barry Schwarz said:
On 4/18/2012 12:24 PM, Barry Schwarz wrote:
[...]
In the absence of a more sophisticated response:

if (boundary& boundary-1){

ITYM `boundary & (boundary - 1)'.

Since minus has higher precedence than and, what is the difference?

Clarity.

One requires the reader to recall the precedence rules, one does not.

One raises the question as to why the author felt it necessary to
include redundant parentheses, the other doesn't.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
474,079
Messages
2,570,574
Members
47,207
Latest member
HelenaCani

Latest Threads

Top