Issue
I am implementing a stack pool to do some basic arithmetic in a specific number of threads.
here is the code:
int add(int a, int b) {return a+b;}
int sub(int a, int b) {return a-b;}
int mul(int a, int b) {return a*b;}
sem_t sem_ops;
void* compute(void* arg){
Args *args = arg;
Operation* op = args->operation;
printOP(*op);
int * value = malloc ( sizeof ( int ) ) ;
* value = op->op(op->a, op->b);
args->is_complete = true;
sem_post(&sem_ops);
return value;
}
void push(Operation op , Queue* q){
q->operations[++(q->last)] = op;
}
Operation *pop(Queue *q){
q->first++;
return &q->operations[q->first];
}
int size(Queue *q){
return q->last - q->first;
}
bool read_operations(char* filename, Queue* ops){
printf("reading from file %s\n",filename);
FILE *fp = fopen(filename, "r");
if(fp == NULL )
{
printf("couldnt open");
return false;
}
int id,a,b;
while(!feof(fp)){
fscanf(fp,"%d %d %d\n",&id,&a,&b);
Operation op;
op.a = a;
op.b = b;
switch (id){
case 0:
op.op = add;
break;
case 1:
op.op = sub;
break;
case 2:
default:
op.op =mul;
break;
}
push(op,ops);
}
return true;
}
ArrayList* execute_thread_pool(char* filename, int poolSize){
sem_init(&sem_ops,0,poolSize);
//init return value
ArrayList* retval =malloc(sizeof(ArrayList));
int res [ TOTAL_OP_COUNT];
retval->results = res;
retval->count = 0;
// populate Q
Queue q;
Operation ops[TOTAL_OP_COUNT];
q.first = 0;
q.last = 0;
q.max = TOTAL_OP_COUNT;
q.operations = ops;
read_operations(filename,&q);
// thread tids
pthread_t threads[TOTAL_OP_COUNT];
//args for each thread
Args args[TOTAL_OP_COUNT];
int* result= NULL;
for(int i =0; i<poolSize; ++i){
sem_wait(&sem_ops);
args[i].operation = pop(&q);
args[i].is_complete=false;
pthread_create(&threads[i],NULL, compute,&args[i]);
}
for(int i =0; i<poolSize; ++i){
if(args[i].is_complete){
pthread_join(threads[i],(void**) result);
res[i] = *result; // line 88
}else --i;
}
return retval;
}
and the structs typedefs:
typedef struct _Operation{
int(*op) (int, int);
int a;
int b;
} Operation;
typedef struct _Args{
Operation* operation;
bool is_complete;
}Args;
typedef struct _Queue{
Operation* operations;
int last;
int first;
int max;
}Queue;
I tried using malloc at a few different places, but can't run away from segfault. this is the content of the main function:
ArrayList *al =malloc(sizeof(ArrayList)) ;
al = execute_thread_pool("bob.txt", 4);
in gdb the bt is as follow:
#0 0x0000555555555762 in execute_thread_pool (filename=0x555555556004 "bob.txt", poolSize=4) at pool.c:88
#1 0x00005555555552db in main (argc=1, argv=0x7fffffffda68) at main.c:5
I've been on this for a few hours, tried multiple ways, tried without semaphores and using not so fun loops and yet the same result. can anyone help me spot the issue?
Solution
You misunderstand the pthread_join
call and how emulating pass-by-reference work in works.
You are supposed to pass a pointer to an int *
variable, using the pointer-to operator &
:
pthread_join(threads[i], &result);
You should also remember to free
the pointer result
, or you will have a memory leak.
Answered By - Some programmer dude Answer Checked By - Senaida (WPSolving Volunteer)