Current-Users archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

Re: Stack alignment with pthreads



On Fri, Aug 29, 2008 at 11:10:31PM +0200, Anthony Mallet wrote:
> Mimicking this patch to our i386/makecontext() gives this:
>         sp  = (unsigned int *)((uintptr_t)sp & ~0x3); 
>         sp -= argc;                     /* Make room for args. */ 
>         sp  = (unsigned int *)((uintptr_t)sp & ~0xf); 
>         sp --;                                /* Make room for ret */
> 

This sounds reasonable, but I'll leave the decision to the x86 experts.

I did some checks with a slightly modified test program on various archs and
the results are clearly not clear. One could conclude that using aligned() on
automatic variables does not work, or if so, only by luck. Besides this, I
see some value to provide (at least) the same stack alignement to main and to
threads in itself, and as you see a few archs do that already.


Martin
#include <stdio.h>
#include <inttypes.h>
#include <stdbool.h>
#include <pthread.h>
#include <strings.h>

static void *
test16(void *data)
{
  int test __attribute__((aligned(16)));
  uintptr_t v = (uintptr_t)&test;
  size_t align;

  align = ffs((int)v);

  printf("aligned(16): %s: address: %p alignement: %d (2^%zu\n",
        align >= 4 ? "PASS" : "FAIL", &test, 1<<align, align);
  return NULL;
}
 
static void *
test32(void *data)
{
  int test __attribute__((aligned(32)));
  uintptr_t v = (uintptr_t)&test;
  size_t align;

  align = ffs((int)v);

  printf("aligned(32): %s: address: %p alignement: %d (2^%zu)\n",
        align >= 5 ? "PASS" : "FAIL", &test, 1<<align, align);
  return NULL;
}
 
static void *
test64(void *data)
{
  int test __attribute__((aligned(64)));
  uintptr_t v = (uintptr_t)&test;
  size_t align;

  align = ffs((int)v);

  printf("aligned(64): %s: address: %p alignement: %d (2^%zu)\n",
        align >= 6 ? "PASS" : "FAIL", &test, 1<<align, align);
  return NULL;
}
 
int
main()
{
  pthread_t tg;

  printf("Testing on main's stack:\n"); 
  test16(NULL);
  test32(NULL);
  test64(NULL);

  printf("Testing on thread's stack:\n"); 

  pthread_create(&tg, NULL, test16, NULL); 
  pthread_join(tg, NULL);

  pthread_create(&tg, NULL, test32, NULL); 
  pthread_join(tg, NULL);

  pthread_create(&tg, NULL, test64, NULL); 
  pthread_join(tg, NULL);

  return 0;
}

cc -Wall -O0 -o test -pthread test.c
uname -mp; ./test

alpha alpha
Testing on main's stack:
aligned(16): PASS: address: 0x1ffffd7f8 alignement: 16 (2^4
aligned(32): FAIL: address: 0x1ffffd7f8 alignement: 16 (2^4)
aligned(64): FAIL: address: 0x1ffffd7f8 alignement: 16 (2^4)
Testing on thread's stack:
aligned(16): PASS: address: 0x1605ffda0 alignement: 64 (2^6
aligned(32): PASS: address: 0x1605ffca0 alignement: 64 (2^6)
aligned(64): PASS: address: 0x1605ffba0 alignement: 64 (2^6)

shark arm
Testing on main's stack:
aligned(16): FAIL: address: 0xefffe85c alignement: 8 (2^3
aligned(32): FAIL: address: 0xefffe85c alignement: 8 (2^3)
aligned(64): FAIL: address: 0xefffe85c alignement: 8 (2^3)
Testing on thread's stack:
aligned(16): PASS: address: 0x22bfffd0 alignement: 32 (2^5
aligned(32): PASS: address: 0x22bfffd0 alignement: 32 (2^5)
aligned(64): FAIL: address: 0x22bfffd0 alignement: 32 (2^5)

i386 i386
Testing on main's stack:
aligned(16): PASS: address: 0xbfbfe7b0 alignement: 32 (2^5
aligned(32): PASS: address: 0xbfbfe7b0 alignement: 32 (2^5)
aligned(64): FAIL: address: 0xbfbfe7b0 alignement: 32 (2^5)
Testing on thread's stack:
aligned(16): FAIL: address: 0xbb7ffd94 alignement: 8 (2^3
aligned(32): FAIL: address: 0xbb7ffc94 alignement: 8 (2^3)
aligned(64): FAIL: address: 0xbb7ffb94 alignement: 8 (2^3)

amd64 x86_64
Testing on main's stack:
aligned(16): PASS: address: 0x7f7fffffdb40 alignement: 128 (2^7
aligned(32): PASS: address: 0x7f7fffffdb40 alignement: 128 (2^7)
aligned(64): PASS: address: 0x7f7fffffdb40 alignement: 128 (2^7)
Testing on thread's stack:
aligned(16): PASS: address: 0x7f7ffd7ffd90 alignement: 32 (2^5
aligned(32): PASS: address: 0x7f7ffd7ffc90 alignement: 32 (2^5)
aligned(64): FAIL: address: 0x7f7ffd7ffb90 alignement: 32 (2^5)

prep powerpc
Testing on main's stack:
aligned(16): PASS: address: 0xffffdd40 alignement: 128 (2^7
aligned(32): PASS: address: 0xffffdd40 alignement: 128 (2^7)
aligned(64): PASS: address: 0xffffdd40 alignement: 128 (2^7)
Testing on thread's stack:
aligned(16): PASS: address: 0xefbffd90 alignement: 32 (2^5
aligned(32): PASS: address: 0xefbffc90 alignement: 32 (2^5)
aligned(64): FAIL: address: 0xefbffb90 alignement: 32 (2^5)

sparc sparc
Testing on main's stack:
aligned(16): PASS: address: 0xefffec60 alignement: 64 (2^6
aligned(32): PASS: address: 0xefffec60 alignement: 64 (2^6)
aligned(64): PASS: address: 0xefffec60 alignement: 64 (2^6)
Testing on thread's stack:
aligned(16): PASS: address: 0x20fffd20 alignement: 64 (2^6
aligned(32): PASS: address: 0x20fffc20 alignement: 64 (2^6)
aligned(64): PASS: address: 0x20fffb20 alignement: 64 (2^6)

mac68k m68k
Testing on main's stack:
aligned(16): PASS: address: 0xffffb968 alignement: 16 (2^4
aligned(32): FAIL: address: 0xffffb968 alignement: 16 (2^4)
aligned(64): FAIL: address: 0xffffb968 alignement: 16 (2^4)
Testing on thread's stack:
aligned(16): PASS: address: 0x45ffdc0 alignement: 128 (2^7
aligned(32): PASS: address: 0x45ffcc0 alignement: 128 (2^7)
aligned(64): PASS: address: 0x45ffbc0 alignement: 128 (2^7)

sgimips mipseb
Testing on main's stack:
aligned(16): PASS: address: 0x7fffdd80 alignement: 256 (2^8
aligned(32): PASS: address: 0x7fffdd80 alignement: 256 (2^8)
aligned(64): PASS: address: 0x7fffdd80 alignement: 256 (2^8)
Testing on thread's stack:
aligned(16): PASS: address: 0x7dbffda0 alignement: 64 (2^6
aligned(32): PASS: address: 0x7dbffca0 alignement: 64 (2^6)
aligned(64): PASS: address: 0x7dbffba0 alignement: 64 (2^6)

sparc64 sparc64
Testing on main's stack:
aligned(16): PASS: address: 0xffffffffffffb9e0 alignement: 64 (2^6
aligned(32): PASS: address: 0xffffffffffffb9e0 alignement: 64 (2^6)
aligned(64): PASS: address: 0xffffffffffffb9e0 alignement: 64 (2^6)
Testing on thread's stack:
aligned(16): PASS: address: 0x40bffc60 alignement: 64 (2^6
aligned(32): PASS: address: 0x40bffb60 alignement: 64 (2^6)
aligned(64): PASS: address: 0x40bffa60 alignement: 64 (2^6)



Home | Main Index | Thread Index | Old Index