Boost logo

Boost :

From: scleary_at_[hidden]
Date: 2001-05-03 09:15:07


> A cursory search of boost has not yielded information
> I need on how to create a maximally aligned integer.
>
> Specifically, given a positive integer n, I need to find
> an integer m, such that p+m is maximally aligned, where
> p is maximally aligned.

As John Maddock said, I don't think it's possible to find this value
directly.

> This calculation is required for ALL code which suballocates
> memory for indeterminate types. My particular problem is
> a garbage collector, which chains allocated blocks together:
> the pointers of the chain are stored in a 'block header'
> before the address returned to the user. I need to know
> how big to make that header.

What I used to guarantee Pool alignment was a side-stepping of this issue,
so I didn't have to calculate the "maximally aligned integer"; what I
actually use is an integer type that guarantees alignment only for a few
well-defined types (the user-specified allocation size, a pointer for the
free list, and std::size_t for the block sizes) -- not *any* type. For
details, see:
  http://www.boost.org/libs/pool/doc/implementation/alignment.html

But note that my solution is able to side-step this issue because Pool
doesn't keep *any* information about allocated chunks. Your problem can use
a similar solution, but only if you go to a footer instead of a header,
which requires you to store additional data in the footer (size of block or
pointer to block) -- but if you already wanted to store this data, then the
following would be ok:

class allocated_chain
{
  private:
    void * list;

  public:
    void * allocate(std::size_t size)
    {
      const std::size_t size_usable_by_process = lcm(sizeof(void *), size);
      const std::size_t size_to_allocate = size_usable_by_process +
2*sizeof(void *);
      char * const block = new char[size_to_allocate];
      // The Standard mandates that "block" is aligned for *any* type T
where
      // sizeof(T) <= size_to_allocate
      // Also, note that "block + size_usable_by_process" is aligned for
"void *"

      // Each block contains a pointer to itself
      char * const block_ptr_in_block = block + size_usable_by_process;
      *((void **) block_ptr_in_block) = block;

      // And a pointer into the next block
      char * const next_ptr_in_block = block_ptr_in_block + sizeof(void *);
      *((void **) next_ptr_in_block) = list;
      list = (void *) next_ptr_in_block;

      return (void *) block;
    }
};

If you don't want that overhead, you'll have to guess at the maximally
aligned integer, using what John suggested. AFAICT, those are your only
options.

        -Steve


Boost list run by bdawes at acm.org, gregod at cs.rpi.edu, cpdaniel at pacbell.net, john at johnmaddock.co.uk