John Slaine
John Slaine

Reputation: 192

Passing a struct to pthread_create()

Here's a function that should recursively find more precise values of Pi and split into a user defined amount of threads to do the recursion concurrently.

void* quad(void* argis){
    struct args* arg=argis;

    double m=(arg->l+arg->r)/2;
    double fm=func(m);
    double larea=(arg->fl+fm)*(m-arg->l)/2;
    double rarea = (fm+arg->fr)*(arg->r-m)/2;

    struct args* arg1 = (struct args*)malloc(sizeof(struct args));
    arg1->l=arg->l;
    arg1->r=m;
    arg1->fl=arg->fl;
    arg1->fr=fm;
    arg1->area=larea;

    struct args* arg2 = (struct args*)malloc(sizeof(struct args));
    arg2->l=m;
    arg2->r=arg->r;
    arg2->fl=fm;
    arg2->fr=arg->fl;
    arg2->area=rarea;

    if(fabs((larea+rarea)-arg->area)>error){
        if(threads<=1){
            void* p1=quad((void*)arg1);
            void* p2=quad((void*)arg2);
            larea=*((double*)p1);
            rarea=*((double*)p2);
            free(p1);
            free(p2);


        }
        else{
            pthread_t thread1, thread2;
            pthread_mutex_lock(&lock1);
            threads--;
            pthread_mutex_unlock(&lock1);

            pthread_create(&thread1, NULL, &quad, (void*)&arg1);
            pthread_create(&thread2, NULL, &quad, (void*)&arg2);

            void* ptr1;
            void* ptr2;

            pthread_join(thread1,&ptr1);
            pthread_join(thread2,&ptr2);


            pthread_mutex_lock(&lock1);
            threads++;
            pthread_mutex_unlock(&lock1);

            larea=*(double*)ptr1;
            rarea=*(double*)ptr2;


        }
    }
    free(arg1);
    free(arg2);

    double ret= (larea+rarea);
    double* poin=(double*)malloc(sizeof(double));
    *poin=ret;

    return (void*)poin;
}

However, it doesn't work. After investigating I've found that the problem seems to be here:

pthread_create(&thread1, NULL, &quad, (void*)&arg1);
pthread_create(&thread2, NULL, &quad, (void*)&arg2);

All arguments in struct arg1 and arg2 just become 0 after they've been passed in to the new thread. arg1 and arg2 aren't local they're in heap and I'm pretty sure threads share heap so that's not the problem. Is this not how you pass arguments to new thread in pthread_create()?

This is my first time working with pthreads so be patient with me. But any help finding out what's causing the structs to be reset would be greatly appreciated. Thanks!

Upvotes: 0

Views: 2298

Answers (1)

alk
alk

Reputation: 70903

As arg1 and arg2 are pointers already you want to pass them to to pthread_create() "as is":

  pthread_create(&thread1, NULL, &quad, arg1);

Also there is no need to cast here:

  void* p1=quad((void*)arg1);

Just do:

  void* p1=quad(arg1);

Same for malloc(), no need to cast its result.

Nor here:

  return (void*)poin;

Doing

  return poin;

is fine.

In C conversion of any pointer to/from void* is done implicitly.

Upvotes: 4

Related Questions