Reputation: 73041
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
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