DungeonCrawl
Loading...
Searching...
No Matches
ringbuffer.c
1
5
6#include "ringbuffer.h"
7
8#include <stdio.h>
9#include <stdlib.h>
10
11#ifdef _WIN32
12 #define INIT_MUTEX(mutex) InitializeCriticalSection(mutex)
13 #define INIT_COND(cond) InitializeConditionVariable(cond)
14
15 #define MUTEX_LOCK(mutex) EnterCriticalSection(mutex)
16 #define MUTEX_UNLOCK(mutex) LeaveCriticalSection(mutex)
17 #define SIGNAL_COND(cond) WakeConditionVariable(cond)
18 #define SIGNAL_WAIT(cond, mutex) SleepConditionVariableCS(cond, mutex, INFINITE)
19#else
20 #define INIT_MUTEX(mutex) pthread_mutex_init(mutex, NULL)
21 #define INIT_COND(cond) pthread_cond_init(cond, NULL)
22
23 #define MUTEX_LOCK(mutex) pthread_mutex_lock(mutex)
24 #define MUTEX_UNLOCK(mutex) pthread_mutex_unlock(mutex)
25 #define SIGNAL_COND(cond) pthread_cond_signal(cond)
26 #define SIGNAL_WAIT(cond, mutex) pthread_cond_wait(cond, mutex)
27#endif
28
29
30int init_ringbuffer(ring_buffer_t* buffer) {
31 buffer->head = 0;
32 buffer->tail = 0;
33 buffer->count = 0;
34
35
36 // allocate pointer array for messages
37 buffer->messages = (char**) malloc(BUFFER_SIZE * sizeof(char*));
38 if (!buffer->messages) {
39 return 1;
40 }
41
42 // allocate memory for messages (at each pointer)
43 for (int i = 0; i < BUFFER_SIZE; i++) {
44 buffer->messages[i] = (char*) malloc(MAX_MSG_LENGTH);
45 if (!buffer->messages[i]) {
46 // if malloc fails, free up all the previous allocated memory
47 for (int j = 0; j < i; j++) {
48 free(buffer->messages[j]);
49 }
50 free(buffer->messages);
51 return 1;
52 }
53 }
54
55 INIT_MUTEX(&buffer->mutex);
56 INIT_COND(&buffer->cond);
57
58 return 0;
59}
60
61void free_ringbuffer(const ring_buffer_t* buffer) {
62 if (buffer->messages) {
63 for (int i = 0; i < BUFFER_SIZE; i++) {
64 free(buffer->messages[i]);
65 }
66 free(buffer->messages);
67 }
68}
69
70void write_to_ringbuffer(ring_buffer_t* buffer, const char* message) {
71 MUTEX_LOCK(&buffer->mutex);
72 if (buffer->count < BUFFER_SIZE) {
73 snprintf(buffer->messages[buffer->tail], MAX_MSG_LENGTH, "%s", message);
74 buffer->tail = (buffer->tail + 1) % BUFFER_SIZE;
75 buffer->count++;
76 SIGNAL_COND(&buffer->cond);
77 }
78 MUTEX_UNLOCK(&buffer->mutex);
79}
80
81
82int read_from_ringbuffer(ring_buffer_t* buffer, char* message) {
83 MUTEX_LOCK(&buffer->mutex);
84 while (buffer->count == 0) {
85 SIGNAL_WAIT(&buffer->cond, &buffer->mutex);
86 }
87 snprintf(message, MAX_MSG_LENGTH, "%s", buffer->messages[buffer->head]);
88 buffer->head = (buffer->head + 1) % BUFFER_SIZE;
89 buffer->count--;
90 MUTEX_UNLOCK(&buffer->mutex);
91 return 0;
92}