koliseo 0.5.10
Loading...
Searching...
No Matches
koliseo.c
Go to the documentation of this file.
1// jgabaut @ github.com/jgabaut
2// SPDX-License-Identifier: GPL-3.0-only
3/*
4 Copyright (C) 2023-2026 jgabaut
5
6 This program is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, version 3 of the License.
9
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU General Public License for more details.
14
15 You should have received a copy of the GNU General Public License
16 along with this program. If not, see <https://www.gnu.org/licenses/>.
17*/
18#include "koliseo.h"
19
21 .kls_collect_stats = 0,
22 .kls_verbose_lvl = 0,
23 .kls_block_while_has_temp = 1,
24 .kls_allow_zerocount_push = 0,
25 .kls_log_fp = NULL,
26 .kls_growable = 0,
27 .kls_log_filepath = "",
28 .err_handlers = {
29#ifndef KOLISEO_HAS_LOCATE
30 .OOM_handler = &KLS_OOM_default_handler__,
31 .PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler__,
32 .ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler__,
33#else
34 .OOM_handler = &KLS_OOM_default_handler_dbg__,
35 .PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__,
36 .ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler_dbg__,
37#endif // KOLISEO_HAS_LOCATE
38 },
39};
40
42 .tot_pushes = 0,
43 .tot_temp_pushes = 0,
44 .tot_pops = 0,
45 .tot_temp_pops = 0,
46 .tot_logcalls = 0,
47 .tot_hiccups = 0,
48#ifdef KLS_DEBUG_CORE
49 .worst_pushcall_time = -1,
50#endif
51};
52
53static bool kls_set_conf(Koliseo * kls, KLS_Conf conf); //Declare function used internally by kls_new() and kls_new_conf()
54
59const char *string_koliseo_version(void)
60{
61 return KOLISEO_API_VERSION_STRING;
62}
63
69{
70 return KOLISEO_API_VERSION_INT;
71}
72
73#if defined(__SANITIZE_ADDRESS__)
74#include <sanitizer/asan_interface.h>
75#define KLS_ASAN_POISON(addr, size) __asan_poison_memory_region((addr), (size))
76#define KLS_ASAN_UNPOISON(addr, size) __asan_unpoison_memory_region((addr), (size))
77#else
78#define KLS_ASAN_POISON(addr, size) ((void)0)
79#define KLS_ASAN_UNPOISON(addr, size) ((void)0)
80#endif // __SANITIZE_ADDRESS__
81
91#ifndef KOLISEO_HAS_LOCATE
92void KLS_OOM_default_handler__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, ptrdiff_t count)
93#else
94void KLS_OOM_default_handler_dbg__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, ptrdiff_t count, Koliseo_Loc loc)
95#endif // KOLISEO_HAS_LOCATE
96{
97#ifndef KOLISEO_HAS_LOCATE
98 fprintf(stderr,
99 "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
100 size * count, available - padding);
101#else
102 fprintf(stderr,
103 "[KLS] " KLS_Loc_Fmt "Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
104 KLS_Loc_Arg(loc),
105 size * count, available - padding);
106#endif // KOLISEO_HAS_LOCATE
107 kls_free(kls); // Is it even worth it to try?
108 exit(EXIT_FAILURE); // Better than nothing. May change to return NULL instead? Requiring refactor of handler signature
109}
110
111#ifndef KOLISEO_HAS_LOCATE
112void KLS_PTRDIFF_MAX_default_handler__(struct Koliseo* kls, ptrdiff_t size, ptrdiff_t count)
113#else
114void KLS_PTRDIFF_MAX_default_handler_dbg__(struct Koliseo* kls, ptrdiff_t size, ptrdiff_t count, Koliseo_Loc loc)
115#endif
116{
117#ifndef _WIN32
118#ifndef KOLISEO_HAS_LOCATE
119 fprintf(stderr,
120 "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
121 count, PTRDIFF_MAX / size);
122#else
123 fprintf(stderr,
124 "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
125 KLS_Loc_Arg(loc),
126 count, PTRDIFF_MAX / size);
127#endif // KOLISEO_HAS_LOCATE
128#else
129#ifndef KOLISEO_HAS_LOCATE
130 fprintf(stderr,
131 "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
132 count, PTRDIFF_MAX / size);
133#else
134 fprintf(stderr,
135 "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
136 KLS_Loc_Arg(loc),
137 count, PTRDIFF_MAX / size);
138#endif // KOLISEO_HAS_LOCATE
139#endif // _WIN32
140 kls_free(kls);
141 exit(EXIT_FAILURE);
142}
143
153#ifndef KOLISEO_HAS_LOCATE
154void KLS_ZEROCOUNT_default_handler__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size)
155#else
156void KLS_ZEROCOUNT_default_handler_dbg__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, Koliseo_Loc loc)
157#endif // KOLISEO_HAS_LOCATE
158{
159#ifndef KOLISEO_HAS_LOCATE
160 fprintf(stderr,
161 "[KLS] Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
162 size, padding, available);
163#else
164 fprintf(stderr,
165 "[KLS] " KLS_Loc_Fmt "Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
166 KLS_Loc_Arg(loc),
167 size, padding, available);
168#endif // KOLISEO_HAS_LOCATE
169 kls_free(kls);
170 exit(EXIT_FAILURE);
171}
172
178KLS_Conf kls_conf_init_handled(int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, int growable, FILE* log_fp, const char* log_filepath, KLS_Err_Handlers err_handlers)
179{
180 KLS_Conf res = {0};
181 res.kls_collect_stats = collect_stats;
182 res.kls_verbose_lvl = verbose_lvl;
183 res.kls_block_while_has_temp = block_while_has_temp;
184 res.kls_allow_zerocount_push = allow_zerocount_push;
185 res.kls_growable = growable;
186 res.kls_log_fp = log_fp;
187 res.kls_log_filepath = log_filepath;
188
189 if (err_handlers.OOM_handler != NULL) {
190 res.err_handlers.OOM_handler = err_handlers.OOM_handler;
191 } else {
192#ifndef KOLISEO_HAS_LOCATE
194#else
195 res.err_handlers.OOM_handler = &KLS_OOM_default_handler_dbg__;
196#endif // KOLISEO_HAS_LOCATE
197 }
198
199 if (err_handlers.PTRDIFF_MAX_handler != NULL) {
201 } else {
202#ifndef KOLISEO_HAS_LOCATE
204#else
205 res.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__;
206#endif // KOLISEO_HAS_LOCATE
207 }
208
209 if (err_handlers.ZEROCOUNT_handler != NULL) {
211 } else {
212#ifndef KOLISEO_HAS_LOCATE
214#else
215 res.err_handlers.ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler_dbg__;
216#endif // KOLISEO_HAS_LOCATE
217 }
218
219 return res;
220}
221
226KLS_Conf kls_conf_init(int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, int growable, FILE* log_fp, const char* log_filepath)
227{
229 return kls_conf_init_handled(collect_stats, verbose_lvl, block_while_has_temp, allow_zerocount_push, growable, log_fp, log_filepath, err_handlers);
230}
231
236{
237#ifdef KOLISEO_HAS_LOCATE
238 bool kls_locate = true;
239#else
240 bool kls_locate = false;
241#endif
242#ifdef KLS_DEBUG_CORE
243 bool kls_debug = true;
244#else
245 bool kls_debug = false;
246#endif
247#ifdef KOLISEO_HAS_EXPER
248 bool kls_exper = true;
249#else
250 bool kls_exper = false;
251#endif
252 bool features[3] = {
253 [0] = kls_debug,
254 [1] = kls_locate,
255 [2] = kls_exper,
256 };
257 int total_enabled = 0;
258 for (int i=0; i<3; i++) {
259 if (features[i]) {
260 total_enabled += 1;
261 }
262 }
263 fprintf(stderr, "[KLS] Enabled features: {");
264 if (total_enabled == 0) {
265 fprintf(stderr, "none}\n");
266 return;
267 } else {
268 if (kls_debug) {
269 fprintf(stderr, "debug%s", (total_enabled > 1 ? ", " : ""));
270 total_enabled -= 1;
271 }
272 if (kls_locate) {
273 fprintf(stderr, "locate%s", (total_enabled > 1 ? ", " : ""));
274 total_enabled -= 1;
275 }
276 if (kls_exper) {
277 fprintf(stderr, "exper");
278 }
279 fprintf(stderr, "}\n");
280 }
281}
282
288ptrdiff_t kls_get_pos(const Koliseo *kls)
289{
290 return kls->offset;
291}
292
293#ifndef KOLISEO_HAS_LOCATE
294void* kls__handle_push_result(Koliseo* kls, KLS_Push_Result r, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t padding, const char* caller_name)
295#else
296void* kls__handle_push_result_dbg(Koliseo* kls, KLS_Push_Result r, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t padding, const char* caller_name, Koliseo_Loc loc)
297#endif
298{
299 if (!kls) return NULL;
300 Koliseo* current = kls;
301 while (current->next != NULL) {
302 current = current->next;
303 }
304 if (r.error) {
305 const ptrdiff_t available = current->size - current->offset;
306 switch (r.error) {
307 case KLS_PUSH_OK: {
308 return r.p;
309 }
310 break;
311 case KLS_PUSH_SIZE_LT1: {
312#ifndef KOLISEO_HAS_LOCATE
313 fprintf(stderr,
314 "[KLS] %s(): size [%td] was < 1.\n",
315 caller_name,
316 size);
317#else
318 fprintf(stderr,
319 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
320 KLS_Loc_Arg(loc),
321 caller_name,
322 size);
323#endif // KOLISEO_HAS_LOCATE
324 }
325 break;
326 case KLS_PUSH_ALIGN_LT1: {
327#ifndef KOLISEO_HAS_LOCATE
328 fprintf(stderr,
329 "[KLS] %s(): align [%td] was < 1.\n",
330 caller_name,
331 align);
332#else
333 fprintf(stderr,
334 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
335 KLS_Loc_Arg(loc),
336 caller_name,
337 align);
338#endif // KOLISEO_HAS_LOCATE
339 }
340 break;
342#ifndef KOLISEO_HAS_LOCATE
343 fprintf(stderr,
344 "[KLS] %s(): align [%td] was not a power of 2.\n",
345 caller_name,
346 align);
347#else
348 fprintf(stderr,
349 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
350 KLS_Loc_Arg(loc),
351 caller_name,
352 align);
353#endif // KOLISEO_HAS_LOCATE
354 }
355 break;
357#ifndef KOLISEO_HAS_LOCATE
358 fprintf(stderr,
359 "[KLS] %s(): count [%td] was < 0.\n",
360 caller_name,
361 count);
362#else
363 fprintf(stderr,
364 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was < 0.\n",
365 KLS_Loc_Arg(loc),
366 caller_name,
367 count);
368#endif // KOLISEO_HAS_LOCATE
369 }
370 break;
371 case KLS_PUSH_ZEROCOUNT: {
372 if (current->conf.err_handlers.ZEROCOUNT_handler != NULL) {
373#ifndef KOLISEO_HAS_LOCATE
374 current->conf.err_handlers.ZEROCOUNT_handler(current, available, padding, size);
375#else
376 current->conf.err_handlers.ZEROCOUNT_handler(current, available, padding, size, loc);
377#endif // KOLISEO_HAS_LOCATE
378 } else {
379#ifndef KOLISEO_HAS_LOCATE
380 fprintf(stderr,
381 "[KLS] %s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
382 caller_name,
383 size, padding, available);
384#else
385 fprintf(stderr,
386 "[KLS] " KLS_Loc_Fmt "%s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
387 KLS_Loc_Arg(loc),
388 caller_name,
389 size, padding, available);
390#endif // KOLISEO_HAS_LOCATE
391 kls_free(kls);
392 exit(EXIT_FAILURE);
393 }
394 }
395 break;
397#ifndef KOLISEO_HAS_LOCATE
398 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", caller_name);
399#else
400 fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), caller_name);
401 kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), caller_name);
402 exit(EXIT_FAILURE);
403#endif // KOLISEO_HAS_LOCATE
404 }
405 break;
407 if (current->conf.err_handlers.PTRDIFF_MAX_handler != NULL) {
408#ifndef KOLISEO_HAS_LOCATE
409 current->conf.err_handlers.PTRDIFF_MAX_handler(current, size, count);
410#else
411 current->conf.err_handlers.PTRDIFF_MAX_handler(current, size, count, loc);
412#endif // KOLISEO_HAS_LOCATE
413 } else { // Let's keep this here for now? It's the original part before adding KLS_PTRDIFF_MAX_default_handler__()
414#ifndef _WIN32
415#ifndef KOLISEO_HAS_LOCATE
416 fprintf(stderr,
417 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
418 caller_name,
419 count, PTRDIFF_MAX / size);
420#else
421 fprintf(stderr,
422 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
423 KLS_Loc_Arg(loc),
424 caller_name,
425 count, PTRDIFF_MAX / size);
426#endif // KOLISEO_HAS_LOCATE
427#else
428#ifndef KOLISEO_HAS_LOCATE
429 fprintf(stderr,
430 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
431 caller_name,
432 count, PTRDIFF_MAX / size);
433#else
434 fprintf(stderr,
435 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
436 KLS_Loc_Arg(loc),
437 caller_name,
438 count, PTRDIFF_MAX / size);
439#endif // KOLISEO_HAS_LOCATE
440#endif // _WIN32
441 }
442 }
443 break;
444 case KLS_PUSH_OOM: {
445 if (current->conf.err_handlers.OOM_handler != NULL) {
446#ifndef KOLISEO_HAS_LOCATE
447 current->conf.err_handlers.OOM_handler(current, available, padding, size, count);
448#else
449 current->conf.err_handlers.OOM_handler(current, available, padding, size, count, loc);
450#endif // KOLISEO_HAS_LOCATE
451 } else { // Let's keep this here for now? It's the original part before adding KLS_OOM_default_handler__()
452#ifndef KOLISEO_HAS_LOCATE
453 fprintf(stderr,
454 "[KLS] %s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
455 caller_name,
456 size * count, available - padding);
457#else
458 fprintf(stderr,
459 "[KLS] " KLS_Loc_Fmt "%s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
460 KLS_Loc_Arg(loc),
461 caller_name,
462 size * count, available - padding);
463#endif // KOLISEO_HAS_LOCATE
464 }
465 }
466 break;
467 default: {
468 fprintf(stderr, "[KLS] %s(): unexpected error code [%i]\n", __func__, r.error);
469 return NULL;
470 }
471 break;
472 }
473 }
474 return r.p;
475}
476
483void kls_log(Koliseo *kls, const char *tag, const char *format, ...)
484{
485 if (kls == NULL) {
486 fprintf(stderr, "[KLS] %s(): Passed kls was NULL.\n", __func__);
487 return;
488 }
489 if (kls->conf.kls_verbose_lvl > 0) {
490 va_list args;
491 FILE *fp = kls->conf.kls_log_fp;
492 va_start(args, format);
493 if (fp == NULL) {
494 fprintf(stderr,
495 "[KLS] %s(): Failed opening file to print logs.\n",
496 __func__);
497 } else {
498 time_t now = time(0);
499 const struct tm *mytime = localtime(&now);
500 char timeheader[500];
501 if (strftime(timeheader, sizeof timeheader, "%X", mytime)) {
502 fprintf(fp, "[%-10.10s] [%s] [", tag, timeheader);
503 vfprintf(fp, format, args);
504 fprintf(fp, "]\n");
505 }
506 }
507 va_end(args);
508 }
509}
510
528#ifndef KOLISEO_HAS_LOCATE
529Koliseo *kls_new_alloc_ext(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
530#else
531Koliseo *kls_new_alloc_ext_dbg(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Hooks* ext_handlers, void** user, size_t ext_len, Koliseo_Loc loc)
532#endif // KOLISEO_HAS_LOCATE
533{
534 if (size < (ptrdiff_t)sizeof(Koliseo)) {
535#ifndef KOLISEO_HAS_LOCATE
536 fprintf(stderr,
537 "[ERROR] at %s(): invalid requested kls size (%td). Min accepted is: (%td).\n",
538 __func__, size, (ptrdiff_t)sizeof(Koliseo));
539#else
540 fprintf(stderr,
541 "[ERROR] " KLS_Loc_Fmt "%s(): invalid requested kls size (%td). Min accepted is: (%td).\n",
542 KLS_Loc_Arg(loc), __func__, size, (ptrdiff_t)sizeof(Koliseo));
543#endif // KOLISEO_HAS_LOCATE
544 //TODO Is it better to abort the program?
545 return NULL;
546 }
547 void *p = alloc_func(size);
548 if (p) {
549 //sprintf(msg,"Allocated (%li) for new KLS.",size);
550 //kls_log("KLS",msg);
551 char h_size[200];
552 kls_formatSize(size, h_size, sizeof(h_size));
553 Koliseo *kls = p;
554 kls->data = p;
555 kls->size = size;
556 kls->offset = sizeof(*kls);
557 kls->prev_offset = kls->offset;
558 kls->has_temp = 0;
559 kls->t_kls = NULL;
560 kls_set_conf(kls, KLS_DEFAULT_CONF);
562 kls->conf.kls_log_fp = stderr;
563 kls->hooks_len = ext_len;
564
565 KLS_ASAN_POISON(kls->data + kls->offset, kls->size - kls->offset);
566
567 for (size_t i=0; i < kls->hooks_len; i++) {
568 kls->hooks[i] = ext_handlers[i];
569 }
570 for (size_t i=0; i < kls->hooks_len; i++) {
571 if (user) {
572 kls->extension_data[i] = user[i];
573 } else {
574 kls->extension_data[i] = NULL;
575 }
576 }
577 kls->free_func = free_func;
578 kls->next = NULL;
579#ifdef KLS_DEBUG_CORE
580 kls_log(kls, "KLS", "API Level { %i } -> Allocated (%s) for new KLS.",
581 int_koliseo_version(), h_size);
582 kls_log(kls, "KLS", "KLS offset: { %p }.", kls);
583 kls_log(kls, "KLS", "Allocation begin offset: { %p }.",
584 kls + kls->offset);
585#endif
586
587 for (size_t i=0; i < kls->hooks_len; i++) {
588 if (kls->hooks[i].on_new_handler != NULL) {
589 // Call on_new extension
590 kls->hooks[i].on_new_handler(kls);
591 }
592 }
593 } else {
594#ifndef KOLISEO_HAS_LOCATE
595 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
596#else
597 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), __func__);
598#endif // KOLISEO_HAS_LOCATE
599 exit(EXIT_FAILURE);
600 }
601#ifdef KLS_DEBUG_CORE
602 Koliseo *kls_ref = p;
603 if (kls_ref->conf.kls_verbose_lvl > 0) {
604 print_kls_2file(kls_ref->conf.kls_log_fp, p);
605 }
606#endif
607 return p;
608}
609
625#ifndef KOLISEO_HAS_LOCATE
626Koliseo *kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
627#else
628Koliseo *kls_new_alloc_dbg(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, Koliseo_Loc loc)
629#endif // KOLISEO_HAS_LOCATE
630{
631#ifndef KOLISEO_HAS_LOCATE
633#else
634 return kls_new_alloc_ext_dbg(size, alloc_func, free_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA, KLS_DEFAULT_EXTENSIONS_LEN, loc);
635#endif // KOLISEO_HAS_LOCATE
636}
637
650Koliseo *kls_new(ptrdiff_t size)
651{
653}
654
671Koliseo *kls_new_conf_alloc_ext(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
672{
673 Koliseo *k = kls_new_alloc_ext(size, alloc_func, free_func, ext_handlers, user, ext_len);
674 bool conf_res = kls_set_conf(k, conf);
675 if (!conf_res) {
676 fprintf(stderr,
677 "[ERROR] [%s()]: Failed to set config for new Koliseo.\n",
678 __func__);
679 exit(EXIT_FAILURE);
680 }
681 return k;
682}
683
700Koliseo *kls_new_conf_alloc(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, kls_free_func free_func)
701{
703}
704
717Koliseo *kls_new_conf_ext(ptrdiff_t size, KLS_Conf conf, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
718{
719 return kls_new_conf_alloc_ext(size, conf, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, ext_handlers, user, ext_len);
720}
721
733Koliseo *kls_new_conf(ptrdiff_t size, KLS_Conf conf)
734{
736}
737
753Koliseo *kls_new_traced_alloc_handled_ext(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
754{
755
756#ifndef KLS_DEBUG_CORE
757 fprintf(stderr,
758 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No tracing allowed.\n",
759 __func__);
760#endif
761 KLS_Conf k = (KLS_Conf) {
762 .kls_collect_stats = 1,.kls_verbose_lvl =
763 1,.kls_log_filepath = output_path,
764#ifndef KOLISEO_HAS_LOCATE
765 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
766 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
767#else
768 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
769 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
770#endif // KOLISEO_HAS_LOCATE
771 };
772 return kls_new_conf_alloc_ext(size, k, alloc_func, free_func, ext_handlers, user, ext_len);
773}
774
789Koliseo *kls_new_traced_alloc_handled(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers)
790{
791 return kls_new_traced_alloc_handled_ext(size, output_path, alloc_func, free_func, err_handlers, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA, KLS_DEFAULT_EXTENSIONS_LEN);
792}
793
806Koliseo *kls_new_traced_ext(ptrdiff_t size, const char *output_path, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
807{
809 return kls_new_traced_alloc_handled_ext(size, output_path, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers, ext_handlers, user, ext_len);
810}
811
825Koliseo *kls_new_traced_alloc(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func)
826{
828 return kls_new_traced_alloc_handled(size, output_path, alloc_func, free_func, err_handlers);
829}
830
842Koliseo *kls_new_traced(ptrdiff_t size, const char *output_path)
843{
845}
846
859Koliseo *kls_new_traced_handled(ptrdiff_t size, const char *output_path, KLS_Err_Handlers err_handlers)
860{
861 return kls_new_traced_alloc_handled(size, output_path, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers);
862}
863
877Koliseo *kls_new_dbg_alloc_handled_ext(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
878{
879#ifndef KLS_DEBUG_CORE
880 fprintf(stderr,
881 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No debugging support.\n",
882 __func__);
883#endif
884 KLS_Conf k = (KLS_Conf) {
885 .kls_collect_stats = 1,.kls_verbose_lvl = 0,
886#ifndef KOLISEO_HAS_LOCATE
887 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
888 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
889#else
890 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
891 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
892#endif // KOLIEO_HAS_LOCATE
893 };
894 Koliseo * kls = kls_new_conf_alloc_ext(size, k, alloc_func, free_func, ext_handlers, user, ext_len);
895 kls->conf.kls_verbose_lvl = 1;
896 return kls;
897}
898
911Koliseo *kls_new_dbg_alloc_handled(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers)
912{
914}
915
926Koliseo *kls_new_dbg_ext(ptrdiff_t size, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
927{
929 return kls_new_dbg_alloc_handled_ext(size, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers, ext_handlers, user, ext_len);
930}
931
943Koliseo *kls_new_dbg_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
944{
946 return kls_new_dbg_alloc_handled(size, alloc_func, free_func, err_handlers);
947}
948
958Koliseo *kls_new_dbg(ptrdiff_t size)
959{
961}
962
973Koliseo *kls_new_dbg_handled(ptrdiff_t size, KLS_Err_Handlers err_handlers)
974{
976}
977
984bool kls_set_conf(Koliseo *kls, KLS_Conf conf)
985{
986 if (kls == NULL) {
987 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
988 //TODO: is it better to exit() here?
989 return false;
990 }
991
992 kls->conf = conf;
993 if (kls->conf.kls_log_fp == NULL) {
994 kls->conf.kls_log_fp = stderr;
995#ifdef KLS_DEBUG_CORE
996#ifdef KLS_SETCONF_DEBUG
997 kls_log(kls, "KLS",
998 "[%s()]: Preliminary set of conf.kls_log_fp to stderr.",
999 __func__);
1000#endif
1001#endif // KLS_DEBUG_CORE
1002 }
1003
1004 if (conf.err_handlers.OOM_handler == NULL) {
1005 fprintf(stderr,
1006 "[ERROR] at %s(): passed OOM_handler is NULL. Using default.\n",
1007 __func__);
1008#ifdef KLS_DEBUG_CORE
1009#ifdef KLS_SETCONF_DEBUG
1010 kls_log(kls, "KLS",
1011 "[%s()]: Passed OOM_handler was NULL, using default.",
1012 __func__);
1013#endif
1014#endif // KLS_DEBUG_CORE
1015#ifndef KOLISEO_HAS_LOCATE
1017#else
1018 kls->conf.err_handlers.OOM_handler = &KLS_OOM_default_handler_dbg__;
1019#endif
1020 }
1021
1022 if (conf.err_handlers.PTRDIFF_MAX_handler == NULL) {
1023 fprintf(stderr,
1024 "[ERROR] at %s(): passed PTRDIFF_MAX_handler is NULL. Using default.\n",
1025 __func__);
1026#ifdef KLS_DEBUG_CORE
1027#ifdef KLS_SETCONF_DEBUG
1028 kls_log(kls, "KLS",
1029 "[%s()]: Passed PTRDIFF_MAX_handler was NULL, using default.",
1030 __func__);
1031#endif
1032#endif // KLS_DEBUG_CORE
1033#ifndef KOLISEO_HAS_LOCATE
1035#else
1036 kls->conf.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__;
1037#endif
1038 }
1039
1040#ifndef KLS_DEBUG_CORE
1041 if (kls->conf.kls_collect_stats == 1) {
1042 fprintf(stderr,
1043 "[WARN] [%s()]: KLS_DEBUG_CORE is not defined. Stats may not be collected in full.\n",
1044 __func__);
1045 }
1046#endif
1047
1048 if (kls->conf.kls_verbose_lvl > 0) {
1049 if (kls->conf.kls_log_fp != NULL) {
1050#ifdef KLS_DEBUG_CORE
1051#ifdef KLS_SETCONF_DEBUG
1052 kls_log(kls, "WARN",
1053 "[%s()]: kls->conf.kls_log_fp was not NULL. Overriding it.",
1054 __func__);
1055#endif
1056#endif
1057 if (kls->conf.kls_collect_stats == 1) {
1058 kls->stats.tot_hiccups += 1;
1059 }
1060 }
1061
1062 FILE *log_fp = NULL;
1063 log_fp = fopen(kls->conf.kls_log_filepath, "w");
1064 if (!log_fp) {
1065 fprintf(stderr,
1066 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [write].\n",
1067 __func__, kls->conf.kls_log_filepath);
1068 return false;
1069 } else {
1070 fprintf(log_fp, "%s", ""); //Reset log_fp
1071 fclose(log_fp);
1072 }
1073 log_fp = fopen(kls->conf.kls_log_filepath, "a");
1074 if (!log_fp) {
1075 fprintf(stderr,
1076 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [append].\n",
1077 __func__, kls->conf.kls_log_filepath);
1078 return false;
1079 } else {
1080 kls->conf.kls_log_fp = log_fp;
1081 }
1082 }
1083 return true;
1084}
1085
1086static bool kls__try_grow(Koliseo* kls, ptrdiff_t needed);
1087
1099#ifndef KOLISEO_HAS_LOCATE
1100KLS_Push_Result kls__advance(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t* padding, const char* caller_name)
1101#else
1102KLS_Push_Result kls__advance_dbg(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t* padding, const char* caller_name, Koliseo_Loc loc)
1103#endif // KOLISEO_HAS_LOCATE
1104{
1105#ifdef KLS_DEBUG_CORE
1106#ifndef _WIN32
1107 struct timespec start_time, end_time;
1108 clock_gettime(CLOCK_MONOTONIC, &start_time);
1109#else
1110 LARGE_INTEGER start_time, end_time, frequency;
1111 QueryPerformanceFrequency(&frequency);
1112 QueryPerformanceCounter(&start_time);
1113#endif
1114#endif
1115
1116 if (kls == NULL) {
1117 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", caller_name);
1118 exit(EXIT_FAILURE);
1119 }
1120 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1121 return (KLS_Push_Result) {
1122 .p = NULL,
1124 };
1125 }
1126
1127#ifndef KOLISEO_HAS_LOCATE
1128 KLS_Push_Error res = kls__check_available_failable(kls, size, align, count, __func__);
1129#else
1130 KLS_Push_Error res = kls__check_available_failable_dbg(kls, size, align, count, __func__, loc);
1131#endif
1132 if (res != 0) {
1133 return (KLS_Push_Result) {
1134 .p = NULL,
1135 .error = res,
1136 };
1137 }
1138 Koliseo* current = kls;
1139 while (current->next != NULL) {
1140 current = current->next;
1141 }
1142 const ptrdiff_t pad = -current->offset & (align - 1);
1143 *padding = pad;
1144 char *p = current->data + current->offset + pad;
1145 current->prev_offset = current->offset;
1146 current->offset += pad + size * count;
1147
1148 KLS_ASAN_UNPOISON(p, size * count);
1149
1150 char h_size[200];
1151 kls_formatSize(size * count, h_size, sizeof(h_size));
1152 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1153 //kls_log("KLS",msg);
1154#ifdef KLS_DEBUG_CORE
1155 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1156 kls_log(current, "KLS", "API Level { %i } -> Pushed zeroes, size (%s) for KLS.",
1157 int_koliseo_version(), h_size);
1158 if (current->conf.kls_verbose_lvl > 0) {
1159 print_kls_2file(current->conf.kls_log_fp, current);
1160 }
1161 if (current->conf.kls_collect_stats == 1) {
1162#ifndef _WIN32
1163 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1164 double elapsed_time =
1165 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1166 start_time.tv_nsec) / 1e9;
1167#else
1168 QueryPerformanceCounter(&end_time); // %.7f
1169 double elapsed_time =
1170 (double)(end_time.QuadPart -
1171 start_time.QuadPart) / frequency.QuadPart;
1172#endif
1173 if (elapsed_time > current->stats.worst_pushcall_time) {
1174 current->stats.worst_pushcall_time = elapsed_time;
1175 }
1176 }
1177#endif
1178 if (current->conf.kls_collect_stats == 1) {
1179 current->stats.tot_pushes += 1;
1180 }
1181 return (KLS_Push_Result) {
1182 .p = p,
1183 .error = KLS_PUSH_OK,
1184 };
1185}
1186
1199#ifndef KOLISEO_HAS_LOCATE
1200KLS_Push_Error kls__check_available_failable(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name)
1201#else
1202KLS_Push_Error kls__check_available_failable_dbg(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name, Koliseo_Loc loc)
1203#endif // KOLISEO_HAS_LOCATE
1204{
1205 assert(kls != NULL);
1206 assert(caller_name != NULL);
1207 if (count < 0) {
1209 }
1210 if (size < 1) {
1211 return KLS_PUSH_SIZE_LT1;
1212 }
1213 if (align < 1) {
1214 return KLS_PUSH_ALIGN_LT1;
1215 }
1216 if (! ((align & (align - 1)) == 0)) {
1218 }
1219 Koliseo* current = kls;
1220 while (current->next != NULL) {
1221 current = current->next;
1222 }
1223 const ptrdiff_t available = current->size - current->offset;
1224 const ptrdiff_t padding = -current->offset & (align - 1);
1225 if (count == 0) {
1226 if (current->conf.kls_allow_zerocount_push != 1) {
1227 return KLS_PUSH_ZEROCOUNT;
1228 } else {
1229#ifdef KLS_DEBUG_CORE
1230 kls_log(current, "DEBUG", "Accepting zero-count push: conf.kls_allow_zerocount_push was 1");
1231#endif // KLS_DEBUG_CORE
1232 }
1233 }
1234
1235 if (count > PTRDIFF_MAX / size || available - padding < size * count) {
1236 if (count > PTRDIFF_MAX / size) {
1237 return KLS_PUSH_PTRDIFF_MAX;
1238 } else {
1239 if (current->conf.kls_growable == 1 && kls__try_grow(current, size + count + padding)) {
1240 return KLS_PUSH_OK;
1241 }
1242 return KLS_PUSH_OOM;
1243 }
1244 }
1245 return KLS_PUSH_OK;
1246}
1247
1259#ifndef KOLISEO_HAS_LOCATE
1260KLS_Push_Result kls__temp_advance(Koliseo_Temp* kls_t, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t* padding, const char* caller_name)
1261#else
1262KLS_Push_Result kls__temp_advance_dbg(Koliseo_Temp* kls_t, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t* padding, const char* caller_name, Koliseo_Loc loc)
1263#endif // KOLISEO_HAS_LOCATE
1264{
1265#ifdef KLS_DEBUG_CORE
1266#ifndef _WIN32
1267 struct timespec start_time, end_time;
1268 clock_gettime(CLOCK_MONOTONIC, &start_time);
1269#else
1270 LARGE_INTEGER start_time, end_time, frequency;
1271 QueryPerformanceFrequency(&frequency);
1272 QueryPerformanceCounter(&start_time);
1273#endif
1274#endif
1275
1276 if (kls_t == NULL) {
1277 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1278 __func__);
1279 exit(EXIT_FAILURE);
1280 }
1281 Koliseo *kls = kls_t->kls;
1282 if (kls == NULL) {
1283 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1284 __func__);
1285 exit(EXIT_FAILURE);
1286 }
1287#ifndef KOLISEO_HAS_LOCATE
1288 KLS_Push_Error res = kls__check_available_failable(kls, size, align, count, __func__);
1289#else
1290 KLS_Push_Error res = kls__check_available_failable_dbg(kls, size, align, count, __func__, loc);
1291#endif
1292 if (res != 0) {
1293 return (KLS_Push_Result) {
1294 .p = NULL,
1295 .error = res,
1296 };
1297 }
1298 Koliseo* current = kls;
1299 while (current->next != NULL) {
1300 current = current->next;
1301 }
1302 ptrdiff_t pad = -current->offset & (align - 1);
1303 char *p = current->data + current->offset + pad;
1304 *padding = pad;
1305 current->prev_offset = current->offset;
1306 current->offset += pad + size * count;
1307
1308 KLS_ASAN_UNPOISON(p, size * count);
1309
1310 char h_size[200];
1311 kls_formatSize(size * count, h_size, sizeof(h_size));
1312 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1313 //kls_log("KLS",msg);
1314#ifdef KLS_DEBUG_CORE
1315 if (current->conf.kls_collect_stats == 1) {
1316#ifndef _WIN32
1317 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1318 double elapsed_time =
1319 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1320 start_time.tv_nsec) / 1e9;
1321#else
1322 QueryPerformanceCounter(&end_time); // %.7f
1323 double elapsed_time =
1324 (double)(end_time.QuadPart -
1325 start_time.QuadPart) / frequency.QuadPart;
1326#endif
1327 if (elapsed_time > current->stats.worst_pushcall_time) {
1328 current->stats.worst_pushcall_time = elapsed_time;
1329 }
1330 }
1331 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1332 kls_log(current, "KLS",
1333 "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.",
1334 int_koliseo_version(), h_size);
1335 if (current->conf.kls_verbose_lvl > 0) {
1336 print_kls_2file(current->conf.kls_log_fp, current);
1337 }
1338#endif
1339 if (current->conf.kls_collect_stats == 1) {
1340 current->stats.tot_temp_pushes += 1;
1341 }
1342 return (KLS_Push_Result) {
1343 .p = p,
1344 .error = KLS_PUSH_OK,
1345 };
1346}
1347
1348bool kls__try_grow(Koliseo* kls, ptrdiff_t needed)
1349{
1350 ptrdiff_t new_size = KLS_MAX(kls->size * 2, needed);
1352 kls_log(kls, "DEBUG", "%s(): growing Koliseo, new size: {%td}", __func__, new_size);
1353 if (!new_kls) return false;
1354 kls->next = new_kls;
1355 return true;
1356}
1357
1368void *kls_push(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1369{
1370 ptrdiff_t padding = 0;
1371#ifndef KOLISEO_HAS_LOCATE
1372 KLS_Push_Result res = kls__advance(kls, size, align, count, &padding, __func__);
1373 return kls__handle_push_result(kls, res, size, align, count, padding, __func__);
1374#else
1375 KLS_Push_Result res = kls__advance_dbg(kls, size, align, count, &padding, __func__, KLS_HERE);
1376 return kls__handle_push_result_dbg(kls, res, size, align, count, padding, __func__, KLS_HERE);
1377#endif // KOLISEO_HAS_LOCATE
1378}
1379
1390#ifndef KOLISEO_HAS_LOCATE
1391void *kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1392 ptrdiff_t count)
1393#else
1394void *kls_push_zero_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1395 ptrdiff_t count, Koliseo_Loc loc)
1396#endif // KOLISEO_HAS_LOCATE
1397{
1398 ptrdiff_t padding = 0;
1399#ifndef KOLISEO_HAS_LOCATE
1400 KLS_Push_Result res = kls__advance(kls, size, align, count, &padding, __func__);
1401 void* p = kls__handle_push_result(kls, res, size, align, count, padding, __func__);
1402#else
1403 KLS_Push_Result res = kls__advance_dbg(kls, size, align, count, &padding, __func__, loc);
1404 void* p = kls__handle_push_result_dbg(kls, res, size, align, count, padding, __func__, loc);
1405#endif // KOLISEO_HAS_LOCATE
1406 if (!p) return NULL;
1407 //Zero new area
1408 memset(p, 0, size * count);
1409 return p;
1410}
1411
1423#ifndef KOLISEO_HAS_LOCATE
1424void *kls_push_zero_ext(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1425 ptrdiff_t count)
1426#else
1427void *kls_push_zero_ext_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1428 ptrdiff_t count, Koliseo_Loc loc)
1429#endif // KOLISEO_HAS_LOCATE
1430{
1431
1432 ptrdiff_t padding = 0;
1433#ifndef KOLISEO_HAS_LOCATE
1434 KLS_Push_Result res = kls__advance(kls, size, align, count, &padding, __func__);
1435 void* p = kls__handle_push_result(kls, res, size, align, count, padding, __func__);
1436#else
1437 KLS_Push_Result res = kls__advance_dbg(kls, size, align, count, &padding, __func__, loc);
1438 void* p = kls__handle_push_result_dbg(kls, res, size, align, count, padding, __func__, loc);
1439#endif // KOLISEO_HAS_LOCATE
1440 if (!p) return NULL;
1441 //Zero new area
1442 memset(p, 0, size * count);
1443
1444 Koliseo* current = kls;
1445 while (current->next != NULL) {
1446 current = current->next;
1447 }
1448
1449 for (size_t i=0; i < current->hooks_len; i++) {
1450 if (current->hooks[i].on_push_handler != NULL) {
1451 /*
1452 struct KLS_EXTENSION_AR_DEFAULT_ARGS {
1453 const char* region_name;
1454 size_t region_name_len;
1455 const char* region_desc;
1456 size_t region_desc_len;
1457 int region_type;
1458 };
1459 struct KLS_EXTENSION_AR_DEFAULT_ARGS ar_args = {
1460 .region_name = KOLISEO_DEFAULT_REGION_NAME,
1461 .region_name_len = strlen(KOLISEO_DEFAULT_REGION_NAME),
1462 .region_desc = KOLISEO_DEFAULT_REGION_DESC,
1463 .region_desc_len = strlen(KOLISEO_DEFAULT_REGION_DESC),
1464 .region_type = KLS_None
1465 };
1466 kls->hooks.on_push_handler(kls, padding, (void*)&ar_args);
1467 */
1468 current->hooks[i].on_push_handler(current, padding, __func__, NULL);
1469 }
1470 }
1471 return p;
1472}
1473
1474#ifndef KOLISEO_HAS_LOCATE
1475char* kls_vsprintf(Koliseo* kls, const char* fmt, va_list args)
1476#else
1477char* kls_vsprintf_dbg(Koliseo* kls, Koliseo_Loc loc, const char* fmt, va_list args)
1478#endif // KOLISEO_HAS_LOCATE
1479{
1480 va_list args_copy;
1481 va_copy(args_copy, args);
1482 int len = vsnprintf(NULL, 0, fmt, args);
1483#ifndef KOLISEO_HAS_LOCATE
1484 char* str = KLS_PUSH_ARR(kls, char, len+1);
1485#else
1486 char* str = kls_push_zero_ext_dbg(kls, sizeof(char), KLS_ALIGNOF(char), len+1, loc);
1487#endif // KOLISEO_HAS_LOCATE
1488 vsnprintf(str, len+1, fmt, args_copy);
1489 va_end(args_copy);
1490 return str;
1491}
1492
1499#ifndef KOLISEO_HAS_LOCATE
1500char* kls_sprintf(Koliseo* kls, const char* fmt, ...)
1501#else
1502char* kls_sprintf_dbg(Koliseo* kls, Koliseo_Loc loc, const char* fmt, ...)
1503#endif // KOLISEO_HAS_LOCATE
1504{
1505 va_list args;
1506 va_start(args, fmt);
1507#ifndef KOLISEO_HAS_LOCATE
1508 char* str = kls_vsprintf(kls, fmt, args);
1509#else
1510 char* str = kls_vsprintf_dbg(kls, loc, fmt, args);
1511#endif // KOLISEO_HAS_LOCATE
1512 va_end(args);
1513 return str;
1514}
1515
1527#ifndef KOLISEO_HAS_LOCATE
1528void *kls_temp_push_zero_ext(Koliseo_Temp *t_kls, ptrdiff_t size,
1529 ptrdiff_t align, ptrdiff_t count)
1530#else
1531void *kls_temp_push_zero_ext_dbg(Koliseo_Temp *t_kls, ptrdiff_t size,
1532 ptrdiff_t align, ptrdiff_t count, Koliseo_Loc loc)
1533#endif // KOLISEO_HAS_LOCATE
1534{
1535
1536 ptrdiff_t padding = 0;
1537
1538#ifndef KOLISEO_HAS_LOCATE
1539 KLS_Push_Result res = kls__temp_advance(t_kls, size, align, count, &padding, __func__);
1540#else
1541 KLS_Push_Result res = kls__temp_advance_dbg(t_kls, size, align, count, &padding, __func__, loc);
1542#endif // KOLISEO_HAS_LOCATE
1543 if (res.error) return NULL;
1544 //Zero new area
1545 memset(res.p, 0, size * count);
1546
1547 Koliseo* kls = t_kls->kls;
1548 Koliseo* current = kls;
1549 while (current->next != NULL) {
1550 current = current->next;
1551 }
1552
1553 for (size_t i=0; i < current->hooks_len; i++) {
1554 if (current->hooks[i].on_temp_push_handler != NULL) {
1555 // Call on_temp_push extension with empty user arg
1556 current->hooks[i].on_temp_push_handler(t_kls, padding, __func__, NULL);
1557 }
1558 }
1559 return res.p;
1560}
1561
1562#ifndef KOLISEO_HAS_LOCATE
1563char* kls_temp_vsprintf(Koliseo_Temp* kls_t, const char* fmt, va_list args)
1564#else
1565char* kls_temp_vsprintf_dbg(Koliseo_Temp* kls_t, Koliseo_Loc loc, const char* fmt, va_list args)
1566#endif // KOLISEO_HAS_LOCATE
1567{
1568 va_list args_copy;
1569 va_copy(args_copy, args);
1570 int len = vsnprintf(NULL, 0, fmt, args);
1571#ifndef KOLISEO_HAS_LOCATE
1572 char* str = KLS_PUSH_ARR_T(kls_t, char, len+1);
1573#else
1574 char* str = kls_temp_push_zero_ext_dbg(kls_t, sizeof(char), KLS_ALIGNOF(char), len+1, loc);
1575#endif // KOLISEO_HAS_LOCATE
1576 vsnprintf(str, len+1, fmt, args_copy);
1577 va_end(args_copy);
1578 return str;
1579}
1580
1581
1588#ifndef KOLISEO_HAS_LOCATE
1589char* kls_temp_sprintf(Koliseo_Temp* kls_t, const char* fmt, ...)
1590#else
1591char* kls_temp_sprintf_dbg(Koliseo_Temp* kls_t, Koliseo_Loc loc, const char* fmt, ...)
1592#endif // KOLISEO_HAS_LOCATE
1593{
1594 va_list args;
1595 va_start(args, fmt);
1596#ifndef KOLISEO_HAS_LOCATE
1597 char* str = kls_temp_vsprintf(kls_t, fmt, args);
1598#else
1599 char* str = kls_temp_vsprintf_dbg(kls_t, loc, fmt, args);
1600#endif // KOLISEO_HAS_LOCATE
1601 va_end(args);
1602 return str;
1603}
1604
1616#ifndef KOLISEO_HAS_LOCATE
1617void *kls_repush(Koliseo *kls, void* old, ptrdiff_t size, ptrdiff_t align,
1618 ptrdiff_t old_count, ptrdiff_t new_count)
1619#else
1620void *kls_repush_dbg(Koliseo *kls, void* old, ptrdiff_t size, ptrdiff_t align,
1621 ptrdiff_t old_count, ptrdiff_t new_count, Koliseo_Loc loc)
1622#endif // KOLISEO_HAS_LOCATE
1623{
1624 if (!old) {
1625#ifndef KOLISEO_HAS_LOCATE
1626 fprintf(stderr,
1627 "[KLS] %s(): old was NULL.\n",
1628 __func__);
1629#else
1630 fprintf(stderr,
1631 "[KLS] " KLS_Loc_Fmt "%s(): old was NULL.\n",
1632 KLS_Loc_Arg(loc),
1633 __func__);
1634#endif // KOLISEO_HAS_LOCATE
1635 return NULL;
1636 }
1637 if (old_count < 0) {
1638#ifndef KOLISEO_HAS_LOCATE
1639 fprintf(stderr,
1640 "[KLS] %s(): old_count [%td] was < 0.\n",
1641 __func__,
1642 old_count);
1643#else
1644 fprintf(stderr,
1645 "[KLS] " KLS_Loc_Fmt "%s(): old_count [%td] was < 0.\n",
1646 KLS_Loc_Arg(loc),
1647 __func__,
1648 old_count);
1649#endif // KOLISEO_HAS_LOCATE
1650 return NULL;
1651 }
1652 if (new_count < 0) {
1653#ifndef KOLISEO_HAS_LOCATE
1654 fprintf(stderr,
1655 "[KLS] %s(): new_count [%td] was < 0.\n",
1656 __func__,
1657 new_count);
1658#else
1659 fprintf(stderr,
1660 "[KLS] " KLS_Loc_Fmt "%s(): new_count [%td] was < 0.\n",
1661 KLS_Loc_Arg(loc),
1662 __func__,
1663 new_count);
1664#endif // KOLISEO_HAS_LOCATE
1665 return NULL;
1666 }
1667 if (size < 1) {
1668#ifndef KOLISEO_HAS_LOCATE
1669 fprintf(stderr,
1670 "[KLS] %s(): size [%td] was < 1.\n",
1671 __func__,
1672 size);
1673#else
1674 fprintf(stderr,
1675 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
1676 KLS_Loc_Arg(loc),
1677 __func__,
1678 size);
1679#endif // KOLISEO_HAS_LOCATE
1680 return NULL;
1681 }
1682 if (align < 1) {
1683#ifndef KOLISEO_HAS_LOCATE
1684 fprintf(stderr,
1685 "[KLS] %s(): align [%td] was < 1.\n",
1686 __func__,
1687 align);
1688#else
1689 fprintf(stderr,
1690 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
1691 KLS_Loc_Arg(loc),
1692 __func__,
1693 align);
1694#endif // KOLISEO_HAS_LOCATE
1695 return NULL;
1696 }
1697 if (! ((align & (align - 1)) == 0)) {
1698#ifndef KOLISEO_HAS_LOCATE
1699 fprintf(stderr,
1700 "[KLS] %s(): align [%td] was not a power of 2.\n",
1701 __func__,
1702 align);
1703#else
1704 fprintf(stderr,
1705 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
1706 KLS_Loc_Arg(loc),
1707 __func__,
1708 align);
1709#endif // KOLISEO_HAS_LOCATE
1710 return NULL;
1711 }
1712 if (kls->has_temp == 1 && kls->conf.kls_block_while_has_temp == 1) {
1713 fprintf(stderr, "%s(): kls has an active temp\n", __func__);
1714 return NULL;
1715 }
1716 size_t old_size = old_count * size;
1717 size_t new_size = new_count * size;
1718 void *new_ptr = kls_push_zero_ext(kls, size, align, new_count);
1719 if (new_ptr && old_size > 0) {
1720 memcpy(new_ptr, old, old_size < new_size ? old_size : new_size);
1721 }
1722 return new_ptr;
1723}
1724
1736#ifndef KOLISEO_HAS_LOCATE
1737void *kls_temp_repush(Koliseo_Temp *t_kls, void* old, ptrdiff_t size, ptrdiff_t align,
1738 ptrdiff_t old_count, ptrdiff_t new_count)
1739#else
1740void *kls_temp_repush_dbg(Koliseo_Temp *t_kls, void* old, ptrdiff_t size, ptrdiff_t align,
1741 ptrdiff_t old_count, ptrdiff_t new_count, Koliseo_Loc loc)
1742#endif // KOLISEO_HAS_LOCATE
1743{
1744 if (!old) {
1745#ifndef KOLISEO_HAS_LOCATE
1746 fprintf(stderr,
1747 "[KLS] %s(): old was NULL.\n",
1748 __func__);
1749#else
1750 fprintf(stderr,
1751 "[KLS] " KLS_Loc_Fmt "%s(): old was NULL.\n",
1752 KLS_Loc_Arg(loc),
1753 __func__);
1754#endif // KOLISEO_HAS_LOCATE
1755 return NULL;
1756 }
1757 if (old_count < 0) {
1758#ifndef KOLISEO_HAS_LOCATE
1759 fprintf(stderr,
1760 "[KLS] %s(): old_count [%td] was < 0.\n",
1761 __func__,
1762 old_count);
1763#else
1764 fprintf(stderr,
1765 "[KLS] " KLS_Loc_Fmt "%s(): old_count [%td] was < 0.\n",
1766 KLS_Loc_Arg(loc),
1767 __func__,
1768 old_count);
1769#endif // KOLISEO_HAS_LOCATE
1770 return NULL;
1771 }
1772 if (new_count < 0) {
1773#ifndef KOLISEO_HAS_LOCATE
1774 fprintf(stderr,
1775 "[KLS] %s(): new_count [%td] was < 0.\n",
1776 __func__,
1777 new_count);
1778#else
1779 fprintf(stderr,
1780 "[KLS] " KLS_Loc_Fmt "%s(): new_count [%td] was < 0.\n",
1781 KLS_Loc_Arg(loc),
1782 __func__,
1783 new_count);
1784#endif // KOLISEO_HAS_LOCATE
1785 return NULL;
1786 }
1787 if (size < 1) {
1788#ifndef KOLISEO_HAS_LOCATE
1789 fprintf(stderr,
1790 "[KLS] %s(): size [%td] was < 1.\n",
1791 __func__,
1792 size);
1793#else
1794 fprintf(stderr,
1795 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
1796 KLS_Loc_Arg(loc),
1797 __func__,
1798 size);
1799#endif // KOLISEO_HAS_LOCATE
1800 return NULL;
1801 }
1802 if (align < 1) {
1803#ifndef KOLISEO_HAS_LOCATE
1804 fprintf(stderr,
1805 "[KLS] %s(): align [%td] was < 1.\n",
1806 __func__,
1807 align);
1808#else
1809 fprintf(stderr,
1810 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
1811 KLS_Loc_Arg(loc),
1812 __func__,
1813 align);
1814#endif // KOLISEO_HAS_LOCATE
1815 return NULL;
1816 }
1817 if (! ((align & (align - 1)) == 0)) {
1818#ifndef KOLISEO_HAS_LOCATE
1819 fprintf(stderr,
1820 "[KLS] %s(): align [%td] was not a power of 2.\n",
1821 __func__,
1822 align);
1823#else
1824 fprintf(stderr,
1825 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
1826 KLS_Loc_Arg(loc),
1827 __func__,
1828 align);
1829#endif // KOLISEO_HAS_LOCATE
1830 return NULL;
1831 }
1832 size_t old_size = old_count * size;
1833 size_t new_size = new_count * size;
1834 void *new_ptr = kls_temp_push_zero_ext(t_kls, size, align, new_count);
1835 if (new_ptr && old_size > 0) {
1836 memcpy(new_ptr, old, old_size < new_size ? old_size : new_size);
1837 }
1838 return new_ptr;
1839}
1840
1846void print_kls_2file(FILE *fp, const Koliseo *kls)
1847{
1848 if (fp == NULL) {
1849 fprintf(stderr, "print_kls_2file(): fp was NULL.\n");
1850 return;
1851 }
1852 if (kls == NULL) {
1853 fprintf(fp, "[KLS] kls was NULL.\n");
1854 } else {
1855 fprintf(fp, "\n[KLS] API Level: { %i }\n", int_koliseo_version());
1856 fprintf(fp, "\n[INFO] Conf: { " KLS_Conf_Fmt " }\n",
1857 KLS_Conf_Arg(kls->conf));
1858 fprintf(fp, "\n[INFO] Stats: { " KLS_Stats_Fmt " }\n",
1859 KLS_Stats_Arg(kls->stats));
1860 fprintf(fp, "\n[KLS] Size: { %td }\n", kls->size);
1861 char human_size[200];
1862 char curr_size[200];
1863 kls_formatSize(kls->size, human_size, sizeof(human_size));
1864 fprintf(fp, "[KLS] Size (Human): { %s }\n", human_size);
1865 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1866 fprintf(fp, "[KLS] Used (Human): { %s }\n", curr_size);
1867 fprintf(fp, "[KLS] Offset: { %td }\n", kls->offset);
1868 fprintf(fp, "[KLS] Prev_Offset: { %td }\n", kls->prev_offset);
1869 fprintf(fp, "\n");
1870 }
1871}
1872
1877void print_dbg_kls(const Koliseo *kls)
1878{
1879 if (kls == NULL) {
1880 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1881 exit(EXIT_FAILURE);
1882 }
1883 print_kls_2file(stderr, kls);
1884}
1885
1891void print_temp_kls_2file(FILE *fp, const Koliseo_Temp *t_kls)
1892{
1893 if (fp == NULL) {
1894 fprintf(stderr, "print_temp_kls_2file(): fp was NULL.\n");
1895 exit(EXIT_FAILURE);
1896 }
1897 if (t_kls == NULL) {
1898 fprintf(fp, "[KLS_T] t_kls was NULL.");
1899 } else if (t_kls->kls == NULL) {
1900 fprintf(fp, "[KLS_T] [%s()]: Referred Koliseo was NULL.\n", __func__);
1901 } else {
1902 const Koliseo *kls = t_kls->kls;
1903 fprintf(fp, "\n[KLS_T] API Level: { %i }\n", int_koliseo_version());
1904 fprintf(fp, "\n[KLS_T] Temp Size: { %td }\n",
1905 kls->size - t_kls->offset);
1906 fprintf(fp, "\n[KLS_T] Refer Size: { %td }\n", kls->size);
1907 char human_size[200];
1908 char curr_size[200];
1909 kls_formatSize(kls->size - t_kls->offset, human_size,
1910 sizeof(human_size));
1911 fprintf(fp, "[KLS_T] Temp Size Human: { %s }\n", human_size);
1912 kls_formatSize(kls->size, human_size, sizeof(human_size));
1913 fprintf(fp, "[KLS_T] Refer Size Human: { %s }\n", human_size);
1914 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1915 fprintf(fp, "[KLS_T] Inner Used (Human): { %s }\n", curr_size);
1916 kls_formatSize(t_kls->offset, curr_size, sizeof(curr_size));
1917 fprintf(fp, "[KLS_T] Temp Used (Human): { %s }\n", curr_size);
1918 fprintf(fp, "[KLS_T] Inner Offset: { %td }\n", kls->offset);
1919 fprintf(fp, "[KLS_T] Temp Offset: { %td }\n", t_kls->offset);
1920 fprintf(fp, "[KLS_T] Inner Prev_Offset: { %td }\n", kls->prev_offset);
1921 fprintf(fp, "[KLS_T] Temp Prev_Offset: { %td }\n\n",
1922 t_kls->prev_offset);
1923 }
1924}
1925
1931{
1932 print_temp_kls_2file(stderr, t_kls);
1933}
1934
1942void kls_formatSize(ptrdiff_t size, char *outputBuffer, size_t bufferSize)
1943{
1944 const char *units[] =
1945 { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
1946 const int numUnits = sizeof(units) / sizeof(units[0]);
1947
1948 int unitIndex = 0;
1949 double sizeValue = (double)size;
1950
1951 while (sizeValue >= 1000 && unitIndex < numUnits - 1) {
1952 sizeValue /= 1000;
1953 unitIndex++;
1954 }
1955
1956 snprintf(outputBuffer, bufferSize, "%.2f %s", sizeValue, units[unitIndex]);
1957}
1958
1965{
1966 if (kls == NULL) {
1967 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1968 exit(EXIT_FAILURE);
1969 }
1970 //Reset pointer
1971 kls->prev_offset = kls->offset;
1972 kls->offset = sizeof(*kls);
1973 KLS_ASAN_POISON(kls->data + kls->offset, kls->size - kls->offset);
1974#ifdef KLS_DEBUG_CORE
1975 kls_log(kls, "KLS", "API Level { %i } -> Cleared offsets for KLS.",
1977#endif
1978}
1979
1986{
1987 if (kls == NULL) {
1988 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1989 exit(EXIT_FAILURE);
1990 }
1991 Koliseo* current = kls;
1992 while (current) {
1993 Koliseo* next = current->next;
1994 current->next = NULL;
1995 for (size_t i=0; i < current->hooks_len; i++) {
1996 if (current->hooks[i].on_free_handler != NULL) {
1997 // Call on_free() extension
1998 current->hooks[i].on_free_handler(current);
1999 }
2000 }
2001 if (current->has_temp == 1) {
2002#ifdef KLS_DEBUG_CORE
2003 kls_log(current, "KLS",
2004 "API Level { %i } -> KLS had an active Koliseo_Temp.",
2006#endif
2007 kls_temp_end(current->t_kls);
2008 }
2009 kls_clear(current);
2010#ifdef KLS_DEBUG_CORE
2011 kls_log(current, "KLS", "API Level { %i } -> Freeing KLS.",
2013#endif
2014 if (current->conf.kls_log_fp != NULL && current->conf.kls_log_fp != stdout
2015 && current->conf.kls_log_fp != stderr) {
2016#ifdef KLS_DEBUG_CORE
2017 kls_log(current, "KLS", "Closing kls log file. Path: {\"%s\"}.",
2018 kls->conf.kls_log_filepath);
2019#endif
2020 int close_res = fclose(current->conf.kls_log_fp);
2021 if (close_res != 0) {
2022 fprintf(stderr,
2023 "[ERROR] %s(): Failed fclose() on log_fp. Path: {\"%s\"}.",
2024 __func__, current->conf.kls_log_filepath);
2025 }
2026 } else if (current->conf.kls_log_fp == stdout || current->conf.kls_log_fp == stderr) {
2027 if (current->conf.kls_verbose_lvl > 1) {
2028 fprintf(stderr,
2029 "[INFO] %s(): kls->conf.kls_log_fp is %s. Not closing it.\n",
2030 __func__,
2031 (current->conf.kls_log_fp == stdout ? "stdout" : "stderr"));
2032 }
2033 }
2034 if (current->free_func == NULL) {
2035 fprintf(stderr,
2036 "[ERROR] %s(): free function was NULL.\n", __func__);
2037 return;
2038 }
2039 current->free_func(current);
2040 current = next;
2041 }
2042}
2043
2051#ifndef KOLISEO_HAS_LOCATE
2053#else
2054Koliseo_Temp *kls_temp_start_dbg(Koliseo *kls, Koliseo_Loc loc)
2055#endif // KOLISEO_HAS_LOCATE
2056{
2057 if (kls == NULL) {
2058 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
2059 exit(EXIT_FAILURE);
2060 }
2061 Koliseo* current = kls;
2062 while (current->next != NULL) {
2063 current = current->next;
2064 }
2065 if (current->has_temp != 0) {
2066 fprintf(stderr,
2067 "[ERROR] [%s()]: Passed Koliseo->has_temp is not 0. {%i}\n",
2068 __func__, current->has_temp);
2069#ifdef KLS_DEBUG_CORE
2070 kls_log(current, "ERROR", "[%s()]: Passed Koliseo->has_temp != 0 . {%i}",
2071 __func__, current->has_temp);
2072#endif
2073 if (current->conf.kls_collect_stats == 1) {
2074 current->stats.tot_hiccups += 1;
2075 }
2076 return NULL;
2077 }
2078 ptrdiff_t prev = current->prev_offset;
2079 ptrdiff_t off = current->offset;
2080
2081 Koliseo_Temp *tmp = KLS_PUSH(current, Koliseo_Temp);
2082 tmp->kls = current;
2083 tmp->prev_offset = prev;
2084 tmp->offset = off;
2085#ifdef KLS_DEBUG_CORE
2086 kls_log(current, "INFO", "Passed kls conf: " KLS_Conf_Fmt "\n",
2087 KLS_Conf_Arg(current->conf));
2088#endif
2089
2090 current->has_temp = 1;
2091 current->t_kls = tmp;
2092 for (size_t i=0; i < current->hooks_len; i++) {
2093 if (current->hooks[i].on_temp_start_handler != NULL) {
2094 // Call on_temp_start extension
2095 current->hooks[i].on_temp_start_handler(tmp);
2096 }
2097 }
2098#ifdef KLS_DEBUG_CORE
2099 kls_log(current, "KLS", "Prepared new Temp KLS.");
2100#endif
2101 return tmp;
2102}
2103
2109{
2110 if (tmp_kls == NULL) {
2111 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
2112 __func__);
2113 exit(EXIT_FAILURE);
2114 }
2115
2116 Koliseo *kls_ref = tmp_kls->kls;
2117 if (kls_ref == NULL) {
2118 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
2119 __func__);
2120 exit(EXIT_FAILURE);
2121 }
2122
2123 for (size_t i=0; i < kls_ref->hooks_len; i++) {
2124 if (kls_ref->hooks[i].on_temp_free_handler != NULL) {
2125 // Call on_temp_free() extension
2126 kls_ref->hooks[i].on_temp_free_handler(tmp_kls);
2127 }
2128 }
2129
2130#ifdef KLS_DEBUG_CORE
2131 kls_log(kls_ref, "KLS", "Ended Temp KLS.");
2132#endif
2133 tmp_kls->kls->has_temp = 0;
2134 tmp_kls->kls->t_kls = NULL;
2135#if defined(__SANITIZE_ADDRESS__)
2136 ptrdiff_t old_offset = tmp_kls->kls->offset;
2137 ptrdiff_t new_offset = tmp_kls->offset;
2138#endif // __SANITIZE_ADDRESS__
2139 tmp_kls->kls->prev_offset = tmp_kls->prev_offset;
2140 tmp_kls->kls->offset = tmp_kls->offset;
2141
2142 // Free any Koliseo chained after the current one
2143 Koliseo* to_free = tmp_kls->kls->next;
2144 if (to_free != NULL) {
2145 kls_free(to_free);
2146 tmp_kls->kls->next = NULL;
2147 }
2148
2149 KLS_ASAN_POISON(tmp_kls->kls->data + new_offset, old_offset - new_offset);
2150 tmp_kls = NULL; // statement with no effect TODO: Clear tmp_kls from caller
2151 if (kls_ref->conf.kls_collect_stats == 1) {
2152 kls_ref->stats.tot_temp_pushes = 0;
2153 kls_ref->stats.tot_temp_pops = 0;
2154 }
2155}
2156
2157#ifdef KOLISEO_HAS_EXPER
2166void *kls_pop(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
2167{
2168 if (kls == NULL) {
2169 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
2170 exit(EXIT_FAILURE);
2171 }
2172 ptrdiff_t padding = -kls->offset & (align - 1);
2173 if (count > PTRDIFF_MAX / size
2174 || (kls->size + kls->offset) < (size * count)) {
2175 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2176 kls_free(kls);
2177 exit(EXIT_FAILURE);
2178 }
2179 char *p = kls->data + kls->offset - padding - size * count;
2180 kls->prev_offset = kls->offset;
2181 kls->offset -= padding + size * count;
2182#ifdef KLS_DEBUG_CORE
2183 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
2184 int_koliseo_version(), size);
2185 if (kls->conf.kls_verbose_lvl > 0) {
2186 print_kls_2file(kls->conf.kls_log_fp, kls);
2187 }
2188#endif
2189 if (kls->conf.kls_collect_stats == 1) {
2190 kls->stats.tot_pops += 1;
2191 }
2192 return p;
2193}
2194
2203void *kls_pop_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
2204{
2205 if (kls == NULL) {
2206 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
2207 exit(EXIT_FAILURE);
2208 }
2209 ptrdiff_t padding = -kls->offset & (align - 1);
2210 if (count > PTRDIFF_MAX / size
2211 || (kls->size + kls->offset) < (size * count)) {
2212 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2213 kls_free(kls);
2214 exit(EXIT_FAILURE);
2215 }
2216 char *p = kls->data + kls->offset - padding - size * count;
2217 kls->prev_offset = kls->offset;
2218 kls->offset -= padding + size * count;
2219#ifdef KLS_DEBUG_CORE
2220 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
2221 int_koliseo_version(), size);
2222 if (kls->conf.kls_verbose_lvl > 0) {
2223 print_kls_2file(kls->conf.kls_log_fp, kls);
2224 }
2225#endif
2226 if (kls->conf.kls_collect_stats == 1) {
2227 kls->stats.tot_pops += 1;
2228 }
2229 return p;
2230}
2231
2240void *kls_temp_pop(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align,
2241 ptrdiff_t count)
2242{
2243 if (t_kls == NULL) {
2244 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
2245 __func__);
2246 exit(EXIT_FAILURE);
2247 }
2248 Koliseo *kls = t_kls->kls;
2249 if (kls == NULL) {
2250 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
2251 __func__);
2252 exit(EXIT_FAILURE);
2253 }
2254 ptrdiff_t padding = -kls->offset & (align - 1);
2255 if (count > PTRDIFF_MAX / size
2256 || (kls->size + kls->offset) < (size * count)) {
2257 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2258 kls_free(kls);
2259 exit(EXIT_FAILURE);
2260 }
2261 char *p = kls->data + kls->offset - padding - size * count;
2262 kls->prev_offset = kls->offset;
2263 kls->offset -= padding + size * count;
2264#ifdef KLS_DEBUG_CORE
2265 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
2266 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
2267 int_koliseo_version(), size);
2268 if (kls->conf.kls_verbose_lvl > 0) {
2269 print_kls_2file(kls->conf.kls_log_fp, kls);
2270 }
2271#endif
2272 if (kls->conf.kls_collect_stats == 1) {
2273 kls->stats.tot_temp_pops += 1;
2274 }
2275 return p;
2276}
2277
2286void *kls_temp_pop_AR(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
2287{
2288 if (t_kls == NULL) {
2289 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
2290 __func__);
2291 exit(EXIT_FAILURE);
2292 }
2293 Koliseo *kls = t_kls->kls;
2294 if (kls == NULL) {
2295 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
2296 __func__);
2297 exit(EXIT_FAILURE);
2298 }
2299 ptrdiff_t padding = -kls->offset & (align - 1);
2300 if (count > PTRDIFF_MAX / size
2301 || (kls->size + kls->offset) < (size * count)) {
2302 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2303 kls_free(kls);
2304 exit(EXIT_FAILURE);
2305 }
2306 char *p = kls->data + kls->offset - padding - size * count;
2307 kls->prev_offset = kls->offset;
2308 kls->offset -= padding + size * count;
2309#ifdef KLS_DEBUG_CORE
2310 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
2311 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
2312 int_koliseo_version(), size);
2313 if (kls->conf.kls_verbose_lvl > 0) {
2314 print_kls_2file(kls->conf.kls_log_fp, kls);
2315 }
2316#endif
2317 if (kls->conf.kls_collect_stats == 1) {
2318 kls->stats.tot_temp_pops += 1;
2319 }
2320 return p;
2321}
2322
2329char* kls_strdup(Koliseo* kls, char* source)
2330{
2331 char* dest = KLS_PUSH_STR(kls, source);
2332 KLS__STRCPY(dest, source);
2333 return dest;
2334}
2335
2342char** kls_strdup_arr(Koliseo* kls, size_t count, char** source)
2343{
2344 char** strings = NULL;
2345 strings = KLS_PUSH_ARR(kls, char*, count);
2346 for (int i=0; i < count; i++) {
2347 strings[i] = KLS_STRDUP(kls, source[i]);
2348 }
2349 return strings;
2350}
2351
2358char* kls_t_strdup(Koliseo_Temp* t_kls, char* source)
2359{
2360 char* dest = KLS_PUSH_STR_T(t_kls, source);
2361 KLS__STRCPY(dest, source);
2362 return dest;
2363}
2364
2371char** kls_t_strdup_arr(Koliseo_Temp* t_kls, size_t count, char** source)
2372{
2373 char** strings = NULL;
2374 strings = KLS_PUSH_ARR_T(t_kls, char*, count);
2375 for (int i=0; i < count; i++) {
2376 strings[i] = KLS_STRDUP_T(t_kls, source[i]);
2377 }
2378 return strings;
2379}
2380#endif // KOLISEO_HAS_EXPER
#define KLS_DEFAULT_HOOKS
Definition kls_region.h:162
#define KLS_DEFAULT_EXTENSIONS_LEN
DEPRECATED: Support for multiple extension will be dropped in the next release.
Definition kls_region.h:176
Koliseo * kls_new_traced(ptrdiff_t size, const char *output_path)
Takes a ptrdiff_t size and a filepath for the trace output file.
Definition koliseo.c:842
Koliseo * kls_new(ptrdiff_t size)
Takes a ptrdiff_t size.
Definition koliseo.c:650
char * kls_strdup(Koliseo *kls, char *source)
Function to dupe a C string to a Koliseo, and return a pointer to the allocated string.
Definition koliseo.c:2329
void * kls_temp_pop(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo_Temp, and ptrdiff_t values for size, align and count.
Definition koliseo.c:2240
Koliseo_Temp * kls_temp_start(Koliseo *kls)
Starts a new savestate for the passed Koliseo pointer, by initialising its Koliseo_Temp pointer and r...
Definition koliseo.c:2052
void print_dbg_temp_kls(const Koliseo_Temp *t_kls)
Prints header fields from the passed Koliseo_Temp pointer, to stderr.
Definition koliseo.c:1930
void * kls_temp_repush(Koliseo_Temp *t_kls, void *old, ptrdiff_t size, ptrdiff_t align, ptrdiff_t old_count, ptrdiff_t new_count)
Takes a Koliseo_Temp pointer, and a void pointer to the old allocation, ptrdiff_t values for size,...
Definition koliseo.c:1737
Koliseo * kls_new_dbg_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
Takes a ptrdiff_t size, an allocation function pointer and a free function pointer,...
Definition koliseo.c:943
void print_temp_kls_2file(FILE *fp, const Koliseo_Temp *t_kls)
Prints header fields from the passed Koliseo_Temp pointer, to the passed FILE pointer.
Definition koliseo.c:1891
char * kls_t_strdup(Koliseo_Temp *t_kls, char *source)
Function to dupe a C string to a Koliseo_Temp, and return a pointer to the allocated string.
Definition koliseo.c:2358
Koliseo * kls_new_traced_alloc_handled(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers)
Takes a ptrdiff_t size, a filepath for the trace output file, an allocation function pointer and a fr...
Definition koliseo.c:789
KLS_Stats KLS_STATS_DEFAULT
Default KLS_Stats values, used by kls_new().
Definition koliseo.c:41
void kls_log(Koliseo *kls, const char *tag, const char *format,...)
Logs a message to the log_fp FILE field of the passed Koliseo pointer, if its conf....
Definition koliseo.c:483
Koliseo * kls_new_traced_alloc_handled_ext(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers, KLS_Hooks *ext_handlers, void **user, size_t ext_len)
Takes a ptrdiff_t size, a filepath for the trace output file, an allocation function pointer and a fr...
Definition koliseo.c:753
char * kls_vsprintf(Koliseo *kls, const char *fmt, va_list args)
Definition koliseo.c:1475
void kls_temp_end(Koliseo_Temp *tmp_kls)
Ends passed Koliseo_Temp pointer.
Definition koliseo.c:2108
void kls_dbg_features(void)
Prints enabled Koliseo features to stderr.
Definition koliseo.c:235
char ** kls_strdup_arr(Koliseo *kls, size_t count, char **source)
Function to dupe a C string array to a Koliseo, and return a pointer to the allocated array.
Definition koliseo.c:2342
void * kls_temp_push_zero_ext(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo_Temp, and ptrdiff_t values for size, align and count.
Definition koliseo.c:1528
void print_dbg_kls(const Koliseo *kls)
Prints header fields from the passed Koliseo pointer, to stderr.
Definition koliseo.c:1877
const char * string_koliseo_version(void)
Returns the constant string representing current version for Koliseo.
Definition koliseo.c:59
void * kls_repush(Koliseo *kls, void *old, ptrdiff_t size, ptrdiff_t align, ptrdiff_t old_count, ptrdiff_t new_count)
Takes a Koliseo pointer, and a void pointer to the old allocation, ptrdiff_t values for size,...
Definition koliseo.c:1617
KLS_Push_Result kls__advance(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t *padding, const char *caller_name)
Takes a Koliseo pointer, and ptrdiff_t values for size, align and count.
Definition koliseo.c:1100
char * kls_temp_vsprintf(Koliseo_Temp *kls_t, const char *fmt, va_list args)
Definition koliseo.c:1563
ptrdiff_t kls_get_pos(const Koliseo *kls)
Returns the current offset (position of pointer bumper) for the passed Koliseo.
Definition koliseo.c:288
void * kls_temp_pop_AR(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo_Temp, and ptrdiff_t values for size, align and count.
Definition koliseo.c:2286
#define KLS_ASAN_UNPOISON(addr, size)
Definition koliseo.c:79
void * kls_pop_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo pointer, and ptrdiff_t values for size, align and count.
Definition koliseo.c:2203
void kls_free(Koliseo *kls)
Calls kls_clear() on the passed Koliseo pointer and the frees the actual Koliseo.
Definition koliseo.c:1985
KLS_Conf kls_conf_init_handled(int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, int growable, FILE *log_fp, const char *log_filepath, KLS_Err_Handlers err_handlers)
Used to prepare a KLS_Conf without caring about KOLISEO_HAS_REGIONS.
Definition koliseo.c:178
Koliseo * kls_new_traced_ext(ptrdiff_t size, const char *output_path, KLS_Hooks *ext_handlers, void **user, size_t ext_len)
Takes a ptrdiff_t size and a filepath for the trace output file.
Definition koliseo.c:806
char * kls_temp_sprintf(Koliseo_Temp *kls_t, const char *fmt,...)
Takes a Koliseo_Temp pointer, and a format cstring, plus varargs.
Definition koliseo.c:1589
char ** kls_t_strdup_arr(Koliseo_Temp *t_kls, size_t count, char **source)
Function to dupe a C string array to a Koliseo_Temp, and return a pointer to the allocated array.
Definition koliseo.c:2371
void * kls_push(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo pointer, and ptrdiff_t values for size, align and count.
Definition koliseo.c:1368
Koliseo * kls_new_dbg_alloc_handled(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers)
Takes a ptrdiff_t size, an allocation function pointer and a free function pointer,...
Definition koliseo.c:911
#define KLS_ASAN_POISON(addr, size)
Definition koliseo.c:78
void * kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo pointer, and ptrdiff_t values for size, align and count.
Definition koliseo.c:1391
Koliseo * kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
Takes a ptrdiff_t size and a function pointer to the allocation function.
Definition koliseo.c:626
Koliseo * kls_new_dbg(ptrdiff_t size)
Takes a ptrdiff_t size and returns a pointer to the prepared Koliseo.
Definition koliseo.c:958
Koliseo * kls_new_traced_alloc(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func)
Takes a ptrdiff_t size, a filepath for the trace output file, an allocation function pointer and a fr...
Definition koliseo.c:825
char * kls_sprintf(Koliseo *kls, const char *fmt,...)
Takes a Koliseo pointer, and a format cstring, plus varargs.
Definition koliseo.c:1500
Koliseo * kls_new_conf_alloc_ext(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Hooks *ext_handlers, void **user, size_t ext_len)
Takes a ptrdiff_t size, a KLS_Conf to configure the new Koliseo, an allocation function pointer and a...
Definition koliseo.c:671
Koliseo * kls_new_traced_handled(ptrdiff_t size, const char *output_path, KLS_Err_Handlers err_handlers)
Takes a ptrdiff_t size and a filepath for the trace output file.
Definition koliseo.c:859
void * kls_pop(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo pointer, and ptrdiff_t values for size, align and count.
Definition koliseo.c:2166
void KLS_PTRDIFF_MAX_default_handler__(struct Koliseo *kls, ptrdiff_t size, ptrdiff_t count)
Used by default when no handler is passed.
Definition koliseo.c:112
KLS_Conf KLS_DEFAULT_CONF
Config used by any new Koliseo by default.
Definition koliseo.c:20
KLS_Conf kls_conf_init(int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, int growable, FILE *log_fp, const char *log_filepath)
Used to prepare a KLS_Conf without caring about KOLISEO_HAS_REGIONS.
Definition koliseo.c:226
void KLS_ZEROCOUNT_default_handler__(Koliseo *kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size)
Used internally for handling zero-count in push calls when no user handler is provided.
Definition koliseo.c:154
KLS_Push_Error kls__check_available_failable(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char *caller_name)
Takes a Koliseo, a ptrdiff_t size, align and count, and a caller name.
Definition koliseo.c:1200
void * kls__handle_push_result(Koliseo *kls, KLS_Push_Result r, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t padding, const char *caller_name)
Definition koliseo.c:294
Koliseo * kls_new_dbg_ext(ptrdiff_t size, KLS_Hooks *ext_handlers, void **user, size_t ext_len)
Takes a ptrdiff_t size.
Definition koliseo.c:926
Koliseo * kls_new_alloc_ext(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Hooks *ext_handlers, void **user, size_t ext_len)
Takes a ptrdiff_t size and a function pointer to the allocation function.
Definition koliseo.c:529
void print_kls_2file(FILE *fp, const Koliseo *kls)
Prints header fields from the passed Koliseo pointer, to the passed FILE pointer.
Definition koliseo.c:1846
Koliseo * kls_new_dbg_alloc_handled_ext(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers, KLS_Hooks *ext_handlers, void **user, size_t ext_len)
Takes a ptrdiff_t size, an allocation function pointer and a free function pointer,...
Definition koliseo.c:877
Koliseo * kls_new_dbg_handled(ptrdiff_t size, KLS_Err_Handlers err_handlers)
Takes a ptrdiff_t size and returns a pointer to the prepared Koliseo.
Definition koliseo.c:973
void kls_clear(Koliseo *kls)
Resets the offset field for the passed Koliseo pointer.
Definition koliseo.c:1964
void * kls_push_zero_ext(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
Takes a Koliseo pointer, and ptrdiff_t values for size, align and count.
Definition koliseo.c:1424
void kls_formatSize(ptrdiff_t size, char *outputBuffer, size_t bufferSize)
Converts a ptrdiff_t size to human-readable SI units (modulo 1000).
Definition koliseo.c:1942
void KLS_OOM_default_handler__(Koliseo *kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, ptrdiff_t count)
Used internally for handling Out-Of-Memory in push calls when no user handler is provided.
Definition koliseo.c:92
Koliseo * kls_new_conf_alloc(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, kls_free_func free_func)
Takes a ptrdiff_t size, a KLS_Conf to configure the new Koliseo, an allocation function pointer and a...
Definition koliseo.c:700
KLS_Push_Result kls__temp_advance(Koliseo_Temp *kls_t, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, ptrdiff_t *padding, const char *caller_name)
Takes a Koliseo_Temp, and ptrdiff_t values for size, align and count.
Definition koliseo.c:1260
int int_koliseo_version(void)
Returns the constant int representing current version for Koliseo.
Definition koliseo.c:68
Koliseo * kls_new_conf(ptrdiff_t size, KLS_Conf conf)
Takes a ptrdiff_t size and a KLS_Conf to configure the new Koliseo.
Definition koliseo.c:733
Koliseo * kls_new_conf_ext(ptrdiff_t size, KLS_Conf conf, KLS_Hooks *ext_handlers, void **user, size_t ext_len)
Takes a ptrdiff_t size and a KLS_Conf to configure the new Koliseo.
Definition koliseo.c:717
void kls_free_func(void *)
Used to select a free function for the arena's backing memory.
Definition koliseo.h:94
#define KLS_PUSH_STR_T(kls_temp, cstr)
Macro to request memory for a C string from a Koliseo_Temp.
Definition koliseo.h:680
#define KLS_Stats_Fmt
Defines a format string for KLS_Stats.
Definition koliseo.h:295
#define KLS_PUSH_STR(kls, cstr)
Macro to request memory for a C string from a Koliseo.
Definition koliseo.h:566
#define KLS_Conf_Arg(conf)
Defines a format macro for KLS_Conf args.
Definition koliseo.h:288
#define KLS_DEFAULT_FREEF
Defines the default free function.
Definition koliseo.h:434
#define KLS_DEFAULT_ALLOCF
Defines the default allocation function.
Definition koliseo.h:430
#define KLS_PUSH(kls, type)
Macro used to request memory from a Koliseo.
Definition koliseo.h:601
#define KLS__STRCPY(dest, source)
Macro to copy a C string from a source buffer to a destination buffer.
Definition koliseo.h:784
#define KLS_ALIGNOF
Definition koliseo.h:22
#define KLS_DEFAULT_EXTENSION_DATA
Defines default hooks that are loaded on kls_new() variants lacking explicit set of KLS_Hooks.
Definition koliseo.h:224
void * kls_alloc_func(size_t)
Used to select an allocation function for the arena's backing memory.
Definition koliseo.h:93
#define KLS_MAX(a, b)
Definition koliseo.h:100
#define KLS_STRDUP(kls, source)
Definition koliseo.h:793
KLS_Push_Error
Defines the result for kls__check_available_failable().
Definition koliseo.h:390
@ KLS_PUSH_NEGATIVE_COUNT
Definition koliseo.h:395
@ KLS_PUSH_ZEROCOUNT
Definition koliseo.h:396
@ KLS_PUSH_ALIGN_NOT_POW2
Definition koliseo.h:394
@ KLS_PUSH_WITH_TEMP_ACTIVE
Definition koliseo.h:397
@ KLS_PUSH_OOM
Definition koliseo.h:399
@ KLS_PUSH_PTRDIFF_MAX
Definition koliseo.h:398
@ KLS_PUSH_SIZE_LT1
Definition koliseo.h:392
@ KLS_PUSH_ALIGN_LT1
Definition koliseo.h:393
@ KLS_PUSH_OK
Definition koliseo.h:391
#define KLS_Stats_Arg(stats)
Defines a format macro for KLS_Stats args.
Definition koliseo.h:305
#define KLS_Conf_Fmt
Defines a format string for KLS_Conf.
Definition koliseo.h:282
#define KLS_PUSH_ARR_T(kls_temp, type, count)
Macro used to request memory for an array of type values from a Koliseo_Temp.
Definition koliseo.h:669
#define KLS_STRDUP_T(t_kls, source)
Definition koliseo.h:803
#define KLS_DEFAULT_ERR_HANDLERS
Definition koliseo.h:180
#define KLS_PUSH_ARR(kls, type, count)
Macro used to request memory for an array of type values from a Koliseo.
Definition koliseo.h:555
Defines flags for Koliseo.
Definition koliseo.h:231
int kls_growable
If set to 1, make the Koliseo grow when a out of memory for a push call.
Definition koliseo.h:238
int kls_collect_stats
If set to 1, make the Koliseo collect performance stats.
Definition koliseo.h:232
int kls_allow_zerocount_push
If set to 1, make the Koliseo accept push calls with a count of 0.
Definition koliseo.h:237
int kls_block_while_has_temp
If set to 1, make the Koliseo reject push calls while it has an open Koliseo_Temp.
Definition koliseo.h:236
int kls_verbose_lvl
If > 0, makes the Koliseo try to acquire kls_log_fp from kls_log_filepath.
Definition koliseo.h:233
KLS_Err_Handlers err_handlers
Used to pass custom error handlers for push calls.
Definition koliseo.h:239
const char * kls_log_filepath
String representing the path to the Koliseo logfile.
Definition koliseo.h:235
FILE * kls_log_fp
FILE pointer used by the Koliseo to print its kls_log() output.
Definition koliseo.h:234
Defines the handlers used for errors in push calls.
Definition koliseo.h:173
KLS_OOM_Handler * OOM_handler
Pointer to handler for Out-Of-Memory errors in push calls.
Definition koliseo.h:174
KLS_ZEROCOUNT_Handler * ZEROCOUNT_handler
Pointer to handler for zero-count errors in push calls.
Definition koliseo.h:176
KLS_PTRDIFF_MAX_Handler * PTRDIFF_MAX_handler
Pointer to handler for count > (PTRDIFF_MAX / size) errors in push calls.
Definition koliseo.h:175
Definition koliseo.h:197
KLS_hook_on_temp_start * on_temp_start_handler
Used to pass custom start handler for kls_temp_start calls.
Definition koliseo.h:201
KLS_hook_on_free * on_free_handler
Used to pass custom free handler for kls_free calls.
Definition koliseo.h:199
KLS_hook_on_temp_free * on_temp_free_handler
Used to pass custom free handler for kls_temp_end calls.
Definition koliseo.h:202
KLS_hook_on_push * on_push_handler
Used to pass custom push handler for kls_push calls.
Definition koliseo.h:200
KLS_hook_on_new * on_new_handler
Used to pass custom new handler for kls_new_alloc calls.
Definition koliseo.h:198
KLS_hook_on_temp_push * on_temp_push_handler
Used to pass custom push handler for kls_temp_push calls.
Definition koliseo.h:203
Defines the result for kls__advance() and kls__temp_advance().
Definition koliseo.h:407
KLS_Push_Error error
Definition koliseo.h:409
void * p
Definition koliseo.h:408
Defines a stat struct for Koliseo.
Definition koliseo.h:252
int tot_pops
Total POP calls done.
Definition koliseo.h:255
double worst_pushcall_time
Longest time taken by a PUSH call.
Definition koliseo.h:260
int tot_temp_pushes
Total PUSH_T calls done.
Definition koliseo.h:254
int tot_pushes
Total PUSH calls done.
Definition koliseo.h:253
int tot_hiccups
Total hiccups encountered.
Definition koliseo.h:258
int tot_temp_pops
Total POP_T calls done.
Definition koliseo.h:256
Represents a savestate for a Koliseo.
Definition koliseo.h:379
ptrdiff_t offset
Current position of memory pointer.
Definition koliseo.h:381
ptrdiff_t prev_offset
Previous position of memory pointer.
Definition koliseo.h:382
Koliseo * kls
Reference to the actual Koliseo we're saving.
Definition koliseo.h:380
Represents the initialised arena allocator struct.
Definition koliseo.h:340
ptrdiff_t size
Size of data field.
Definition koliseo.h:342
ptrdiff_t offset
Current position of memory pointer.
Definition koliseo.h:343
ptrdiff_t prev_offset
Previous position of memory pointer.
Definition koliseo.h:344
KLS_Conf conf
Contains flags to change the Koliseo behaviour.
Definition koliseo.h:346
void * extension_data[KLS_MAX_EXTENSIONS]
Points to data for extensions.
Definition koliseo.h:350
struct Koliseo_Temp * t_kls
Points to related active Kolieo_Temp, when has_temp == 1.
Definition koliseo.h:348
char * data
Points to data field.
Definition koliseo.h:341
size_t hooks_len
Length for hooks and extension_data.
Definition koliseo.h:351
struct Koliseo * next
Points to the next Koliseo when conf.kls_growable == 1.
Definition koliseo.h:353
int has_temp
When == 1, a Koliseo_Temp is currently active on this Koliseo.
Definition koliseo.h:345
KLS_Stats stats
Contains stats for Koliseo performance analysis.
Definition koliseo.h:347
KLS_Hooks hooks[KLS_MAX_EXTENSIONS]
Contains handlers for extensions.
Definition koliseo.h:349
kls_free_func * free_func
Points to the free function for the arena's backing memory.
Definition koliseo.h:352