koliseo 0.5.2
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
20KLS_Conf KLS_DEFAULT_CONF = {
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
41KLS_Stats KLS_STATS_DEFAULT = {
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
184 res.err_handlers.OOM_handler = &KLS_OOM_default_handler__;
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) {
191 res.err_handlers.PTRDIFF_MAX_handler = err_handlers.PTRDIFF_MAX_handler;
192 } else {
193#ifndef KOLISEO_HAS_LOCATE
194 res.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler__;
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) {
201 res.err_handlers.ZEROCOUNT_handler = err_handlers.ZEROCOUNT_handler;
202 } else {
203#ifndef KOLISEO_HAS_LOCATE
204 res.err_handlers.ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler__;
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{
219 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
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)
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, 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);
368 kls->stats = KLS_STATS_DEFAULT;
369 kls->conf.kls_log_fp = stderr;
370 kls->hooks = ext_handlers;
371 kls->extension_data = user;
372 kls->free_func = free_func;
373 kls->next = NULL;
374#ifdef KLS_DEBUG_CORE
375 kls_log(kls, "KLS", "API Level { %i } -> Allocated (%s) for new KLS.",
376 int_koliseo_version(), h_size);
377 kls_log(kls, "KLS", "KLS offset: { %p }.", kls);
378 kls_log(kls, "KLS", "Allocation begin offset: { %p }.",
379 kls + kls->offset);
380#endif
381
382 if (kls->hooks.on_new_handler != NULL) {
383 // Call on_new extension
384 kls->hooks.on_new_handler(kls);
385 }
386 } else {
387#ifndef KOLISEO_HAS_LOCATE
388 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
389#else
390 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), __func__);
391#endif // KOLISEO_HAS_LOCATE
392 exit(EXIT_FAILURE);
393 }
394#ifdef KLS_DEBUG_CORE
395 Koliseo *kls_ref = p;
396 if (kls_ref->conf.kls_verbose_lvl > 0) {
397 print_kls_2file(kls_ref->conf.kls_log_fp, p);
398 }
399#endif
400 return p;
401}
402
418#ifndef KOLISEO_HAS_LOCATE
419Koliseo *kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
420#else
421Koliseo *kls_new_alloc_dbg(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, Koliseo_Loc loc)
422#endif // KOLISEO_HAS_LOCATE
423{
424#ifndef KOLISEO_HAS_LOCATE
425 return kls_new_alloc_ext(size, alloc_func, free_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA);
426#else
427 return kls_new_alloc_ext_dbg(size, alloc_func, free_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA, loc);
428#endif // KOLISEO_HAS_LOCATE
429}
430
447Koliseo *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)
448{
449 Koliseo *k = kls_new_alloc_ext(size, alloc_func, free_func, ext_handlers, user);
450 bool conf_res = kls_set_conf(k, conf);
451 if (!conf_res) {
452 fprintf(stderr,
453 "[ERROR] [%s()]: Failed to set config for new Koliseo.\n",
454 __func__);
455 exit(EXIT_FAILURE);
456 }
457 return k;
458}
459
476Koliseo *kls_new_conf_alloc(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, kls_free_func free_func)
477{
478 return kls_new_conf_alloc_ext(size, conf, alloc_func, free_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA);
479}
480
496Koliseo *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)
497{
498
499#ifndef KLS_DEBUG_CORE
500 fprintf(stderr,
501 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No tracing allowed.\n",
502 __func__);
503#endif
504 KLS_Conf k = (KLS_Conf) {
505 .kls_collect_stats = 1,.kls_verbose_lvl =
506 1,.kls_log_filepath = output_path,
507#ifndef KOLISEO_HAS_LOCATE
508 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
509 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
510#else
511 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
512 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
513#endif // KOLISEO_HAS_LOCATE
514 };
515 return kls_new_conf_alloc_ext(size, k, alloc_func, free_func, ext_handlers, user);
516}
517
532Koliseo *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)
533{
534 return kls_new_traced_alloc_handled_ext(size, output_path, alloc_func, free_func, err_handlers, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA);
535}
536
549Koliseo *kls_new_traced_ext(ptrdiff_t size, const char *output_path, KLS_Hooks ext_handlers, void* user)
550{
551 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
552 return kls_new_traced_alloc_handled_ext(size, output_path, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers, ext_handlers, user);
553}
554
568Koliseo *kls_new_traced_alloc(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, kls_free_func free_func)
569{
570 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
571 return kls_new_traced_alloc_handled(size, output_path, alloc_func, free_func, err_handlers);
572}
573
587Koliseo *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)
588{
589#ifndef KLS_DEBUG_CORE
590 fprintf(stderr,
591 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No debugging support.\n",
592 __func__);
593#endif
594 KLS_Conf k = (KLS_Conf) {
595 .kls_collect_stats = 1,.kls_verbose_lvl = 0,
596#ifndef KOLISEO_HAS_LOCATE
597 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
598 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
599#else
600 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
601 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
602#endif // KOLIEO_HAS_LOCATE
603 };
604 Koliseo * kls = kls_new_conf_alloc_ext(size, k, alloc_func, free_func, ext_handlers, user);
605 kls->conf.kls_verbose_lvl = 1;
606 return kls;
607}
608
621Koliseo *kls_new_dbg_alloc_handled(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Err_Handlers err_handlers)
622{
623 return kls_new_dbg_alloc_handled_ext(size, alloc_func, free_func, err_handlers, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA);
624}
625
636Koliseo *kls_new_dbg_ext(ptrdiff_t size, KLS_Hooks ext_handlers, void* user)
637{
638 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
639 return kls_new_dbg_alloc_handled_ext(size, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, err_handlers, ext_handlers, user);
640}
641
653Koliseo *kls_new_dbg_alloc(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func)
654{
655 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
656 return kls_new_dbg_alloc_handled(size, alloc_func, free_func, err_handlers);
657}
658
665bool kls_set_conf(Koliseo *kls, KLS_Conf conf)
666{
667 if (kls == NULL) {
668 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
669 //TODO: is it better to exit() here?
670 return false;
671 }
672
673 kls->conf = conf;
674 if (kls->conf.kls_log_fp == NULL) {
675 kls->conf.kls_log_fp = stderr;
676#ifdef KLS_DEBUG_CORE
677#ifdef KLS_SETCONF_DEBUG
678 kls_log(kls, "KLS",
679 "[%s()]: Preliminary set of conf.kls_log_fp to stderr.",
680 __func__);
681#endif
682#endif // KLS_DEBUG_CORE
683 }
684
685 if (conf.err_handlers.OOM_handler == NULL) {
686 fprintf(stderr,
687 "[ERROR] at %s(): passed OOM_handler is NULL. Using default.\n",
688 __func__);
689#ifdef KLS_DEBUG_CORE
690#ifdef KLS_SETCONF_DEBUG
691 kls_log(kls, "KLS",
692 "[%s()]: Passed OOM_handler was NULL, using default.",
693 __func__);
694#endif
695#endif // KLS_DEBUG_CORE
696#ifndef KOLISEO_HAS_LOCATE
697 kls->conf.err_handlers.OOM_handler = &KLS_OOM_default_handler__;
698#else
699 kls->conf.err_handlers.OOM_handler = &KLS_OOM_default_handler_dbg__;
700#endif
701 }
702
703 if (conf.err_handlers.PTRDIFF_MAX_handler == NULL) {
704 fprintf(stderr,
705 "[ERROR] at %s(): passed PTRDIFF_MAX_handler is NULL. Using default.\n",
706 __func__);
707#ifdef KLS_DEBUG_CORE
708#ifdef KLS_SETCONF_DEBUG
709 kls_log(kls, "KLS",
710 "[%s()]: Passed PTRDIFF_MAX_handler was NULL, using default.",
711 __func__);
712#endif
713#endif // KLS_DEBUG_CORE
714#ifndef KOLISEO_HAS_LOCATE
715 kls->conf.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler__;
716#else
717 kls->conf.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__;
718#endif
719 }
720
721#ifndef KLS_DEBUG_CORE
722 if (kls->conf.kls_collect_stats == 1) {
723 fprintf(stderr,
724 "[WARN] [%s()]: KLS_DEBUG_CORE is not defined. Stats may not be collected in full.\n",
725 __func__);
726 }
727#endif
728
729 if (kls->conf.kls_verbose_lvl > 0) {
730 if (kls->conf.kls_log_fp != NULL) {
731#ifdef KLS_DEBUG_CORE
732#ifdef KLS_SETCONF_DEBUG
733 kls_log(kls, "WARN",
734 "[%s()]: kls->conf.kls_log_fp was not NULL. Overriding it.",
735 __func__);
736#endif
737#endif
738 if (kls->conf.kls_collect_stats == 1) {
739 kls->stats.tot_hiccups += 1;
740 }
741 }
742
743 FILE *log_fp = NULL;
744 log_fp = fopen(kls->conf.kls_log_filepath, "w");
745 if (!log_fp) {
746 fprintf(stderr,
747 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [write].\n",
748 __func__, kls->conf.kls_log_filepath);
749 return false;
750 } else {
751 fprintf(log_fp, "%s", ""); //Reset log_fp
752 fclose(log_fp);
753 }
754 log_fp = fopen(kls->conf.kls_log_filepath, "a");
755 if (!log_fp) {
756 fprintf(stderr,
757 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [append].\n",
758 __func__, kls->conf.kls_log_filepath);
759 return false;
760 } else {
761 kls->conf.kls_log_fp = log_fp;
762 }
763 }
764 return true;
765}
766
767static bool kls__try_grow(Koliseo* kls, ptrdiff_t needed);
768
781#ifndef KOLISEO_HAS_LOCATE
782int kls__check_available_failable(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name)
783#else
784int kls__check_available_failable_dbg(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name, Koliseo_Loc loc)
785#endif // KOLISEO_HAS_LOCATE
786{
787 assert(kls != NULL);
788 assert(caller_name != NULL);
789 if (count < 0) {
790#ifndef KOLISEO_HAS_LOCATE
791 fprintf(stderr,
792 "[KLS] %s(): count [%td] was < 0.\n",
793 caller_name,
794 count);
795#else
796 fprintf(stderr,
797 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was < 0.\n",
798 KLS_Loc_Arg(loc),
799 caller_name,
800 count);
801#endif // KOLISEO_HAS_LOCATE
802 return -1;
803 }
804 if (size < 1) {
805#ifndef KOLISEO_HAS_LOCATE
806 fprintf(stderr,
807 "[KLS] %s(): size [%td] was < 1.\n",
808 caller_name,
809 size);
810#else
811 fprintf(stderr,
812 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
813 KLS_Loc_Arg(loc),
814 caller_name,
815 size);
816#endif // KOLISEO_HAS_LOCATE
817 return -1;
818 }
819 if (align < 1) {
820#ifndef KOLISEO_HAS_LOCATE
821 fprintf(stderr,
822 "[KLS] %s(): align [%td] was < 1.\n",
823 caller_name,
824 align);
825#else
826 fprintf(stderr,
827 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
828 KLS_Loc_Arg(loc),
829 caller_name,
830 align);
831#endif // KOLISEO_HAS_LOCATE
832 return -1;
833 }
834 if (! ((align & (align - 1)) == 0)) {
835#ifndef KOLISEO_HAS_LOCATE
836 fprintf(stderr,
837 "[KLS] %s(): align [%td] was not a power of 2.\n",
838 caller_name,
839 align);
840#else
841 fprintf(stderr,
842 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
843 KLS_Loc_Arg(loc),
844 caller_name,
845 align);
846#endif // KOLISEO_HAS_LOCATE
847 return -1;
848 }
849 Koliseo* current = kls;
850 while (current->next != NULL) {
851 current = current->next;
852 }
853 const ptrdiff_t available = current->size - current->offset;
854 const ptrdiff_t padding = -current->offset & (align - 1);
855 bool ZEROCOUNT_happened = false;
856 bool ZEROCOUNT_handled = false;
857 if (count == 0) {
858 if (current->conf.kls_allow_zerocount_push != 1) {
859 ZEROCOUNT_happened = true;
860 if (current->conf.err_handlers.ZEROCOUNT_handler != NULL) {
861#ifndef KOLISEO_HAS_LOCATE
862 current->conf.err_handlers.ZEROCOUNT_handler(current, available, padding, size);
863#else
864 current->conf.err_handlers.ZEROCOUNT_handler(current, available, padding, size, loc);
865#endif // KOLISEO_HAS_LOCATE
866 ZEROCOUNT_handled = true;
867 } else {
868#ifndef KOLISEO_HAS_LOCATE
869 fprintf(stderr,
870 "[KLS] %s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
871 caller_name,
872 size, padding, available);
873#else
874 fprintf(stderr,
875 "[KLS] " KLS_Loc_Fmt "%s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
876 KLS_Loc_Arg(loc),
877 caller_name,
878 size, padding, available);
879#endif // KOLISEO_HAS_LOCATE
880 kls_free(kls);
881 exit(EXIT_FAILURE);
882 }
883 } else {
884#ifdef KLS_DEBUG_CORE
885 kls_log(current, "DEBUG", "Accepting zero-count push: conf.kls_allow_zerocount_push was 1");
886#endif // KLS_DEBUG_CORE
887 }
888 }
889
890 if (ZEROCOUNT_happened && ZEROCOUNT_handled) {
891#ifdef KLS_DEBUG_CORE
892 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.");
893#endif // KLS_DEBUG_CORE
894#ifndef KOLISEO_HAS_LOCATE
895 fprintf(stderr,
896 "[KLS] %s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
897 caller_name,
898 size, padding, available);
899#else
900 fprintf(stderr,
901 "[KLS] " KLS_Loc_Fmt "%s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
902 KLS_Loc_Arg(loc),
903 caller_name,
904 size, padding, available);
905#endif // KOLISEO_HAS_LOCATE
906 kls_free(kls);
907 exit(EXIT_FAILURE);
908 }
909
910 bool OOM_happened = false;
911 bool OOM_handled = false;
912 bool PTRDIFF_MAX_happened = false;
913 bool PTRDIFF_MAX_handled = false;
914 if (count > PTRDIFF_MAX / size || available - padding < size * count) {
915 if (count > PTRDIFF_MAX / size) {
916 PTRDIFF_MAX_happened = true;
917 if (current->conf.err_handlers.PTRDIFF_MAX_handler != NULL) {
918#ifndef KOLISEO_HAS_LOCATE
919 current->conf.err_handlers.PTRDIFF_MAX_handler(current, size, count);
920#else
921 current->conf.err_handlers.PTRDIFF_MAX_handler(current, size, count, loc);
922#endif // KOLISEO_HAS_LOCATE
923 PTRDIFF_MAX_handled = true;
924 } else { // Let's keep this here for now? It's the original part before adding KLS_PTRDIFF_MAX_default_handler__()
925#ifndef _WIN32
926#ifndef KOLISEO_HAS_LOCATE
927 fprintf(stderr,
928 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
929 caller_name,
930 count, PTRDIFF_MAX / size);
931#else
932 fprintf(stderr,
933 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
934 KLS_Loc_Arg(loc),
935 caller_name,
936 count, PTRDIFF_MAX / size);
937#endif // KOLISEO_HAS_LOCATE
938#else
939#ifndef KOLISEO_HAS_LOCATE
940 fprintf(stderr,
941 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
942 caller_name,
943 count, PTRDIFF_MAX / size);
944#else
945 fprintf(stderr,
946 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
947 KLS_Loc_Arg(loc),
948 caller_name,
949 count, PTRDIFF_MAX / size);
950#endif // KOLISEO_HAS_LOCATE
951#endif // _WIN32
952 }
953 } else {
954 if (current->conf.kls_growable == 1 && kls__try_grow(current, size + count + padding)) {
955 return 0;
956 }
957 OOM_happened = true;
958 if (current->conf.err_handlers.OOM_handler != NULL) {
959#ifndef KOLISEO_HAS_LOCATE
960 current->conf.err_handlers.OOM_handler(current, available, padding, size, count);
961#else
962 current->conf.err_handlers.OOM_handler(current, available, padding, size, count, loc);
963#endif // KOLISEO_HAS_LOCATE
964 OOM_handled = true;
965 } else { // Let's keep this here for now? It's the original part before adding KLS_OOM_default_handler__()
966#ifndef KOLISEO_HAS_LOCATE
967 fprintf(stderr,
968 "[KLS] %s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
969 caller_name,
970 size * count, available - padding);
971#else
972 fprintf(stderr,
973 "[KLS] " KLS_Loc_Fmt "%s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
974 KLS_Loc_Arg(loc),
975 caller_name,
976 size * count, available - padding);
977#endif // KOLISEO_HAS_LOCATE
978 }
979 }
980 if (PTRDIFF_MAX_happened) {
981 if (current->conf.err_handlers.PTRDIFF_MAX_handler && PTRDIFF_MAX_handled) {
982#ifndef KOLISEO_HAS_LOCATE
983 fprintf(stderr, "[KLS] %s(): PTRDIFF_MAX fault happened and was handled.\n", caller_name);
984#ifdef KLS_DEBUG_CORE
985 kls_log(current, "DEBUG", "%s(): PTRDIFF_MAX fault happened and was handled.", caller_name);
986#endif // KLS_DEBUG_CORE
987#else
988 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "%s(): PTRDIFF_MAX fault happened and was handled.\n", KLS_Loc_Arg(loc), caller_name);
989#ifdef KLS_DEBUG_CORE
990 kls_log(current, "DEBUG", KLS_Loc_Fmt "%s(): PTRDIFF_MAX fault happened and was handled.", KLS_Loc_Arg(loc), caller_name);
991#endif // KLS_DEBUG_CORE
992#endif // KOLISEO_HAS_LOCATE
993 return -1;
994 }
995 } else if (OOM_happened) {
996 if (current->conf.err_handlers.PTRDIFF_MAX_handler && OOM_handled) {
997#ifndef KOLISEO_HAS_LOCATE
998 fprintf(stderr, "[KLS] %s(): OOM fault happened and was handled.\n", caller_name);
999#ifdef KLS_DEBUG_CORE
1000 kls_log(current, "DEBUG", "%s(): OOM fault happened and was handled.", caller_name);
1001#endif // KLS_DEBUG_CORE
1002#else
1003 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "%s(): OOM fault happened and was handled.\n", KLS_Loc_Arg(loc), caller_name);
1004#ifdef KLS_DEBUG_CORE
1005 kls_log(current, "DEBUG", KLS_Loc_Fmt "%s(): OOM fault happened and was handled.", KLS_Loc_Arg(loc), caller_name);
1006#endif // KLS_DEBUG_CORE
1007#endif // KOLISEO_HAS_LOCATE
1008 return -1;
1009 }
1010 }
1011#ifndef KOLISEO_HAS_LOCATE
1012 fprintf(stderr, "[KLS] Failed %s() call.\n", caller_name);
1013#else
1014 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), caller_name);
1015#endif // KOLISEO_HAS_LOCATE
1016 kls_free(kls);
1017 exit(EXIT_FAILURE);
1018 }
1019 return 0;
1020}
1021
1022bool kls__try_grow(Koliseo* kls, ptrdiff_t needed)
1023{
1024 ptrdiff_t new_size = KLS_MAX(kls->size * 2, needed);
1025 Koliseo* new_kls = kls_new_conf_alloc_ext(new_size, kls->conf, KLS_DEFAULT_ALLOCF, KLS_DEFAULT_FREEF, kls->hooks, kls->extension_data);
1026 kls_log(kls, "DEBUG", "%s(): growing Koliseo, new size: {%td}", __func__, new_size);
1027 if (!new_kls) return false;
1028 kls->next = new_kls;
1029 return true;
1030}
1031
1041void *kls_push(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1042{
1043
1044#ifdef KLS_DEBUG_CORE
1045#ifndef _WIN32
1046 struct timespec start_time, end_time;
1047 clock_gettime(CLOCK_MONOTONIC, &start_time);
1048#else
1049 LARGE_INTEGER start_time, end_time, frequency;
1050 QueryPerformanceFrequency(&frequency);
1051 QueryPerformanceCounter(&start_time);
1052#endif
1053#endif
1054
1055 if (kls == NULL) {
1056 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1057 exit(EXIT_FAILURE);
1058 }
1059 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1060 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1061#ifdef KLS_DEBUG_CORE
1062 kls_log(kls, "ERROR", "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", __func__);
1063 exit(EXIT_FAILURE);
1064#endif // KLS_DEBUG_CORE
1065 return NULL;
1066 }
1067#ifndef KOLISEO_HAS_LOCATE
1068 kls__check_available(kls, size, align, count);
1069#else
1070 kls__check_available_dbg(kls, size, align, count, KLS_HERE);
1071#endif // KOLISEO_HAS_LOCATE
1072 Koliseo* current = kls;
1073 while (current->next != NULL) {
1074 current = current->next;
1075 }
1076 ptrdiff_t padding = -current->offset & (align - 1);
1077 char *p = current->data + current->offset + padding;
1078 current->prev_offset = current->offset;
1079 current->offset += padding + size * count;
1080 char h_size[200];
1081 kls_formatSize(size * count, h_size, sizeof(h_size));
1082 //sprintf(msg,"Pushed size (%li) for KLS.",size);
1083 //kls_log("KLS",msg);
1084#ifdef KLS_DEBUG_CORE
1085 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1086 kls_log(current, "KLS", "API Level { %i } -> Pushed size (%s) for KLS.",
1087 int_koliseo_version(), h_size);
1088 if (current->conf.kls_verbose_lvl > 0) {
1089 print_kls_2file(current->conf.kls_log_fp, current);
1090 }
1091 if (current->conf.kls_collect_stats == 1) {
1092#ifndef _WIN32
1093 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1094 double elapsed_time =
1095 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1096 start_time.tv_nsec) / 1e9;
1097#else
1098 QueryPerformanceCounter(&end_time); // %.7f
1099 double elapsed_time =
1100 (double)(end_time.QuadPart -
1101 start_time.QuadPart) / frequency.QuadPart;
1102#endif
1103 if (elapsed_time > current->stats.worst_pushcall_time) {
1104 current->stats.worst_pushcall_time = elapsed_time;
1105 }
1106 }
1107#endif
1108 if (current->conf.kls_collect_stats == 1) {
1109 current->stats.tot_pushes += 1;
1110 }
1111 return p;
1112}
1113
1123#ifndef KOLISEO_HAS_LOCATE
1124void *kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1125 ptrdiff_t count)
1126#else
1127void *kls_push_zero_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1128 ptrdiff_t count, Koliseo_Loc loc)
1129#endif // KOLISEO_HAS_LOCATE
1130{
1131
1132#ifdef KLS_DEBUG_CORE
1133#ifndef _WIN32
1134 struct timespec start_time, end_time;
1135 clock_gettime(CLOCK_MONOTONIC, &start_time);
1136#else
1137 LARGE_INTEGER start_time, end_time, frequency;
1138 QueryPerformanceFrequency(&frequency);
1139 QueryPerformanceCounter(&start_time);
1140#endif
1141#endif
1142
1143 if (kls == NULL) {
1144 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1145 exit(EXIT_FAILURE);
1146 }
1147 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1148#ifndef KOLISEO_HAS_LOCATE
1149 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1150#else
1151 fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__);
1152 kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__);
1153 exit(EXIT_FAILURE);
1154#endif // KOLISEO_HAS_LOCATE
1155 return NULL;
1156 }
1157#ifndef KOLISEO_HAS_LOCATE
1158 kls__check_available(kls, size, align, count);
1159#else
1160 kls__check_available_dbg(kls, size, align, count, loc);
1161#endif
1162 Koliseo* current = kls;
1163 while (current->next != NULL) {
1164 current = current->next;
1165 }
1166 ptrdiff_t padding = -current->offset & (align - 1);
1167 char *p = current->data + current->offset + padding;
1168 //Zero new area
1169 memset(p, 0, size * count);
1170 current->prev_offset = current->offset;
1171 current->offset += padding + size * count;
1172 char h_size[200];
1173 kls_formatSize(size * count, h_size, sizeof(h_size));
1174 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1175 //kls_log("KLS",msg);
1176#ifdef KLS_DEBUG_CORE
1177 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1178 kls_log(current, "KLS", "API Level { %i } -> Pushed zeroes, size (%s) for KLS.",
1179 int_koliseo_version(), h_size);
1180 if (current->conf.kls_verbose_lvl > 0) {
1181 print_kls_2file(current->conf.kls_log_fp, current);
1182 }
1183 if (current->conf.kls_collect_stats == 1) {
1184#ifndef _WIN32
1185 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1186 double elapsed_time =
1187 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1188 start_time.tv_nsec) / 1e9;
1189#else
1190 QueryPerformanceCounter(&end_time); // %.7f
1191 double elapsed_time =
1192 (double)(end_time.QuadPart -
1193 start_time.QuadPart) / frequency.QuadPart;
1194#endif
1195 if (elapsed_time > current->stats.worst_pushcall_time) {
1196 current->stats.worst_pushcall_time = elapsed_time;
1197 }
1198 }
1199#endif
1200 if (current->conf.kls_collect_stats == 1) {
1201 current->stats.tot_pushes += 1;
1202 }
1203 return p;
1204}
1205
1215#ifndef KOLISEO_HAS_LOCATE
1216void *kls_push_zero_ext(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1217 ptrdiff_t count)
1218#else
1219void *kls_push_zero_ext_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1220 ptrdiff_t count, Koliseo_Loc loc)
1221#endif // KOLISEO_HAS_LOCATE
1222{
1223
1224#ifdef KLS_DEBUG_CORE
1225#ifndef _WIN32
1226 struct timespec start_time, end_time;
1227 clock_gettime(CLOCK_MONOTONIC, &start_time);
1228#else
1229 LARGE_INTEGER start_time, end_time, frequency;
1230 QueryPerformanceFrequency(&frequency);
1231 QueryPerformanceCounter(&start_time);
1232#endif
1233#endif
1234
1235 if (kls == NULL) {
1236 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1237 exit(EXIT_FAILURE);
1238 }
1239 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1240#ifndef KOLISEO_HAS_LOCATE
1241 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1242#else
1243 fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__);
1244 kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__);
1245 exit(EXIT_FAILURE);
1246#endif // KOLISEO_HAS_LOCATE
1247 return NULL;
1248 }
1249
1250#ifndef KOLISEO_HAS_LOCATE
1251 kls__check_available(kls, size, align, count);
1252#else
1253 kls__check_available_dbg(kls, size, align, count, loc);
1254#endif
1255 Koliseo* current = kls;
1256 while (current->next != NULL) {
1257 current = current->next;
1258 }
1259 ptrdiff_t padding = -current->offset & (align - 1);
1260 char *p = current->data + current->offset + padding;
1261 //Zero new area
1262 memset(p, 0, size * count);
1263 current->prev_offset = current->offset;
1264 current->offset += padding + size * count;
1265
1266 if (current->hooks.on_push_handler != NULL) {
1267 /*
1268 struct KLS_EXTENSION_AR_DEFAULT_ARGS {
1269 const char* region_name;
1270 size_t region_name_len;
1271 const char* region_desc;
1272 size_t region_desc_len;
1273 int region_type;
1274 };
1275 struct KLS_EXTENSION_AR_DEFAULT_ARGS ar_args = {
1276 .region_name = KOLISEO_DEFAULT_REGION_NAME,
1277 .region_name_len = strlen(KOLISEO_DEFAULT_REGION_NAME),
1278 .region_desc = KOLISEO_DEFAULT_REGION_DESC,
1279 .region_desc_len = strlen(KOLISEO_DEFAULT_REGION_DESC),
1280 .region_type = KLS_None
1281 };
1282 kls->hooks.on_push_handler(kls, padding, (void*)&ar_args);
1283 */
1284 current->hooks.on_push_handler(current, padding, __func__, NULL);
1285 }
1286
1287 char h_size[200];
1288 kls_formatSize(size * count, h_size, sizeof(h_size));
1289 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1290 //kls_log("KLS",msg);
1291#ifdef KLS_DEBUG_CORE
1292 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1293 kls_log(current, "KLS", "API Level { %i } -> Pushed zeroes, size (%s) for KLS.",
1294 int_koliseo_version(), h_size);
1295 if (current->conf.kls_verbose_lvl > 0) {
1296 print_kls_2file(current->conf.kls_log_fp, current);
1297 }
1298 if (current->conf.kls_collect_stats == 1) {
1299#ifndef _WIN32
1300 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1301 double elapsed_time =
1302 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1303 start_time.tv_nsec) / 1e9;
1304#else
1305 QueryPerformanceCounter(&end_time); // %.7f
1306 double elapsed_time =
1307 (double)(end_time.QuadPart -
1308 start_time.QuadPart) / frequency.QuadPart;
1309#endif
1310 if (elapsed_time > current->stats.worst_pushcall_time) {
1311 current->stats.worst_pushcall_time = elapsed_time;
1312 }
1313 }
1314#endif
1315 if (current->conf.kls_collect_stats == 1) {
1316 current->stats.tot_pushes += 1;
1317 }
1318 return p;
1319}
1320
1331#ifndef KOLISEO_HAS_LOCATE
1332void *kls_temp_push_zero_ext(Koliseo_Temp *t_kls, ptrdiff_t size,
1333 ptrdiff_t align, ptrdiff_t count)
1334#else
1335void *kls_temp_push_zero_ext_dbg(Koliseo_Temp *t_kls, ptrdiff_t size,
1336 ptrdiff_t align, ptrdiff_t count, Koliseo_Loc loc)
1337#endif // KOLISEO_HAS_LOCATE
1338{
1339
1340#ifdef KLS_DEBUG_CORE
1341#ifndef _WIN32
1342 struct timespec start_time, end_time;
1343 clock_gettime(CLOCK_MONOTONIC, &start_time);
1344#else
1345 LARGE_INTEGER start_time, end_time, frequency;
1346 QueryPerformanceFrequency(&frequency);
1347 QueryPerformanceCounter(&start_time);
1348#endif
1349#endif
1350
1351 if (t_kls == NULL) {
1352 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1353 __func__);
1354 exit(EXIT_FAILURE);
1355 }
1356 Koliseo *kls = t_kls->kls;
1357 if (kls == NULL) {
1358 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1359 __func__);
1360 exit(EXIT_FAILURE);
1361 }
1362#ifndef KOLISEO_HAS_LOCATE
1363 kls__check_available(kls, size, align, count);
1364#else
1365 kls__check_available_dbg(kls, size, align, count, loc);
1366#endif
1367 Koliseo* current = kls;
1368 while (current->next != NULL) {
1369 current = current->next;
1370 }
1371 ptrdiff_t padding = -current->offset & (align - 1);
1372 char *p = current->data + current->offset + padding;
1373 //Zero new area
1374 memset(p, 0, size * count);
1375 current->prev_offset = current->offset;
1376 current->offset += padding + size * count;
1377
1378 if (current->hooks.on_temp_push_handler != NULL) {
1379 // Call on_temp_push extension with empty user arg
1380 current->hooks.on_temp_push_handler(t_kls, padding, __func__, NULL);
1381 }
1382
1383 char h_size[200];
1384 kls_formatSize(size * count, h_size, sizeof(h_size));
1385 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1386 //kls_log("KLS",msg);
1387#ifdef KLS_DEBUG_CORE
1388 if (current->conf.kls_collect_stats == 1) {
1389#ifndef _WIN32
1390 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1391 double elapsed_time =
1392 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1393 start_time.tv_nsec) / 1e9;
1394#else
1395 QueryPerformanceCounter(&end_time); // %.7f
1396 double elapsed_time =
1397 (double)(end_time.QuadPart -
1398 start_time.QuadPart) / frequency.QuadPart;
1399#endif
1400 if (elapsed_time > current->stats.worst_pushcall_time) {
1401 current->stats.worst_pushcall_time = elapsed_time;
1402 }
1403 }
1404 kls_log(current, "KLS", "Curr offset: { %p }.", current + current->offset);
1405 kls_log(current, "KLS",
1406 "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.",
1407 int_koliseo_version(), h_size);
1408 if (current->conf.kls_verbose_lvl > 0) {
1409 print_kls_2file(current->conf.kls_log_fp, current);
1410 }
1411#endif
1412 if (current->conf.kls_collect_stats == 1) {
1413 current->stats.tot_temp_pushes += 1;
1414 }
1415 return p;
1416}
1417
1423void print_kls_2file(FILE *fp, const Koliseo *kls)
1424{
1425 if (fp == NULL) {
1426 fprintf(stderr, "print_kls_2file(): fp was NULL.\n");
1427 return;
1428 }
1429 if (kls == NULL) {
1430 fprintf(fp, "[KLS] kls was NULL.\n");
1431 } else {
1432 fprintf(fp, "\n[KLS] API Level: { %i }\n", int_koliseo_version());
1433 fprintf(fp, "\n[INFO] Conf: { " KLS_Conf_Fmt " }\n",
1434 KLS_Conf_Arg(kls->conf));
1435 fprintf(fp, "\n[INFO] Stats: { " KLS_Stats_Fmt " }\n",
1436 KLS_Stats_Arg(kls->stats));
1437 fprintf(fp, "\n[KLS] Size: { %td }\n", kls->size);
1438 char human_size[200];
1439 char curr_size[200];
1440 kls_formatSize(kls->size, human_size, sizeof(human_size));
1441 fprintf(fp, "[KLS] Size (Human): { %s }\n", human_size);
1442 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1443 fprintf(fp, "[KLS] Used (Human): { %s }\n", curr_size);
1444 fprintf(fp, "[KLS] Offset: { %td }\n", kls->offset);
1445 fprintf(fp, "[KLS] Prev_Offset: { %td }\n", kls->prev_offset);
1446 fprintf(fp, "\n");
1447 }
1448}
1449
1454void print_dbg_kls(const Koliseo *kls)
1455{
1456 if (kls == NULL) {
1457 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1458 exit(EXIT_FAILURE);
1459 }
1460 print_kls_2file(stderr, kls);
1461}
1462
1468void print_temp_kls_2file(FILE *fp, const Koliseo_Temp *t_kls)
1469{
1470 if (fp == NULL) {
1471 fprintf(stderr, "print_temp_kls_2file(): fp was NULL.\n");
1472 exit(EXIT_FAILURE);
1473 }
1474 if (t_kls == NULL) {
1475 fprintf(fp, "[KLS_T] t_kls was NULL.");
1476 } else if (t_kls->kls == NULL) {
1477 fprintf(fp, "[KLS_T] [%s()]: Referred Koliseo was NULL.\n", __func__);
1478 } else {
1479 const Koliseo *kls = t_kls->kls;
1480 fprintf(fp, "\n[KLS_T] API Level: { %i }\n", int_koliseo_version());
1481 fprintf(fp, "\n[KLS_T] Temp Size: { %td }\n",
1482 kls->size - t_kls->offset);
1483 fprintf(fp, "\n[KLS_T] Refer Size: { %td }\n", kls->size);
1484 char human_size[200];
1485 char curr_size[200];
1486 kls_formatSize(kls->size - t_kls->offset, human_size,
1487 sizeof(human_size));
1488 fprintf(fp, "[KLS_T] Temp Size Human: { %s }\n", human_size);
1489 kls_formatSize(kls->size, human_size, sizeof(human_size));
1490 fprintf(fp, "[KLS_T] Refer Size Human: { %s }\n", human_size);
1491 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1492 fprintf(fp, "[KLS_T] Inner Used (Human): { %s }\n", curr_size);
1493 kls_formatSize(t_kls->offset, curr_size, sizeof(curr_size));
1494 fprintf(fp, "[KLS_T] Temp Used (Human): { %s }\n", curr_size);
1495 fprintf(fp, "[KLS_T] Inner Offset: { %td }\n", kls->offset);
1496 fprintf(fp, "[KLS_T] Temp Offset: { %td }\n", t_kls->offset);
1497 fprintf(fp, "[KLS_T] Inner Prev_Offset: { %td }\n", kls->prev_offset);
1498 fprintf(fp, "[KLS_T] Temp Prev_Offset: { %td }\n\n",
1499 t_kls->prev_offset);
1500 }
1501}
1502
1507void print_dbg_temp_kls(const Koliseo_Temp *t_kls)
1508{
1509 print_temp_kls_2file(stderr, t_kls);
1510}
1511
1519void kls_formatSize(ptrdiff_t size, char *outputBuffer, size_t bufferSize)
1520{
1521 const char *units[] =
1522 { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
1523 const int numUnits = sizeof(units) / sizeof(units[0]);
1524
1525 int unitIndex = 0;
1526 double sizeValue = (double)size;
1527
1528 while (sizeValue >= 1000 && unitIndex < numUnits - 1) {
1529 sizeValue /= 1000;
1530 unitIndex++;
1531 }
1532
1533 snprintf(outputBuffer, bufferSize, "%.2f %s", sizeValue, units[unitIndex]);
1534}
1535
1541void kls_clear(Koliseo *kls)
1542{
1543 if (kls == NULL) {
1544 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1545 exit(EXIT_FAILURE);
1546 }
1547 //Reset pointer
1548 kls->prev_offset = kls->offset;
1549 kls->offset = sizeof(*kls);
1550#ifdef KLS_DEBUG_CORE
1551 kls_log(kls, "KLS", "API Level { %i } -> Cleared offsets for KLS.",
1553#endif
1554}
1555
1561void kls_free(Koliseo *kls)
1562{
1563 if (kls == NULL) {
1564 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1565 exit(EXIT_FAILURE);
1566 }
1567 Koliseo* current = kls;
1568 while (current) {
1569 Koliseo* next = current->next;
1570 current->next = NULL;
1571 if (current->hooks.on_free_handler != NULL) {
1572 // Call on_free() extension
1573 current->hooks.on_free_handler(current);
1574 }
1575 if (current->has_temp == 1) {
1576#ifdef KLS_DEBUG_CORE
1577 kls_log(current, "KLS",
1578 "API Level { %i } -> KLS had an active Koliseo_Temp.",
1580#endif
1581 kls_temp_end(current->t_kls);
1582 }
1583 kls_clear(current);
1584#ifdef KLS_DEBUG_CORE
1585 kls_log(current, "KLS", "API Level { %i } -> Freeing KLS.",
1587#endif
1588 if (current->conf.kls_log_fp != NULL && current->conf.kls_log_fp != stdout
1589 && current->conf.kls_log_fp != stderr) {
1590#ifdef KLS_DEBUG_CORE
1591 kls_log(current, "KLS", "Closing kls log file. Path: {\"%s\"}.",
1592 kls->conf.kls_log_filepath);
1593#endif
1594 int close_res = fclose(current->conf.kls_log_fp);
1595 if (close_res != 0) {
1596 fprintf(stderr,
1597 "[ERROR] %s(): Failed fclose() on log_fp. Path: {\"%s\"}.",
1598 __func__, current->conf.kls_log_filepath);
1599 }
1600 } else if (current->conf.kls_log_fp == stdout || current->conf.kls_log_fp == stderr) {
1601 if (current->conf.kls_verbose_lvl > 1) {
1602 fprintf(stderr,
1603 "[INFO] %s(): kls->conf.kls_log_fp is %s. Not closing it.\n",
1604 __func__,
1605 (current->conf.kls_log_fp == stdout ? "stdout" : "stderr"));
1606 }
1607 }
1608 if (current->free_func == NULL) {
1609 fprintf(stderr,
1610 "[ERROR] %s(): free function was NULL.\n", __func__);
1611 return;
1612 }
1613 current->free_func(current);
1614 current = next;
1615 }
1616}
1617
1625#ifndef KOLISEO_HAS_LOCATE
1626Koliseo_Temp *kls_temp_start(Koliseo *kls)
1627#else
1628Koliseo_Temp *kls_temp_start_dbg(Koliseo *kls, Koliseo_Loc loc)
1629#endif // KOLISEO_HAS_LOCATE
1630{
1631 if (kls == NULL) {
1632 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1633 exit(EXIT_FAILURE);
1634 }
1635 Koliseo* current = kls;
1636 while (current->next != NULL) {
1637 current = current->next;
1638 }
1639 if (current->has_temp != 0) {
1640 fprintf(stderr,
1641 "[ERROR] [%s()]: Passed Koliseo->has_temp is not 0. {%i}\n",
1642 __func__, current->has_temp);
1643#ifdef KLS_DEBUG_CORE
1644 kls_log(current, "ERROR", "[%s()]: Passed Koliseo->has_temp != 0 . {%i}",
1645 __func__, current->has_temp);
1646#endif
1647 if (current->conf.kls_collect_stats == 1) {
1648 current->stats.tot_hiccups += 1;
1649 }
1650 return NULL;
1651 }
1652 ptrdiff_t prev = current->prev_offset;
1653 ptrdiff_t off = current->offset;
1654
1655 Koliseo_Temp *tmp = KLS_PUSH(current, Koliseo_Temp);
1656 tmp->kls = current;
1657 tmp->prev_offset = prev;
1658 tmp->offset = off;
1659#ifdef KLS_DEBUG_CORE
1660 kls_log(current, "INFO", "Passed kls conf: " KLS_Conf_Fmt "\n",
1661 KLS_Conf_Arg(current->conf));
1662#endif
1663
1664 current->has_temp = 1;
1665 current->t_kls = tmp;
1666 if (current->hooks.on_temp_start_handler != NULL) {
1667 // Call on_temp_start extension
1668 current->hooks.on_temp_start_handler(tmp);
1669 }
1670#ifdef KLS_DEBUG_CORE
1671 kls_log(current, "KLS", "Prepared new Temp KLS.");
1672#endif
1673 return tmp;
1674}
1675
1680void kls_temp_end(Koliseo_Temp *tmp_kls)
1681{
1682 if (tmp_kls == NULL) {
1683 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1684 __func__);
1685 exit(EXIT_FAILURE);
1686 }
1687
1688 Koliseo *kls_ref = tmp_kls->kls;
1689 if (kls_ref == NULL) {
1690 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1691 __func__);
1692 exit(EXIT_FAILURE);
1693 }
1694
1695 if (kls_ref->hooks.on_temp_free_handler != NULL) {
1696 // Call on_temp_free() extension
1697 kls_ref->hooks.on_temp_free_handler(tmp_kls);
1698 }
1699
1700#ifdef KLS_DEBUG_CORE
1701 kls_log(kls_ref, "KLS", "Ended Temp KLS.");
1702#endif
1703 tmp_kls->kls->has_temp = 0;
1704 tmp_kls->kls->t_kls = NULL;
1705 tmp_kls->kls->prev_offset = tmp_kls->prev_offset;
1706 tmp_kls->kls->offset = tmp_kls->offset;
1707
1708 // Free any Koliseo chained after the current one
1709 Koliseo* to_free = tmp_kls->kls->next;
1710 if (to_free != NULL) {
1711 kls_free(to_free);
1712 tmp_kls->kls->next = NULL;
1713 }
1714
1715 tmp_kls = NULL; // statement with no effect TODO: Clear tmp_kls from caller
1716 if (kls_ref->conf.kls_collect_stats == 1) {
1717 kls_ref->stats.tot_temp_pushes = 0;
1718 kls_ref->stats.tot_temp_pops = 0;
1719 }
1720}
1721
1722#ifdef KOLISEO_HAS_EXPER
1731void *kls_pop(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1732{
1733 if (kls == NULL) {
1734 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1735 exit(EXIT_FAILURE);
1736 }
1737 ptrdiff_t padding = -kls->offset & (align - 1);
1738 if (count > PTRDIFF_MAX / size
1739 || (kls->size + kls->offset) < (size * count)) {
1740 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1741 kls_free(kls);
1742 exit(EXIT_FAILURE);
1743 }
1744 char *p = kls->data + kls->offset - padding - size * count;
1745 kls->prev_offset = kls->offset;
1746 kls->offset -= padding + size * count;
1747#ifdef KLS_DEBUG_CORE
1748 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
1749 int_koliseo_version(), size);
1750 if (kls->conf.kls_verbose_lvl > 0) {
1751 print_kls_2file(kls->conf.kls_log_fp, kls);
1752 }
1753#endif
1754 if (kls->conf.kls_collect_stats == 1) {
1755 kls->stats.tot_pops += 1;
1756 }
1757 return p;
1758}
1759
1768void *kls_pop_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1769{
1770 if (kls == NULL) {
1771 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1772 exit(EXIT_FAILURE);
1773 }
1774 ptrdiff_t padding = -kls->offset & (align - 1);
1775 if (count > PTRDIFF_MAX / size
1776 || (kls->size + kls->offset) < (size * count)) {
1777 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1778 kls_free(kls);
1779 exit(EXIT_FAILURE);
1780 }
1781 char *p = kls->data + kls->offset - padding - size * count;
1782 kls->prev_offset = kls->offset;
1783 kls->offset -= padding + size * count;
1784#ifdef KLS_DEBUG_CORE
1785 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
1786 int_koliseo_version(), size);
1787 if (kls->conf.kls_verbose_lvl > 0) {
1788 print_kls_2file(kls->conf.kls_log_fp, kls);
1789 }
1790#endif
1791 if (kls->conf.kls_collect_stats == 1) {
1792 kls->stats.tot_pops += 1;
1793 }
1794 return p;
1795}
1796
1805void *kls_temp_pop(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align,
1806 ptrdiff_t count)
1807{
1808 if (t_kls == NULL) {
1809 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1810 __func__);
1811 exit(EXIT_FAILURE);
1812 }
1813 Koliseo *kls = t_kls->kls;
1814 if (kls == NULL) {
1815 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1816 __func__);
1817 exit(EXIT_FAILURE);
1818 }
1819 ptrdiff_t padding = -kls->offset & (align - 1);
1820 if (count > PTRDIFF_MAX / size
1821 || (kls->size + kls->offset) < (size * count)) {
1822 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1823 kls_free(kls);
1824 exit(EXIT_FAILURE);
1825 }
1826 char *p = kls->data + kls->offset - padding - size * count;
1827 kls->prev_offset = kls->offset;
1828 kls->offset -= padding + size * count;
1829#ifdef KLS_DEBUG_CORE
1830 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
1831 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
1832 int_koliseo_version(), size);
1833 if (kls->conf.kls_verbose_lvl > 0) {
1834 print_kls_2file(kls->conf.kls_log_fp, kls);
1835 }
1836#endif
1837 if (kls->conf.kls_collect_stats == 1) {
1838 kls->stats.tot_temp_pops += 1;
1839 }
1840 return p;
1841}
1842
1851void *kls_temp_pop_AR(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1852{
1853 if (t_kls == NULL) {
1854 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1855 __func__);
1856 exit(EXIT_FAILURE);
1857 }
1858 Koliseo *kls = t_kls->kls;
1859 if (kls == NULL) {
1860 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1861 __func__);
1862 exit(EXIT_FAILURE);
1863 }
1864 ptrdiff_t padding = -kls->offset & (align - 1);
1865 if (count > PTRDIFF_MAX / size
1866 || (kls->size + kls->offset) < (size * count)) {
1867 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1868 kls_free(kls);
1869 exit(EXIT_FAILURE);
1870 }
1871 char *p = kls->data + kls->offset - padding - size * count;
1872 kls->prev_offset = kls->offset;
1873 kls->offset -= padding + size * count;
1874#ifdef KLS_DEBUG_CORE
1875 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
1876 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
1877 int_koliseo_version(), size);
1878 if (kls->conf.kls_verbose_lvl > 0) {
1879 print_kls_2file(kls->conf.kls_log_fp, kls);
1880 }
1881#endif
1882 if (kls->conf.kls_collect_stats == 1) {
1883 kls->stats.tot_temp_pops += 1;
1884 }
1885 return p;
1886}
1887
1894char* kls_strdup(Koliseo* kls, char* source)
1895{
1896 char* dest = KLS_PUSH_STR(kls, source);
1897 KLS__STRCPY(dest, source);
1898 return dest;
1899}
1900
1907char** kls_strdup_arr(Koliseo* kls, size_t count, char** source)
1908{
1909 char** strings = NULL;
1910 strings = KLS_PUSH_ARR(kls, char*, count);
1911 for (int i=0; i < count; i++) {
1912 strings[i] = KLS_STRDUP(kls, source[i]);
1913 }
1914 return strings;
1915}
1916
1923char* kls_t_strdup(Koliseo_Temp* t_kls, char* source)
1924{
1925 char* dest = KLS_PUSH_STR_T(t_kls, source);
1926 KLS__STRCPY(dest, source);
1927 return dest;
1928}
1929
1936char** kls_t_strdup_arr(Koliseo_Temp* t_kls, size_t count, char** source)
1937{
1938 char** strings = NULL;
1939 strings = KLS_PUSH_ARR_T(t_kls, char*, count);
1940 for (int i=0; i < count; i++) {
1941 strings[i] = KLS_STRDUP_T(t_kls, source[i]);
1942 }
1943 return strings;
1944}
1945#endif // KOLISEO_HAS_EXPER
#define KLS_DEFAULT_HOOKS
Definition kls_region.h:162
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:1894
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:1805
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:1626
void print_dbg_temp_kls(const Koliseo_Temp *t_kls)
Prints header fields from the passed Koliseo_Temp pointer, to stderr.
Definition koliseo.c:1507
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:653
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:1468
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:1923
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:532
KLS_Stats KLS_STATS_DEFAULT
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
void kls_temp_end(Koliseo_Temp *tmp_kls)
Ends passed Koliseo_Temp pointer.
Definition koliseo.c:1680
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:1907
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:1332
void print_dbg_kls(const Koliseo *kls)
Prints header fields from the passed Koliseo pointer, to stderr.
Definition koliseo.c:1454
const char * string_koliseo_version(void)
Returns the constant string representing current version for Koliseo.
Definition koliseo.c:59
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:1851
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)
Takes a ptrdiff_t size, an allocation function pointer and a free function pointer,...
Definition koliseo.c:587
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:1768
void kls_free(Koliseo *kls)
Calls kls_clear() on the passed Koliseo pointer and the frees the actual Koliseo.
Definition koliseo.c:1561
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_dbg_ext(ptrdiff_t size, KLS_Hooks ext_handlers, void *user)
Takes a ptrdiff_t size.
Definition koliseo.c:636
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:1936
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:1041
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:621
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:1124
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:419
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:782
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:568
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:1731
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)
Takes a ptrdiff_t size, a KLS_Conf to configure the new Koliseo, an allocation function pointer and a...
Definition koliseo.c:447
void KLS_PTRDIFF_MAX_default_handler__(struct Koliseo *kls, ptrdiff_t size, ptrdiff_t count)
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_alloc_ext(ptrdiff_t size, kls_alloc_func alloc_func, kls_free_func free_func, KLS_Hooks ext_handlers, void *user)
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:1423
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)
Takes a ptrdiff_t size, a filepath for the trace output file, an allocation function pointer and a fr...
Definition koliseo.c:496
void kls_clear(Koliseo *kls)
Resets the offset field for the passed Koliseo pointer.
Definition koliseo.c:1541
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:1216
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:1519
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:476
int int_koliseo_version(void)
Returns the constant int representing current version for Koliseo.
Definition koliseo.c:68
Koliseo * kls_new_traced_ext(ptrdiff_t size, const char *output_path, KLS_Hooks ext_handlers, void *user)
Takes a ptrdiff_t size and a filepath for the trace output file.
Definition koliseo.c:549