koliseo 0.4.9
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_log_filepath = "",
27 .err_handlers = {
28#ifndef KOLISEO_HAS_LOCATE
29 .OOM_handler = &KLS_OOM_default_handler__,
30 .PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler__,
31 .ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler__,
32#else
33 .OOM_handler = &KLS_OOM_default_handler_dbg__,
34 .PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__,
35 .ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler_dbg__,
36#endif // KOLISEO_HAS_LOCATE
37 },
38};
39
40KLS_Stats KLS_STATS_DEFAULT = {
41 .tot_pushes = 0,
42 .tot_temp_pushes = 0,
43 .tot_pops = 0,
44 .tot_temp_pops = 0,
45 .tot_logcalls = 0,
46 .tot_hiccups = 0,
47#ifdef KLS_DEBUG_CORE
48 .worst_pushcall_time = -1,
49#endif
50};
51
52static bool kls_set_conf(Koliseo * kls, KLS_Conf conf); //Declare function used internally by kls_new() and kls_new_conf()
53
58const char *string_koliseo_version(void)
59{
60 return KOLISEO_API_VERSION_STRING;
61}
62
68{
69 return KOLISEO_API_VERSION_INT;
70}
71
81#ifndef KOLISEO_HAS_LOCATE
82void KLS_OOM_default_handler__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, ptrdiff_t count)
83#else
84void KLS_OOM_default_handler_dbg__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, ptrdiff_t count, Koliseo_Loc loc)
85#endif // KOLISEO_HAS_LOCATE
86{
87#ifndef KOLISEO_HAS_LOCATE
88 fprintf(stderr,
89 "[KLS] Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
90 size * count, available - padding);
91#else
92 fprintf(stderr,
93 "[KLS] " KLS_Loc_Fmt "Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
94 KLS_Loc_Arg(loc),
95 size * count, available - padding);
96#endif // KOLISEO_HAS_LOCATE
97 kls_free(kls); // Is it even worth it to try?
98 exit(EXIT_FAILURE); // Better than nothing. May change to return NULL instead? Requiring refactor of handler signature
99}
100
101#ifndef KOLISEO_HAS_LOCATE
102void KLS_PTRDIFF_MAX_default_handler__(struct Koliseo* kls, ptrdiff_t size, ptrdiff_t count)
103#else
104void KLS_PTRDIFF_MAX_default_handler_dbg__(struct Koliseo* kls, ptrdiff_t size, ptrdiff_t count, Koliseo_Loc loc)
105#endif
106{
107#ifndef _WIN32
108#ifndef KOLISEO_HAS_LOCATE
109 fprintf(stderr,
110 "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
111 count, PTRDIFF_MAX / size);
112#else
113 fprintf(stderr,
114 "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
115 KLS_Loc_Arg(loc),
116 count, PTRDIFF_MAX / size);
117#endif // KOLISEO_HAS_LOCATE
118#else
119#ifndef KOLISEO_HAS_LOCATE
120 fprintf(stderr,
121 "[KLS] count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
122 count, PTRDIFF_MAX / size);
123#else
124 fprintf(stderr,
125 "[KLS] " KLS_Loc_Fmt "count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
126 KLS_Loc_Arg(loc),
127 count, PTRDIFF_MAX / size);
128#endif // KOLISEO_HAS_LOCATE
129#endif // _WIN32
130 kls_free(kls);
131 exit(EXIT_FAILURE);
132}
133
143#ifndef KOLISEO_HAS_LOCATE
144void KLS_ZEROCOUNT_default_handler__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size)
145#else
146void KLS_ZEROCOUNT_default_handler_dbg__(Koliseo* kls, ptrdiff_t available, ptrdiff_t padding, ptrdiff_t size, Koliseo_Loc loc)
147#endif // KOLISEO_HAS_LOCATE
148{
149#ifndef KOLISEO_HAS_LOCATE
150 fprintf(stderr,
151 "[KLS] Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
152 size, padding, available);
153#else
154 fprintf(stderr,
155 "[KLS] " KLS_Loc_Fmt "Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
156 KLS_Loc_Arg(loc),
157 size, padding, available);
158#endif // KOLISEO_HAS_LOCATE
159 kls_free(kls);
160 exit(EXIT_FAILURE);
161}
162
168KLS_Conf kls_conf_init_handled(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, FILE* log_fp, const char* log_filepath, KLS_Err_Handlers err_handlers)
169{
170 KLS_Conf res = {0};
171 (void) autoset_regions;
172 (void) alloc_backend;
173 (void) reglist_kls_size;
174 (void) autoset_temp_regions;
175 res.kls_collect_stats = collect_stats;
176 res.kls_verbose_lvl = verbose_lvl;
177 res.kls_block_while_has_temp = block_while_has_temp;
178 res.kls_allow_zerocount_push = allow_zerocount_push;
179 res.kls_log_fp = log_fp;
180 res.kls_log_filepath = log_filepath;
181
182 if (err_handlers.OOM_handler != NULL) {
183 res.err_handlers.OOM_handler = err_handlers.OOM_handler;
184 } else {
185#ifndef KOLISEO_HAS_LOCATE
186 res.err_handlers.OOM_handler = &KLS_OOM_default_handler__;
187#else
188 res.err_handlers.OOM_handler = &KLS_OOM_default_handler_dbg__;
189#endif // KOLISEO_HAS_LOCATE
190 }
191
192 if (err_handlers.PTRDIFF_MAX_handler != NULL) {
193 res.err_handlers.PTRDIFF_MAX_handler = err_handlers.PTRDIFF_MAX_handler;
194 } else {
195#ifndef KOLISEO_HAS_LOCATE
196 res.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler__;
197#else
198 res.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__;
199#endif // KOLISEO_HAS_LOCATE
200 }
201
202 if (err_handlers.ZEROCOUNT_handler != NULL) {
203 res.err_handlers.ZEROCOUNT_handler = err_handlers.ZEROCOUNT_handler;
204 } else {
205#ifndef KOLISEO_HAS_LOCATE
206 res.err_handlers.ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler__;
207#else
208 res.err_handlers.ZEROCOUNT_handler = &KLS_ZEROCOUNT_default_handler_dbg__;
209#endif // KOLISEO_HAS_LOCATE
210 }
211
212 return res;
213}
214
219KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, FILE* log_fp, const char* log_filepath)
220{
221 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
222 return kls_conf_init_handled(autoset_regions, alloc_backend, reglist_kls_size, autoset_temp_regions, collect_stats, verbose_lvl, block_while_has_temp, allow_zerocount_push, log_fp, log_filepath, err_handlers);
223}
224
229{
230#ifdef KOLISEO_HAS_LOCATE
231 bool kls_locate = true;
232#else
233 bool kls_locate = false;
234#endif
235#ifdef KLS_DEBUG_CORE
236 bool kls_debug = true;
237#else
238 bool kls_debug = false;
239#endif
240#ifdef KOLISEO_HAS_EXPER
241 bool kls_exper = true;
242#else
243 bool kls_exper = false;
244#endif
245 bool features[3] = {
246 [0] = kls_debug,
247 [1] = kls_locate,
248 [2] = kls_exper,
249 };
250 int total_enabled = 0;
251 for (int i=0; i<3; i++) {
252 if (features[i]) {
253 total_enabled += 1;
254 }
255 }
256 fprintf(stderr, "[KLS] Enabled features: {");
257 if (total_enabled == 0) {
258 fprintf(stderr, "none}\n");
259 return;
260 } else {
261 if (kls_debug) {
262 fprintf(stderr, "debug%s", (total_enabled > 1 ? ", " : ""));
263 total_enabled -= 1;
264 }
265 if (kls_locate) {
266 fprintf(stderr, "locate%s", (total_enabled > 1 ? ", " : ""));
267 total_enabled -= 1;
268 }
269 if (kls_exper) {
270 fprintf(stderr, "exper");
271 }
272 fprintf(stderr, "}\n");
273 }
274}
275
281ptrdiff_t kls_get_pos(const Koliseo *kls)
282{
283 return kls->offset;
284}
285
292void kls_log(Koliseo *kls, const char *tag, const char *format, ...)
293{
294 if (kls == NULL) {
295 fprintf(stderr, "[KLS] %s(): Passed kls was NULL.\n", __func__);
296 return;
297 }
298 if (kls->conf.kls_verbose_lvl > 0) {
299 va_list args;
300 FILE *fp = kls->conf.kls_log_fp;
301 va_start(args, format);
302 if (fp == NULL) {
303 fprintf(stderr,
304 "[KLS] %s(): Failed opening file to print logs.\n",
305 __func__);
306 } else {
307 time_t now = time(0);
308 const struct tm *mytime = localtime(&now);
309 char timeheader[500];
310 if (strftime(timeheader, sizeof timeheader, "%X", mytime)) {
311 fprintf(fp, "[%-10.10s] [%s] [", tag, timeheader);
312 vfprintf(fp, format, args);
313 fprintf(fp, "]\n");
314 }
315 }
316 va_end(args);
317 }
318}
319
337#ifndef KOLISEO_HAS_LOCATE
338Koliseo *kls_new_alloc_ext(ptrdiff_t size, kls_alloc_func alloc_func, KLS_Hooks ext_handlers, void* user)
339#else
340Koliseo *kls_new_alloc_ext_dbg(ptrdiff_t size, kls_alloc_func alloc_func, KLS_Hooks ext_handlers, void* user, Koliseo_Loc loc)
341#endif // KOLISEO_HAS_LOCATE
342{
343 if (size < (ptrdiff_t)sizeof(Koliseo)) {
344#ifndef KOLISEO_HAS_LOCATE
345 fprintf(stderr,
346 "[ERROR] at %s(): invalid requested kls size (%td). Min accepted is: (%td).\n",
347 __func__, size, (ptrdiff_t)sizeof(Koliseo));
348#else
349 fprintf(stderr,
350 "[ERROR] " KLS_Loc_Fmt "%s(): invalid requested kls size (%td). Min accepted is: (%td).\n",
351 KLS_Loc_Arg(loc), __func__, size, (ptrdiff_t)sizeof(Koliseo));
352#endif // KOLISEO_HAS_LOCATE
353 //TODO Is it better to abort the program?
354 return NULL;
355 }
356 void *p = alloc_func(size);
357 if (p) {
358 //sprintf(msg,"Allocated (%li) for new KLS.",size);
359 //kls_log("KLS",msg);
360 char h_size[200];
361 kls_formatSize(size, h_size, sizeof(h_size));
362 Koliseo *kls = p;
363 kls->data = p;
364 kls->size = size;
365 kls->offset = sizeof(*kls);
366 kls->prev_offset = kls->offset;
367 kls->has_temp = 0;
368 kls->t_kls = NULL;
369 kls_set_conf(kls, KLS_DEFAULT_CONF);
370 kls->stats = KLS_STATS_DEFAULT;
371 kls->conf.kls_log_fp = stderr;
372 kls->hooks = ext_handlers;
373 kls->extension_data = user;
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)
420#else
421Koliseo *kls_new_alloc_dbg(ptrdiff_t size, kls_alloc_func alloc_func, Koliseo_Loc loc)
422#endif // KOLISEO_HAS_LOCATE
423{
424#ifndef KOLISEO_HAS_LOCATE
425 return kls_new_alloc_ext(size, alloc_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA);
426#else
427 return kls_new_alloc_ext_dbg(size, alloc_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA, loc);
428#endif // KOLISEO_HAS_LOCATE
429}
430
446Koliseo *kls_new_conf_alloc_ext(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, KLS_Hooks ext_handlers, void* user)
447{
448 Koliseo *k = kls_new_alloc_ext(size, alloc_func, ext_handlers, user);
449 bool conf_res = kls_set_conf(k, conf);
450 if (!conf_res) {
451 fprintf(stderr,
452 "[ERROR] [%s()]: Failed to set config for new Koliseo.\n",
453 __func__);
454 exit(EXIT_FAILURE);
455 }
456 return k;
457}
458
474Koliseo *kls_new_conf_alloc(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func)
475{
476 return kls_new_conf_alloc_ext(size, conf, alloc_func, KLS_DEFAULT_HOOKS, KLS_DEFAULT_EXTENSION_DATA);
477}
478
492Koliseo *kls_new_traced_alloc_handled(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, KLS_Err_Handlers err_handlers)
493{
494
495#ifndef KLS_DEBUG_CORE
496 fprintf(stderr,
497 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No tracing allowed.\n",
498 __func__);
499#endif
500 KLS_Conf k = (KLS_Conf) {
501 .kls_collect_stats = 1,.kls_verbose_lvl =
502 1,.kls_log_filepath = output_path,
503#ifndef KOLISEO_HAS_LOCATE
504 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
505 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
506#else
507 .err_handlers.OOM_handler = (err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
508 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
509#endif // KOLISEO_HAS_LOCATE
510 };
511 return kls_new_conf_alloc(size, k, alloc_func);
512}
513
526Koliseo *kls_new_traced_alloc(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func)
527{
528 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
529 return kls_new_traced_alloc_handled(size, output_path, alloc_func, err_handlers);
530}
531
543Koliseo *kls_new_dbg_alloc_handled(ptrdiff_t size, kls_alloc_func alloc_func, KLS_Err_Handlers err_handlers)
544{
545#ifndef KLS_DEBUG_CORE
546 fprintf(stderr,
547 "[WARN] %s(): KLS_DEBUG_CORE is not defined. No debugging support.\n",
548 __func__);
549#endif
550 KLS_Conf k = (KLS_Conf) {
551 .kls_collect_stats = 1,.kls_verbose_lvl = 0,
552#ifndef KOLISEO_HAS_LOCATE
553 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler__),
554 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler__),
555#else
556 .err_handlers.OOM_handler = ( err_handlers.OOM_handler != NULL ? err_handlers.OOM_handler : &KLS_OOM_default_handler_dbg__),
557 .err_handlers.PTRDIFF_MAX_handler = ( err_handlers.PTRDIFF_MAX_handler != NULL ? err_handlers.PTRDIFF_MAX_handler : &KLS_PTRDIFF_MAX_default_handler_dbg__),
558#endif // KOLIEO_HAS_LOCATE
559 };
560 Koliseo * kls = kls_new_conf_alloc(size, k, alloc_func);
561 kls->conf.kls_verbose_lvl = 1;
562 return kls;
563}
564
575Koliseo *kls_new_dbg_alloc(ptrdiff_t size, kls_alloc_func alloc_func)
576{
577 KLS_Err_Handlers err_handlers = KLS_DEFAULT_ERR_HANDLERS;
578 return kls_new_dbg_alloc_handled(size, alloc_func, err_handlers);
579}
580
587bool kls_set_conf(Koliseo *kls, KLS_Conf conf)
588{
589 if (kls == NULL) {
590 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
591 //TODO: is it better to exit() here?
592 return false;
593 }
594
595 kls->conf = conf;
596 if (kls->conf.kls_log_fp == NULL) {
597 kls->conf.kls_log_fp = stderr;
598#ifdef KLS_DEBUG_CORE
599#ifdef KLS_SETCONF_DEBUG
600 kls_log(kls, "KLS",
601 "[%s()]: Preliminary set of conf.kls_log_fp to stderr.",
602 __func__);
603#endif
604#endif // KLS_DEBUG_CORE
605 }
606
607 if (conf.err_handlers.OOM_handler == NULL) {
608 fprintf(stderr,
609 "[ERROR] at %s(): passed OOM_handler is NULL. Using default.\n",
610 __func__);
611#ifdef KLS_DEBUG_CORE
612#ifdef KLS_SETCONF_DEBUG
613 kls_log(kls, "KLS",
614 "[%s()]: Passed OOM_handler was NULL, using default.",
615 __func__);
616#endif
617#endif // KLS_DEBUG_CORE
618#ifndef KOLISEO_HAS_LOCATE
619 kls->conf.err_handlers.OOM_handler = &KLS_OOM_default_handler__;
620#else
621 kls->conf.err_handlers.OOM_handler = &KLS_OOM_default_handler_dbg__;
622#endif
623 }
624
625 if (conf.err_handlers.PTRDIFF_MAX_handler == NULL) {
626 fprintf(stderr,
627 "[ERROR] at %s(): passed PTRDIFF_MAX_handler is NULL. Using default.\n",
628 __func__);
629#ifdef KLS_DEBUG_CORE
630#ifdef KLS_SETCONF_DEBUG
631 kls_log(kls, "KLS",
632 "[%s()]: Passed PTRDIFF_MAX_handler was NULL, using default.",
633 __func__);
634#endif
635#endif // KLS_DEBUG_CORE
636#ifndef KOLISEO_HAS_LOCATE
637 kls->conf.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler__;
638#else
639 kls->conf.err_handlers.PTRDIFF_MAX_handler = &KLS_PTRDIFF_MAX_default_handler_dbg__;
640#endif
641 }
642
643#ifndef KLS_DEBUG_CORE
644 if (kls->conf.kls_collect_stats == 1) {
645 fprintf(stderr,
646 "[WARN] [%s()]: KLS_DEBUG_CORE is not defined. Stats may not be collected in full.\n",
647 __func__);
648 }
649#endif
650
651 if (kls->conf.kls_verbose_lvl > 0) {
652 if (kls->conf.kls_log_fp != NULL) {
653#ifdef KLS_DEBUG_CORE
654#ifdef KLS_SETCONF_DEBUG
655 kls_log(kls, "WARN",
656 "[%s()]: kls->conf.kls_log_fp was not NULL. Overriding it.",
657 __func__);
658#endif
659#endif
660 if (kls->conf.kls_collect_stats == 1) {
661 kls->stats.tot_hiccups += 1;
662 }
663 }
664
665 FILE *log_fp = NULL;
666 log_fp = fopen(kls->conf.kls_log_filepath, "w");
667 if (!log_fp) {
668 fprintf(stderr,
669 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [write].\n",
670 __func__, kls->conf.kls_log_filepath);
671 return false;
672 } else {
673 fprintf(log_fp, "%s", ""); //Reset log_fp
674 fclose(log_fp);
675 }
676 log_fp = fopen(kls->conf.kls_log_filepath, "a");
677 if (!log_fp) {
678 fprintf(stderr,
679 "[ERROR] [%s()]: Failed opening logfile at {\"%s\"} [append].\n",
680 __func__, kls->conf.kls_log_filepath);
681 return false;
682 } else {
683 kls->conf.kls_log_fp = log_fp;
684 }
685 }
686 return true;
687}
688
701#ifndef KOLISEO_HAS_LOCATE
702int kls__check_available_failable(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name)
703#else
704int kls__check_available_failable_dbg(Koliseo* kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count, const char* caller_name, Koliseo_Loc loc)
705#endif // KOLISEO_HAS_LOCATE
706{
707 assert(kls != NULL);
708 assert(caller_name != NULL);
709 if (count < 0) {
710#ifndef KOLISEO_HAS_LOCATE
711 fprintf(stderr,
712 "[KLS] %s(): count [%td] was < 0.\n",
713 caller_name,
714 count);
715#else
716 fprintf(stderr,
717 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was < 0.\n",
718 KLS_Loc_Arg(loc),
719 caller_name,
720 count);
721#endif // KOLISEO_HAS_LOCATE
722 return -1;
723 }
724 if (size < 1) {
725#ifndef KOLISEO_HAS_LOCATE
726 fprintf(stderr,
727 "[KLS] %s(): size [%td] was < 1.\n",
728 caller_name,
729 size);
730#else
731 fprintf(stderr,
732 "[KLS] " KLS_Loc_Fmt "%s(): size [%td] was < 1.\n",
733 KLS_Loc_Arg(loc),
734 caller_name,
735 size);
736#endif // KOLISEO_HAS_LOCATE
737 return -1;
738 }
739 if (align < 1) {
740#ifndef KOLISEO_HAS_LOCATE
741 fprintf(stderr,
742 "[KLS] %s(): align [%td] was < 1.\n",
743 caller_name,
744 align);
745#else
746 fprintf(stderr,
747 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was < 1.\n",
748 KLS_Loc_Arg(loc),
749 caller_name,
750 align);
751#endif // KOLISEO_HAS_LOCATE
752 return -1;
753 }
754 if (! ((align & (align - 1)) == 0)) {
755#ifndef KOLISEO_HAS_LOCATE
756 fprintf(stderr,
757 "[KLS] %s(): align [%td] was not a power of 2.\n",
758 caller_name,
759 align);
760#else
761 fprintf(stderr,
762 "[KLS] " KLS_Loc_Fmt "%s(): align [%td] was not a power of 2.\n",
763 KLS_Loc_Arg(loc),
764 caller_name,
765 align);
766#endif // KOLISEO_HAS_LOCATE
767 return -1;
768 }
769 const ptrdiff_t available = kls->size - kls->offset;
770 const ptrdiff_t padding = -kls->offset & (align - 1);
771 bool ZEROCOUNT_happened = false;
772 bool ZEROCOUNT_handled = false;
773 if (count == 0) {
774 if (kls->conf.kls_allow_zerocount_push != 1) {
775 ZEROCOUNT_happened = true;
776 if (kls->conf.err_handlers.ZEROCOUNT_handler != NULL) {
777#ifndef KOLISEO_HAS_LOCATE
778 kls->conf.err_handlers.ZEROCOUNT_handler(kls, available, padding, size);
779#else
780 kls->conf.err_handlers.ZEROCOUNT_handler(kls, available, padding, size, loc);
781#endif // KOLISEO_HAS_LOCATE
782 ZEROCOUNT_handled = true;
783 } else {
784#ifndef KOLISEO_HAS_LOCATE
785 fprintf(stderr,
786 "[KLS] %s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
787 caller_name,
788 size, padding, available);
789#else
790 fprintf(stderr,
791 "[KLS] " KLS_Loc_Fmt "%s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
792 KLS_Loc_Arg(loc),
793 caller_name,
794 size, padding, available);
795#endif // KOLISEO_HAS_LOCATE
796 kls_free(kls);
797 exit(EXIT_FAILURE);
798 }
799 } else {
800#ifdef KLS_DEBUG_CORE
801 kls_log(kls, "DEBUG", "Accepting zero-count push: conf.kls_allow_zerocount_push was 1");
802#endif // KLS_DEBUG_CORE
803 }
804 }
805
806 if (ZEROCOUNT_happened && ZEROCOUNT_handled) {
807#ifdef KLS_DEBUG_CORE
808 kls_log(kls, "DEBUG", "Requested a zero-count push while kls_allow_zerocount_push is not 1, but the error handler returned instead of exiting.");
809#endif // KLS_DEBUG_CORE
810#ifndef KOLISEO_HAS_LOCATE
811 fprintf(stderr,
812 "[KLS] %s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
813 caller_name,
814 size, padding, available);
815#else
816 fprintf(stderr,
817 "[KLS] " KLS_Loc_Fmt "%s(): Doing a zero-count push. size [%td] padding [%td] available [%td].\n",
818 KLS_Loc_Arg(loc),
819 caller_name,
820 size, padding, available);
821#endif // KOLISEO_HAS_LOCATE
822 kls_free(kls);
823 exit(EXIT_FAILURE);
824 }
825
826 bool OOM_happened = false;
827 bool OOM_handled = false;
828 bool PTRDIFF_MAX_happened = false;
829 bool PTRDIFF_MAX_handled = false;
830 if (count > PTRDIFF_MAX / size || available - padding < size * count) {
831 if (count > PTRDIFF_MAX / size) {
832 PTRDIFF_MAX_happened = true;
833 if (kls->conf.err_handlers.PTRDIFF_MAX_handler != NULL) {
834#ifndef KOLISEO_HAS_LOCATE
835 kls->conf.err_handlers.PTRDIFF_MAX_handler(kls, size, count);
836#else
837 kls->conf.err_handlers.PTRDIFF_MAX_handler(kls, size, count, loc);
838#endif // KOLISEO_HAS_LOCATE
839 PTRDIFF_MAX_handled = true;
840 } else { // Let's keep this here for now? It's the original part before adding KLS_PTRDIFF_MAX_default_handler__()
841#ifndef _WIN32
842#ifndef KOLISEO_HAS_LOCATE
843 fprintf(stderr,
844 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
845 caller_name,
846 count, PTRDIFF_MAX / size);
847#else
848 fprintf(stderr,
849 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%li].\n",
850 KLS_Loc_Arg(loc),
851 caller_name,
852 count, PTRDIFF_MAX / size);
853#endif // KOLISEO_HAS_LOCATE
854#else
855#ifndef KOLISEO_HAS_LOCATE
856 fprintf(stderr,
857 "[KLS] %s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
858 caller_name,
859 count, PTRDIFF_MAX / size);
860#else
861 fprintf(stderr,
862 "[KLS] " KLS_Loc_Fmt "%s(): count [%td] was bigger than PTRDIFF_MAX/size [%lli].\n",
863 KLS_Loc_Arg(loc),
864 caller_name,
865 count, PTRDIFF_MAX / size);
866#endif // KOLISEO_HAS_LOCATE
867#endif // _WIN32
868 }
869 } else {
870 OOM_happened = true;
871 if (kls->conf.err_handlers.OOM_handler != NULL) {
872#ifndef KOLISEO_HAS_LOCATE
873 kls->conf.err_handlers.OOM_handler(kls, available, padding, size, count);
874#else
875 kls->conf.err_handlers.OOM_handler(kls, available, padding, size, count, loc);
876#endif // KOLISEO_HAS_LOCATE
877 OOM_handled = true;
878 } else { // Let's keep this here for now? It's the original part before adding KLS_OOM_default_handler__()
879#ifndef KOLISEO_HAS_LOCATE
880 fprintf(stderr,
881 "[KLS] %s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
882 caller_name,
883 size * count, available - padding);
884#else
885 fprintf(stderr,
886 "[KLS] " KLS_Loc_Fmt "%s(): Out of memory. size*count [%td] was bigger than available-padding [%td].\n",
887 KLS_Loc_Arg(loc),
888 caller_name,
889 size * count, available - padding);
890#endif // KOLISEO_HAS_LOCATE
891 }
892 }
893 if (PTRDIFF_MAX_happened) {
894 if (kls->conf.err_handlers.PTRDIFF_MAX_handler && PTRDIFF_MAX_handled) {
895#ifndef KOLISEO_HAS_LOCATE
896 fprintf(stderr, "[KLS] %s(): PTRDIFF_MAX fault happened and was handled.\n", caller_name);
897#ifdef KLS_DEBUG_CORE
898 kls_log(kls, "DEBUG", "%s(): PTRDIFF_MAX fault happened and was handled.", caller_name);
899#endif // KLS_DEBUG_CORE
900#else
901 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "%s(): PTRDIFF_MAX fault happened and was handled.\n", KLS_Loc_Arg(loc), caller_name);
902#ifdef KLS_DEBUG_CORE
903 kls_log(kls, "DEBUG", KLS_Loc_Fmt "%s(): PTRDIFF_MAX fault happened and was handled.", KLS_Loc_Arg(loc), caller_name);
904#endif // KLS_DEBUG_CORE
905#endif // KOLISEO_HAS_LOCATE
906 return -1;
907 }
908 } else if (OOM_happened) {
909 if (kls->conf.err_handlers.PTRDIFF_MAX_handler && OOM_handled) {
910#ifndef KOLISEO_HAS_LOCATE
911 fprintf(stderr, "[KLS] %s(): OOM fault happened and was handled.\n", caller_name);
912#ifdef KLS_DEBUG_CORE
913 kls_log(kls, "DEBUG", "%s(): OOM fault happened and was handled.", caller_name);
914#endif // KLS_DEBUG_CORE
915#else
916 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "%s(): OOM fault happened and was handled.\n", KLS_Loc_Arg(loc), caller_name);
917#ifdef KLS_DEBUG_CORE
918 kls_log(kls, "DEBUG", KLS_Loc_Fmt "%s(): OOM fault happened and was handled.", KLS_Loc_Arg(loc), caller_name);
919#endif // KLS_DEBUG_CORE
920#endif // KOLISEO_HAS_LOCATE
921 return -1;
922 }
923 }
924#ifndef KOLISEO_HAS_LOCATE
925 fprintf(stderr, "[KLS] Failed %s() call.\n", caller_name);
926#else
927 fprintf(stderr, "[KLS] " KLS_Loc_Fmt "Failed %s() call.\n", KLS_Loc_Arg(loc), caller_name);
928#endif // KOLISEO_HAS_LOCATE
929 kls_free(kls);
930 exit(EXIT_FAILURE);
931 }
932 return 0;
933}
934
944void *kls_push(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
945{
946
947#ifdef KLS_DEBUG_CORE
948#ifndef _WIN32
949 struct timespec start_time, end_time;
950 clock_gettime(CLOCK_MONOTONIC, &start_time);
951#else
952 LARGE_INTEGER start_time, end_time, frequency;
953 QueryPerformanceFrequency(&frequency);
954 QueryPerformanceCounter(&start_time);
955#endif
956#endif
957
958 if (kls == NULL) {
959 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
960 exit(EXIT_FAILURE);
961 }
962 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
963 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
964#ifdef KLS_DEBUG_CORE
965 kls_log(kls, "ERROR", "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", __func__);
966 exit(EXIT_FAILURE);
967#endif // KLS_DEBUG_CORE
968 return NULL;
969 }
970#ifndef KOLISEO_HAS_LOCATE
971 kls__check_available(kls, size, align, count);
972#else
973 kls__check_available_dbg(kls, size, align, count, KLS_HERE);
974#endif // KOLISEO_HAS_LOCATE
975 ptrdiff_t padding = -kls->offset & (align - 1);
976 char *p = kls->data + kls->offset + padding;
977 kls->prev_offset = kls->offset;
978 kls->offset += padding + size * count;
979 char h_size[200];
980 kls_formatSize(size * count, h_size, sizeof(h_size));
981 //sprintf(msg,"Pushed size (%li) for KLS.",size);
982 //kls_log("KLS",msg);
983#ifdef KLS_DEBUG_CORE
984 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
985 kls_log(kls, "KLS", "API Level { %i } -> Pushed size (%s) for KLS.",
986 int_koliseo_version(), h_size);
987 if (kls->conf.kls_verbose_lvl > 0) {
988 print_kls_2file(kls->conf.kls_log_fp, kls);
989 }
990 if (kls->conf.kls_collect_stats == 1) {
991#ifndef _WIN32
992 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
993 double elapsed_time =
994 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
995 start_time.tv_nsec) / 1e9;
996#else
997 QueryPerformanceCounter(&end_time); // %.7f
998 double elapsed_time =
999 (double)(end_time.QuadPart -
1000 start_time.QuadPart) / frequency.QuadPart;
1001#endif
1002 if (elapsed_time > kls->stats.worst_pushcall_time) {
1003 kls->stats.worst_pushcall_time = elapsed_time;
1004 }
1005 }
1006#endif
1007 if (kls->conf.kls_collect_stats == 1) {
1008 kls->stats.tot_pushes += 1;
1009 }
1010 return p;
1011}
1012
1022#ifndef KOLISEO_HAS_LOCATE
1023void *kls_push_zero(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1024 ptrdiff_t count)
1025#else
1026void *kls_push_zero_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1027 ptrdiff_t count, Koliseo_Loc loc)
1028#endif // KOLISEO_HAS_LOCATE
1029{
1030
1031#ifdef KLS_DEBUG_CORE
1032#ifndef _WIN32
1033 struct timespec start_time, end_time;
1034 clock_gettime(CLOCK_MONOTONIC, &start_time);
1035#else
1036 LARGE_INTEGER start_time, end_time, frequency;
1037 QueryPerformanceFrequency(&frequency);
1038 QueryPerformanceCounter(&start_time);
1039#endif
1040#endif
1041
1042 if (kls == NULL) {
1043 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1044 exit(EXIT_FAILURE);
1045 }
1046 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1047#ifndef KOLISEO_HAS_LOCATE
1048 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1049#else
1050 fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__);
1051 kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__);
1052 exit(EXIT_FAILURE);
1053#endif // KOLISEO_HAS_LOCATE
1054 return NULL;
1055 }
1056#ifndef KOLISEO_HAS_LOCATE
1057 kls__check_available(kls, size, align, count);
1058#else
1059 kls__check_available_dbg(kls, size, align, count, loc);
1060#endif
1061
1062 ptrdiff_t padding = -kls->offset & (align - 1);
1063 char *p = kls->data + kls->offset + padding;
1064 //Zero new area
1065 memset(p, 0, size * count);
1066 kls->prev_offset = kls->offset;
1067 kls->offset += padding + size * count;
1068 char h_size[200];
1069 kls_formatSize(size * count, h_size, sizeof(h_size));
1070 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1071 //kls_log("KLS",msg);
1072#ifdef KLS_DEBUG_CORE
1073 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
1074 kls_log(kls, "KLS", "API Level { %i } -> Pushed zeroes, size (%s) for KLS.",
1075 int_koliseo_version(), h_size);
1076 if (kls->conf.kls_verbose_lvl > 0) {
1077 print_kls_2file(kls->conf.kls_log_fp, kls);
1078 }
1079 if (kls->conf.kls_collect_stats == 1) {
1080#ifndef _WIN32
1081 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1082 double elapsed_time =
1083 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1084 start_time.tv_nsec) / 1e9;
1085#else
1086 QueryPerformanceCounter(&end_time); // %.7f
1087 double elapsed_time =
1088 (double)(end_time.QuadPart -
1089 start_time.QuadPart) / frequency.QuadPart;
1090#endif
1091 if (elapsed_time > kls->stats.worst_pushcall_time) {
1092 kls->stats.worst_pushcall_time = elapsed_time;
1093 }
1094 }
1095#endif
1096 if (kls->conf.kls_collect_stats == 1) {
1097 kls->stats.tot_pushes += 1;
1098 }
1099 return p;
1100}
1101
1111#ifndef KOLISEO_HAS_LOCATE
1112void *kls_push_zero_ext(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1113 ptrdiff_t count)
1114#else
1115void *kls_push_zero_ext_dbg(Koliseo *kls, ptrdiff_t size, ptrdiff_t align,
1116 ptrdiff_t count, Koliseo_Loc loc)
1117#endif // KOLISEO_HAS_LOCATE
1118{
1119
1120#ifdef KLS_DEBUG_CORE
1121#ifndef _WIN32
1122 struct timespec start_time, end_time;
1123 clock_gettime(CLOCK_MONOTONIC, &start_time);
1124#else
1125 LARGE_INTEGER start_time, end_time, frequency;
1126 QueryPerformanceFrequency(&frequency);
1127 QueryPerformanceCounter(&start_time);
1128#endif
1129#endif
1130
1131 if (kls == NULL) {
1132 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1133 exit(EXIT_FAILURE);
1134 }
1135 if ((kls->has_temp == 1) && (kls->conf.kls_block_while_has_temp == 1)) {
1136#ifndef KOLISEO_HAS_LOCATE
1137 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", __func__);
1138#else
1139 fprintf(stderr, "[ERROR] " KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.\n", KLS_Loc_Arg(loc), __func__);
1140 kls_log(kls, "ERROR", KLS_Loc_Fmt "[%s()]: Passed Koliseo has an open Koliseo_Temp session.", KLS_Loc_Arg(loc), __func__);
1141 exit(EXIT_FAILURE);
1142#endif // KOLISEO_HAS_LOCATE
1143 return NULL;
1144 }
1145
1146#ifndef KOLISEO_HAS_LOCATE
1147 kls__check_available(kls, size, align, count);
1148#else
1149 kls__check_available_dbg(kls, size, align, count, loc);
1150#endif
1151 ptrdiff_t padding = -kls->offset & (align - 1);
1152 char *p = kls->data + kls->offset + padding;
1153 //Zero new area
1154 memset(p, 0, size * count);
1155 kls->prev_offset = kls->offset;
1156 kls->offset += padding + size * count;
1157
1158 if (kls->hooks.on_push_handler != NULL) {
1159 /*
1160 struct KLS_EXTENSION_AR_DEFAULT_ARGS {
1161 const char* region_name;
1162 size_t region_name_len;
1163 const char* region_desc;
1164 size_t region_desc_len;
1165 int region_type;
1166 };
1167 struct KLS_EXTENSION_AR_DEFAULT_ARGS ar_args = {
1168 .region_name = KOLISEO_DEFAULT_REGION_NAME,
1169 .region_name_len = strlen(KOLISEO_DEFAULT_REGION_NAME),
1170 .region_desc = KOLISEO_DEFAULT_REGION_DESC,
1171 .region_desc_len = strlen(KOLISEO_DEFAULT_REGION_DESC),
1172 .region_type = KLS_None
1173 };
1174 kls->hooks.on_push_handler(kls, padding, (void*)&ar_args);
1175 */
1176 kls->hooks.on_push_handler(kls, padding, __func__, NULL);
1177 }
1178
1179 char h_size[200];
1180 kls_formatSize(size * count, h_size, sizeof(h_size));
1181 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1182 //kls_log("KLS",msg);
1183#ifdef KLS_DEBUG_CORE
1184 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
1185 kls_log(kls, "KLS", "API Level { %i } -> Pushed zeroes, size (%s) for KLS.",
1186 int_koliseo_version(), h_size);
1187 if (kls->conf.kls_verbose_lvl > 0) {
1188 print_kls_2file(kls->conf.kls_log_fp, kls);
1189 }
1190 if (kls->conf.kls_collect_stats == 1) {
1191#ifndef _WIN32
1192 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1193 double elapsed_time =
1194 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1195 start_time.tv_nsec) / 1e9;
1196#else
1197 QueryPerformanceCounter(&end_time); // %.7f
1198 double elapsed_time =
1199 (double)(end_time.QuadPart -
1200 start_time.QuadPart) / frequency.QuadPart;
1201#endif
1202 if (elapsed_time > kls->stats.worst_pushcall_time) {
1203 kls->stats.worst_pushcall_time = elapsed_time;
1204 }
1205 }
1206#endif
1207 if (kls->conf.kls_collect_stats == 1) {
1208 kls->stats.tot_pushes += 1;
1209 }
1210 return p;
1211}
1212
1223#ifndef KOLISEO_HAS_LOCATE
1224void *kls_temp_push_zero_ext(Koliseo_Temp *t_kls, ptrdiff_t size,
1225 ptrdiff_t align, ptrdiff_t count)
1226#else
1227void *kls_temp_push_zero_ext_dbg(Koliseo_Temp *t_kls, ptrdiff_t size,
1228 ptrdiff_t align, ptrdiff_t count, Koliseo_Loc loc)
1229#endif // KOLISEO_HAS_LOCATE
1230{
1231
1232#ifdef KLS_DEBUG_CORE
1233#ifndef _WIN32
1234 struct timespec start_time, end_time;
1235 clock_gettime(CLOCK_MONOTONIC, &start_time);
1236#else
1237 LARGE_INTEGER start_time, end_time, frequency;
1238 QueryPerformanceFrequency(&frequency);
1239 QueryPerformanceCounter(&start_time);
1240#endif
1241#endif
1242
1243 if (t_kls == NULL) {
1244 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1245 __func__);
1246 exit(EXIT_FAILURE);
1247 }
1248 Koliseo *kls = t_kls->kls;
1249 if (kls == NULL) {
1250 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1251 __func__);
1252 exit(EXIT_FAILURE);
1253 }
1254#ifndef KOLISEO_HAS_LOCATE
1255 kls__check_available(kls, size, align, count);
1256#else
1257 kls__check_available_dbg(kls, size, align, count, loc);
1258#endif
1259 ptrdiff_t padding = -kls->offset & (align - 1);
1260 char *p = kls->data + kls->offset + padding;
1261 //Zero new area
1262 memset(p, 0, size * count);
1263 kls->prev_offset = kls->offset;
1264 kls->offset += padding + size * count;
1265
1266 if (kls->hooks.on_temp_push_handler != NULL) {
1267 // Call on_temp_push extension with empty user arg
1268 kls->hooks.on_temp_push_handler(t_kls, padding, __func__, NULL);
1269 }
1270
1271 char h_size[200];
1272 kls_formatSize(size * count, h_size, sizeof(h_size));
1273 //sprintf(msg,"Pushed zeroes, size (%li) for KLS.",size);
1274 //kls_log("KLS",msg);
1275#ifdef KLS_DEBUG_CORE
1276 if (kls->conf.kls_collect_stats == 1) {
1277#ifndef _WIN32
1278 clock_gettime(CLOCK_MONOTONIC, &end_time); // %.9f
1279 double elapsed_time =
1280 (end_time.tv_sec - start_time.tv_sec) + (end_time.tv_nsec -
1281 start_time.tv_nsec) / 1e9;
1282#else
1283 QueryPerformanceCounter(&end_time); // %.7f
1284 double elapsed_time =
1285 (double)(end_time.QuadPart -
1286 start_time.QuadPart) / frequency.QuadPart;
1287#endif
1288 if (elapsed_time > kls->stats.worst_pushcall_time) {
1289 kls->stats.worst_pushcall_time = elapsed_time;
1290 }
1291 }
1292 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
1293 kls_log(kls, "KLS",
1294 "API Level { %i } -> Pushed zeroes, size (%s) for Temp_KLS.",
1295 int_koliseo_version(), h_size);
1296 if (kls->conf.kls_verbose_lvl > 0) {
1297 print_kls_2file(kls->conf.kls_log_fp, kls);
1298 }
1299#endif
1300 if (kls->conf.kls_collect_stats == 1) {
1301 kls->stats.tot_temp_pushes += 1;
1302 }
1303 return p;
1304}
1305
1311void print_kls_2file(FILE *fp, const Koliseo *kls)
1312{
1313 if (fp == NULL) {
1314 fprintf(stderr, "print_kls_2file(): fp was NULL.\n");
1315 return;
1316 }
1317 if (kls == NULL) {
1318 fprintf(fp, "[KLS] kls was NULL.\n");
1319 } else {
1320 fprintf(fp, "\n[KLS] API Level: { %i }\n", int_koliseo_version());
1321 fprintf(fp, "\n[INFO] Conf: { " KLS_Conf_Fmt " }\n",
1322 KLS_Conf_Arg(kls->conf));
1323 fprintf(fp, "\n[INFO] Stats: { " KLS_Stats_Fmt " }\n",
1324 KLS_Stats_Arg(kls->stats));
1325 fprintf(fp, "\n[KLS] Size: { %td }\n", kls->size);
1326 char human_size[200];
1327 char curr_size[200];
1328 kls_formatSize(kls->size, human_size, sizeof(human_size));
1329 fprintf(fp, "[KLS] Size (Human): { %s }\n", human_size);
1330 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1331 fprintf(fp, "[KLS] Used (Human): { %s }\n", curr_size);
1332 fprintf(fp, "[KLS] Offset: { %td }\n", kls->offset);
1333 fprintf(fp, "[KLS] Prev_Offset: { %td }\n", kls->prev_offset);
1334 fprintf(fp, "\n");
1335 }
1336}
1337
1342void print_dbg_kls(const Koliseo *kls)
1343{
1344 if (kls == NULL) {
1345 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1346 exit(EXIT_FAILURE);
1347 }
1348 print_kls_2file(stderr, kls);
1349}
1350
1356void print_temp_kls_2file(FILE *fp, const Koliseo_Temp *t_kls)
1357{
1358 if (fp == NULL) {
1359 fprintf(stderr, "print_temp_kls_2file(): fp was NULL.\n");
1360 exit(EXIT_FAILURE);
1361 }
1362 if (t_kls == NULL) {
1363 fprintf(fp, "[KLS_T] t_kls was NULL.");
1364 } else if (t_kls->kls == NULL) {
1365 fprintf(fp, "[KLS_T] [%s()]: Referred Koliseo was NULL.\n", __func__);
1366 } else {
1367 const Koliseo *kls = t_kls->kls;
1368 fprintf(fp, "\n[KLS_T] API Level: { %i }\n", int_koliseo_version());
1369 fprintf(fp, "\n[KLS_T] Temp Size: { %td }\n",
1370 kls->size - t_kls->offset);
1371 fprintf(fp, "\n[KLS_T] Refer Size: { %td }\n", kls->size);
1372 char human_size[200];
1373 char curr_size[200];
1374 kls_formatSize(kls->size - t_kls->offset, human_size,
1375 sizeof(human_size));
1376 fprintf(fp, "[KLS_T] Temp Size Human: { %s }\n", human_size);
1377 kls_formatSize(kls->size, human_size, sizeof(human_size));
1378 fprintf(fp, "[KLS_T] Refer Size Human: { %s }\n", human_size);
1379 kls_formatSize(kls->offset, curr_size, sizeof(curr_size));
1380 fprintf(fp, "[KLS_T] Inner Used (Human): { %s }\n", curr_size);
1381 kls_formatSize(t_kls->offset, curr_size, sizeof(curr_size));
1382 fprintf(fp, "[KLS_T] Temp Used (Human): { %s }\n", curr_size);
1383 fprintf(fp, "[KLS_T] Inner Offset: { %td }\n", kls->offset);
1384 fprintf(fp, "[KLS_T] Temp Offset: { %td }\n", t_kls->offset);
1385 fprintf(fp, "[KLS_T] Inner Prev_Offset: { %td }\n", kls->prev_offset);
1386 fprintf(fp, "[KLS_T] Temp Prev_Offset: { %td }\n\n",
1387 t_kls->prev_offset);
1388 }
1389}
1390
1395void print_dbg_temp_kls(const Koliseo_Temp *t_kls)
1396{
1397 print_temp_kls_2file(stderr, t_kls);
1398}
1399
1407void kls_formatSize(ptrdiff_t size, char *outputBuffer, size_t bufferSize)
1408{
1409 const char *units[] =
1410 { "bytes", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB" };
1411 const int numUnits = sizeof(units) / sizeof(units[0]);
1412
1413 int unitIndex = 0;
1414 double sizeValue = (double)size;
1415
1416 while (sizeValue >= 1000 && unitIndex < numUnits - 1) {
1417 sizeValue /= 1000;
1418 unitIndex++;
1419 }
1420
1421 snprintf(outputBuffer, bufferSize, "%.2f %s", sizeValue, units[unitIndex]);
1422}
1423
1429void kls_clear(Koliseo *kls)
1430{
1431 if (kls == NULL) {
1432 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1433 exit(EXIT_FAILURE);
1434 }
1435 //Reset pointer
1436 kls->prev_offset = kls->offset;
1437 kls->offset = sizeof(*kls);
1438#ifdef KLS_DEBUG_CORE
1439 kls_log(kls, "KLS", "API Level { %i } -> Cleared offsets for KLS.",
1441#endif
1442}
1443
1449void kls_free(Koliseo *kls)
1450{
1451 if (kls == NULL) {
1452 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1453 exit(EXIT_FAILURE);
1454 }
1455 if (kls->hooks.on_free_handler != NULL) {
1456 // Call on_free() extension
1457 kls->hooks.on_free_handler(kls);
1458 }
1459 if (kls->has_temp == 1) {
1460#ifdef KLS_DEBUG_CORE
1461 kls_log(kls, "KLS",
1462 "API Level { %i } -> KLS had an active Koliseo_Temp.",
1464#endif
1465 kls_temp_end(kls->t_kls);
1466 }
1467 kls_clear(kls);
1468#ifdef KLS_DEBUG_CORE
1469 kls_log(kls, "KLS", "API Level { %i } -> Freeing KLS.",
1471#endif
1472 if (kls->conf.kls_log_fp != NULL && kls->conf.kls_log_fp != stdout
1473 && kls->conf.kls_log_fp != stderr) {
1474#ifdef KLS_DEBUG_CORE
1475 kls_log(kls, "KLS", "Closing kls log file. Path: {\"%s\"}.",
1476 kls->conf.kls_log_filepath);
1477#endif
1478 int close_res = fclose(kls->conf.kls_log_fp);
1479 if (close_res != 0) {
1480 fprintf(stderr,
1481 "[ERROR] %s(): Failed fclose() on log_fp. Path: {\"%s\"}.",
1482 __func__, kls->conf.kls_log_filepath);
1483 }
1484 } else if (kls->conf.kls_log_fp == stdout || kls->conf.kls_log_fp == stderr) {
1485 if (kls->conf.kls_verbose_lvl > 1) {
1486 fprintf(stderr,
1487 "[INFO] %s(): kls->conf.kls_log_fp is %s. Not closing it.\n",
1488 __func__,
1489 (kls->conf.kls_log_fp == stdout ? "stdout" : "stderr"));
1490 }
1491 }
1492 free(kls);
1493}
1494
1502#ifndef KOLISEO_HAS_LOCATE
1503Koliseo_Temp *kls_temp_start(Koliseo *kls)
1504#else
1505Koliseo_Temp *kls_temp_start_dbg(Koliseo *kls, Koliseo_Loc loc)
1506#endif // KOLISEO_HAS_LOCATE
1507{
1508 if (kls == NULL) {
1509 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1510 exit(EXIT_FAILURE);
1511 }
1512 if (kls->has_temp != 0) {
1513 fprintf(stderr,
1514 "[ERROR] [%s()]: Passed Koliseo->has_temp is not 0. {%i}\n",
1515 __func__, kls->has_temp);
1516#ifdef KLS_DEBUG_CORE
1517 kls_log(kls, "ERROR", "[%s()]: Passed Koliseo->has_temp != 0 . {%i}",
1518 __func__, kls->has_temp);
1519#endif
1520 if (kls->conf.kls_collect_stats == 1) {
1521 kls->stats.tot_hiccups += 1;
1522 }
1523 return NULL;
1524 }
1525 ptrdiff_t prev = kls->prev_offset;
1526 ptrdiff_t off = kls->offset;
1527
1528 Koliseo_Temp *tmp = KLS_PUSH(kls, Koliseo_Temp);
1529 tmp->kls = kls;
1530 tmp->prev_offset = prev;
1531 tmp->offset = off;
1532#ifdef KLS_DEBUG_CORE
1533 kls_log(kls, "INFO", "Passed kls conf: " KLS_Conf_Fmt "\n",
1534 KLS_Conf_Arg(kls->conf));
1535#endif
1536
1537 kls->has_temp = 1;
1538 kls->t_kls = tmp;
1539 if (kls->hooks.on_temp_start_handler != NULL) {
1540 // Call on_temp_start extension
1541 kls->hooks.on_temp_start_handler(tmp);
1542 }
1543#ifdef KLS_DEBUG_CORE
1544 kls_log(kls, "KLS", "Prepared new Temp KLS.");
1545#endif
1546 return tmp;
1547}
1548
1553void kls_temp_end(Koliseo_Temp *tmp_kls)
1554{
1555 if (tmp_kls == NULL) {
1556 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1557 __func__);
1558 exit(EXIT_FAILURE);
1559 }
1560
1561 Koliseo *kls_ref = tmp_kls->kls;
1562 if (kls_ref == NULL) {
1563 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1564 __func__);
1565 exit(EXIT_FAILURE);
1566 }
1567
1568 if (kls_ref->hooks.on_temp_free_handler != NULL) {
1569 // Call on_temp_free() extension
1570 kls_ref->hooks.on_temp_free_handler(tmp_kls);
1571 }
1572
1573#ifdef KLS_DEBUG_CORE
1574 kls_log(kls_ref, "KLS", "Ended Temp KLS.");
1575#endif
1576 tmp_kls->kls->has_temp = 0;
1577 tmp_kls->kls->t_kls = NULL;
1578 tmp_kls->kls->prev_offset = tmp_kls->prev_offset;
1579 tmp_kls->kls->offset = tmp_kls->offset;
1580 tmp_kls = NULL; // statement with no effect TODO: Clear tmp_kls from caller
1581 if (kls_ref->conf.kls_collect_stats == 1) {
1582 kls_ref->stats.tot_temp_pushes = 0;
1583 kls_ref->stats.tot_temp_pops = 0;
1584 }
1585}
1586
1587#ifdef KOLISEO_HAS_EXPER
1596void *kls_pop(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1597{
1598 if (kls == NULL) {
1599 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1600 exit(EXIT_FAILURE);
1601 }
1602 ptrdiff_t padding = -kls->offset & (align - 1);
1603 if (count > PTRDIFF_MAX / size
1604 || (kls->size + kls->offset) < (size * count)) {
1605 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1606 kls_free(kls);
1607 exit(EXIT_FAILURE);
1608 }
1609 char *p = kls->data + kls->offset - padding - size * count;
1610 kls->prev_offset = kls->offset;
1611 kls->offset -= padding + size * count;
1612#ifdef KLS_DEBUG_CORE
1613 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
1614 int_koliseo_version(), size);
1615 if (kls->conf.kls_verbose_lvl > 0) {
1616 print_kls_2file(kls->conf.kls_log_fp, kls);
1617 }
1618#endif
1619 if (kls->conf.kls_collect_stats == 1) {
1620 kls->stats.tot_pops += 1;
1621 }
1622 return p;
1623}
1624
1633void *kls_pop_AR(Koliseo *kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1634{
1635 if (kls == NULL) {
1636 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo was NULL.\n", __func__);
1637 exit(EXIT_FAILURE);
1638 }
1639 ptrdiff_t padding = -kls->offset & (align - 1);
1640 if (count > PTRDIFF_MAX / size
1641 || (kls->size + kls->offset) < (size * count)) {
1642 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1643 kls_free(kls);
1644 exit(EXIT_FAILURE);
1645 }
1646 char *p = kls->data + kls->offset - padding - size * count;
1647 kls->prev_offset = kls->offset;
1648 kls->offset -= padding + size * count;
1649#ifdef KLS_DEBUG_CORE
1650 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for KLS.",
1651 int_koliseo_version(), size);
1652 if (kls->conf.kls_verbose_lvl > 0) {
1653 print_kls_2file(kls->conf.kls_log_fp, kls);
1654 }
1655#endif
1656 if (kls->conf.kls_collect_stats == 1) {
1657 kls->stats.tot_pops += 1;
1658 }
1659 return p;
1660}
1661
1670void *kls_temp_pop(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align,
1671 ptrdiff_t count)
1672{
1673 if (t_kls == NULL) {
1674 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1675 __func__);
1676 exit(EXIT_FAILURE);
1677 }
1678 Koliseo *kls = t_kls->kls;
1679 if (kls == NULL) {
1680 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1681 __func__);
1682 exit(EXIT_FAILURE);
1683 }
1684 ptrdiff_t padding = -kls->offset & (align - 1);
1685 if (count > PTRDIFF_MAX / size
1686 || (kls->size + kls->offset) < (size * count)) {
1687 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1688 kls_free(kls);
1689 exit(EXIT_FAILURE);
1690 }
1691 char *p = kls->data + kls->offset - padding - size * count;
1692 kls->prev_offset = kls->offset;
1693 kls->offset -= padding + size * count;
1694#ifdef KLS_DEBUG_CORE
1695 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
1696 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
1697 int_koliseo_version(), size);
1698 if (kls->conf.kls_verbose_lvl > 0) {
1699 print_kls_2file(kls->conf.kls_log_fp, kls);
1700 }
1701#endif
1702 if (kls->conf.kls_collect_stats == 1) {
1703 kls->stats.tot_temp_pops += 1;
1704 }
1705 return p;
1706}
1707
1716void *kls_temp_pop_AR(Koliseo_Temp *t_kls, ptrdiff_t size, ptrdiff_t align, ptrdiff_t count)
1717{
1718 if (t_kls == NULL) {
1719 fprintf(stderr, "[ERROR] [%s()]: Passed Koliseo_Temp was NULL.\n",
1720 __func__);
1721 exit(EXIT_FAILURE);
1722 }
1723 Koliseo *kls = t_kls->kls;
1724 if (kls == NULL) {
1725 fprintf(stderr, "[ERROR] [%s()]: Referred Koliseo was NULL.\n",
1726 __func__);
1727 exit(EXIT_FAILURE);
1728 }
1729 ptrdiff_t padding = -kls->offset & (align - 1);
1730 if (count > PTRDIFF_MAX / size
1731 || (kls->size + kls->offset) < (size * count)) {
1732 fprintf(stderr, "[KLS] Failed %s() call.\n", __func__);
1733 kls_free(kls);
1734 exit(EXIT_FAILURE);
1735 }
1736 char *p = kls->data + kls->offset - padding - size * count;
1737 kls->prev_offset = kls->offset;
1738 kls->offset -= padding + size * count;
1739#ifdef KLS_DEBUG_CORE
1740 kls_log(kls, "KLS", "Curr offset: { %p }.", kls + kls->offset);
1741 kls_log(kls, "KLS", "API Level { %i } -> Popped (%li) for Temp_KLS.",
1742 int_koliseo_version(), size);
1743 if (kls->conf.kls_verbose_lvl > 0) {
1744 print_kls_2file(kls->conf.kls_log_fp, kls);
1745 }
1746#endif
1747 if (kls->conf.kls_collect_stats == 1) {
1748 kls->stats.tot_temp_pops += 1;
1749 }
1750 return p;
1751}
1752
1759char* kls_strdup(Koliseo* kls, char* source)
1760{
1761 char* dest = KLS_PUSH_STR(kls, source);
1762 KLS__STRCPY(dest, source);
1763 return dest;
1764}
1765
1772char** kls_strdup_arr(Koliseo* kls, size_t count, char** source)
1773{
1774 char** strings = NULL;
1775 strings = KLS_PUSH_ARR(kls, char*, count);
1776 for (int i=0; i < count; i++) {
1777 strings[i] = KLS_STRDUP(kls, source[i]);
1778 }
1779 return strings;
1780}
1781
1788char* kls_t_strdup(Koliseo_Temp* t_kls, char* source)
1789{
1790 char* dest = KLS_PUSH_STR_T(t_kls, source);
1791 KLS__STRCPY(dest, source);
1792 return dest;
1793}
1794
1801char** kls_t_strdup_arr(Koliseo_Temp* t_kls, size_t count, char** source)
1802{
1803 char** strings = NULL;
1804 strings = KLS_PUSH_ARR_T(t_kls, char*, count);
1805 for (int i=0; i < count; i++) {
1806 strings[i] = KLS_STRDUP_T(t_kls, source[i]);
1807 }
1808 return strings;
1809}
1810#endif // KOLISEO_HAS_EXPER
#define KLS_DEFAULT_HOOKS
Definition kls_region.h:161
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:1759
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:1670
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:1503
void print_dbg_temp_kls(const Koliseo_Temp *t_kls)
Prints header fields from the passed Koliseo_Temp pointer, to stderr.
Definition koliseo.c:1395
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:1356
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:1788
KLS_Stats KLS_STATS_DEFAULT
Definition koliseo.c:40
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:292
void kls_temp_end(Koliseo_Temp *tmp_kls)
Ends passed Koliseo_Temp pointer.
Definition koliseo.c:1553
void kls_dbg_features(void)
Prints enabled Koliseo features to stderr.
Definition koliseo.c:228
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:1772
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:1224
void print_dbg_kls(const Koliseo *kls)
Prints header fields from the passed Koliseo pointer, to stderr.
Definition koliseo.c:1342
const char * string_koliseo_version(void)
Returns the constant string representing current version for Koliseo.
Definition koliseo.c:58
Koliseo * kls_new_dbg_alloc(ptrdiff_t size, kls_alloc_func alloc_func)
Takes a ptrdiff_t size and an allocation function pointer, and returns a pointer to the prepared Koli...
Definition koliseo.c:575
ptrdiff_t kls_get_pos(const Koliseo *kls)
Returns the current offset (position of pointer bumper) for the passed Koliseo.
Definition koliseo.c:281
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:1716
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:1633
Koliseo * kls_new_conf_alloc(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func)
Takes a ptrdiff_t size, a KLS_Conf to configure the new Koliseo, and an allocation function pointer.
Definition koliseo.c:474
void kls_free(Koliseo *kls)
Calls kls_clear() on the passed Koliseo pointer and the frees the actual Koliseo.
Definition koliseo.c:1449
Koliseo * kls_new_traced_alloc(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func)
Takes a ptrdiff_t size, a filepath for the trace output file, and an allocation function pointer.
Definition koliseo.c:526
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:1801
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:944
Koliseo * kls_new_dbg_alloc_handled(ptrdiff_t size, kls_alloc_func alloc_func, KLS_Err_Handlers err_handlers)
Takes a ptrdiff_t size and an allocation function pointer, and returns a pointer to the prepared Koli...
Definition koliseo.c:543
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:1023
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:702
Koliseo * kls_new_alloc(ptrdiff_t size, kls_alloc_func alloc_func)
Takes a ptrdiff_t size and a function pointer to the allocation function.
Definition koliseo.c:419
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:1596
void KLS_PTRDIFF_MAX_default_handler__(struct Koliseo *kls, ptrdiff_t size, ptrdiff_t count)
Definition koliseo.c:102
KLS_Conf KLS_DEFAULT_CONF
Config used by any new Koliseo by default.
Definition koliseo.c:20
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:144
Koliseo * kls_new_conf_alloc_ext(ptrdiff_t size, KLS_Conf conf, kls_alloc_func alloc_func, KLS_Hooks ext_handlers, void *user)
Takes a ptrdiff_t size, a KLS_Conf to configure the new Koliseo, and an allocation function pointer.
Definition koliseo.c:446
Koliseo * kls_new_traced_alloc_handled(ptrdiff_t size, const char *output_path, kls_alloc_func alloc_func, KLS_Err_Handlers err_handlers)
Takes a ptrdiff_t size, a filepath for the trace output file, and an allocation function pointer.
Definition koliseo.c:492
KLS_Conf kls_conf_init(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, FILE *log_fp, const char *log_filepath)
Used to prepare a KLS_Conf without caring about KOLISEO_HAS_REGIONS.
Definition koliseo.c:219
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:1311
KLS_Conf kls_conf_init_handled(int autoset_regions, int alloc_backend, ptrdiff_t reglist_kls_size, int autoset_temp_regions, int collect_stats, int verbose_lvl, int block_while_has_temp, int allow_zerocount_push, 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:168
Koliseo * kls_new_alloc_ext(ptrdiff_t size, kls_alloc_func alloc_func, KLS_Hooks ext_handlers, void *user)
Takes a ptrdiff_t size and a function pointer to the allocation function.
Definition koliseo.c:338
void kls_clear(Koliseo *kls)
Resets the offset field for the passed Koliseo pointer.
Definition koliseo.c:1429
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:1112
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:1407
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:82
int int_koliseo_version(void)
Returns the constant int representing current version for Koliseo.
Definition koliseo.c:67