Zadania rekrutacyjne i ćwiczeniowe
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

76 lines
1.7 KiB

#include "thread/Blocker.h"
#include <stdlib.h>
#include <stdio.h>
#include <pthread.h>
#include <time.h>
#ifndef BLOCKER_COUNT_MAX
#define BLOCKER_COUNT_MAX 8
#endif
typedef struct PtBlocker
{
pthread_mutex_t mutex;
pthread_cond_t cond;
} PtBlocker;
// TODO: dynamic list?
static PtBlocker* blockers[BLOCKER_COUNT_MAX] = {NULL};
BlockerHandle createBlocker(void)
{
BlockerHandle id = 0;
while (blockers[id] != NULL && id < BLOCKER_COUNT_MAX) {
++id;
}
if (id == BLOCKER_COUNT_MAX) {
return -1;
}
blockers[id] = calloc(1, sizeof(PtBlocker));
return id;
}
void lockBlocker(BlockerHandle id)
{
pthread_mutex_lock(&blockers[id]->mutex);
pthread_cond_wait(&blockers[id]->cond, &blockers[id]->mutex);
pthread_mutex_unlock(&blockers[id]->mutex);
}
enum PTB_TIMEOUT_STATUS lockBlockerTimed(BlockerHandle id, uint32_t timeoutMs)
{
enum PTB_TIMEOUT_STATUS status = PTB_TIMEOUT;
int waitResult = 0;
struct timespec timeout;
clock_gettime(CLOCK_REALTIME, &timeout);
timeout.tv_sec += timeoutMs / 1000;
timeout.tv_nsec += (timeoutMs % 1000) * 1000000;
pthread_mutex_lock(&blockers[id]->mutex);
waitResult = pthread_cond_timedwait(&blockers[id]->cond, &blockers[id]->mutex, &timeout);
if (waitResult == 0) {
status = PTB_NO_TIMEOUT;
}
pthread_mutex_unlock(&blockers[id]->mutex);
return status;
}
void notifyBlocker(BlockerHandle id)
{
pthread_mutex_lock(&blockers[id]->mutex);
pthread_cond_signal(&blockers[id]->cond);
pthread_mutex_unlock(&blockers[id]->mutex);
}
void freeBlocker(BlockerHandle* id)
{
if (*id == -1) {
return;
}
pthread_mutex_destroy(&blockers[*id]->mutex);
pthread_cond_destroy(&blockers[*id]->cond);
free(blockers[*id]);
blockers[*id] = NULL;
*id = -1;
}