2
votes

Here is the function which is giving segfault in pthread_join:


void call_merge()    
{    
    int no_runs = No_sub_seq;    
        int no_joins=no_runs-1;
    int magic1=0,j=0,inc = 1;
    int temp_runs = no_runs/2;        
    int i,k;
    while(temp_runs!=0)    
    {
        magic1=0;
        std::list<pthread_t> threadList;
        pthread_t thread;
        for(i=0;i<=temp_runs-1;i++)
        {
                    if((magic1 + inc) <= no_joins)    
                    {
                        data *d=(data *)malloc(sizeof(data));

                        d->a=magic1;
                        d->b=magic1+inc;
                        d->c=inc;
                         pthread_create(&thread,NULL,(void* (*)(void*))merge, (void*)d);  
                         threadList.push_front(thread);

                    }
                    magic1 = magic1 + (inc * 2); 
        }
        std::list<pthread_t>::iterator m;
        for(m=threadList.begin();m!=threadList.end();m++)
                pthread_join(*m,NULL);
        if((no_runs % 2) != 0)
            temp_runs++;    
        no_runs = temp_runs;
        temp_runs = no_runs/2;     
        inc = inc * 2;
        }
}

here is the merge function


void merge(void *param)
{
    data *d=(data *)param;

    int low=Sq[d->a],high;

    int mid=Sq[d->b]-1;

    if(Sq[d->b + d->c]==0)
        high=size-1;
    else
        high=Sq[d->b + d->c]-1;

    int k;

    int i=0;
    int j=low;

    while(j<=mid)
        b[i++]=a[j++];

    i=0; k=low;
    while (k<j && j<=high)
        if (b[i]<=a[j])
            a[k++]=b[i++];
        else
            a[k++]=a[j++];

    while (k<j)
        a[k++]=b[i++];

}

the merge function called in the above code simply merges the subarrays passed using the parameters d->a,d->b,d->c. and there is no thread code written in the merge function. The above program works fine when there are no threads and gives sorted sequence of the input array.When i tried to debug this using gdb, it shows a segault in pthread_join(). I am unable to figure out why is it happening so??? thanks in advance

2
doesn't answer your question, but since you are using c++, you should allocate your d variable with: data *d = new data; it is simpler. Just remember to release it with delete and not free.Evan Teran

2 Answers

2
votes

One of your calls to pthread_create() is probably failing, e.g. because you're exceeding the limit on the total number of threads per process.

In that case thread contains an undefined value. Since you ignore the error, you go ahead and store that undefined value in your list, then call pthread_join() on it later, which results in a segfault.

EDIT: Now that you handle errors from pthread_create(), the segfault is gone but some of your threads still don't get created, so they can't perform their work. That's why your code works with a range of 1000 but doesn't with range of 10000.

Your design seems well-suited for thread pooling, i.e. spawning a fixed number of threads and give them more work as soon as they finish their current tasks. See here or there for pool implementations using POSIX threads.

0
votes

At what scope do you define the threadList object? You push_front the newly created threads into the list but in your code I neither see a explicit erase of the joined threads, nor a RAII deleting of the entire thread list. Since you iterate over the entire list of threads you're probably calling pthread_join multiple times for already canceled threads...