diff options
| author | TazyFoundSoup <gardendistrict0x0@outlook.com> | 2026-05-22 09:43:59 +1000 |
|---|---|---|
| committer | TazyFoundSoup <gardendistrict0x0@outlook.com> | 2026-05-22 09:43:59 +1000 |
| commit | 77aa9a3259ddfd6c64534d63424d5b0fa3010900 (patch) | |
| tree | 3744ec77c3cbe164457d1e421fd4bf7dceff4c02 | |
| parent | 4d42b317f4970bd08f9b81fcc184fc015736ff58 (diff) | |
refactor: move benches to include directory
| -rw-r--r-- | Makefile | 46 | ||||
| -rw-r--r-- | bench/README.md | 9 | ||||
| -rw-r--r-- | bench/src/format/image/png.c | 6 | ||||
| -rw-r--r-- | compile_commands.json | 54 | ||||
| -rw-r--r-- | include/bridges/stdio/stream_bridge.h | 2 | ||||
| -rw-r--r-- | include/tinyff/bench/bench.h (renamed from bench/bench.h) | 25 | ||||
| -rw-r--r-- | include/tinyff/common.h | 2 | ||||
| -rw-r--r-- | include/tinyff/dbg.h | 6 | ||||
| -rw-r--r-- | include/tinyff/result.h | 1 | ||||
| -rw-r--r-- | include/tinyff/stream.h | 5 | ||||
| -rw-r--r-- | src/bridges/stdio/stream_bridge.c | 2 | ||||
| -rw-r--r-- | src/dbg.c | 157 | ||||
| -rw-r--r-- | src/format/image/png.c | 16 | ||||
| -rw-r--r-- | tests/format/image/png/png_open.c | 2 |
14 files changed, 246 insertions, 87 deletions
@@ -2,17 +2,18 @@ CC ?= gcc AR ?= ar OUTDIR = build -BENCH_OUT = $(OUTDIR)/bench LIB = libtinyff.a -ALL_CFLAGS = -Wall -Wextra -Werror -std=c11 -Iinclude --coverage +ALL_CFLAGS = -Wall -Wextra -Werror -std=c11 -Iinclude DEBUG_FLAGS = -g -O0 -fno-omit-frame-pointer RELEASE_FLAGS = -O2 SANFLAGS = -fsanitize=address,undefined -g -O1 +COVERAGE_FLAGS = -fprofile-instr-generate -fcoverage-mapping +COVERAGE_LDFLAGS = -fprofile-instr-generate -fcoverage-mapping + SRC = $(shell find src -name "*.c") -BENCH_SRC = $(shell find bench/src -name "*.c") ifeq ($(USE_HOSTED),1) ALL_CFLAGS += -DUSE_HOSTED -Iinclude/bridges @@ -20,8 +21,7 @@ SRC += $(shell find src/bridges -name "*.c") endif ifeq ($(USE_BENCH),1) -ALL_CFLAGS += -DUSE_BENCH -Ibench -SRC += $(shell find bench/src -name "*.c") +ALL_CFLAGS += -DUSE_BENCH endif OBJ = $(patsubst %.c,$(OUTDIR)/%.o,$(SRC)) @@ -37,7 +37,7 @@ $(OUTDIR)/%.o: %.c $(CC) $(ALL_CFLAGS) $(CFLAGS) -c $< -o $@ clean: - rm -rf $(OUTDIR) png_test coverage coverage.info .coverage + rm -rf $(OUTDIR) coverage coverage.info png_test bench_png debug: CFLAGS = $(DEBUG_FLAGS) debug: $(OUTDIR)/$(LIB) @@ -51,26 +51,40 @@ asan: clean $(OUTDIR)/$(LIB) test-png: clean $(MAKE) USE_HOSTED=1 debug - $(CC) $(ALL_CFLAGS) $(DEBUG_FLAGS) -DUSE_HOSTED tests/format/image/png/png_open.c -o $(OUTDIR)/png_test -L$(OUTDIR) -ltinyff && ./$(OUTDIR)/png_test + $(CC) $(ALL_CFLAGS) $(DEBUG_FLAGS) \ + -DUSE_HOSTED \ + tests/format/image/png/png_open.c \ + -o $(OUTDIR)/png_test \ + -L$(OUTDIR) -ltinyff + ./$(OUTDIR)/png_test test: test-png gdb: debug gdb -x debug/.gdbinit $(OUTDIR)/$(TEST) -bench: $(OUTDIR)/$(LIB) - mkdir -p $(BENCH_OUT) - $(CC) $(ALL_CFLAGS) $(RELEASE_FLAGS) $(BENCH_SRC) -o $(BENCH_OUT)/bench -L$(OUTDIR) -ltinyff - $(BENCH_OUT)/bench +bench: clean + $(MAKE) USE_HOSTED=1 USE_BENCH=1 release + $(CC) $(ALL_CFLAGS) $(RELEASE_FLAGS) \ + -DUSE_HOSTED -DUSE_BENCH \ + bench/src/format/image/png.c \ + -o $(OUTDIR)/bench_png \ + -L$(OUTDIR) -ltinyff + ./$(OUTDIR)/bench_png coverage: clean - $(MAKE) USE_HOSTED=1 debug - $(CC) $(ALL_CFLAGS) $(DEBUG_FLAGS) -DUSE_HOSTED tests/format/image/png/png_open.c -o $(OUTDIR)/png_test -L$(OUTDIR) -ltinyff + $(MAKE) USE_HOSTED=1 CFLAGS="$(COVERAGE_FLAGS)" LDFLAGS="$(COVERAGE_LDFLAGS)" debug + + $(CC) $(ALL_CFLAGS) $(DEBUG_FLAGS) $(COVERAGE_FLAGS) \ + -DUSE_HOSTED \ + tests/format/image/png/png_open.c \ + -o $(OUTDIR)/png_test \ + -L$(OUTDIR) -ltinyff $(COVERAGE_LDFLAGS) + ./$(OUTDIR)/png_test || true + lcov --capture --directory . --output-file coverage.info lcov --remove coverage.info '/usr/*' --output-file coverage.info --ignore-errors unused genhtml coverage.info --output-directory coverage - lcov --list coverage.info - @echo "" - @echo "HTML report generated at coverage/index.html" + .PHONY: all clean debug release asan test test-png gdb bench coverage
\ No newline at end of file diff --git a/bench/README.md b/bench/README.md deleted file mode 100644 index 4016024..0000000 --- a/bench/README.md +++ /dev/null @@ -1,9 +0,0 @@ -# tinyff benching util - -This folder contains benchmarks for every format. It also contains an API which is used to make custom benches. - -## Structure - -`format/`: Contains benchmark tests for formats -`test/`: Contains tests for common formats. These are example programs. -`bench.c & bench.h`: The API for the making the `format/` directory.
\ No newline at end of file diff --git a/bench/src/format/image/png.c b/bench/src/format/image/png.c deleted file mode 100644 index 016f686..0000000 --- a/bench/src/format/image/png.c +++ /dev/null @@ -1,6 +0,0 @@ -#include "bench.h" - -int main(void) -{ - -} diff --git a/compile_commands.json b/compile_commands.json index a9d21f0..163cafc 100644 --- a/compile_commands.json +++ b/compile_commands.json @@ -7,16 +7,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/bridges/stdio/stream_bridge.o", + "build/src/bridges/stdio/stream_bridge.o", "src/bridges/stdio/stream_bridge.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/bridges/stdio/stream_bridge.c", - "output": "/home/watson/tinyff/dist/src/bridges/stdio/stream_bridge.o" + "output": "/home/watson/tinyff/build/src/bridges/stdio/stream_bridge.o" }, { "arguments": [ @@ -26,16 +26,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/common.o", + "build/src/common.o", "src/common.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/common.c", - "output": "/home/watson/tinyff/dist/src/common.o" + "output": "/home/watson/tinyff/build/src/common.o" }, { "arguments": [ @@ -45,16 +45,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/stream.o", + "build/src/stream.o", "src/stream.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/stream.c", - "output": "/home/watson/tinyff/dist/src/stream.o" + "output": "/home/watson/tinyff/build/src/stream.o" }, { "arguments": [ @@ -64,16 +64,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/dbg.o", + "build/src/dbg.o", "src/dbg.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/dbg.c", - "output": "/home/watson/tinyff/dist/src/dbg.o" + "output": "/home/watson/tinyff/build/src/dbg.o" }, { "arguments": [ @@ -83,16 +83,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/format/image/bmp.o", + "build/src/format/image/bmp.o", "src/format/image/bmp.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/format/image/bmp.c", - "output": "/home/watson/tinyff/dist/src/format/image/bmp.o" + "output": "/home/watson/tinyff/build/src/format/image/bmp.o" }, { "arguments": [ @@ -102,16 +102,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/format/image/png.o", + "build/src/format/image/png.o", "src/format/image/png.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/format/image/png.c", - "output": "/home/watson/tinyff/dist/src/format/image/png.o" + "output": "/home/watson/tinyff/build/src/format/image/png.o" }, { "arguments": [ @@ -121,16 +121,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/tinyff.o", + "build/src/tinyff.o", "src/tinyff.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/tinyff.c", - "output": "/home/watson/tinyff/dist/src/tinyff.o" + "output": "/home/watson/tinyff/build/src/tinyff.o" }, { "arguments": [ @@ -140,16 +140,16 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/ext/crc32.o", + "build/src/ext/crc32.o", "src/ext/crc32.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/ext/crc32.c", - "output": "/home/watson/tinyff/dist/src/ext/crc32.o" + "output": "/home/watson/tinyff/build/src/ext/crc32.o" }, { "arguments": [ @@ -159,15 +159,15 @@ "-Werror", "-std=c11", "-Iinclude", - "-Ibench", + "--coverage", "-O2", "-c", "-o", - "dist/src/ext/tinflate.o", + "build/src/ext/tinflate.o", "src/ext/tinflate.c" ], "directory": "/home/watson/tinyff", "file": "/home/watson/tinyff/src/ext/tinflate.c", - "output": "/home/watson/tinyff/dist/src/ext/tinflate.o" + "output": "/home/watson/tinyff/build/src/ext/tinflate.o" } ] diff --git a/include/bridges/stdio/stream_bridge.h b/include/bridges/stdio/stream_bridge.h index 219b101..561fa8a 100644 --- a/include/bridges/stdio/stream_bridge.h +++ b/include/bridges/stdio/stream_bridge.h @@ -4,7 +4,7 @@ // Default reads for common types (just FILE for now, memory later) size_t ff_file_read(void *ptr, size_t size, void *user); -size_t ff_file_write(const void *ptr, size_t size, const void *user); +size_t ff_file_write(const void *ptr, size_t size, void *user); // Stream creation helpers ff_stream ff_create_file_stream(FILE *f);
\ No newline at end of file diff --git a/bench/bench.h b/include/tinyff/bench/bench.h index fc226d9..f623e0f 100644 --- a/bench/bench.h +++ b/include/tinyff/bench/bench.h @@ -1,9 +1,16 @@ +#ifdef USE_BENCH + #ifndef TINYFF_BENCH_H_ #define TINYFF_BENCH_H_ #include <time.h> #include <tinyff/result.h> +// Forward declarations +typedef struct ff_ctx ff_ctx; +ff_result ff_dprintf(ff_ctx* ctx, const char *msg, ...); + + #define FF_BENCH_MAX_MARKERS 32 typedef struct ff_ctx ff_ctx; @@ -54,4 +61,20 @@ static inline double ff_bench_seconds(const ff_bench *b) { return (double)(b->_end - b->_start) / CLOCKS_PER_SEC; } -#endif // TINYFF_BENCH_H
\ No newline at end of file +static inline void ff_bench_print(ff_ctx* ctx, const ff_bench *b) +{ + double total_ms = (double)(b->_end - b->_start) * 1000.0 / CLOCKS_PER_SEC; + + ff_dprintf(ctx, "== bench: %s ==\n", b->label); + + for (int i = 0; i < b->_mcount; i++) { + double ms = (double)(b->markers[i].tick - b->_start) * 1000.0 / CLOCKS_PER_SEC; + ff_dprintf(ctx, " [%s] +%.3f ms\n", b->markers[i].label, ms); + } + + ff_dprintf(ctx, "total: %.3f ms\n", total_ms); +} + + +#endif // TINYFF_BENCH_H +#endif // USE_BENCH
\ No newline at end of file diff --git a/include/tinyff/common.h b/include/tinyff/common.h index 1efe930..d4215ed 100644 --- a/include/tinyff/common.h +++ b/include/tinyff/common.h @@ -10,7 +10,7 @@ #ifdef USE_BENCH -#include <bench.h> +#include <tinyff/bench/bench.h> #define FF_BENCH_MARK(ctx, label) \ do { \ diff --git a/include/tinyff/dbg.h b/include/tinyff/dbg.h index 3fac931..379e6ce 100644 --- a/include/tinyff/dbg.h +++ b/include/tinyff/dbg.h @@ -14,13 +14,13 @@ #include <tinyff/common.h> #include <tinyff/stream.h> +#include <stdarg.h> + // Sets the debug stream. If stream is NULL, debug is disabled. ff_result ff_set_debug_stream(ff_stream* stream, ff_ctx* ctx); // Prints a string to the debug stream if debug is enabled. -// Note: I removed stdarg. That crap nearly made me kill myself. -// 0/10, would not recommend. Jokes on you though, I don't have a soul to kill. -ff_result ff_dprintf(ff_ctx* ctx, const char *msg); +ff_result ff_dprintf(ff_ctx* ctx, const char *msg, ...); #endif
\ No newline at end of file diff --git a/include/tinyff/result.h b/include/tinyff/result.h index f15af1b..f167277 100644 --- a/include/tinyff/result.h +++ b/include/tinyff/result.h @@ -24,6 +24,7 @@ typedef enum { // Generic FF_RESULT_ERROR_OUT_OF_BOUNDS, + FF_RESULT_ERROR_NULL_PTR, // Media specific diff --git a/include/tinyff/stream.h b/include/tinyff/stream.h index 95c5884..88cea69 100644 --- a/include/tinyff/stream.h +++ b/include/tinyff/stream.h @@ -9,10 +9,7 @@ typedef size_t (*ff_read_cb)(void *ptr, size_t size, void *user); -typedef size_t (*ff_write_cb)(const void *ptr, size_t size, const void *user); -// ^ -// | -// there clang, happy now? +typedef size_t (*ff_write_cb)(const void *ptr, size_t size, void *user); typedef struct { ff_read_cb read; diff --git a/src/bridges/stdio/stream_bridge.c b/src/bridges/stdio/stream_bridge.c index 17a3191..09aad14 100644 --- a/src/bridges/stdio/stream_bridge.c +++ b/src/bridges/stdio/stream_bridge.c @@ -9,7 +9,7 @@ size_t ff_file_read(void *ptr, size_t size, void *user) return fread(ptr, 1, size, f); } -size_t ff_file_write(const void *ptr, size_t size, const void *user) +size_t ff_file_write(const void *ptr, size_t size, void *user) { FILE *f = (FILE *)user; return fwrite(ptr, 1, size, f); @@ -1,26 +1,157 @@ #include <tinyff/stream.h> #include <tinyff/dbg.h> +#include <stdarg.h> +#include <stdint.h> + +static size_t ff_internal_itoa(int value, char* buf) +{ + char temp[12]; + size_t i = 0, j = 0; + + if (value == 0) { + buf[0] = '0'; + return 1; + } + + unsigned int uvalue; + + if (value < 0) { + buf[j++] = '-'; + uvalue = (unsigned int)(-(long)value); + } else { + uvalue = (unsigned int)value; + } + + while (uvalue > 0) { + temp[i++] = (uvalue % 10) + '0'; + uvalue /= 10; + } + + while (i > 0) { + buf[j++] = temp[--i]; + } + + return j; +} ff_result ff_set_debug_stream(ff_stream* stream, ff_ctx* ctx) { - ctx->ff_debug_stream = *stream; - ctx->ff_debug_enabled = (stream != NULL); + if (!ctx) return FF_RESULT_ERROR_NULL_PTR; + + if (stream) { + ctx->ff_debug_stream = *stream; + ctx->ff_debug_enabled = true; + } else { + ctx->ff_debug_enabled = false; + } - // TODO: Add banner back maybe - return FF_RESULT_OK; } -ff_result ff_dprintf(ff_ctx* ctx, const char *msg) +static inline void ff_debug_flush(ff_ctx* ctx, char* buffer, size_t* idx) +{ + if (*idx == 0) return; + + ctx->ff_debug_stream.write( + &ctx->ff_debug_stream, + *idx, + (uint8_t*)buffer + ); + + *idx = 0; +} + +ff_result ff_dprintf(ff_ctx* ctx, const char *format, ...) { - if (!ctx->ff_debug_enabled){ + if (!ctx || !ctx->ff_debug_enabled || !ctx->ff_debug_stream.write) { return FF_RESULT_WARN_DEBUG_DISABLED; } - - if (!ctx->ff_debug_stream.write){ - return FF_RESULT_WARN_DEBUG_DISABLED; + + va_list args; + va_start(args, format); + + char buffer[512]; + size_t buf_idx = 0; + const char* p = format; + + while (*p) { + + if (buf_idx >= sizeof(buffer) - 64) { + ff_debug_flush(ctx, buffer, &buf_idx); + } + + if (*p == '%') { + p++; + + if (!*p) break; + + if (*p == 's') { + const char* s = va_arg(args, const char*); + if (!s) s = "(null)"; + + while (*s) { + buffer[buf_idx++] = *s++; + + if (buf_idx >= sizeof(buffer)) { + ff_debug_flush(ctx, buffer, &buf_idx); + } + } + } + else if (*p == 'd') { + int d = va_arg(args, int); + buf_idx += ff_internal_itoa(d, &buffer[buf_idx]); + } + else if (*p == 'u') { + unsigned int u = va_arg(args, unsigned int); + buf_idx += ff_internal_itoa((int)u, &buffer[buf_idx]); + } + else if (*p == 'l' && *(p + 1) == 'd') { + long d = va_arg(args, long); + buf_idx += ff_internal_itoa((int)d, &buffer[buf_idx]); + p++; + } + else if (*p == 'f') { + double f = va_arg(args, double); + + if (f < 0) { + buffer[buf_idx++] = '-'; + f = -f; + } + + int whole = (int)f; + double frac = f - whole; + + buf_idx += ff_internal_itoa(whole, &buffer[buf_idx]); + + buffer[buf_idx++] = '.'; + + for (int i = 0; i < 3; i++) { + frac *= 10.0; + int digit = (int)frac; + buffer[buf_idx++] = '0' + digit; + frac -= digit; + } + } + else if (*p == 'c') { + buffer[buf_idx++] = (char)va_arg(args, int); + } + else if (*p == '%') { + buffer[buf_idx++] = '%'; + } + else { + buffer[buf_idx++] = '%'; + buffer[buf_idx++] = *p; + } + } + else { + buffer[buf_idx++] = *p; + } + + p++; } - - ctx->ff_debug_stream.write(msg, ff_strlen(msg), ctx->ff_debug_stream.user); - return FF_RESULT_OK; // result_ok means the result is ok -} + + ff_debug_flush(ctx, buffer, &buf_idx); + + va_end(args); + return FF_RESULT_OK; +}
\ No newline at end of file diff --git a/src/format/image/png.c b/src/format/image/png.c index 12080d6..d5959bc 100644 --- a/src/format/image/png.c +++ b/src/format/image/png.c @@ -483,10 +483,16 @@ ff_result ff_close_png(ff_ctx* ctx, ff_png_ctx *png_ctx) ff_result ff_write_chunk(ff_stream *stream, const char *type, uint8_t *buf, size_t len) { - stream->write(stream, 4, type); - stream->write(stream, 4, (uint32_t*)&len); - stream->write(stream, len, buf); - stream->write(stream, 4, (uint32_t*)0); // TODO: Implement actual CRC calculation (use ff_write_be32) + stream->write(type, 4, stream->user); + + uint32_t be_len = (uint32_t)len; + stream->write(&be_len, 4, stream->user); + + stream->write(buf, len, stream->user); + + uint32_t zero_crc = 0; + stream->write(&zero_crc, 4, stream->user); + return FF_RESULT_OK; } @@ -495,7 +501,7 @@ ff_result ff_encode_png(ff_ctx *ctx, ff_png_ctx *png_ctx, ff_stream *stream) FF_BENCH_START(ctx, "png"); FF_BENCH_MARK(ctx, "ff_encode_png"); - stream->write(stream, 8, PNG_SIGNATURE); + stream->write(stream, 8, (void *)PNG_SIGNATURE); // TODO: Actually write the PNG data // For now I'll void the parameters diff --git a/tests/format/image/png/png_open.c b/tests/format/image/png/png_open.c index 97392fb..3542ffa 100644 --- a/tests/format/image/png/png_open.c +++ b/tests/format/image/png/png_open.c @@ -2,6 +2,7 @@ #include <tinyff/tinyff.h>
#include <tinyff/image/png.h>
#include <bridges/stdio/stream_bridge.h>
+#include <tinyff/bench/bench.h>
#include <stdio.h>
ff_result fftest_rgb2x2(ff_ctx* ctx) {
@@ -35,6 +36,7 @@ ff_result fftest_lenna256(ff_ctx* ctx) { fclose(file);
ff_close_png(ctx, png_ctx);
+ ff_bench_print(ctx, &(ctx)->bench);
return res;
}
|
