8 byte alignment

Go To Last Post
16 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Guys, how do I align address to 8 bytes?

For example, how would I align the following:

 

// Allocate Memory for the Stack
	tcb->stack_allocation = (unsigned char *)safe_malloc(mpu_mem * sizeof(int));

EDITED: would this work?

	/* Align stack pointer.                                 */
	cpu_context = (unsigned int *)((unsigned int)(cpu_context) & 0xFFFFFFF8);

 

This topic has a solution.
Last Edited: Mon. Jul 13, 2020 - 06:21 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don''t know why you would want to do that.  What you could do is malloc 8 bytes.  Then search the byte addresses in that clump until you find an address that ends with 3 zeros.    In other words, any address that is xxxx...xxxx000 is on an 8 byte boundary.  Well, I think so but my old brain only knows 2 + 2 = 4 on a good day.

 

If you want to allocate an array that starts on an 8 byte boundary, allocate the size of the array + 8.  Then search the clump to find the first byte address that ends with .....000.

This reply has been marked as the solution. 
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or ignore the first (8 - address modulo 8) bytes. You might waste 8 bytes though.

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Rather than 'fixing' the problem after the fact, write a safe_malloc with a parameter for alignment. On a 32bit micro the default alignment should be 32bit anyways, so you're halfway there by default.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Kartman wrote:

Rather than 'fixing' the problem after the fact, write a safe_malloc with a parameter for alignment. On a 32bit micro the default alignment should be 32bit anyways, so you're halfway there by default.

 

I'll do that Kartman.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

 

Don't we need to know the toolchain and target first?

 

[I'll wager a virtual cold one that this is not an AVR target.  I wish we could all get together and collect all of those that have been won/lost over the years.]

 

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

 

 

Don't we need to know the toolchain and target first?

 

[I'll wager a virtual cold one that this is not an AVR target.  I wish we could all get together and collect all of those that have been won/lost over the years.]

 

 

 

cheeky it is still a simple c question.  target is not really of any importance. 

 

Wm.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Or implement this: https://man7.org/linux/man-pages...

The function posix_memalign() allocates size bytes and places the
       address of the allocated memory in *memptr.  The address of the
       allocated memory will be a multiple of alignment, which must be a
       power of two and a multiple of sizeof(void *).  If size is 0, then
       the value placed in *memptr is either NULL, or a unique pointer value
       that can later be successfully passed to free(3).
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Fianawarrior wrote:

Guys, how do I align address to 8 bytes?

 

First and foremost, you check `_Alignof(max_align_t)`. If the resultant value is 8 or greater than you don't need to do anything: pointers returned by `malloc` (or any other standard allocation function) are already guaranteed to be aligned on 8 byte boundary.

 

Otherwise, you will have to align the pointers yourself. Every time you `malloc` something you will have to request at least `8 - _Alignof(max_align_t)` more bytes than actually reqiured. And then you will have to shift the resultant pointer forward by at most `8 - _Alignof(max_align_t)` bytes to achieve the desired alignment.

 

You can reduce the allocation overhead by implementing your own aligned allocation pool on top of `malloc`.

 

Fianawarrior wrote:
it is still a simple c question

 

As a "simple C question" it has a simple C answer: starting from C11 you have 

 

    void *aligned_alloc(size_t alignment, size_t size);

 

in <stdlib.h> (http://port70.net/~nsz/c/c11/n1570.html#7.22.3.1), which takes care of everything (aside from possible overhead).

Dessine-moi un mouton

Last Edited: Sat. Jul 11, 2020 - 04:02 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So why do aligned_alloc() and posix_memalign() both require that the size allocated be a multiple of the alignment?

I ran into this recently contemplating dynamic allocation of a new exception table, which has to be aligned to the next-higher power-of-two from Nvectors*4.  On a SAMD51, alignment needs to be 1024 bytes (!) but it only needs 612 bytes or so.  That wastes 400-odd bytes, which grates...   I don't understand why I can't get a 612+overhead block aligned on the 1024 byte boundry plus an ~400byte block on the free list...

 

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

 

Fianawarrior wrote:

 

cheeky it is still a simple c question.  target is not really of any importance. 

 

 

 

C targets matter.

 

 

I hint, but this is the answer I get -- no mea culpa in sight.  We've gone down this road many times before; references upon request.  Yeah, yeah -- "I don't get no answers there."  Maybe if OP here would promote that forum it would get more activity. 

 

But the veterans here seem to support these inappropriate threads here by this poster with investigation and references.  Is it really a free-for-all?  I seem to recall various threads by various posters that were reported and moved in the past.  Oh, well, no matter I guess ... OP has gotten the research and answer so will smugly wait for the next time.

 

Remember that this is the same poster that scoffs at intellectual property laws.

 

You can put lipstick on a pig, but it is still a pig.

I've never met a pig I didn't like, as long as you have some salt and pepper.

Last Edited: Sat. Jul 11, 2020 - 11:46 AM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I like solution in #3.  I think this should do it, and you waste maybe 7 bytes: double *d = (malloc(size + 7)+7)&~7;

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

theusch wrote:

 

 

Fianawarrior wrote:

 

 

cheeky it is still a simple c question. 

 

 

C has  nothing to do with it. Addresses are addresses and 8 is still 8 whether you use a, b, c, c# cpp, d, e, f, cobol or assembler. 

 

This is somewhat appropriate here.  The USB on the Xmega requires the endpoint structs be on a 16 bit boundary.  I get memory the size of the struct + 1.  If the first address is even, the struct goes there.  I'll leave it to the reader to figure out where it goes if the first address is odd.  wink

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Lee has made a good point(s).

 

What target is the OP looking at, and toolchain? 

 

 

Jim

I would rather attempt something great and fail, than attempt nothing and succeed - Fortune Cookie

 

"The critical shortage here is not stuff, but time." - Johan Ekdahl

 

"Step N is required before you can do step N+1!" - ka7ehk

 

"If you want a career with a known path - become an undertaker. Dead people don't sue!" - Kartman

"Why is there a "Highway to Hell" and only a "Stairway to Heaven"? A prediction of the expected traffic load?"  - Lee "theusch"

 

Speak sweetly. It makes your words easier to digest when at a later date you have to eat them ;-)  - Source Unknown

Please Read: Code-of-Conduct

Atmel Studio6.2/AS7, DipTrace, Quartus, MPLAB, RSLogix user

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

He may have the latest Microchip chip.  I heard it has a 64 bit int.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0