Angus
Angus

Reputation: 12631

Setting the stacksize of the threads

I was trying a simple program to set the attribute - stacksize of the threads. But with the below codes output I see that the stacksize is not changed.

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

#define NUMTHREADS 5

pthread_attr_t myattr;

void* mythread(void* arg){
        size_t stacksize;

        pthread_attr_getstacksize(&myattr,&stacksize);

        printf("\n tid : %u : %d stacksize : %d \n",(unsigned int)pthread_self(),(int)arg,stacksize);
        pthread_exit(NULL);
}

int main(){
        int i = 0;
        pthread_t threads[NUMTHREADS];
        pthread_attr_t myattr;
        size_t stacksize;

        /*Initialse and set thread detach attribute */
        pthread_attr_init(&myattr);
//      pthread_attr_setdetachstate(&myattr,PTHREAD_CREATE_JOINABLE);
        pthread_attr_getstacksize(&myattr,&stacksize);
        printf("\n Initial Stack size : %d \n",stacksize);

        stacksize = stacksize + 100;

        pthread_attr_setstacksize(&myattr,stacksize);

        //pthread_attr_destroy(&myattr);

        for(i = 0; i < NUMTHREADS; i++){
                printf("\n Creating Threads! \n");
                pthread_create(&threads[i],&myattr,&mythread,(void*)i);
        }

#if 1
        for(i = 0; i < NUMTHREADS; i++){
                printf("\n Joining Threads! \n");
                pthread_join(threads[i],NULL);
        }
#endif

        pthread_attr_getstacksize(&myattr,&stacksize);
        printf("\n Initial Stack size : %d \n",stacksize);

        printf("\n Main tid : %u \n",(unsigned int)pthread_self());
        pthread_exit(NULL);
}

Output :

angus@ubuntu:~/angus/thread$ ./a.out

Initial Stack size : 8388608

Creating Threads!

Creating Threads!

Creating Threads!

Creating Threads!

Creating Threads!

Joining Threads!

tid : 2443623808 : 4 stacksize : 8388608

tid : 2443726208 : 3 stacksize : 8388608

tid : 2443828608 : 2 stacksize : 8388608

tid : 2443931008 : 1 stacksize : 8388608

tid : 2444033408 : 0 stacksize : 8388608

Joining Threads!

Joining Threads!

Joining Threads!

Joining Threads!

Main tid : 2444044032

EDITED : O/P after the edit by commenting pthread_attr_destroy() based on "R's" answer

angus@ubuntu:~/angus/thread$ ./a.out

Initial Stack size : 8388608

Creating Threads!

Creating Threads!

Creating Threads!

Creating Threads!

Creating Threads!

Joining Threads!

tid : 855779136 : 4 stacksize : 8388608

tid : 864171840 : 3 stacksize : 8388608

tid : 872564544 : 2 stacksize : 8388608

tid : 880957248 : 1 stacksize : 8388608

tid : 889349952 : 0 stacksize : 8388608

Joining Threads!

Joining Threads!

Joining Threads!

Joining Threads!

Initial Stack size : 8388708

Main tid : 897656576

Upvotes: 1

Views: 1083

Answers (2)

brainovergrow
brainovergrow

Reputation: 458

There is a method to measure stack size, however error prone.

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

#define NUMTHREADS 2

pthread_attr_t myattr;


void* mythread(void* arg){
        char stack_start = (char) (unsigned int)pthread_self();  //make sure compiler does not optimize us out 
        // int huge_stack_array[4096] = {1,2,3};
        printf("\nhello, im the beginning of tid:%u stack > %p <",(unsigned int)pthread_self(), &stack_start);
        pthread_exit(NULL);
}

int main(){
        int i = 0;
        pthread_t threads[NUMTHREADS];
        pthread_attr_t myattr;
        size_t stacksize;
        pthread_attr_init(&myattr);
        pthread_attr_getstacksize(&myattr,&stacksize);
        printf("\n Initial Stack size : %d \n",stacksize);
        stacksize = 1024*16;
        if (pthread_attr_setstacksize(&myattr,stacksize)) goto failed;
        printf("\n Stack size now : %d \n",stacksize);
        for(i = 0; i < NUMTHREADS; i++){
                pthread_create(&threads[i],&myattr,&mythread,(void*)i);
        }
#if 1
        for(i = 0; i < NUMTHREADS; i++){
                pthread_join(threads[i],NULL);
        }
#endif

        stacksize = 1024*28;
        if (pthread_attr_setstacksize(&myattr,stacksize)) goto failed;
        printf("\n Stack size now : %d \n",stacksize);
        for(i = 0; i < NUMTHREADS; i++){
                pthread_create(&threads[i],&myattr,&mythread,(void*)i);
        }
#if 1
        for(i = 0; i < NUMTHREADS; i++){
                pthread_join(threads[i],NULL);
        }
#endif
        pthread_attr_destroy(&myattr);
        printf("\n Main tid : %u \n",(unsigned int)pthread_self());
        pthread_exit(NULL);

        failed: 
                printf("Can't set stacksize - is it multiplication of PAGE_SIZE, and >16384?\n");
}

Outputs:

 $ gcc -pthread  test.c -o test && ./test

 Initial Stack size : 8388608 

 Stack size now : 16384 

hello, im the beginning of tid:3078323008 stack > 0xb77b735f <
hello, im the beginning of tid:3078306624 stack > 0xb77b335f <
 Stack size now : 28672 

hello, im the beginning of tid:3078290240 stack > 0xb77af35f <
hello, im the beginning of tid:3078261568 stack > 0xb77a835f <
 Main tid : 3076368064 

Now, calc goes to work:

$ calc
; 0xb77b735f-0xb77b335f
    16384
; 0xb77af35f-0xb77a835f
    28672

Oh and yes, if You create int huge_array[4096] on first thread stack it segfaults, whereas works as intended on second one.

Upvotes: 0

R.. GitHub STOP HELPING ICE
R.. GitHub STOP HELPING ICE

Reputation: 215607

You're using an attribute object after destroying it, so the behavior is undefined. Remove this line or move it after the thread creation:

    pthread_attr_destroy(&myattr);

Upvotes: 0

Related Questions