Search code examples
cfunctionstructpthreadscircular-buffer

Returning struct from function defined in thread


I have a struct defined like

typedef struct{
    int op;
    int id;
    int val;
} command_t;

command_t cmd_buffer[10];

I am creating a bunch of threads to work with a struct array in a circular buffer. In the thread creaction I call the function start_thread which calls removefrombuffer which is supposed to return a struct or at least pass a struct to the start_thread function

void *start_thread (void *arg){
    int i;
    command_t item;
    getfrombuffer(item);
    ///// bunch of operations from the item removed from buffer
}

command_t getfrombuffer (command_t item){
    sem_wait(&fullpositions);
    pthread_mutex_lock(&mutex);
    item = cmd_buffer[buff_read_idx++];
    if(buff_read_idx >= 6)
        buff_read_idx=0;
    pthread_mutex_unlock(&mutex);
    sem_post(&freepositions);
    return item;    
}

Unfortunately after the start_thread function calls getfrombuffer(), after I try to do operations from that that returned item or simply printf of item.id for example it will return a random valor in memory and not the value that was removed from the buffer.

How can I properly return a structure from a function like this?


Solution

  • the problem is that item is passed by value to your function.

    You can correct it in two ways:

    1. Using a simple return value

    void *start_thread (void *arg){
        int i;
        command_t item = getfrombuffer();
        ///// bunch of operations from the item removed from buffer
    }
    
    command_t getfrombuffer (void)
    {
        sem_wait(&fullpositions);
        pthread_mutex_lock(&mutex);
        command_t item = cmd_buffer[buff_read_idx++];
        if(buff_read_idx >= 6)
            buff_read_idx=0;
        pthread_mutex_unlock(&mutex);
        sem_post(&freepositions);
        return item;    
    }
    
    1. Using pointers

    void *start_thread (void *arg)
    {
        int i;
        command_t item;
        getfrombuffer(&item);
        ///// bunch of operations from the item removed from buffer
    }
    
    void getfrombuffer (command_t *item)
    {
        sem_wait(&fullpositions);
        pthread_mutex_lock(&mutex);
        *item = cmd_buffer[buff_read_idx++];
        if(buff_read_idx >= 6)
            buff_read_idx=0;
        pthread_mutex_unlock(&mutex);
        sem_post(&freepositions);   
    }