patterncMinor
Concurrent stack in C
Viewed 0 times
concurrentstackstackoverflow
Problem
(See also the follow-up question.)
I was in the mood for
My codez looks like this:
concurrent_stack.h
```
#ifndef CONCURRENT_STACK_H
#define CONCURRENT_STACK_H
#include
typedef struct concurrent_stack
{
/***
The number of elements stored in this stack.
***/
size_t size;
/
The maximum number of elements this stack can hold.
/
size_t capacity;
/
The actual array holding the data of the stack.
/
void** storage;
/****
The mutual exclusion lock for updating the stack.
****/
pthread_mutex_t mutex;
/*****
Guards against an empty stack.
*****/
pthread_cond_t empty_condition_variable;
/***
Guards against a full stack.
***/
pthread_cond_t full_condition_variable;
}
concurrent_stack;
/*
Initializes a new, empty concurrent stack.
*/
void concurrent_stack_init(concurrent_stack* stack, size_t capacity);
/
Pushes a datum onto the top of the stack.
/
void concurrent_stack_push(concurrent_stack stack, void datum);
/*
I was in the mood for
pthread.h and decided to write a concurrent stack data structure. My requirements:- the stack has maximum capacity,
- pushing an element,
- removing the top element without returning it,
- peeking the top element,
- client is blocked whenever popping from an empty stack,
- client is blocked whenever pushing to a full stack.
My codez looks like this:
concurrent_stack.h
```
#ifndef CONCURRENT_STACK_H
#define CONCURRENT_STACK_H
#include
typedef struct concurrent_stack
{
/***
The number of elements stored in this stack.
***/
size_t size;
/
The maximum number of elements this stack can hold.
/
size_t capacity;
/
The actual array holding the data of the stack.
/
void** storage;
/****
The mutual exclusion lock for updating the stack.
****/
pthread_mutex_t mutex;
/*****
Guards against an empty stack.
*****/
pthread_cond_t empty_condition_variable;
/***
Guards against a full stack.
***/
pthread_cond_t full_condition_variable;
}
concurrent_stack;
/*
Initializes a new, empty concurrent stack.
*/
void concurrent_stack_init(concurrent_stack* stack, size_t capacity);
/
Pushes a datum onto the top of the stack.
/
void concurrent_stack_push(concurrent_stack stack, void datum);
/*
Solution
Issues:
Failed to check the return value of all these system calls:
You may be destroying objects that are currently in use in another thread.
Before you can start freeing the resources you have to make sure that no other thread is using these resources. This means you have to force a flush and make sure there are no threads in your object.
Failed to check the return value of all these system calls:
stack->storage = malloc(sizeof(void*) * stack->capacity);
pthread_mutex_init(&stack->mutex, NULL);
pthread_cond_init(&stack->empty_condition_variable, NULL);
pthread_cond_init(&stack->full_condition_variable, NULL);
pthread_mutex_lock(&stack->mutex);
pthread_cond_wait(&stack->full_condition_variable, &stack->mutex);
pthread_cond_signal(&stack->empty_condition_variable);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_lock(&stack->mutex);
pthread_cond_wait(&stack->empty_condition_variable, &stack->mutex);
pthread_cond_signal(&stack->full_condition_variable);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_lock(&stack->mutex);
pthread_cond_wait(&stack->empty_condition_variable, &stack->mutex);
pthread_cond_signal(&stack->full_condition_variable);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_lock(&stack->mutex);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_destroy(&stack->mutex);
pthread_cond_destroy(&stack->empty_condition_variable);
pthread_cond_destroy(&stack->full_condition_variable);You may be destroying objects that are currently in use in another thread.
void concurrent_stack_free(concurrent_stack* stack)
{
free(stack->storage);
pthread_mutex_destroy(&stack->mutex);
pthread_cond_destroy(&stack->empty_condition_variable);
pthread_cond_destroy(&stack->full_condition_variable);
}Before you can start freeing the resources you have to make sure that no other thread is using these resources. This means you have to force a flush and make sure there are no threads in your object.
Code Snippets
stack->storage = malloc(sizeof(void*) * stack->capacity);
pthread_mutex_init(&stack->mutex, NULL);
pthread_cond_init(&stack->empty_condition_variable, NULL);
pthread_cond_init(&stack->full_condition_variable, NULL);
pthread_mutex_lock(&stack->mutex);
pthread_cond_wait(&stack->full_condition_variable, &stack->mutex);
pthread_cond_signal(&stack->empty_condition_variable);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_lock(&stack->mutex);
pthread_cond_wait(&stack->empty_condition_variable, &stack->mutex);
pthread_cond_signal(&stack->full_condition_variable);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_lock(&stack->mutex);
pthread_cond_wait(&stack->empty_condition_variable, &stack->mutex);
pthread_cond_signal(&stack->full_condition_variable);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_lock(&stack->mutex);
pthread_mutex_unlock(&stack->mutex);
pthread_mutex_destroy(&stack->mutex);
pthread_cond_destroy(&stack->empty_condition_variable);
pthread_cond_destroy(&stack->full_condition_variable);void concurrent_stack_free(concurrent_stack* stack)
{
free(stack->storage);
pthread_mutex_destroy(&stack->mutex);
pthread_cond_destroy(&stack->empty_condition_variable);
pthread_cond_destroy(&stack->full_condition_variable);
}Context
StackExchange Code Review Q#151657, answer score: 7
Revisions (0)
No revisions yet.