summaryrefslogtreecommitdiff
path: root/src/deque.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/deque.c')
-rw-r--r--src/deque.c47
1 files changed, 37 insertions, 10 deletions
diff --git a/src/deque.c b/src/deque.c
index 9b63b55..1046575 100644
--- a/src/deque.c
+++ b/src/deque.c
@@ -1,32 +1,40 @@
#include "deque.h"
#include "smrt_arena.h"
+#include "log.h"
#include <bits/pthreadtypes.h>
#include <pthread.h>
#include <semaphore.h>
-#include <stdlib.h>
#include <string.h>
ez_deque_t *ez_deque_create(smrt_arena_t *arena, u64 elem_size, u64 size) {
u64 total_size = EZ_DEQUE_BASE_POS + (elem_size * size);
- ez_deque_t *q = smrt_arena_push(arena, total_size, true);
+ ez_deque_t *q = smrt_arena_mark_push(arena, total_size, true);
+ if (!q) {
+ log_error("Failed to allocate deque");
+ smrt_arena_pop_to_mark(arena);
+ return NULL;
+ }
q->size = size;
q->element_size_bytes = elem_size;
+ #ifndef NLOG_TRACE
+ log_trace("Created deque; elem size %lu, capacity %lu", elem_size, size);
+ #endif /* ifndef NLOG_TRACE */
return q;
}
-// Returns false if queue can't hold elem.
-b32 ez_deque_enqueue(ez_deque_t *q, void *elem) {
+// Returns -1 if queue can't hold element, otherwise 0.
+i32 ez_deque_enqueue(ez_deque_t *q, void *elem) {
if (q->occupied < q->size) {
u64 insert_pos = EZ_DEQUE_BASE_POS + (q->back * q->element_size_bytes);
memcpy((u8*)q+insert_pos, elem, q->element_size_bytes);
q->back = (q->back + 1) % q->size;
q->occupied++;
- return true;
+ return 0;
}
- return false;
+ return -1;
}
void *ez_deque_pop(ez_deque_t *q) {
@@ -39,12 +47,27 @@ void *ez_deque_pop(ez_deque_t *q) {
// Sync constructs are allocated on arena
ts_deque_t ts_deque_create(smrt_arena_t *arena, ez_deque_t *q) {
- pthread_mutex_t *m = smrt_arena_push(arena, sizeof(pthread_mutex_t), true);
+ pthread_mutex_t *m = smrt_arena_mark_push(arena, sizeof(pthread_mutex_t), true);
+ if (!m) {
+ log_error("Failed to allocate TSQ mutex");
+ smrt_arena_pop_to_mark(arena);
+ return (ts_deque_t){0};
+ }
+
pthread_mutex_init(m, NULL);
sem_t *s = smrt_arena_push(arena, sizeof(sem_t), true);
+ if (!s) {
+ log_error("Failed to allocate TSQ semaphore");
+ smrt_arena_pop_to_mark(arena);
+ return (ts_deque_t){0};
+ }
sem_init(s, 0, 0);
+ #ifndef NLOG_TRACE
+ log_trace("Created thread-safe Deque; queue %p", q);
+ #endif /* ifndef NLOG_TRACE */
+
return (ts_deque_t){
.queue = q,
.write_lock = m,
@@ -55,13 +78,17 @@ ts_deque_t ts_deque_create(smrt_arena_t *arena, ez_deque_t *q) {
void ts_deque_destroy(ts_deque_t tsq) {
sem_destroy(tsq.count_sem);
pthread_mutex_destroy(tsq.write_lock);
+
+ #ifndef NLOG_TRACE
+ log_trace("Destroyed thread-safe Deque");
+ #endif /* ifndef NLOG_TRACE */
}
-b32 ts_deque_enqueue(ts_deque_t tsq, void *elem) {
+i32 ts_deque_enqueue(ts_deque_t tsq, void *elem) {
pthread_mutex_lock(tsq.write_lock);
- b32 result = ez_deque_enqueue(tsq.queue, elem);
+ i32 result = ez_deque_enqueue(tsq.queue, elem);
pthread_mutex_unlock(tsq.write_lock);
- if (result) sem_post(tsq.count_sem);
+ if (result == 0) sem_post(tsq.count_sem);
return result;
}