Natesh bhat
Natesh bhat

Reputation: 13192

Error in my system calls usage

I am trying to implement linear search by divide and conquer and giving each subproblem to a new process which i create using fork .

Here is the full code of it :

#include<sys/wait.h>
#include<stdio.h>
#include<stdlib.h>
#include<ctype.h>
#include<unistd.h>


int PID ; 

unsigned long long LinearSearchHelper(unsigned long long arr[] , unsigned long long low , unsigned long long high, unsigned long long key)
{
    if(low>high) exit(0) ; 
    if(low==high)
        exit(arr[low]==key ? low : 0 ) ; 

    unsigned long long mid = (low+high)/2 ;

    int leftProcess = fork() ; 
    if(leftProcess==0){
        exit(LinearSearchHelper(arr , low , mid , key)) ; 
    }

    int rightProcess = fork() ; 

    if(rightProcess==0)
    {
        exit(LinearSearchHelper(arr , mid+1 ,high , key)) ;
    }

    if(leftProcess<0 || rightProcess<0){
        printf("\nFAILED TO FORK PROCESS !" ) ; 
        exit(0) ; 
    }

    unsigned long long stat1 , stat2 ; 
    waitpid(leftProcess , &stat1 , 0  ) ; 
    waitpid(rightProcess , &stat2 , 0 ) ; 

    unsigned long long l = WEXITSTATUS(stat1) ; 
    unsigned long long r = WEXITSTATUS(stat2) ; 

    exit(l!=0?l : r) ;
}


unsigned long long LinearSearch(unsigned long long arr[] , unsigned long long low , unsigned long long high, unsigned long long key)
{
    int taskid = fork() ; 
    if(taskid<0){
        printf("\nFAILED TO FORK PROCESS !" ) ; 
    }
    int res ; 
    if(taskid==0){
        exit(LinearSearchHelper(arr , low , high , key)) ;
    }
    else{
        unsigned long long status ; 
        waitpid(taskid , &status , 0 ) ;
        return WEXITSTATUS(status) ; 
    } 
}



void fnGenRand(unsigned long long arr[] , unsigned long long n )
{
    unsigned long long i =0 ; 
    for(i = 0 ; i < n ; i++) {
        arr[i] = rand() %10000 ; 
    }
}



unsigned long long main(void)
{
    PID = getpid() ; 
    unsigned long long size = 400000 ; 
    unsigned long long  * arr = malloc(size * sizeof(unsigned long long))  ;  
    unsigned long long  i =0 , n = 200 ;
    struct timeval tv ; 
    double start , end ;
    srand(time(NULL)) ; 
    FILE * fp = fopen("mergeplot.dat" ,"w") ; 

    unsigned long long key ; 


    for(i=100 ; i<300; i+=30)
    {
        n =  i; 

        fnGenRand(arr , n  ) ; 

        key = rand()%10000 ; 

        gettimeofday(&tv , NULL) ; 
        start = tv.tv_sec + (tv.tv_usec/1000000.0) ; 
        unsigned long long res = LinearSearch(arr , 0 , n-1  , key ) ; 
        gettimeofday(&tv , NULL) ; 
        end = tv.tv_sec + (tv.tv_usec/1000000.0) ; 

        fprintf(fp , "%d\t%1lf\n" , i , end-start) ; 
    }

    fclose(fp) ; 
}

The issue is that I want to write the size of the current array and the corresponding search time into the file "mergeplot.dat" .

But the problem I am facing is that the mergeplot.dat file is getting lot of duplicate entries and I can't figure out what's wrong and why ?

It seems multiple processes are writing to my file at once and hence the duplicate size entries . Is there something wrong in the way i have forked and called the recursive function ?

Please provide an explanation as to what i am doing wrong. I'm new to System calls .

Upvotes: 0

Views: 44

Answers (1)

Andrew Henle
Andrew Henle

Reputation: 1

Your argument to waitpid() is wrong. waitpid() is declared as

#include <sys/wait.h>

pid_t waitpid(pid_t pid, int *stat_loc, int options);

Note that the second option is an int *. You are passing waitpid() the address of an unsigned long long:

unsigned long long status ; 
waitpid(taskid , &status , 0 ) ;

That won't work.

You're also likely to have problems with the range that your child processes can return. A process can only provide return values in the range of 0-255. Per the wait() man page:

WEXITSTATUS(wstatus)

returns the exit status of the child. This consists of the least significant 8 bits of the status argument that the child specified in a call to exit(3) or _exit(2) or as the argument for a return statement in main(). This macro should be employed only if WIFEXITED returned true.

Upvotes: 2

Related Questions