diff --git a/3rdparty/rmalloc.h b/3rdparty/rmalloc.h new file mode 100644 index 0000000..444b155 --- /dev/null +++ b/3rdparty/rmalloc.h @@ -0,0 +1,145 @@ +#ifndef RMALLOC_H +#define RMALLOC_H +#ifndef RMALLOC_OVERRIDE +#define RMALLOC_OVERRIDE 1 +#endif +#ifdef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE_TEMP _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif +#ifndef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#endif +#ifndef ulonglong +#define ulonglong unsigned long long +#endif +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <locale.h> +#include "rtemp.h" +#ifdef _POSIX_C_SOURCE_TEMP +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE _POSIX_C_SOURCE_TEMP +#undef _POSIX_C_SOURCE_TEMP +#else +#undef _POSIX_C_SOURCE +#endif +ulonglong rmalloc_count = 0; +ulonglong rmalloc_alloc_count = 0; +ulonglong rmalloc_free_count = 0; +ulonglong rmalloc_total_bytes_allocated = 0; + +void *_rmalloc_prev_realloc_obj = NULL; +size_t _rmalloc_prev_realloc_obj_size = 0; + +void *rmalloc(size_t size) { + void *result; + while (!(result = malloc(size))) { + fprintf(stderr, "Warning: malloc failed, trying again.\n"); + } + rmalloc_count++; + rmalloc_alloc_count++; + rmalloc_total_bytes_allocated += size; + return result; +} +void *rcalloc(size_t count, size_t size) { + void *result; + while (!(result = calloc(count, size))) { + fprintf(stderr, "Warning: calloc failed, trying again.\n"); + } + rmalloc_alloc_count++; + rmalloc_count++; + rmalloc_total_bytes_allocated += count * size; + return result; +} +void *rrealloc(void *obj, size_t size) { + if (!obj) { + rmalloc_count++; + } + + rmalloc_alloc_count++; + if (obj == _rmalloc_prev_realloc_obj) { + rmalloc_total_bytes_allocated += size - _rmalloc_prev_realloc_obj_size; + _rmalloc_prev_realloc_obj_size = size - _rmalloc_prev_realloc_obj_size; + + } else { + _rmalloc_prev_realloc_obj_size = size; + } + void *result; + while (!(result = realloc(obj, size))) { + fprintf(stderr, "Warning: realloc failed, trying again.\n"); + } + _rmalloc_prev_realloc_obj = result; + + return result; +} + +char *rstrdup(const char *s) { + if (!s) + return NULL; + + char *result; + size_t size = strlen(s) + 1; + + result = rmalloc(size); + memcpy(result, s, size); + rmalloc_total_bytes_allocated += size; + return result; +} +void *rfree(void *obj) { + rmalloc_count--; + rmalloc_free_count++; + free(obj); + return NULL; +} + +#if RMALLOC_OVERRIDE +#define malloc rmalloc +#define calloc rcalloc +#define realloc rrealloc +#define free rfree +#define strdup rstrdup +#endif + +char *rmalloc_lld_format(ulonglong num) { + + char res[100]; + res[0] = 0; + sprintf(res, "%'lld", num); + char *resp = res; + while (*resp) { + if (*resp == ',') + *resp = '.'; + resp++; + } + return sbuf(res); +} + +char *rmalloc_bytes_format(int factor, ulonglong num) { + char *sizes[] = {"B", "KB", "MB", "GB", "TB", "PB", "EB", "ZB", "YB"}; + if (num > 1024) { + return rmalloc_bytes_format(factor + 1, num / 1024); + } + char res[100]; + sprintf(res, "%s %s", rmalloc_lld_format(num), sizes[factor]); + return sbuf(res); +} + +char *rmalloc_stats() { + static char res[200]; + res[0] = 0; + // int original_locale = localeconv(); + setlocale(LC_NUMERIC, "en_US.UTF-8"); + sprintf(res, "Memory usage: %s, %s (re)allocated, %s unqiue free'd, %s in use.", rmalloc_bytes_format(0, rmalloc_total_bytes_allocated), + rmalloc_lld_format(rmalloc_alloc_count), rmalloc_lld_format(rmalloc_free_count), + + rmalloc_lld_format(rmalloc_count)); + // setlocale(LC_NUMERIC, original_locale); + + setlocale(LC_NUMERIC, ""); + return res; +} + +#endif diff --git a/3rdparty/rprint.h b/3rdparty/rprint.h new file mode 100644 index 0000000..2b615ee --- /dev/null +++ b/3rdparty/rprint.h @@ -0,0 +1,287 @@ +#ifndef RPRINT_H +#define RPRINT_H +#include "rtime.h" +#include <stdarg.h> +#include <stdbool.h> +#include <stdio.h> +#include <stdlib.h> +#include <unistd.h> + +long rpline_number = 0; +nsecs_t rprtime = 0; + +int8_t _env_rdisable_colors = -1; +bool _rprint_enable_colors = true; + +bool rprint_is_color_enabled() { + if (_env_rdisable_colors == -1) { + _env_rdisable_colors = getenv("RDISABLE_COLORS") != NULL; + } + if (_env_rdisable_colors) { + _rprint_enable_colors = false; + } + return _rprint_enable_colors; +} + +void rprint_disable_colors() { _rprint_enable_colors = false; } +void rprint_enable_colors() { _rprint_enable_colors = true; } +void rprint_toggle_colors() { _rprint_enable_colors = !_rprint_enable_colors; } + +void rclear() { printf("\033[2J"); } + +void rprintpf(FILE *f, const char *prefix, const char *format, va_list args) { + char *pprefix = (char *)prefix; + char *pformat = (char *)format; + bool reset_color = false; + bool press_any_key = false; + char new_format[4096]; + bool enable_color = rprint_is_color_enabled(); + memset(new_format, 0, 4096); + int new_format_length = 0; + char temp[1000]; + memset(temp, 0, 1000); + if (enable_color && pprefix[0]) { + strcat(new_format, pprefix); + new_format_length += strlen(pprefix); + reset_color = true; + } + while (true) { + if (pformat[0] == '\\' && pformat[1] == 'i') { + strcat(new_format, "\e[3m"); + new_format_length += strlen("\e[3m"); + reset_color = true; + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 'u') { + strcat(new_format, "\e[4m"); + new_format_length += strlen("\e[4m"); + reset_color = true; + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 'b') { + strcat(new_format, "\e[1m"); + new_format_length += strlen("\e[1m"); + reset_color = true; + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 'C') { + press_any_key = true; + rpline_number++; + pformat++; + pformat++; + reset_color = false; + } else if (pformat[0] == '\\' && pformat[1] == 'k') { + press_any_key = true; + rpline_number++; + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 'c') { + rpline_number++; + strcat(new_format, "\e[2J\e[H"); + new_format_length += strlen("\e[2J\e[H"); + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 'L') { + rpline_number++; + temp[0] = 0; + sprintf(temp, "%ld", rpline_number); + strcat(new_format, temp); + new_format_length += strlen(temp); + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 'l') { + rpline_number++; + temp[0] = 0; + sprintf(temp, "%.5ld", rpline_number); + strcat(new_format, temp); + new_format_length += strlen(temp); + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 'T') { + nsecs_t nsecs_now = nsecs(); + nsecs_t end = rprtime ? nsecs_now - rprtime : 0; + temp[0] = 0; + sprintf(temp, "%s", format_time(end)); + strcat(new_format, temp); + new_format_length += strlen(temp); + rprtime = nsecs_now; + pformat++; + pformat++; + } else if (pformat[0] == '\\' && pformat[1] == 't') { + rprtime = nsecs(); + pformat++; + pformat++; + } else { + new_format[new_format_length] = *pformat; + new_format_length++; + if (!*pformat) + break; + + // printf("%c",*pformat); + pformat++; + } + } + if (reset_color) { + strcat(new_format, "\e[0m"); + new_format_length += strlen("\e[0m"); + } + + new_format[new_format_length] = 0; + vfprintf(f, new_format, args); + + fflush(stdout); + if (press_any_key) { + nsecs_t s = nsecs(); + fgetc(stdin); + rprtime += nsecs() - s; + } +} + +void rprintp(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "", format, args); + va_end(args); +} + +void rprintf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "", format, args); + va_end(args); +} +void rprint(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "", format, args); + va_end(args); +} +#define printf rprint + +// Print line +void rprintlf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\\l", format, args); + va_end(args); +} +void rprintl(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\\l", format, args); + va_end(args); +} + +// Black +void rprintkf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[30m", format, args); + va_end(args); +} +void rprintk(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[30m", format, args); + va_end(args); +} + +// Red +void rprintrf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[31m", format, args); + va_end(args); +} +void rprintr(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[31m", format, args); + va_end(args); +} + +// Green +void rprintgf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[32m", format, args); + va_end(args); +} +void rprintg(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[32m", format, args); + va_end(args); +} + +// Yellow +void rprintyf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[33m", format, args); + va_end(args); +} +void rprinty(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[33m", format, args); + va_end(args); +} + +// Blue +void rprintbf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[34m", format, args); + va_end(args); +} + +void rprintb(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[34m", format, args); + va_end(args); +} + +// Magenta +void rprintmf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[35m", format, args); + va_end(args); +} +void rprintm(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[35m", format, args); + va_end(args); +} + +// Cyan +void rprintcf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[36m", format, args); + va_end(args); +} +void rprintc(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[36m", format, args); + va_end(args); +} + +// White +void rprintwf(FILE *f, const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(f, "\e[37m", format, args); + va_end(args); +} +void rprintw(const char *format, ...) { + va_list args; + va_start(args, format); + rprintpf(stdout, "\e[37m", format, args); + va_end(args); +} +#endif \ No newline at end of file diff --git a/3rdparty/rtemp.h b/3rdparty/rtemp.h new file mode 100644 index 0000000..2d7f99a --- /dev/null +++ b/3rdparty/rtemp.h @@ -0,0 +1,53 @@ +#ifndef RTEMP_H +#define RTEMP_H +#include "rtypes.h" +#include <pthread.h> +#ifndef RTEMPC_SLOT_COUNT +#define RTEMPC_SLOT_COUNT 20 +#endif +#ifndef RTEMPC_SLOT_SIZE +#define RTEMPC_SLOT_SIZE 1024 * 64 * 128 +#endif + +bool _rtempc_initialized = 0; +pthread_mutex_t _rtempc_thread_lock; +bool rtempc_use_mutex = true; +byte _current_rtempc_slot = 1; +char _rtempc_buffer[RTEMPC_SLOT_COUNT][RTEMPC_SLOT_SIZE]; +char *rtempc(char *data) { + + if (rtempc_use_mutex) { + if (!_rtempc_initialized) { + _rtempc_initialized = true; + pthread_mutex_init(&_rtempc_thread_lock, NULL); + } + + pthread_mutex_lock(&_rtempc_thread_lock); + } + + uint current_rtempc_slot = _current_rtempc_slot; + _rtempc_buffer[current_rtempc_slot][0] = 0; + strcpy(_rtempc_buffer[current_rtempc_slot], data); + _current_rtempc_slot++; + if (_current_rtempc_slot == RTEMPC_SLOT_COUNT) { + _current_rtempc_slot = 0; + } + if (rtempc_use_mutex) + pthread_mutex_unlock(&_rtempc_thread_lock); + return _rtempc_buffer[current_rtempc_slot]; +} + +#define sstring(_pname, _psize) \ + static char _##_pname[_psize]; \ + _##_pname[0] = 0; \ + char *_pname = _##_pname; + +#define string(_pname, _psize) \ + char _##_pname[_psize]; \ + _##_pname[0] = 0; \ + char *_pname = _##_pname; + +#define sreset(_pname, _psize) _pname = _##_pname; + +#define sbuf(val) rtempc(val) +#endif \ No newline at end of file diff --git a/3rdparty/rtime.h b/3rdparty/rtime.h new file mode 100644 index 0000000..9b05239 --- /dev/null +++ b/3rdparty/rtime.h @@ -0,0 +1,147 @@ + +#ifndef RLIB_TIME +#define RLIB_TIME + +#ifndef _POSIX_C_SOURCE_199309L + +#define _POSIX_C_SOURCE_199309L +#endif +#include "rtemp.h" +#include <sys/time.h> +#include <time.h> +#undef _POSIX_C_SOURCE_199309L +#include <errno.h> +#include <stdint.h> +#include <stdio.h> +#include <string.h> +#ifndef CLOCK_MONOTONIC +#define CLOCK_MONOTONIC 1 +#endif + +typedef uint64_t nsecs_t; +void nsleep(nsecs_t nanoseconds); + +void tick() { nsleep(1); } + +typedef unsigned long long msecs_t; + +nsecs_t nsecs() { + unsigned int lo, hi; + __asm__ volatile("rdtsc" : "=a"(lo), "=d"(hi)); + return ((uint64_t)hi << 32) | lo; +} + +msecs_t rnsecs_to_msecs(nsecs_t nsecs) { return nsecs / 1000 / 1000; } + +nsecs_t rmsecs_to_nsecs(msecs_t msecs) { return msecs * 1000 * 1000; } + +msecs_t usecs() { + struct timeval tv; + gettimeofday(&tv, NULL); + return (long long)(tv.tv_sec) * 1000000 + (long long)(tv.tv_usec); +} + +msecs_t msecs() { + struct timeval tv; + gettimeofday(&tv, NULL); + return (long long)(tv.tv_sec) * 1000 + (tv.tv_usec / 1000); +} +char *msecs_strs(msecs_t ms) { + static char str[22]; + str[0] = 0; + sprintf(str, "%f", ms * 0.001); + for (int i = strlen(str); i > 0; i--) { + if (str[i] > '0') + break; + str[i] = 0; + } + return str; +} +char *msecs_strms(msecs_t ms) { + static char str[22]; + str[0] = 0; + sprintf(str, "%lld", ms); + return str; +} +char *msecs_str(long long ms) { + static char result[30]; + result[0] = 0; + if (ms > 999) { + char *s = msecs_strs(ms); + sprintf(result, "%ss", s); + } else { + char *s = msecs_strms(ms); + sprintf(result, "%sMs", s); + } + return result; +} + +void nsleep(nsecs_t nanoseconds) { + long seconds = 0; + int factor = 0; + while (nanoseconds > 1000000000) { + factor++; + nanoseconds = nanoseconds / 10; + } + if (factor) { + seconds = 1; + factor--; + while (factor) { + seconds = seconds * 10; + factor--; + } + } + + struct timespec req = {seconds, nanoseconds}; + struct timespec rem; + + nanosleep(&req, &rem); +} + +void ssleep(double s) { + long nanoseconds = (long)(1000000000 * s); + + // long seconds = 0; + + // struct timespec req = {seconds, nanoseconds}; + // struct timespec rem; + + nsleep(nanoseconds); +} +void msleep(long miliseonds) { + long nanoseconds = miliseonds * 1000000; + nsleep(nanoseconds); +} + +char *format_time(int64_t nanoseconds) { + char output[1024]; + size_t output_size = sizeof(output); + output[0] = 0; + if (nanoseconds < 1000) { + // Less than 1 microsecond + snprintf(output, output_size, "%ldns", nanoseconds); + } else if (nanoseconds < 1000000) { + // Less than 1 millisecond + double us = nanoseconds / 1000.0; + snprintf(output, output_size, "%.2fµs", us); + } else if (nanoseconds < 1000000000) { + // Less than 1 second + double ms = nanoseconds / 1000000.0; + snprintf(output, output_size, "%.2fms", ms); + } else { + // 1 second or more + double s = nanoseconds / 1000000000.0; + if (s > 60 * 60) { + s = s / 60 / 60; + snprintf(output, output_size, "%.2fh", s); + } else if (s > 60) { + s = s / 60; + snprintf(output, output_size, "%.2fm", s); + } else { + snprintf(output, output_size, "%.2fs", s); + } + } + return sbuf(output); +} + +#endif diff --git a/3rdparty/rtypes.h b/3rdparty/rtypes.h new file mode 100644 index 0000000..76c6214 --- /dev/null +++ b/3rdparty/rtypes.h @@ -0,0 +1,32 @@ + +#ifndef RTYPES_H +#define RTYPES_H +#ifdef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE_TEMP _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif +#ifndef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE 200112L +#endif +#include <stdbool.h> +#include <stdint.h> // uint +#include <sys/types.h> // ulong +#include <string.h> +#ifndef ulonglong +#define ulonglong unsigned long long +#endif +#ifndef uint +typedef unsigned int uint; +#endif +#ifndef byte +typedef unsigned char byte; +#endif +#ifdef _POSIX_C_SOURCE_TEMP +#undef _POSIX_C_SOURCE +#define _POSIX_C_SOURCE _POSIX_C_SOURCE_TEMP +#undef _POSIX_C_SOURCE_TEMP +#else +#undef _POSIX_C_SOURCE +#endif +#endif