Jeremy Friesner
Jeremy Friesner

Reputation: 73041

Why is pthread_attr_setstacksize() not working for me?

I noticed just now that when I spawn a thread using pthread_create(), my request for setting a custom stack size for the thread seems to be ignored. In particular, if I call pthread_attr_getstacksize() from within the spawned thread, it always reports the default stack size, regardless of what I had asked for.

This behavior is seen under both Linux and MacOS/X, so I suspect that I am doing something wrong, but I don't know what it is.

To reproduce the problem, compile and run the code below (via "g++ stack_test.cpp -lpthread ; ./a.out"). It tries a bunch of different stack sizes and complains if its requests aren't honored. The problematic output looks like this:

Jeremys-Mini:~ lcsuser1$ ./a.out 
Testing creation of a thread with stack size:  8192
ThreadFunc:  ERROR, wrong stack size!  (Requested:  8192, got: 524288)
Testing creation of a thread with stack size:  16384
ThreadFunc:  ERROR, wrong stack size!  (Requested:  16384, got: 524288)
Testing creation of a thread with stack size:  24576
ThreadFunc:  ERROR, wrong stack size!  (Requested:  24576, got: 524288)
[...]
Testing creation of a thread with stack size:  8372224
ThreadFunc:  ERROR, wrong stack size!  (Requested:  8372224, got: 524288)
Testing creation of a thread with stack size:  8380416
ThreadFunc:  ERROR, wrong stack size!  (Requested:  8380416, got: 524288)

... and here is the code:

#include <stdio.h>
#include <pthread.h>

static void * ThreadFunc(void * pDesiredStackSize)
{
   const size_t desiredStackSize = *((size_t *)pDesiredStackSize);

   pthread_attr_t tattr;
   if (pthread_attr_init(&tattr) == 0)
   {
      size_t actualStackSize;
      if (pthread_attr_getstacksize(&tattr, &actualStackSize) == 0)
      {
         if (actualStackSize == desiredStackSize)
         {
            printf("ThreadFunc:  Stack size is as expected:  %zu\n", actualStackSize);
         }
         else
         {
            printf("ThreadFunc:  ERROR, wrong stack size!  (Requested:  %zu, got: %zu)\n", desiredStackSize, actualStackSize);
         }
      }
      else perror("pthread_attr_getstacksize");
   }
   else perror("pthread_attr_init(2)");

   return NULL;
}

static void TestCustomStackSize(size_t desiredStackSizeBytes)
{
   printf("Testing creation of a thread with stack size:  %zu\n", desiredStackSizeBytes);

   pthread_attr_t attr;
   if (pthread_attr_init(&attr) != 0)
   {
      perror("pthread_attr_init");
      return;
   }

   int r = pthread_attr_setstacksize(&attr, desiredStackSizeBytes);
   if (r == 0)
   {
      pthread_t thread;
      if (pthread_create(&thread, &attr, ThreadFunc, &desiredStackSizeBytes) == 0)
      {
         if (pthread_join(thread, NULL) != 0) perror("pthread_join");
      }
      else perror("pthread_create");
   }
   else
   {
      perror("pthread_attr_setstacksize");
      printf("pthread_attr_setstacksize returned %i\n", r);
   }
}

int main(int argv, char ** argc)
{
   const int PAGE_SIZE=8*1024;
   for (size_t stackSizePages=1; stackSizePages<1024; stackSizePages++) TestCustomStackSize(stackSizePages*PAGE_SIZE);
   printf("Done!\n");
   return 0;
}

Upvotes: 5

Views: 3628

Answers (1)

P.P
P.P

Reputation: 121347

The problem is that tattr doesn't refer to current thread's attribute. It's simply initialized as a brand new attribute, whereas pthread_attr_getstacksize() returns the given stack size set in the given attribute i.e. the attribute passed to it.

So, if you pass the correct attribute to pthread_attr_getstacksize(), it should work.

Call

  pthread_getattr_np(pthread_self(), &tattr);

before

  if (pthread_attr_getstacksize(&tattr, &actualStackSize) == 0)

instead of initializing the tattr.

Note pthread_getattr_np() is a non-standard function (not in POSIX).

Upvotes: 3

Related Questions