summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
author@syxhe <https://t.me/syxhe>2025-05-08 17:49:16 -0500
committer@syxhe <https://t.me/syxhe>2025-05-08 17:49:16 -0500
commit9be8b5f26a29dad04035386331461c4c320f9237 (patch)
tree92a6486a7625e5149233ae4aa6aba2665a132af6 /src
parent8a6d1e4074bbe26685f8c0ca6efef97d99680afb (diff)
kms immediately
Diffstat (limited to 'src')
-rwxr-xr-xsrc/main.c273
1 files changed, 79 insertions, 194 deletions
diff --git a/src/main.c b/src/main.c
index c885c5e..9d1c5ab 100755
--- a/src/main.c
+++ b/src/main.c
@@ -1,71 +1,72 @@
1///usr/bin/true; gcc -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 main.c -o main && ./main; exit $? 1///usr/bin/true; gcc -std=c2x -Wall -Wextra -Wpedantic -pedantic-errors -fanalyzer -Wanalyzer-too-complex -ggdb -g3 -O0 main.c -o main && ./main; exit $?
2 2
3// #include <errno.h> 3#include <asm-generic/errno-base.h>
4// #include <error.h>
5// #include <stdio.h>
6// #include <threads.h>
7// #include <unistd.h>
8// #include <string.h>
9
10#include <stdlib.h> 4#include <stdlib.h>
11#include <errno.h> 5#include <errno.h>
12#include <sys/types.h> 6#include <error.h>
13#include <string.h>
14#include <stdio.h>
15#include <threads.h> 7#include <threads.h>
16 8
9#define RETURNWERR(eval, rval) do { \
10 errno = (eval); \
11 return (rval); \
12} while (0)
13
14#define ERROR(exitval, errval, msg, __VA_ARGS__) do { \
15 error((exitval), (errval), (msg)__VA_ARGS__); \
16 abort(); \
17} while (0)
17 18
18void * xcalloc(size_t nmemb, size_t size) { 19void * xcalloc(size_t nmemb, size_t size) {
19 void *mem = calloc(nmemb, size); 20 void *mem = calloc(nmemb, size);
20 if(!mem) 21 if(!mem)
21 abort(); 22 ERROR(-1, errno, "<xcalloc> failed to allocate memory ", );
22 23
23 return mem; 24 return mem;
24} 25}
25 26
26 27
27 28
29typedef int (*gcallback)(void*);
28typedef void (*fcallback)(void*); 30typedef void (*fcallback)(void*);
29typedef struct gdata { 31typedef struct gdata {
30 void *data; 32 void *data;
31 fcallback freer; 33 fcallback fcb;
32} gdata; 34} gdata;
33 35
34gdata * gdata_init(void *data, fcallback fcb) { 36gdata * gdata_init(void *data, fcallback fcb) {
35 gdata *gd = xcalloc(1, sizeof(*gd)); 37 gdata *gd = xcalloc(1, sizeof(*gd));
36 gd->data = data; 38 gd->data = data;
37 gd->freer = fcb; 39 gd->fcb = fcb;
38 40
39 return gd; 41 return gd;
40} 42}
41 43
42void gdata_free(gdata *gd) { 44void gdata_free(void *gd) {
43 if(!gd) 45 if(!gd)
44 return; 46 return;
45 47
46 if(gd->freer != NULL) 48 gdata *real = (gdata*)gd;
47 gd->freer(gd->data); 49 if(real->fcb != NULL)
48 free(gd); 50 real->fcb(real->data);
51 free(real);
49 52
50 return; 53 return;
51} 54}
52 55
53void * gdata_getdata(gdata * const gd) { 56void * gdata_getdata(gdata * const gd) {
54 if(!gd) { 57 if(!gd)
55 errno = EINVAL; 58 RETURNWERR(EINVAL, NULL);
56 return NULL; 59
57 }
58
59 return gd->data; 60 return gd->data;
60} 61}
61 62
62void gdata_destruct(gdata *gd, void **storage) { 63void * gdata_destruct(gdata *gd) {
63 if(!gd || !storage) 64 if(!gd)
64 return; 65 RETURNWERR(EINVAL, NULL);
65 66
66 *storage = gd->data; 67 void *data = gdata_getdata(gd);
67 free(gd); 68 free(gd);
68 return; 69 return data;
69} 70}
70 71
71 72
@@ -78,7 +79,7 @@ typedef struct stack {
78 79
79stack * stack_init(int size) { 80stack * stack_init(int size) {
80 if(size < 1) 81 if(size < 1)
81 return NULL; 82 RETURNWERR(EINVAL, NULL);
82 83
83 stack *st = xcalloc(1, sizeof(*st)); 84 stack *st = xcalloc(1, sizeof(*st));
84 st->size = size; 85 st->size = size;
@@ -88,220 +89,104 @@ stack * stack_init(int size) {
88 return st; 89 return st;
89} 90}
90 91
91void stack_free(stack *st) { 92void stack_free(void *st) {
92 if(!st) 93 if(!st)
93 return; 94 return;
94 95
95 for(int i = 0; i < st->used; i++) 96 stack *real = (stack*)st;
96 gdata_free(st->arr[i]); 97 for(int i = 0; i < real->used; i++)
97 free(st->arr); 98 gdata_free(real->arr[i]);
98 free(st); 99 free(real->arr);
99 100 free(real);
101
100 return; 102 return;
101} 103}
102 104
103int stack_getsize(stack * const st) { 105int stack_push(stack *st, gdata *gd) {
104 if(!st) 106 if(!st || !gd)
105 return -1; 107 RETURNWERR(EINVAL, -1);
108 if(!(st->used < st->size))
109 RETURNWERR(ENOMEM, 0);
106 110
107 return st->size; 111 st->arr[st->used++] = gd;
112 return st->used;
108} 113}
109 114
110int stack_hasroom(stack * const st) { 115gdata * stack_pop(stack *st) {
111 if(!st) 116 if(!st)
112 return -1; 117 RETURNWERR(EINVAL, NULL);
113 118 if(st->used <= 0)
114 return (st->used < st->size); 119 RETURNWERR(ENODATA, 0);
115}
116
117int stack_push(stack *st, gdata *data) {
118 if(!st || !data)
119 return -1;
120 if(!stack_hasroom(st))
121 return 0;
122
123 st->arr[st->used++] = data;
124 120
125 return st->used; 121 return st->arr[--st->used];
126} 122}
127 123
128int stack_pushd(stack *st, void *data, fcallback fcb) { 124int stack_pushd(stack *st, void *data, fcallback fcb) {
129 if(!st) 125 if(!st)
130 return -1; 126 RETURNWERR(EINVAL, -1);
131 if(!stack_hasroom(st)) 127
132 return 0;
133
134 gdata *gd = gdata_init(data, fcb); 128 gdata *gd = gdata_init(data, fcb);
135 int retval = stack_push(st, gd); 129 int retval = stack_push(st, gd);
136 if(!(retval > 0)) 130 if(retval <= 0)
137 gdata_free(gd); 131 gdata_free(gd);
138 132
139 return retval; 133 return retval;
140} 134}
141 135
142gdata * stack_pop(stack *st) { 136void * stack_popd(stack *st) {
143 if(!st) 137 if(!st)
144 return NULL; 138 RETURNWERR(EINVAL, NULL);
145 if(st->used <= 0)
146 return NULL;
147 139
148 gdata *gd = st->arr[--st->used];
149 return gd;
150}
151
152void * stack_popd(stack *st) {
153 gdata *gd = stack_pop(st); 140 gdata *gd = stack_pop(st);
154 void *data = NULL; 141 if(!gd)
155 142 return NULL;
156 gdata_destruct(gd, &data); 143
157 return data; 144 return gdata_destruct(gd);
158} 145}
159 146
160 147
161 148
162typedef struct cstack { 149typedef struct cstack {
163 stack *stack; 150 stack *st;
164 mtx_t mutex; 151 mtx_t mutex;
165 cnd_t cond; 152 cnd_t cond;
166 unsigned char canceled; 153 unsigned char canceled;
154
167} cstack; 155} cstack;
168 156
169cstack * cstack_init(int size) { 157cstack * cstack_init(int size) {
170 if(size < 1) 158 if(size < 1)
171 return NULL; 159 RETURNWERR(EINVAL, NULL);
172 160
173 cstack *cs = xcalloc(1, sizeof(*cs)); 161 cstack *cst = xcalloc(1, sizeof(*cst));
174 cs->canceled = 0; 162 cst->st = stack_init(size);
175 cs->stack = stack_init(size); 163 cst->canceled = 0;
176 mtx_init(&cs->mutex, mtx_plain); 164 mtx_init(&cst->mutex, mtx_plain);
177 cnd_init(&cs->cond); 165 cnd_init(&cst->cond);
178 166
179 return cs; 167 return cst;
180} 168}
181 169
182int cstack_cancel(cstack *cs) { 170int cstack_cancel(cstack * const cst) {
183 if(!cs) 171 if(!cst)
184 return -1; 172 RETURNWERR(EINVAL, -1);
185 173
186 mtx_lock(&cs->mutex); 174 mtx_lock(&cst->mutex);
187 cs->canceled = 1; 175 cst->canceled = 1;
188 mtx_unlock(&cs->mutex); 176 mtx_unlock(&cst->mutex);
189 cnd_broadcast(&cs->cond); 177 cnd_broadcast(&cst->cond);
190 178
191 return 0; 179 return 0;
192} 180}
193 181
194void cstack_free(cstack *cs) { 182void cstack_free(void *cst) {
195 if(!cs) 183 if(!cst)
196 return; 184 return;
197 185
198 cstack_cancel(cs); 186 cstack *real = (cstack*)cst;
199 stack_free(cs->stack);
200 mtx_destroy(&cs->mutex);
201 cnd_destroy(&cs->cond);
202
203 return;
204}
205
206int cstack_push(cstack *cs, gdata *data) {
207 if(!cs || !data)
208 return -1;
209
210 mtx_lock(&cs->mutex);
211 stack_push(cs->stack, data);
212 mtx_unlock(&cs->mutex);
213 cnd_signal(&cs->cond);
214
215 return 0;
216}
217
218int cstack_pushd(cstack *cs, void *data, fcallback fcb) {
219 if(!cs)
220 return -1;
221
222 mtx_lock(&cs->mutex);
223 stack_pushd(cs->stack, data, fcb);
224 mtx_unlock(&cs->mutex);
225 cnd_signal(&cs->cond);
226
227 return 0;
228}
229
230gdata * cstack_pop(cstack *cs) {
231 if(!cs)
232 return NULL;
233
234 gdata *gd = NULL;
235 int csize = -1;
236
237 mtx_lock(&cs->mutex);
238
239 // Wait until there's data to pop or the thing gets canceled
240 for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;)
241 cnd_wait(&cs->cond, &cs->mutex);
242
243 // If the stack was canceled, or there's an error, exit
244 if(cs->canceled || csize < 0)
245 thrd_exit(-1);
246
247 // Otherwise, there's data, of which pop it to gd
248 gd = stack_pop(cs->stack);
249
250 mtx_unlock(&cs->mutex);
251
252 return gd;
253}
254
255void * cstack_popd(cstack *cs) {
256 if(!cs)
257 return NULL;
258
259 gdata *gd = NULL;
260 int csize = -1;
261
262 mtx_lock(&cs->mutex);
263
264 // Wait until there's data to pop or the thing gets canceled
265 for(; (csize = stack_getsize(cs->stack)) == 0 || !cs->canceled;)
266 cnd_wait(&cs->cond, &cs->mutex);
267 187
268 // If the stack was canceled, or there's an error, exit 188 cstack_cancel(real);
269 if(cs->canceled || csize < 0) 189 // Ok I don't think there's a good way to wait for all threads to die without registering the threads
270 thrd_exit(-1);
271
272 // Otherwise, there's data, of which pop it to gd
273 gd = stack_pop(cs->stack);
274
275 mtx_unlock(&cs->mutex);
276
277 void *realdata = NULL;
278 gdata_destruct(gd, &realdata);
279
280 return realdata;
281}
282 190
283 191 return;
284
285int main() {
286 // stack *st = stack_init(10);
287 // stack_pushd(st, (void*)10, NULL);
288 // stack_pushd(st, (void*)11, NULL);
289 // stack_pushd(st, (void*)12, NULL);
290 // stack_pushd(st, strdup("This is some data"), free);
291
292 // char *data = stack_popd(st);
293 // printf("%s\n", (data) ? data : "null");
294 // free(data);
295
296 // stack_free(st);
297
298 cstack *cst = cstack_init(10);
299 cstack_pushd(cst, (void*)10, NULL);
300 cstack_pushd(cst, (void*)11, NULL);
301 cstack_pushd(cst, (void*)12, NULL);
302 cstack_pushd(cst, (void*)strdup("This is some data"), free);
303
304 cstack_free(cst);
305
306 return 0;
307} \ No newline at end of file 192} \ No newline at end of file