0
votes

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?

2
You should study something about pointers, or correct the code as item = getfrombuffer(item); in the calling side.LPs

2 Answers

1
votes

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);   
}
1
votes

You never set item in the *start_thread function to anything. Change getfromebuffer(item) to item = getfrombuffer(item).

Another fix would be to change getfrombuffer to void type and pass item by reference (read: pass a pointer to item), making your code as such:

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);    
}