koliseo 0.5.7
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-2025 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
82#ifndef KOLISEO_HAS_LOCATE
83void KLS_OOM_default_handler__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, ptrdiff_t count)
84#else
85void KLS_OOM_default_handler_dbg__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, ptrdiff_t count, Koliseo_Loc loc)
86#endif // KOLISEO_HAS_LOCATE
87{
88#ifndef KOLISEO_HAS_LOCATE
89 fprintf(stderr,
90 "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
91 size * count, available - padding);
92#else
93 fprintf(stderr,
94 "[KLS] " KLS_Loc_Fmt "Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
95 KLS_Loc_Arg(loc),
96 size * count, available - padding);
97#endif // KOLISEO_HAS_LOCATE
98 kls_free(kls); // Is it even worth it to try?
99 exit(EXIT_FAILURE); // Better than nothing. May change to return NULL instead? Requiring refactor of handler signature
100}
101
102#ifndef KOLISEO_HAS_LOCATE
103void KLS_PTRDIFF_MAX_default_handler__(struct Koliseo* kls, ptrdiff_t size, ptrdiff_t count)
104#else
105void KLS_PTRDIFF_MAX_default_handler_dbg__(struct Koliseo* kls, ptrdiff_t size, ptrdiff_t count, Koliseo_Loc loc)
106#endif
107{
108#ifndef _WIN32
109#ifndef KOLISEO_HAS_LOCATE
110 fprintf(stderr,
111 "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
112 count, PTRDIFF_MAX / size);
113#else
114 fprintf(stderr,
115 "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
116 KLS_Loc_Arg(loc),
117 count, PTRDIFF_MAX / size);
118#endif // KOLISEO_HAS_LOCATE
119#else
120#ifndef KOLISEO_HAS_LOCATE
121 fprintf(stderr,
122 "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
123 count, PTRDIFF_MAX / size);
124#else
125 fprintf(stderr,
126 "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
127 KLS_Loc_Arg(loc),
128 count, PTRDIFF_MAX / size);
129#endif // KOLISEO_HAS_LOCATE
130#endif // _WIN32
131 kls_free(kls);
132 exit(EXIT_FAILURE);
133}
134
144#ifndef KOLISEO_HAS_LOCATE
145void KLS_ZEROCOUNT_default_handler__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size)
146#else
147void KLS_ZEROCOUNT_default_handler_dbg__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, Koliseo_Loc loc)
148#endif // KOLISEO_HAS_LOCATE
149{
150#ifndef KOLISEO_HAS_LOCATE
151 fprintf(stderr,
152 "[KLS] Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
153 size, padding, available);
154#else
155 fprintf(stderr,
156 "[KLS] " KLS_Loc_Fmt "Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
157 KLS_Loc_Arg(loc),
158 size, padding, available);
159#endif // KOLISEO_HAS_LOCATE
160 kls_free(kls);
161 exit(EXIT_FAILURE);
162}
163
169KLS_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)
170{
171 KLS_Conf res = {0};
172 res.kls_collect_stats = collect_stats;
173 res.kls_verbose_lvl = verbose_lvl;
174 res.kls_block_while_has_temp = block_while_has_temp;
175 res.kls_allow_zerocount_push = allow_zerocount_push;
176 res.kls_growable = growable;
177 res.kls_log_fp = log_fp;
178 res.kls_log_filepath = log_filepath;
179
180 if (err_handlers.OOM_handler != NULL) {
181 res.err_handlers.OOM_handler = err_handlers.OOM_handler;
182 } else {
183#ifndef KOLISEO_HAS_LOCATE
185#else
186 res.err_handlers.OOM_handler = &KLS_OOM_default_handler_dbg__;
187#endif // KOLISEO_HAS_LOCATE
188 }
189
190 if (err_handlers.PTRDIFF_MAX_handler != NULL) {
192 } else {
193#ifndef KOLISEO_HAS_LOCATE
195#else
196 res.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__;
197#endif // KOLISEO_HAS_LOCATE
198 }
199
200 if (err_handlers.ZEROCOUNT_handler != NULL) {
202 } else {
203#ifndef KOLISEO_HAS_LOCATE
205#else
206 res.err_handlers.ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler_dbg__;
207#endif // KOLISEO_HAS_LOCATE
208 }
209
210 return res;
211}
212
217KLS_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)
218{
220 return kls_conf_init_handled(collect_stats, verbose_lvl, block_while_has_temp, allow_zerocount_push, growable, log_fp, log_filepath, err_handlers);
221}
222
227{
228#ifdef KOLISEO_HAS_LOCATE
229 bool kls_locate = true;
230#else
231 bool kls_locate = false;
232#endif
233#ifdef KLS_DEBUG_CORE
234 bool kls_debug = true;
235#else
236 bool kls_debug = false;
237#endif
238#ifdef KOLISEO_HAS_EXPER
239 bool kls_exper = true;
240#else
241 bool kls_exper = false;
242#endif
243 bool features[3] = {
244 [0] = kls_debug,
245 [1] = kls_locate,
246 [2] = kls_exper,
247 };
248 int total_enabled = 0;
249 for (int i=0; i<3; i++) {
250 if (features[i]) {
251 total_enabled += 1;
252 }
253 }
254 fprintf(stderr, "[KLS] Enabled features: {");
255 if (total_enabled == 0) {
256 fprintf(stderr, "none}\n");
257 return;
258 } else {
259 if (kls_debug) {
260 fprintf(stderr, "debug%s", (total_enabled > 1 ? ", " : ""));
261 total_enabled -= 1;
262 }
263 if (kls_locate) {
264 fprintf(stderr, "locate%s", (total_enabled > 1 ? ", " : ""));
265 total_enabled -= 1;
266 }
267 if (kls_exper) {
268 fprintf(stderr, "exper");
269 }
270 fprintf(stderr, "}\n");
271 }
272}
273
279ptrdiff_t kls_get_pos(const Koliseo *kls)
280{
281 return kls->offset;
282}
283
290void kls_log(Koliseo *kls, const char *tag, const char *format, ...)
291{
292 if (kls == NULL) {
293 fprintf(stderr, "[KLS] %s(): Passed kls was NULL.\n", __func__);
294 return;
295 }
296 if (kls->conf.kls_verbose_lvl > 0) {
297 va_list args;
298 FILE *fp = kls->conf.kls_log_fp;
299 va_start(args, format);
300 if (fp == NULL) {
301 fprintf(stderr,
302 "[KLS] %s(): Failed opening file to print logs.\n",
303 __func__);
304 } else {
305 time_t now = time(0);
306 const struct tm *mytime = localtime(&now);
307 char timeheader[500];
308 if (strftime(timeheader, sizeof timeheader, "%X", mytime)) {
309 fprintf(fp, "[%-10.10s] [%s] [", tag, timeheader);
310 vfprintf(fp, format, args);
311 fprintf(fp, "]\n");
312 }
313 }
314 va_end(args);
315 }
316}
317
335#ifndef KOLISEO_HAS_LOCATE
336Koliseo *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)
337#else
338Koliseo *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)
339#endif // KOLISEO_HAS_LOCATE
340{
341 if (size < (ptrdiff_t)sizeof(Koliseo)) {
342#ifndef KOLISEO_HAS_LOCATE
343 fprintf(stderr,
344 "[ERROR] at %s(): invalid requested kls size (%td). Min accepted is: (%td).\n",
345 __func__, size, (ptrdiff_t)sizeof(Koliseo));
346#else
347 fprintf(stderr,
348 "[ERROR] " KLS_Loc_Fmt "%s(): invalid requested kls size (%td). Min accepted is: (%td).\n",
349 KLS_Loc_Arg(loc), __func__, size, (ptrdiff_t)sizeof(Koliseo));
350#endif // KOLISEO_HAS_LOCATE
351 //TODO Is it better to abort the program?
352 return NULL;
353 }
354 void *p = alloc_func(size);
355 if (p) {
356 //sprintf(msg,"Allocated (%li) for new KLS.",size);
357 //kls_log("KLS",msg);
358 char h_size[200];
359 kls_formatSize(size, h_size, sizeof(h_size));
360 Koliseo *kls = p;
361 kls->data = p;
362 kls->size = size;
363 kls->offset = sizeof(*kls);
364 kls->prev_offset = kls->offset;
365 kls->has_temp = 0;
366 kls->t_kls = NULL;
367 kls_set_conf(kls, KLS_DEFAULT_CONF);
369 kls->conf.kls_log_fp = stderr;
370 kls->hooks_len = ext_len;
371
372 for (size_t i=0; i < kls->hooks_len; i++) {
373 kls->hooks[i] = ext_handlers[i];
374 }
375 for (size_t i=0; i < kls->hooks_len; i++) {
376 if (user) {
377 kls->extension_data[i] = user[i];
378 } else {
379 kls->extension_data[i] = NULL;
380 }
381 }
382 kls->free_func = free_func;
383 kls->next = NULL;
384#ifdef KLS_DEBUG_CORE
385 kls_log(kls, "KLS", "API Level { %i } -> Allocated (%s) for new KLS.",
386 int_koliseo_version(), h_size);
387 kls_log(kls, "KLS", "KLS offset: { %p }.", kls);
388 kls_log(kls, "KLS", "Allocation begin offset: { %p }.",
389 kls + kls->offset);
390#endif
391
392 for (size_t i=0; i < kls->hooks_len; i++) {
393 if (kls->hooks[i].on_new_handler != NULL) {
394 // Call on_new extension
395 kls->hooks[i].on_new_handler(kls);
396 }
397 }
398 } else {
399#ifndef KOLISEO_HAS_LOCATE
400 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
401#else
402 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), __func__);
403#endif // KOLISEO_HAS_LOCATE
404 exit(EXIT_FAILURE);
405 }
406#ifdef KLS_DEBUG_CORE
407 Koliseo *kls_ref = p;
408 if (kls_ref->conf.kls_verbose_lvl > 0) {
409 print_kls_2file(kls_ref->conf.kls_log_fp, p);
410 }
411#endif
412 return p;
413}
414
430#ifndef KOLISEO_HAS_LOCATE
431Koliseo *kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
432#else
433Koliseo *kls_new_alloc_dbg(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, Koliseo_Loc loc)
434#endif // KOLISEO_HAS_LOCATE
435{
436#ifndef KOLISEO_HAS_LOCATE
438#else
439 return kls_new_alloc_ext_dbg(size, alloc_func, free_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA, KLS_DEFAULT_EXTENSIONS_LEN, loc);
440#endif // KOLISEO_HAS_LOCATE
441}
442
455Koliseo *kls_new(ptrdiff_t size)
456{
458}
459
476Koliseo *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)
477{
478 Koliseo *k = kls_new_alloc_ext(size, alloc_func, free_func, ext_handlers, user, ext_len);
479 bool conf_res = kls_set_conf(k, conf);
480 if (!conf_res) {
481 fprintf(stderr,
482 "[ERROR] [%s()]: Failed to set config for new Koliseo.\n",
483 __func__);
484 exit(EXIT_FAILURE);
485 }
486 return k;
487}
488
505Koliseo *kls_new_conf_alloc(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, kls_free_func free_func)
506{
508}
509
522Koliseo *kls_new_conf_ext(ptrdiff_t size, KLS_Conf conf, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
523{
524 return kls_new_conf_alloc_ext(size, conf, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, ext_handlers, user, ext_len);
525}
526
538Koliseo *kls_new_conf(ptrdiff_t size, KLS_Conf conf)
539{
541}
542
558Koliseo *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)
559{
560
561#ifndef KLS_DEBUG_CORE
562 fprintf(stderr,
563 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No tracing allowed.\n",
564 __func__);
565#endif
566 KLS_Conf k = (KLS_Conf) {
567 .kls_collect_stats = 1,.kls_verbose_lvl =
568 1,.kls_log_filepath = output_path,
569#ifndef KOLISEO_HAS_LOCATE
570 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
571 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
572#else
573 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
574 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
575#endif // KOLISEO_HAS_LOCATE
576 };
577 return kls_new_conf_alloc_ext(size, k, alloc_func, free_func, ext_handlers, user, ext_len);
578}
579
594Koliseo *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)
595{
596 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);
597}
598
611Koliseo *kls_new_traced_ext(ptrdiff_t size, const char *output_path, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
612{
614 return kls_new_traced_alloc_handled_ext(size, output_path, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers, ext_handlers, user, ext_len);
615}
616
630Koliseo *kls_new_traced_alloc(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func)
631{
633 return kls_new_traced_alloc_handled(size, output_path, alloc_func, free_func, err_handlers);
634}
635
647Koliseo *kls_new_traced(ptrdiff_t size, const char *output_path)
648{
650}
651
664Koliseo *kls_new_traced_handled(ptrdiff_t size, const char *output_path, KLS_Err_Handlers err_handlers)
665{
666 return kls_new_traced_alloc_handled(size, output_path, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers);
667}
668
682Koliseo *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)
683{
684#ifndef KLS_DEBUG_CORE
685 fprintf(stderr,
686 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No debugging support.\n",
687 __func__);
688#endif
689 KLS_Conf k = (KLS_Conf) {
690 .kls_collect_stats = 1,.kls_verbose_lvl = 0,
691#ifndef KOLISEO_HAS_LOCATE
692 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
693 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
694#else
695 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
696 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
697#endif // KOLIEO_HAS_LOCATE
698 };
699 Koliseo * kls = kls_new_conf_alloc_ext(size, k, alloc_func, free_func, ext_handlers, user, ext_len);
700 kls->conf.kls_verbose_lvl = 1;
701 return kls;
702}
703
716Koliseo *kls_new_dbg_alloc_handled(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers)
717{
719}
720
731Koliseo *kls_new_dbg_ext(ptrdiff_t size, KLS_Hooks* ext_handlers, void** user, size_t ext_len)
732{
734 return kls_new_dbg_alloc_handled_ext(size, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers, ext_handlers, user, ext_len);
735}
736
748Koliseo *kls_new_dbg_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
749{
751 return kls_new_dbg_alloc_handled(size, alloc_func, free_func, err_handlers);
752}
753
763Koliseo *kls_new_dbg(ptrdiff_t size)
764{
766}
767
778Koliseo *kls_new_dbg_handled(ptrdiff_t size, KLS_Err_Handlers err_handlers)
779{
781}
782
789bool kls_set_conf(Koliseo *kls, KLS_Conf conf)
790{
791 if (kls == NULL) {
792 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
793 //TODO: is it better to exit() here?
794 return false;
795 }
796
797 kls->conf = conf;
798 if (kls->conf.kls_log_fp == NULL) {
799 kls->conf.kls_log_fp = stderr;
800#ifdef KLS_DEBUG_CORE
801#ifdef KLS_SETCONF_DEBUG
802 kls_log(kls, "KLS",
803 "[%s()]: Preliminary set of conf.kls_log_fp to stderr.",
804 __func__);
805#endif
806#endif // KLS_DEBUG_CORE
807 }
808
809 if (conf.err_handlers.OOM_handler == NULL) {
810 fprintf(stderr,
811 "[ERROR] at %s(): passed OOM_handler is NULL. Using default.\n",
812 __func__);
813#ifdef KLS_DEBUG_CORE
814#ifdef KLS_SETCONF_DEBUG
815 kls_log(kls, "KLS",
816 "[%s()]: Passed OOM_handler was NULL, using default.",
817 __func__);
818#endif
819#endif // KLS_DEBUG_CORE
820#ifndef KOLISEO_HAS_LOCATE
822#else
823 kls->conf.err_handlers.OOM_handler = &KLS_OOM_default_handler_dbg__;
824#endif
825 }
826
827 if (conf.err_handlers.PTRDIFF_MAX_handler == NULL) {
828 fprintf(stderr,
829 "[ERROR] at %s(): passed PTRDIFF_MAX_handler is NULL. Using default.\n",
830 __func__);
831#ifdef KLS_DEBUG_CORE
832#ifdef KLS_SETCONF_DEBUG
833 kls_log(kls, "KLS",
834 "[%s()]: Passed PTRDIFF_MAX_handler was NULL, using default.",
835 __func__);
836#endif
837#endif // KLS_DEBUG_CORE
838#ifndef KOLISEO_HAS_LOCATE
840#else
841 kls->conf.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__;
842#endif
843 }
844
845#ifndef KLS_DEBUG_CORE
846 if (kls->conf.kls_collect_stats == 1) {
847 fprintf(stderr,
848 "[WARN] [%s()]: KLS_DEBUG_CORE is not defined. Stats may not be collected in full.\n",
849 __func__);
850 }
851#endif
852
853 if (kls->conf.kls_verbose_lvl > 0) {
854 if (kls->conf.kls_log_fp != NULL) {
855#ifdef KLS_DEBUG_CORE
856#ifdef KLS_SETCONF_DEBUG
857 kls_log(kls, "WARN",
858 "[%s()]: kls->conf.kls_log_fp was not NULL. Overriding it.",
859 __func__);
860#endif
861#endif
862 if (kls->conf.kls_collect_stats == 1) {
863 kls->stats.tot_hiccups += 1;
864 }
865 }
866
867 FILE *log_fp = NULL;
868 log_fp = fopen(kls->conf.kls_log_filepath, "w");
869 if (!log_fp) {
870 fprintf(stderr,
871 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [write].\n",
872 __func__, kls->conf.kls_log_filepath);
873 return false;
874 } else {
875 fprintf(log_fp, "%s", ""); //Reset log_fp
876 fclose(log_fp);
877 }
878 log_fp = fopen(kls->conf.kls_log_filepath, "a");
879 if (!log_fp) {
880 fprintf(stderr,
881 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [append].\n",
882 __func__, kls->conf.kls_log_filepath);
883 return false;
884 } else {
885 kls->conf.kls_log_fp = log_fp;
886 }
887 }
888 return true;
889}
890
891static bool kls__try_grow(Koliseo* kls, ptrdiff_t needed);
892
905#ifndef KOLISEO_HAS_LOCATE
906int kls__check_available_failable(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name)
907#else
908int kls__check_available_failable_dbg(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name, Koliseo_Loc loc)
909#endif // KOLISEO_HAS_LOCATE
910{
911 assert(kls != NULL);
912 assert(caller_name != NULL);
913 if (count < 0) {
914#ifndef KOLISEO_HAS_LOCATE
915 fprintf(stderr,
916 "[KLS] %s(): count [%td] was < 0.\n",
917 caller_name,
918 count);
919#else
920 fprintf(stderr,
921 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was < 0.\n",
922 KLS_Loc_Arg(loc),
923 caller_name,
924 count);
925#endif // KOLISEO_HAS_LOCATE
926 return -1;
927 }
928 if (size < 1) {
929#ifndef KOLISEO_HAS_LOCATE
930 fprintf(stderr,
931 "[KLS] %s(): size [%td] was < 1.\n",
932 caller_name,
933 size);
934#else
935 fprintf(stderr,
936 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
937 KLS_Loc_Arg(loc),
938 caller_name,
939 size);
940#endif // KOLISEO_HAS_LOCATE
941 return -1;
942 }
943 if (align < 1) {
944#ifndef KOLISEO_HAS_LOCATE
945 fprintf(stderr,
946 "[KLS] %s(): align [%td] was < 1.\n",
947 caller_name,
948 align);
949#else
950 fprintf(stderr,
951 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
952 KLS_Loc_Arg(loc),
953 caller_name,
954 align);
955#endif // KOLISEO_HAS_LOCATE
956 return -1;
957 }
958 if (! ((align & (align - 1)) == 0)) {
959#ifndef KOLISEO_HAS_LOCATE
960 fprintf(stderr,
961 "[KLS] %s(): align [%td] was not a power of 2.\n",
962 caller_name,
963 align);
964#else
965 fprintf(stderr,
966 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
967 KLS_Loc_Arg(loc),
968 caller_name,
969 align);
970#endif // KOLISEO_HAS_LOCATE
971 return -1;
972 }
973 Koliseo* current = kls;
974 while (current->next != NULL) {
975 current = current->next;
976 }
977 const ptrdiff_t available = current->size - current->offset;
978 const ptrdiff_t padding = -current->offset & (align - 1);
979 bool ZEROCOUNT_happened = false;
980 bool ZEROCOUNT_handled = false;
981 if (count == 0) {
982 if (current->conf.kls_allow_zerocount_push != 1) {
983 ZEROCOUNT_happened = true;
984 if (current->conf.err_handlers.ZEROCOUNT_handler != NULL) {
985#ifndef KOLISEO_HAS_LOCATE
986 current->conf.err_handlers.ZEROCOUNT_handler(current, available, padding, size);
987#else
988 current->conf.err_handlers.ZEROCOUNT_handler(current, available, padding, size, loc);
989#endif // KOLISEO_HAS_LOCATE
990 ZEROCOUNT_handled = true;
991 } else {
992#ifndef KOLISEO_HAS_LOCATE
993 fprintf(stderr,
994 "[KLS] %s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
995 caller_name,
996 size, padding, available);
997#else
998 fprintf(stderr,
999 "[KLS] " KLS_Loc_Fmt "%s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
1000 KLS_Loc_Arg(loc),
1001 caller_name,
1002 size, padding, available);
1003#endif // KOLISEO_HAS_LOCATE
1004 kls_free(kls);
1005 exit(EXIT_FAILURE);
1006 }
1007 } else {
1008#ifdef KLS_DEBUG_CORE
1009 kls_log(current, "DEBUG", "Accepting zero-count push: conf.kls_allow_zerocount_push was 1");
1010#endif // KLS_DEBUG_CORE
1011 }
1012 }
1013
1014 if (ZEROCOUNT_happened && ZEROCOUNT_handled) {
1015#ifdef KLS_DEBUG_CORE
1016 kls_log(current, "DEBUG", "Requested a zero-count push while kls_allow_zerocount_push is not 1, but the error handler returned instead of exiting.");
1017#endif // KLS_DEBUG_CORE
1018#ifndef KOLISEO_HAS_LOCATE
1019 fprintf(stderr,
1020 "[KLS] %s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
1021 caller_name,
1022 size, padding, available);
1023#else
1024 fprintf(stderr,
1025 "[KLS] " KLS_Loc_Fmt "%s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
1026 KLS_Loc_Arg(loc),
1027 caller_name,
1028 size, padding, available);
1029#endif // KOLISEO_HAS_LOCATE
1030 kls_free(kls);
1031 exit(EXIT_FAILURE);
1032 }
1033
1034 bool OOM_happened = false;
1035 bool OOM_handled = false;
1036 bool PTRDIFF_MAX_happened = false;
1037 bool PTRDIFF_MAX_handled = false;
1038 if (count > PTRDIFF_MAX / size || available - padding < size * count) {
1039 if (count > PTRDIFF_MAX / size) {
1040 PTRDIFF_MAX_happened = true;
1041 if (current->conf.err_handlers.PTRDIFF_MAX_handler != NULL) {
1042#ifndef KOLISEO_HAS_LOCATE
1043 current->conf.err_handlers.PTRDIFF_MAX_handler(current, size, count);
1044#else
1045 current->conf.err_handlers.PTRDIFF_MAX_handler(current, size, count, loc);
1046#endif // KOLISEO_HAS_LOCATE
1047 PTRDIFF_MAX_handled = true;
1048 } else { // Let's keep this here for now? It's the original part before adding KLS_PTRDIFF_MAX_default_handler__()
1049#ifndef _WIN32
1050#ifndef KOLISEO_HAS_LOCATE
1051 fprintf(stderr,
1052 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
1053 caller_name,
1054 count, PTRDIFF_MAX / size);
1055#else
1056 fprintf(stderr,
1057 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
1058 KLS_Loc_Arg(loc),
1059 caller_name,
1060 count, PTRDIFF_MAX / size);
1061#endif // KOLISEO_HAS_LOCATE
1062#else
1063#ifndef KOLISEO_HAS_LOCATE
1064 fprintf(stderr,
1065 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
1066 caller_name,
1067 count, PTRDIFF_MAX / size);
1068#else
1069 fprintf(stderr,
1070 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
1071 KLS_Loc_Arg(loc),
1072 caller_name,
1073 count, PTRDIFF_MAX / size);
1074#endif // KOLISEO_HAS_LOCATE
1075#endif // _WIN32
1076 }
1077 } else {
1078 if (current->conf.kls_growable == 1 && kls__try_grow(current, size + count + padding)) {
1079 return 0;
1080 }
1081 OOM_happened = true;
1082 if (current->conf.err_handlers.OOM_handler != NULL) {
1083#ifndef KOLISEO_HAS_LOCATE
1084 current->conf.err_handlers.OOM_handler(current, available, padding, size, count);
1085#else
1086 current->conf.err_handlers.OOM_handler(current, available, padding, size, count, loc);
1087#endif // KOLISEO_HAS_LOCATE
1088 OOM_handled = true;
1089 } else { // Let's keep this here for now? It's the original part before adding KLS_OOM_default_handler__()
1090#ifndef KOLISEO_HAS_LOCATE
1091 fprintf(stderr,
1092 "[KLS] %s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
1093 caller_name,
1094 size * count, available - padding);
1095#else
1096 fprintf(stderr,
1097 "[KLS] " KLS_Loc_Fmt "%s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
1098 KLS_Loc_Arg(loc),
1099 caller_name,
1100 size * count, available - padding);
1101#endif // KOLISEO_HAS_LOCATE
1102 }
1103 }
1104 if (PTRDIFF_MAX_happened) {
1105 if (current->conf.err_handlers.PTRDIFF_MAX_handler && PTRDIFF_MAX_handled) {
1106#ifndef KOLISEO_HAS_LOCATE
1107 fprintf(stderr, "[KLS] %s(): PTRDIFF_MAX fault happened and was handled.\n", caller_name);
1108#ifdef KLS_DEBUG_CORE
1109 kls_log(current, "DEBUG", "%s(): PTRDIFF_MAX fault happened and was handled.", caller_name);
1110#endif // KLS_DEBUG_CORE
1111#else
1112 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "%s(): PTRDIFF_MAX fault happened and was handled.\n", KLS_Loc_Arg(loc), caller_name);
1113#ifdef KLS_DEBUG_CORE
1114 kls_log(current, "DEBUG", KLS_Loc_Fmt "%s(): PTRDIFF_MAX fault happened and was handled.", KLS_Loc_Arg(loc), caller_name);
1115#endif // KLS_DEBUG_CORE
1116#endif // KOLISEO_HAS_LOCATE
1117 return -1;
1118 }
1119 } else if (OOM_happened) {
1120 if (current->conf.err_handlers.OOM_handler && OOM_handled) {
1121#ifndef KOLISEO_HAS_LOCATE
1122 fprintf(stderr, "[KLS] %s(): OOM fault happened and was handled.\n", caller_name);
1123#ifdef KLS_DEBUG_CORE
1124 kls_log(current, "DEBUG", "%s(): OOM fault happened and was handled.", caller_name);
1125#endif // KLS_DEBUG_CORE
1126#else
1127 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "%s(): OOM fault happened and was handled.\n", KLS_Loc_Arg(loc), caller_name);
1128#ifdef KLS_DEBUG_CORE
1129 kls_log(current, "DEBUG", KLS_Loc_Fmt "%s(): OOM fault happened and was handled.", KLS_Loc_Arg(loc), caller_name);
1130#endif // KLS_DEBUG_CORE
1131#endif // KOLISEO_HAS_LOCATE
1132 return -1;
1133 }
1134 }
1135#ifndef KOLISEO_HAS_LOCATE
1136 fprintf(stderr, "[KLS] Failed %s() call.\n", caller_name);
1137#else
1138 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), caller_name);
1139#endif // KOLISEO_HAS_LOCATE
1140 kls_free(kls);
1141 exit(EXIT_FAILURE);
1142 }
1143 return 0;
1144}
1145
1146bool kls__try_grow(Koliseo* kls, ptrdiff_t needed)
1147{
1148 ptrdiff_t new_size = KLS_MAX(kls->size * 2, needed);
1150 kls_log(kls, "DEBUG", "%s(): growing Koliseo, new size: {%td}", __func__, new_size);
1151 if (!new_kls) return false;
1152 kls->next = new_kls;
1153 return true;
1154}
1155
1165void *kls_push(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1166{
1167
1168#ifdef KLS_DEBUG_CORE
1169#ifndef _WIN32
1170 struct timespec start_time, end_time;
1171 clock_gettime(CLOCK_MONOTONIC, &start_time);
1172#else
1173 LARGE_INTEGER start_time, end_time, frequency;
1174 QueryPerformanceFrequency(&frequency);
1175 QueryPerformanceCounter(&start_time);
1176#endif
1177#endif
1178
1179 if (kls == NULL) {
1180 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1181 exit(EXIT_FAILURE);
1182 }
1183 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1184 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1185#ifdef KLS_DEBUG_CORE
1186 kls_log(kls, "ERROR", "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", __func__);
1187 exit(EXIT_FAILURE);
1188#endif // KLS_DEBUG_CORE
1189 return NULL;
1190 }
1191#ifndef KOLISEO_HAS_LOCATE
1192 kls__check_available(kls, size, align, count);
1193#else
1194 kls__check_available_dbg(kls, size, align, count, KLS_HERE);
1195#endif // KOLISEO_HAS_LOCATE
1196 Koliseo* current = kls;
1197 while (current->next != NULL) {
1198 current = current->next;
1199 }
1200 ptrdiff_t padding = -current->offset & (align - 1);
1201 char *p = current->data + current->offset + padding;
1202 current->prev_offset = current->offset;
1203 current->offset += padding + size * count;
1204 char h_size[200];
1205 kls_formatSize(size * count, h_size, sizeof(h_size));
1206 //sprintf(msg,"Pushed size (%li) for KLS.",size);
1207 //kls_log("KLS",msg);
1208#ifdef KLS_DEBUG_CORE
1209 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1210 kls_log(current, "KLS", "API Level { %i } -> Pushed size (%s) for KLS.",
1211 int_koliseo_version(), h_size);
1212 if (current->conf.kls_verbose_lvl > 0) {
1213 print_kls_2file(current->conf.kls_log_fp, current);
1214 }
1215 if (current->conf.kls_collect_stats == 1) {
1216#ifndef _WIN32
1217 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1218 double elapsed_time =
1219 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1220 start_time.tv_nsec) / 1e9;
1221#else
1222 QueryPerformanceCounter(&end_time); // %.7f
1223 double elapsed_time =
1224 (double)(end_time.QuadPart -
1225 start_time.QuadPart) / frequency.QuadPart;
1226#endif
1227 if (elapsed_time > current->stats.worst_pushcall_time) {
1228 current->stats.worst_pushcall_time = elapsed_time;
1229 }
1230 }
1231#endif
1232 if (current->conf.kls_collect_stats == 1) {
1233 current->stats.tot_pushes += 1;
1234 }
1235 return p;
1236}
1237
1247#ifndef KOLISEO_HAS_LOCATE
1248void *kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1249 ptrdiff_t count)
1250#else
1251void *kls_push_zero_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1252 ptrdiff_t count, Koliseo_Loc loc)
1253#endif // KOLISEO_HAS_LOCATE
1254{
1255
1256#ifdef KLS_DEBUG_CORE
1257#ifndef _WIN32
1258 struct timespec start_time, end_time;
1259 clock_gettime(CLOCK_MONOTONIC, &start_time);
1260#else
1261 LARGE_INTEGER start_time, end_time, frequency;
1262 QueryPerformanceFrequency(&frequency);
1263 QueryPerformanceCounter(&start_time);
1264#endif
1265#endif
1266
1267 if (kls == NULL) {
1268 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1269 exit(EXIT_FAILURE);
1270 }
1271 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1272#ifndef KOLISEO_HAS_LOCATE
1273 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1274#else
1275 fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__);
1276 kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__);
1277 exit(EXIT_FAILURE);
1278#endif // KOLISEO_HAS_LOCATE
1279 return NULL;
1280 }
1281#ifndef KOLISEO_HAS_LOCATE
1282 kls__check_available(kls, size, align, count);
1283#else
1284 kls__check_available_dbg(kls, size, align, count, loc);
1285#endif
1286 Koliseo* current = kls;
1287 while (current->next != NULL) {
1288 current = current->next;
1289 }
1290 ptrdiff_t padding = -current->offset & (align - 1);
1291 char *p = current->data + current->offset + padding;
1292 //Zero new area
1293 memset(p, 0, size * count);
1294 current->prev_offset = current->offset;
1295 current->offset += padding + size * count;
1296 char h_size[200];
1297 kls_formatSize(size * count, h_size, sizeof(h_size));
1298 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1299 //kls_log("KLS",msg);
1300#ifdef KLS_DEBUG_CORE
1301 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1302 kls_log(current, "KLS", "API Level { %i } -> Pushed zeroes, size (%s) for KLS.",
1303 int_koliseo_version(), h_size);
1304 if (current->conf.kls_verbose_lvl > 0) {
1305 print_kls_2file(current->conf.kls_log_fp, current);
1306 }
1307 if (current->conf.kls_collect_stats == 1) {
1308#ifndef _WIN32
1309 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1310 double elapsed_time =
1311 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1312 start_time.tv_nsec) / 1e9;
1313#else
1314 QueryPerformanceCounter(&end_time); // %.7f
1315 double elapsed_time =
1316 (double)(end_time.QuadPart -
1317 start_time.QuadPart) / frequency.QuadPart;
1318#endif
1319 if (elapsed_time > current->stats.worst_pushcall_time) {
1320 current->stats.worst_pushcall_time = elapsed_time;
1321 }
1322 }
1323#endif
1324 if (current->conf.kls_collect_stats == 1) {
1325 current->stats.tot_pushes += 1;
1326 }
1327 return p;
1328}
1329
1339#ifndef KOLISEO_HAS_LOCATE
1340void *kls_push_zero_ext(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1341 ptrdiff_t count)
1342#else
1343void *kls_push_zero_ext_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1344 ptrdiff_t count, Koliseo_Loc loc)
1345#endif // KOLISEO_HAS_LOCATE
1346{
1347
1348#ifdef KLS_DEBUG_CORE
1349#ifndef _WIN32
1350 struct timespec start_time, end_time;
1351 clock_gettime(CLOCK_MONOTONIC, &start_time);
1352#else
1353 LARGE_INTEGER start_time, end_time, frequency;
1354 QueryPerformanceFrequency(&frequency);
1355 QueryPerformanceCounter(&start_time);
1356#endif
1357#endif
1358
1359 if (kls == NULL) {
1360 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1361 exit(EXIT_FAILURE);
1362 }
1363 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1364#ifndef KOLISEO_HAS_LOCATE
1365 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1366#else
1367 fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__);
1368 kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__);
1369 exit(EXIT_FAILURE);
1370#endif // KOLISEO_HAS_LOCATE
1371 return NULL;
1372 }
1373
1374#ifndef KOLISEO_HAS_LOCATE
1375 kls__check_available(kls, size, align, count);
1376#else
1377 kls__check_available_dbg(kls, size, align, count, loc);
1378#endif
1379 Koliseo* current = kls;
1380 while (current->next != NULL) {
1381 current = current->next;
1382 }
1383 ptrdiff_t padding = -current->offset & (align - 1);
1384 char *p = current->data + current->offset + padding;
1385 //Zero new area
1386 memset(p, 0, size * count);
1387 current->prev_offset = current->offset;
1388 current->offset += padding + size * count;
1389
1390 for (size_t i=0; i < kls->hooks_len; i++) {
1391 if (current->hooks[i].on_push_handler != NULL) {
1392 /*
1393 struct KLS_EXTENSION_AR_DEFAULT_ARGS {
1394 const char* region_name;
1395 size_t region_name_len;
1396 const char* region_desc;
1397 size_t region_desc_len;
1398 int region_type;
1399 };
1400 struct KLS_EXTENSION_AR_DEFAULT_ARGS ar_args = {
1401 .region_name = KOLISEO_DEFAULT_REGION_NAME,
1402 .region_name_len = strlen(KOLISEO_DEFAULT_REGION_NAME),
1403 .region_desc = KOLISEO_DEFAULT_REGION_DESC,
1404 .region_desc_len = strlen(KOLISEO_DEFAULT_REGION_DESC),
1405 .region_type = KLS_None
1406 };
1407 kls->hooks.on_push_handler(kls, padding, (void*)&ar_args);
1408 */
1409 current->hooks[i].on_push_handler(current, padding, __func__, NULL);
1410 }
1411 }
1412
1413 char h_size[200];
1414 kls_formatSize(size * count, h_size, sizeof(h_size));
1415 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1416 //kls_log("KLS",msg);
1417#ifdef KLS_DEBUG_CORE
1418 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1419 kls_log(current, "KLS", "API Level { %i } -> Pushed zeroes, size (%s) for KLS.",
1420 int_koliseo_version(), h_size);
1421 if (current->conf.kls_verbose_lvl > 0) {
1422 print_kls_2file(current->conf.kls_log_fp, current);
1423 }
1424 if (current->conf.kls_collect_stats == 1) {
1425#ifndef _WIN32
1426 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1427 double elapsed_time =
1428 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1429 start_time.tv_nsec) / 1e9;
1430#else
1431 QueryPerformanceCounter(&end_time); // %.7f
1432 double elapsed_time =
1433 (double)(end_time.QuadPart -
1434 start_time.QuadPart) / frequency.QuadPart;
1435#endif
1436 if (elapsed_time > current->stats.worst_pushcall_time) {
1437 current->stats.worst_pushcall_time = elapsed_time;
1438 }
1439 }
1440#endif
1441 if (current->conf.kls_collect_stats == 1) {
1442 current->stats.tot_pushes += 1;
1443 }
1444 return p;
1445}
1446
1457#ifndef KOLISEO_HAS_LOCATE
1458void *kls_temp_push_zero_ext(Koliseo_Temp *t_kls, ptrdiff_t size,
1459 ptrdiff_t align, ptrdiff_t count)
1460#else
1461void *kls_temp_push_zero_ext_dbg(Koliseo_Temp *t_kls, ptrdiff_t size,
1462 ptrdiff_t align, ptrdiff_t count, Koliseo_Loc loc)
1463#endif // KOLISEO_HAS_LOCATE
1464{
1465
1466#ifdef KLS_DEBUG_CORE
1467#ifndef _WIN32
1468 struct timespec start_time, end_time;
1469 clock_gettime(CLOCK_MONOTONIC, &start_time);
1470#else
1471 LARGE_INTEGER start_time, end_time, frequency;
1472 QueryPerformanceFrequency(&frequency);
1473 QueryPerformanceCounter(&start_time);
1474#endif
1475#endif
1476
1477 if (t_kls == NULL) {
1478 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1479 __func__);
1480 exit(EXIT_FAILURE);
1481 }
1482 Koliseo *kls = t_kls->kls;
1483 if (kls == NULL) {
1484 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1485 __func__);
1486 exit(EXIT_FAILURE);
1487 }
1488#ifndef KOLISEO_HAS_LOCATE
1489 kls__check_available(kls, size, align, count);
1490#else
1491 kls__check_available_dbg(kls, size, align, count, loc);
1492#endif
1493 Koliseo* current = kls;
1494 while (current->next != NULL) {
1495 current = current->next;
1496 }
1497 ptrdiff_t padding = -current->offset & (align - 1);
1498 char *p = current->data + current->offset + padding;
1499 //Zero new area
1500 memset(p, 0, size * count);
1501 current->prev_offset = current->offset;
1502 current->offset += padding + size * count;
1503
1504 for (size_t i=0; i < kls->hooks_len; i++) {
1505 if (current->hooks[i].on_temp_push_handler != NULL) {
1506 // Call on_temp_push extension with empty user arg
1507 current->hooks[i].on_temp_push_handler(t_kls, padding, __func__, NULL);
1508 }
1509 }
1510
1511 char h_size[200];
1512 kls_formatSize(size * count, h_size, sizeof(h_size));
1513 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1514 //kls_log("KLS",msg);
1515#ifdef KLS_DEBUG_CORE
1516 if (current->conf.kls_collect_stats == 1) {
1517#ifndef _WIN32
1518 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1519 double elapsed_time =
1520 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1521 start_time.tv_nsec) / 1e9;
1522#else
1523 QueryPerformanceCounter(&end_time); // %.7f
1524 double elapsed_time =
1525 (double)(end_time.QuadPart -
1526 start_time.QuadPart) / frequency.QuadPart;
1527#endif
1528 if (elapsed_time > current->stats.worst_pushcall_time) {
1529 current->stats.worst_pushcall_time = elapsed_time;
1530 }
1531 }
1532 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1533 kls_log(current, "KLS",
1534 "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.",
1535 int_koliseo_version(), h_size);
1536 if (current->conf.kls_verbose_lvl > 0) {
1537 print_kls_2file(current->conf.kls_log_fp, current);
1538 }
1539#endif
1540 if (current->conf.kls_collect_stats == 1) {
1541 current->stats.tot_temp_pushes += 1;
1542 }
1543 return p;
1544}
1545
1557#ifndef KOLISEO_HAS_LOCATE
1558void *kls_repush(Koliseo *kls, void* old, ptrdiff_t size, ptrdiff_t align,
1559 ptrdiff_t old_count, ptrdiff_t new_count)
1560#else
1561void *kls_repush_dbg(Koliseo *kls, void* old, ptrdiff_t size, ptrdiff_t align,
1562 ptrdiff_t old_count, ptrdiff_t new_count, Koliseo_Loc loc)
1563#endif // KOLISEO_HAS_LOCATE
1564{
1565 if (!old) {
1566#ifndef KOLISEO_HAS_LOCATE
1567 fprintf(stderr,
1568 "[KLS] %s(): old was NULL.\n",
1569 __func__);
1570#else
1571 fprintf(stderr,
1572 "[KLS] " KLS_Loc_Fmt "%s(): old was NULL.\n",
1573 KLS_Loc_Arg(loc),
1574 __func__);
1575#endif // KOLISEO_HAS_LOCATE
1576 return NULL;
1577 }
1578 if (old_count < 0) {
1579#ifndef KOLISEO_HAS_LOCATE
1580 fprintf(stderr,
1581 "[KLS] %s(): old_count [%td] was < 0.\n",
1582 __func__,
1583 old_count);
1584#else
1585 fprintf(stderr,
1586 "[KLS] " KLS_Loc_Fmt "%s(): old_count [%td] was < 0.\n",
1587 KLS_Loc_Arg(loc),
1588 __func__,
1589 old_count);
1590#endif // KOLISEO_HAS_LOCATE
1591 return NULL;
1592 }
1593 if (new_count < 0) {
1594#ifndef KOLISEO_HAS_LOCATE
1595 fprintf(stderr,
1596 "[KLS] %s(): new_count [%td] was < 0.\n",
1597 __func__,
1598 new_count);
1599#else
1600 fprintf(stderr,
1601 "[KLS] " KLS_Loc_Fmt "%s(): new_count [%td] was < 0.\n",
1602 KLS_Loc_Arg(loc),
1603 __func__,
1604 new_count);
1605#endif // KOLISEO_HAS_LOCATE
1606 return NULL;
1607 }
1608 if (size < 1) {
1609#ifndef KOLISEO_HAS_LOCATE
1610 fprintf(stderr,
1611 "[KLS] %s(): size [%td] was < 1.\n",
1612 __func__,
1613 size);
1614#else
1615 fprintf(stderr,
1616 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
1617 KLS_Loc_Arg(loc),
1618 __func__,
1619 size);
1620#endif // KOLISEO_HAS_LOCATE
1621 return NULL;
1622 }
1623 if (align < 1) {
1624#ifndef KOLISEO_HAS_LOCATE
1625 fprintf(stderr,
1626 "[KLS] %s(): align [%td] was < 1.\n",
1627 __func__,
1628 align);
1629#else
1630 fprintf(stderr,
1631 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
1632 KLS_Loc_Arg(loc),
1633 __func__,
1634 align);
1635#endif // KOLISEO_HAS_LOCATE
1636 return NULL;
1637 }
1638 if (! ((align & (align - 1)) == 0)) {
1639#ifndef KOLISEO_HAS_LOCATE
1640 fprintf(stderr,
1641 "[KLS] %s(): align [%td] was not a power of 2.\n",
1642 __func__,
1643 align);
1644#else
1645 fprintf(stderr,
1646 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
1647 KLS_Loc_Arg(loc),
1648 __func__,
1649 align);
1650#endif // KOLISEO_HAS_LOCATE
1651 return NULL;
1652 }
1653 if (kls->has_temp == 1 && kls->conf.kls_block_while_has_temp == 1) {
1654 fprintf(stderr, "%s(): kls has an active temp\n", __func__);
1655 return NULL;
1656 }
1657 size_t old_size = old_count * size;
1658 size_t new_size = new_count * size;
1659 void *new_ptr = kls_push_zero_ext(kls, size, align, new_count);
1660 if (new_ptr && old_size > 0) {
1661 memcpy(new_ptr, old, old_size < new_size ? old_size : new_size);
1662 }
1663 return new_ptr;
1664}
1665
1677#ifndef KOLISEO_HAS_LOCATE
1678void *kls_temp_repush(Koliseo_Temp *t_kls, void* old, ptrdiff_t size, ptrdiff_t align,
1679 ptrdiff_t old_count, ptrdiff_t new_count)
1680#else
1681void *kls_temp_repush_dbg(Koliseo_Temp *t_kls, void* old, ptrdiff_t size, ptrdiff_t align,
1682 ptrdiff_t old_count, ptrdiff_t new_count, Koliseo_Loc loc)
1683#endif // KOLISEO_HAS_LOCATE
1684{
1685 if (!old) {
1686#ifndef KOLISEO_HAS_LOCATE
1687 fprintf(stderr,
1688 "[KLS] %s(): old was NULL.\n",
1689 __func__);
1690#else
1691 fprintf(stderr,
1692 "[KLS] " KLS_Loc_Fmt "%s(): old was NULL.\n",
1693 KLS_Loc_Arg(loc),
1694 __func__);
1695#endif // KOLISEO_HAS_LOCATE
1696 return NULL;
1697 }
1698 if (old_count < 0) {
1699#ifndef KOLISEO_HAS_LOCATE
1700 fprintf(stderr,
1701 "[KLS] %s(): old_count [%td] was < 0.\n",
1702 __func__,
1703 old_count);
1704#else
1705 fprintf(stderr,
1706 "[KLS] " KLS_Loc_Fmt "%s(): old_count [%td] was < 0.\n",
1707 KLS_Loc_Arg(loc),
1708 __func__,
1709 old_count);
1710#endif // KOLISEO_HAS_LOCATE
1711 return NULL;
1712 }
1713 if (new_count < 0) {
1714#ifndef KOLISEO_HAS_LOCATE
1715 fprintf(stderr,
1716 "[KLS] %s(): new_count [%td] was < 0.\n",
1717 __func__,
1718 new_count);
1719#else
1720 fprintf(stderr,
1721 "[KLS] " KLS_Loc_Fmt "%s(): new_count [%td] was < 0.\n",
1722 KLS_Loc_Arg(loc),
1723 __func__,
1724 new_count);
1725#endif // KOLISEO_HAS_LOCATE
1726 return NULL;
1727 }
1728 if (size < 1) {
1729#ifndef KOLISEO_HAS_LOCATE
1730 fprintf(stderr,
1731 "[KLS] %s(): size [%td] was < 1.\n",
1732 __func__,
1733 size);
1734#else
1735 fprintf(stderr,
1736 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
1737 KLS_Loc_Arg(loc),
1738 __func__,
1739 size);
1740#endif // KOLISEO_HAS_LOCATE
1741 return NULL;
1742 }
1743 if (align < 1) {
1744#ifndef KOLISEO_HAS_LOCATE
1745 fprintf(stderr,
1746 "[KLS] %s(): align [%td] was < 1.\n",
1747 __func__,
1748 align);
1749#else
1750 fprintf(stderr,
1751 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
1752 KLS_Loc_Arg(loc),
1753 __func__,
1754 align);
1755#endif // KOLISEO_HAS_LOCATE
1756 return NULL;
1757 }
1758 if (! ((align & (align - 1)) == 0)) {
1759#ifndef KOLISEO_HAS_LOCATE
1760 fprintf(stderr,
1761 "[KLS] %s(): align [%td] was not a power of 2.\n",
1762 __func__,
1763 align);
1764#else
1765 fprintf(stderr,
1766 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
1767 KLS_Loc_Arg(loc),
1768 __func__,
1769 align);
1770#endif // KOLISEO_HAS_LOCATE
1771 return NULL;
1772 }
1773 size_t old_size = old_count * size;
1774 size_t new_size = new_count * size;
1775 void *new_ptr = kls_temp_push_zero_ext(t_kls, size, align, new_count);
1776 if (new_ptr && old_size > 0) {
1777 memcpy(new_ptr, old, old_size < new_size ? old_size : new_size);
1778 }
1779 return new_ptr;
1780}
1781
1787void print_kls_2file(FILE *fp, const Koliseo *kls)
1788{
1789 if (fp == NULL) {
1790 fprintf(stderr, "print_kls_2file(): fp was NULL.\n");
1791 return;
1792 }
1793 if (kls == NULL) {
1794 fprintf(fp, "[KLS] kls was NULL.\n");
1795 } else {
1796 fprintf(fp, "\n[KLS] API Level: { %i }\n", int_koliseo_version());
1797 fprintf(fp, "\n[INFO] Conf: { " KLS_Conf_Fmt " }\n",
1798 KLS_Conf_Arg(kls->conf));
1799 fprintf(fp, "\n[INFO] Stats: { " KLS_Stats_Fmt " }\n",
1800 KLS_Stats_Arg(kls->stats));
1801 fprintf(fp, "\n[KLS] Size: { %td }\n", kls->size);
1802 char human_size[200];
1803 char curr_size[200];
1804 kls_formatSize(kls->size, human_size, sizeof(human_size));
1805 fprintf(fp, "[KLS] Size (Human): { %s }\n", human_size);
1806 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1807 fprintf(fp, "[KLS] Used (Human): { %s }\n", curr_size);
1808 fprintf(fp, "[KLS] Offset: { %td }\n", kls->offset);
1809 fprintf(fp, "[KLS] Prev_Offset: { %td }\n", kls->prev_offset);
1810 fprintf(fp, "\n");
1811 }
1812}
1813
1818void print_dbg_kls(const Koliseo *kls)
1819{
1820 if (kls == NULL) {
1821 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1822 exit(EXIT_FAILURE);
1823 }
1824 print_kls_2file(stderr, kls);
1825}
1826
1832void print_temp_kls_2file(FILE *fp, const Koliseo_Temp *t_kls)
1833{
1834 if (fp == NULL) {
1835 fprintf(stderr, "print_temp_kls_2file(): fp was NULL.\n");
1836 exit(EXIT_FAILURE);
1837 }
1838 if (t_kls == NULL) {
1839 fprintf(fp, "[KLS_T] t_kls was NULL.");
1840 } else if (t_kls->kls == NULL) {
1841 fprintf(fp, "[KLS_T] [%s()]: Referred Koliseo was NULL.\n", __func__);
1842 } else {
1843 const Koliseo *kls = t_kls->kls;
1844 fprintf(fp, "\n[KLS_T] API Level: { %i }\n", int_koliseo_version());
1845 fprintf(fp, "\n[KLS_T] Temp Size: { %td }\n",
1846 kls->size - t_kls->offset);
1847 fprintf(fp, "\n[KLS_T] Refer Size: { %td }\n", kls->size);
1848 char human_size[200];
1849 char curr_size[200];
1850 kls_formatSize(kls->size - t_kls->offset, human_size,
1851 sizeof(human_size));
1852 fprintf(fp, "[KLS_T] Temp Size Human: { %s }\n", human_size);
1853 kls_formatSize(kls->size, human_size, sizeof(human_size));
1854 fprintf(fp, "[KLS_T] Refer Size Human: { %s }\n", human_size);
1855 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1856 fprintf(fp, "[KLS_T] Inner Used (Human): { %s }\n", curr_size);
1857 kls_formatSize(t_kls->offset, curr_size, sizeof(curr_size));
1858 fprintf(fp, "[KLS_T] Temp Used (Human): { %s }\n", curr_size);
1859 fprintf(fp, "[KLS_T] Inner Offset: { %td }\n", kls->offset);
1860 fprintf(fp, "[KLS_T] Temp Offset: { %td }\n", t_kls->offset);
1861 fprintf(fp, "[KLS_T] Inner Prev_Offset: { %td }\n", kls->prev_offset);
1862 fprintf(fp, "[KLS_T] Temp Prev_Offset: { %td }\n\n",
1863 t_kls->prev_offset);
1864 }
1865}
1866
1872{
1873 print_temp_kls_2file(stderr, t_kls);
1874}
1875
1883void kls_formatSize(ptrdiff_t size, char *outputBuffer, size_t bufferSize)
1884{
1885 const char *units[] =
1886 { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
1887 const int numUnits = sizeof(units) / sizeof(units[0]);
1888
1889 int unitIndex = 0;
1890 double sizeValue = (double)size;
1891
1892 while (sizeValue >= 1000 && unitIndex < numUnits - 1) {
1893 sizeValue /= 1000;
1894 unitIndex++;
1895 }
1896
1897 snprintf(outputBuffer, bufferSize, "%.2f %s", sizeValue, units[unitIndex]);
1898}
1899
1906{
1907 if (kls == NULL) {
1908 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1909 exit(EXIT_FAILURE);
1910 }
1911 //Reset pointer
1912 kls->prev_offset = kls->offset;
1913 kls->offset = sizeof(*kls);
1914#ifdef KLS_DEBUG_CORE
1915 kls_log(kls, "KLS", "API Level { %i } -> Cleared offsets for KLS.",
1917#endif
1918}
1919
1926{
1927 if (kls == NULL) {
1928 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1929 exit(EXIT_FAILURE);
1930 }
1931 Koliseo* current = kls;
1932 while (current) {
1933 Koliseo* next = current->next;
1934 current->next = NULL;
1935 for (size_t i=0; i < current->hooks_len; i++) {
1936 if (current->hooks[i].on_free_handler != NULL) {
1937 // Call on_free() extension
1938 current->hooks[i].on_free_handler(current);
1939 }
1940 }
1941 if (current->has_temp == 1) {
1942#ifdef KLS_DEBUG_CORE
1943 kls_log(current, "KLS",
1944 "API Level { %i } -> KLS had an active Koliseo_Temp.",
1946#endif
1947 kls_temp_end(current->t_kls);
1948 }
1949 kls_clear(current);
1950#ifdef KLS_DEBUG_CORE
1951 kls_log(current, "KLS", "API Level { %i } -> Freeing KLS.",
1953#endif
1954 if (current->conf.kls_log_fp != NULL && current->conf.kls_log_fp != stdout
1955 && current->conf.kls_log_fp != stderr) {
1956#ifdef KLS_DEBUG_CORE
1957 kls_log(current, "KLS", "Closing kls log file. Path: {\"%s\"}.",
1958 kls->conf.kls_log_filepath);
1959#endif
1960 int close_res = fclose(current->conf.kls_log_fp);
1961 if (close_res != 0) {
1962 fprintf(stderr,
1963 "[ERROR] %s(): Failed fclose() on log_fp. Path: {\"%s\"}.",
1964 __func__, current->conf.kls_log_filepath);
1965 }
1966 } else if (current->conf.kls_log_fp == stdout || current->conf.kls_log_fp == stderr) {
1967 if (current->conf.kls_verbose_lvl > 1) {
1968 fprintf(stderr,
1969 "[INFO] %s(): kls->conf.kls_log_fp is %s. Not closing it.\n",
1970 __func__,
1971 (current->conf.kls_log_fp == stdout ? "stdout" : "stderr"));
1972 }
1973 }
1974 if (current->free_func == NULL) {
1975 fprintf(stderr,
1976 "[ERROR] %s(): free function was NULL.\n", __func__);
1977 return;
1978 }
1979 current->free_func(current);
1980 current = next;
1981 }
1982}
1983
1991#ifndef KOLISEO_HAS_LOCATE
1993#else
1994Koliseo_Temp *kls_temp_start_dbg(Koliseo *kls, Koliseo_Loc loc)
1995#endif // KOLISEO_HAS_LOCATE
1996{
1997 if (kls == NULL) {
1998 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1999 exit(EXIT_FAILURE);
2000 }
2001 Koliseo* current = kls;
2002 while (current->next != NULL) {
2003 current = current->next;
2004 }
2005 if (current->has_temp != 0) {
2006 fprintf(stderr,
2007 "[ERROR] [%s()]: Passed Koliseo->has_temp is not 0. {%i}\n",
2008 __func__, current->has_temp);
2009#ifdef KLS_DEBUG_CORE
2010 kls_log(current, "ERROR", "[%s()]: Passed Koliseo->has_temp != 0 . {%i}",
2011 __func__, current->has_temp);
2012#endif
2013 if (current->conf.kls_collect_stats == 1) {
2014 current->stats.tot_hiccups += 1;
2015 }
2016 return NULL;
2017 }
2018 ptrdiff_t prev = current->prev_offset;
2019 ptrdiff_t off = current->offset;
2020
2021 Koliseo_Temp *tmp = KLS_PUSH(current, Koliseo_Temp);
2022 tmp->kls = current;
2023 tmp->prev_offset = prev;
2024 tmp->offset = off;
2025#ifdef KLS_DEBUG_CORE
2026 kls_log(current, "INFO", "Passed kls conf: " KLS_Conf_Fmt "\n",
2027 KLS_Conf_Arg(current->conf));
2028#endif
2029
2030 current->has_temp = 1;
2031 current->t_kls = tmp;
2032 for (size_t i=0; i < kls->hooks_len; i++) {
2033 if (current->hooks[i].on_temp_start_handler != NULL) {
2034 // Call on_temp_start extension
2035 current->hooks[i].on_temp_start_handler(tmp);
2036 }
2037 }
2038#ifdef KLS_DEBUG_CORE
2039 kls_log(current, "KLS", "Prepared new Temp KLS.");
2040#endif
2041 return tmp;
2042}
2043
2049{
2050 if (tmp_kls == NULL) {
2051 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
2052 __func__);
2053 exit(EXIT_FAILURE);
2054 }
2055
2056 Koliseo *kls_ref = tmp_kls->kls;
2057 if (kls_ref == NULL) {
2058 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
2059 __func__);
2060 exit(EXIT_FAILURE);
2061 }
2062
2063 for (size_t i=0; i < kls_ref->hooks_len; i++) {
2064 if (kls_ref->hooks[i].on_temp_free_handler != NULL) {
2065 // Call on_temp_free() extension
2066 kls_ref->hooks[i].on_temp_free_handler(tmp_kls);
2067 }
2068 }
2069
2070#ifdef KLS_DEBUG_CORE
2071 kls_log(kls_ref, "KLS", "Ended Temp KLS.");
2072#endif
2073 tmp_kls->kls->has_temp = 0;
2074 tmp_kls->kls->t_kls = NULL;
2075 tmp_kls->kls->prev_offset = tmp_kls->prev_offset;
2076 tmp_kls->kls->offset = tmp_kls->offset;
2077
2078 // Free any Koliseo chained after the current one
2079 Koliseo* to_free = tmp_kls->kls->next;
2080 if (to_free != NULL) {
2081 kls_free(to_free);
2082 tmp_kls->kls->next = NULL;
2083 }
2084
2085 tmp_kls = NULL; // statement with no effect TODO: Clear tmp_kls from caller
2086 if (kls_ref->conf.kls_collect_stats == 1) {
2087 kls_ref->stats.tot_temp_pushes = 0;
2088 kls_ref->stats.tot_temp_pops = 0;
2089 }
2090}
2091
2092#ifdef KOLISEO_HAS_EXPER
2101void *kls_pop(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
2102{
2103 if (kls == NULL) {
2104 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
2105 exit(EXIT_FAILURE);
2106 }
2107 ptrdiff_t padding = -kls->offset & (align - 1);
2108 if (count > PTRDIFF_MAX / size
2109 || (kls->size + kls->offset) < (size * count)) {
2110 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2111 kls_free(kls);
2112 exit(EXIT_FAILURE);
2113 }
2114 char *p = kls->data + kls->offset - padding - size * count;
2115 kls->prev_offset = kls->offset;
2116 kls->offset -= padding + size * count;
2117#ifdef KLS_DEBUG_CORE
2118 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
2119 int_koliseo_version(), size);
2120 if (kls->conf.kls_verbose_lvl > 0) {
2121 print_kls_2file(kls->conf.kls_log_fp, kls);
2122 }
2123#endif
2124 if (kls->conf.kls_collect_stats == 1) {
2125 kls->stats.tot_pops += 1;
2126 }
2127 return p;
2128}
2129
2138void *kls_pop_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
2139{
2140 if (kls == NULL) {
2141 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
2142 exit(EXIT_FAILURE);
2143 }
2144 ptrdiff_t padding = -kls->offset & (align - 1);
2145 if (count > PTRDIFF_MAX / size
2146 || (kls->size + kls->offset) < (size * count)) {
2147 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2148 kls_free(kls);
2149 exit(EXIT_FAILURE);
2150 }
2151 char *p = kls->data + kls->offset - padding - size * count;
2152 kls->prev_offset = kls->offset;
2153 kls->offset -= padding + size * count;
2154#ifdef KLS_DEBUG_CORE
2155 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
2156 int_koliseo_version(), size);
2157 if (kls->conf.kls_verbose_lvl > 0) {
2158 print_kls_2file(kls->conf.kls_log_fp, kls);
2159 }
2160#endif
2161 if (kls->conf.kls_collect_stats == 1) {
2162 kls->stats.tot_pops += 1;
2163 }
2164 return p;
2165}
2166
2175void *kls_temp_pop(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align,
2176 ptrdiff_t count)
2177{
2178 if (t_kls == NULL) {
2179 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
2180 __func__);
2181 exit(EXIT_FAILURE);
2182 }
2183 Koliseo *kls = t_kls->kls;
2184 if (kls == NULL) {
2185 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
2186 __func__);
2187 exit(EXIT_FAILURE);
2188 }
2189 ptrdiff_t padding = -kls->offset & (align - 1);
2190 if (count > PTRDIFF_MAX / size
2191 || (kls->size + kls->offset) < (size * count)) {
2192 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2193 kls_free(kls);
2194 exit(EXIT_FAILURE);
2195 }
2196 char *p = kls->data + kls->offset - padding - size * count;
2197 kls->prev_offset = kls->offset;
2198 kls->offset -= padding + size * count;
2199#ifdef KLS_DEBUG_CORE
2200 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
2201 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
2202 int_koliseo_version(), size);
2203 if (kls->conf.kls_verbose_lvl > 0) {
2204 print_kls_2file(kls->conf.kls_log_fp, kls);
2205 }
2206#endif
2207 if (kls->conf.kls_collect_stats == 1) {
2208 kls->stats.tot_temp_pops += 1;
2209 }
2210 return p;
2211}
2212
2221void *kls_temp_pop_AR(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
2222{
2223 if (t_kls == NULL) {
2224 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
2225 __func__);
2226 exit(EXIT_FAILURE);
2227 }
2228 Koliseo *kls = t_kls->kls;
2229 if (kls == NULL) {
2230 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
2231 __func__);
2232 exit(EXIT_FAILURE);
2233 }
2234 ptrdiff_t padding = -kls->offset & (align - 1);
2235 if (count > PTRDIFF_MAX / size
2236 || (kls->size + kls->offset) < (size * count)) {
2237 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
2238 kls_free(kls);
2239 exit(EXIT_FAILURE);
2240 }
2241 char *p = kls->data + kls->offset - padding - size * count;
2242 kls->prev_offset = kls->offset;
2243 kls->offset -= padding + size * count;
2244#ifdef KLS_DEBUG_CORE
2245 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
2246 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
2247 int_koliseo_version(), size);
2248 if (kls->conf.kls_verbose_lvl > 0) {
2249 print_kls_2file(kls->conf.kls_log_fp, kls);
2250 }
2251#endif
2252 if (kls->conf.kls_collect_stats == 1) {
2253 kls->stats.tot_temp_pops += 1;
2254 }
2255 return p;
2256}
2257
2264char* kls_strdup(Koliseo* kls, char* source)
2265{
2266 char* dest = KLS_PUSH_STR(kls, source);
2267 KLS__STRCPY(dest, source);
2268 return dest;
2269}
2270
2277char** kls_strdup_arr(Koliseo* kls, size_t count, char** source)
2278{
2279 char** strings = NULL;
2280 strings = KLS_PUSH_ARR(kls, char*, count);
2281 for (int i=0; i < count; i++) {
2282 strings[i] = KLS_STRDUP(kls, source[i]);
2283 }
2284 return strings;
2285}
2286
2293char* kls_t_strdup(Koliseo_Temp* t_kls, char* source)
2294{
2295 char* dest = KLS_PUSH_STR_T(t_kls, source);
2296 KLS__STRCPY(dest, source);
2297 return dest;
2298}
2299
2306char** kls_t_strdup_arr(Koliseo_Temp* t_kls, size_t count, char** source)
2307{
2308 char** strings = NULL;
2309 strings = KLS_PUSH_ARR_T(t_kls, char*, count);
2310 for (int i=0; i < count; i++) {
2311 strings[i] = KLS_STRDUP_T(t_kls, source[i]);
2312 }
2313 return strings;
2314}
2315#endif // KOLISEO_HAS_EXPER
#define KLS_DEFAULT_HOOKS
Definition kls_region.h:162
#define KLS_DEFAULT_EXTENSIONS_LEN
Definition kls_region.h:173
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:647
Koliseo * kls_new(ptrdiff_t size)
Takes a ptrdiff_t size.
Definition koliseo.c:455
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:2264
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:2175
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:1992
void print_dbg_temp_kls(const Koliseo_Temp *t_kls)
Prints header fields from the passed Koliseo_Temp pointer, to stderr.
Definition koliseo.c:1871
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:1678
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:748
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:1832
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:2293
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:594
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:290
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:558
void kls_temp_end(Koliseo_Temp *tmp_kls)
Ends passed Koliseo_Temp pointer.
Definition koliseo.c:2048
void kls_dbg_features(void)
Prints enabled Koliseo features to stderr.
Definition koliseo.c:226
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:2277
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:1458
void print_dbg_kls(const Koliseo *kls)
Prints header fields from the passed Koliseo pointer, to stderr.
Definition koliseo.c:1818
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:1558
ptrdiff_t kls_get_pos(const Koliseo *kls)
Returns the current offset (position of pointer bumper) for the passed Koliseo.
Definition koliseo.c:279
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:2221
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:2138
void kls_free(Koliseo *kls)
Calls kls_clear() on the passed Koliseo pointer and the frees the actual Koliseo.
Definition koliseo.c:1925
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:169
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:611
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:2306
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:1165
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:716
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:1248
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:431
Koliseo * kls_new_dbg(ptrdiff_t size)
Takes a ptrdiff_t size and returns a pointer to the prepared Koliseo.
Definition koliseo.c:763
int 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:906
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:630
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:476
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:664
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:2101
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:103
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:217
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:145
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:731
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:336
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:1787
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:682
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:778
void kls_clear(Koliseo *kls)
Resets the offset field for the passed Koliseo pointer.
Definition koliseo.c:1905
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:1340
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:1883
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:83
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:505
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:538
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:522
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:594
#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:509
#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:405
#define KLS_DEFAULT_ALLOCF
Defines the default allocation function.
Definition koliseo.h:401
#define KLS_PUSH(kls, type)
Macro used to request memory from a Koliseo.
Definition koliseo.h:534
#define KLS__STRCPY(dest, source)
Macro to copy a C string from a source buffer to a destination buffer.
Definition koliseo.h:698
#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:707
#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__check_available(kls, size, align, count)
Macro to return NULL on errors from kls__check_available_failable.
Definition koliseo.h:440
#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:588
#define KLS_STRDUP_T(t_kls, source)
Definition koliseo.h:717
#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:493
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 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:377
ptrdiff_t offset
Current position of memory pointer.
Definition koliseo.h:379
ptrdiff_t prev_offset
Previous position of memory pointer.
Definition koliseo.h:380
Koliseo * kls
Reference to the actual Koliseo we're saving.
Definition koliseo.h:378
Represents the initialised arena allocator struct.
Definition koliseo.h:338
ptrdiff_t size
Size of data field.
Definition koliseo.h:340
ptrdiff_t offset
Current position of memory pointer.
Definition koliseo.h:341
ptrdiff_t prev_offset
Previous position of memory pointer.
Definition koliseo.h:342
KLS_Conf conf
Contains flags to change the Koliseo behaviour.
Definition koliseo.h:344
void * extension_data[KLS_MAX_EXTENSIONS]
Points to data for extensions.
Definition koliseo.h:348
struct Koliseo_Temp * t_kls
Points to related active Kolieo_Temp, when has_temp == 1.
Definition koliseo.h:346
char * data
Points to data field.
Definition koliseo.h:339
size_t hooks_len
Length for hooks and extension_data.
Definition koliseo.h:349
struct Koliseo * next
Points to the next Koliseo when conf.kls_growable == 1.
Definition koliseo.h:351
int has_temp
When == 1, a Koliseo_Temp is currently active on this Koliseo.
Definition koliseo.h:343
KLS_Stats stats
Contains stats for Koliseo performance analysis.
Definition koliseo.h:345
KLS_Hooks hooks[KLS_MAX_EXTENSIONS]
Contains handlers for extensions.
Definition koliseo.h:347
kls_free_func * free_func
Points to the free function for the arena's backing memory.
Definition koliseo.h:350