Tramway SDK
queue.h
Go to the documentation of this file.
1// TRAMWAY DRIFT AND DUNGEON EXPLORATION SIMULATOR 2022
2// All rights reserved.
3
4#ifndef TRAM_SDK_TEMPLATES_QUEUE_H
5#define TRAM_SDK_TEMPLATES_QUEUE_H
6
7#include <iostream>
8#include <atomic>
9
10namespace tram {
11
12template <typename T>
13class Queue {
14public:
15 Queue () = delete;
16 Queue (const Queue&) = delete;
17 Queue (Queue&&) = delete;
18 Queue (const char* name, size_t count) : name(name), count(count) {
19 T* allocated_memory = (T*)::operator new (count * sizeof(T));
20
21 first = allocated_memory;
22 last = allocated_memory;
23
24 memory_start = allocated_memory;
25 memory_end = allocated_memory + count;
26
27 csize = 0;
28 }
29
31 template <typename... Args>
32 void push (Args&&... args) {
33 lock();
34
35 if (count == csize) {
36 std::cout << "Queue " << name << " out of space!" << std::endl;
37 unlock();
38 return;
39 }
40
41 new (last) T (std::forward<Args>(args)...);
42
43 last++;
44 csize++;
45
46 // wrap around
47 if (last == memory_end) {
49 }
50
51 unlock();
52 }
53
54 void pop () {
55 first->~T();
56
57 first++;
58 csize--;
59
60 // wrap around
61 if (first == memory_end) {
63 }
64 }
65
66 T& front () {
67 return *first;
68 }
69
70 T& back () {
71 if (T* elem = last - 1; elem < memory_start) {
72 return *(memory_end - 1);
73 } else {
74 return *last;
75 }
76 }
77
82 bool try_pop (T& value) {
83 lock();
84
85 if (csize == 0) {
86 unlock();
87 return false;
88 }
89
90 value = *first;
91 pop();
92
93 unlock();
94 return true;
95 }
96
97 size_t size () { return csize; }
98
99 void lock () { while (spinlock.exchange(true)); }
100 void unlock () { spinlock.store(false); }
101
102protected:
103 const char* name; // name of queue for log messages etc.
104 size_t csize; // how many elements are in queue right now
105 size_t count; // how many elements can be added to queue
106 T* first; // first element in queue
107 T* last; // one past last element in queue
108 T* memory_start; // beginning of allocated memory
109 T* memory_end; // end of allocated memory
110
111 std::atomic<bool> spinlock = {false};
112};
113
114}
115
116#endif // TRAM_SDK_TEMPLATES_QUEUE_H
Definition: queue.h:13
bool try_pop(T &value)
Thread safe.
Definition: queue.h:82
void unlock()
Definition: queue.h:100
void lock()
Definition: queue.h:99
T * memory_start
Definition: queue.h:108
Queue(Queue &&)=delete
void push(Args &&... args)
Thread safe.
Definition: queue.h:32
T & front()
Definition: queue.h:66
Queue(const Queue &)=delete
std::atomic< bool > spinlock
Definition: queue.h:111
void pop()
Definition: queue.h:54
T * last
Definition: queue.h:107
size_t count
Definition: queue.h:105
const char * name
Definition: queue.h:103
T * memory_end
Definition: queue.h:109
T & back()
Definition: queue.h:70
Queue(const char *name, size_t count)
Definition: queue.h:18
Queue()=delete
T * first
Definition: queue.h:106
size_t csize
Definition: queue.h:104
size_t size()
Definition: queue.h:97
Definition: api.h:9