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