aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Oliver <contact@pauloliver.dev>2025-10-14 04:35:12 +0200
committerPaul Oliver <contact@pauloliver.dev>2025-10-19 22:35:42 +0200
commit70db2bcd5b31d3ee76932d240787848e41f763a0 (patch)
tree7b892ff645478cfb75ccfcd33f9a61c6a280431a
parent5b765abf4748b8b26f8cca5939839dcd1c14134a (diff)
Adds optional compression using zlib
-rwxr-xr-xsalis21
-rw-r--r--src/salis.c93
-rw-r--r--src/ui/curses.c2
3 files changed, 111 insertions, 5 deletions
diff --git a/salis b/salis
index 243f947..ad5aded 100755
--- a/salis
+++ b/salis
@@ -91,6 +91,7 @@ options=(
"t|thread-gap|N|Memory gap between cores in bytes (could help reduce cache misses?)||0x100|bench:load:new"
"u|ui|UI|User interface|${uis}|curses|load:new"
"y|sync-pow|POW|Core sync interval exponent (interval == 2^POW)||20|bench:new"
+ "x|compress||Compress save files (requires 'zlib')||true|new"
"z|auto-save-pow|POW|Auto-save interval exponent (interval == 2^POW)||36|new"
)
@@ -196,7 +197,8 @@ parse_next() {
nopt=opt_${lopt//-/_}
if [[ -z ${meta} ]] ; then
- eval ${nopt}=true
+ defv=`field "${vopt}" 6`
+ eval ${nopt}=`[[ ${defv} == true ]] && echo false || echo true`
shift_next=1
else
eval ${nopt}=${2}
@@ -275,7 +277,7 @@ act_new=3
act_var="act_${cmd}"
-gcc_flags="-Wall -Wextra -Werror -std=c11 -pedantic"
+gcc_flags="-Wall -Wextra -Werror -std=gnu11 -pedantic"
fquote() {
echo "\\\"${1}\\\""
@@ -285,7 +287,7 @@ fpow() {
printf '%#xul' $((1 << ${1}))
}
-bcmd="gcc src/salis.c -o ${salis_exe} ${gcc_flags} -Isrc -lncursesw -pthread"
+bcmd="gcc src/salis.c -o ${salis_exe} ${gcc_flags} -Isrc -pthread"
bcmd="${bcmd} `[[ ${opt_optimized} == true ]] && echo "-O3 -DNDEBUG" || echo "-ggdb"`"
bcmd="${bcmd} -DACTION=${!act_var}"
bcmd="${bcmd} -DARCHITECTURE=`fquote ${opt_arch}`"
@@ -337,7 +339,18 @@ load|new)
bcmd="${bcmd} -DMUTA_FLIP_BIT=`[[ ${opt_muta_flip} == true ]] && echo 1 || echo 0`"
bcmd="${bcmd} -DSIM_NAME=`fquote ${opt_name}`"
bcmd="${bcmd} -DSIM_PATH=`fquote ${sim_path}`"
- bcmd="${bcmd} -DUI=`fquote ui/${opt_ui}.c`"
+
+ ui_file=ui/${opt_ui}.c
+ ui_flags=`sed -n -e 's/^.*GCC_EXTRA_FLAGS //p' src/${ui_file}`
+
+ shopt -s extglob
+ bcmd="${bcmd} -DUI=`fquote ${ui_file}` ${ui_flags}"
+ bcmd="${bcmd%%*( )}"
+ shopt -u extglob
+
+ if [[ ${opt_compress} == true ]] ; then
+ bcmd="${bcmd} -DCOMPRESS -lz"
+ fi
;;
esac
diff --git a/src/salis.c b/src/salis.c
index 6714038..74054f6 100644
--- a/src/salis.c
+++ b/src/salis.c
@@ -16,6 +16,10 @@
#include <string.h>
#include <threads.h>
+#ifdef COMPRESS
+#include <zlib.h>
+#endif
+
#define ACT_BENCH (1)
#define ACT_LOAD (2)
#define ACT_NEW (3)
@@ -518,7 +522,13 @@ void core_step(Core *core) {
#if ACTION == ACT_LOAD || ACTION == ACT_NEW
void salis_save(const char *path) {
- FILE *f = fopen(path, "wb");
+#ifdef COMPRESS
+ size_t size = 0;
+ char *in = NULL;
+ FILE *f = open_memstream(&in, &size);
+#else
+ FILE *f = fopen(path, "wb");
+#endif
assert(f);
@@ -529,6 +539,39 @@ void salis_save(const char *path) {
fwrite(&g_steps, sizeof(u64), 1, f);
fwrite(&g_syncs, sizeof(u64), 1, f);
fclose(f);
+
+#ifdef COMPRESS
+ assert(size);
+
+ char *out = malloc(size);
+ assert(out);
+
+ z_stream strm = { 0 };
+ strm.zalloc = NULL,
+ strm.zfree = NULL,
+ strm.opaque = NULL,
+
+ deflateInit(&strm, Z_DEFAULT_COMPRESSION);
+
+ strm.avail_in = size;
+ strm.avail_out = size;
+ strm.next_in = (Bytef *)in;
+ strm.next_out = (Bytef *)out;
+
+ deflate(&strm, Z_FINISH);
+
+ FILE *fx = fopen(path, "wb");
+ assert(fx);
+
+ fwrite(&size, sizeof(size_t), 1, fx);
+ fwrite(out, sizeof(char), strm.total_out, fx);
+ fclose(fx);
+
+ deflateEnd(&strm);
+
+ free(in);
+ free(out);
+#endif
}
void salis_auto_save() {
@@ -578,7 +621,50 @@ void salis_init() {
#if ACTION == ACT_LOAD
void salis_load() {
+#ifdef COMPRESS
+ FILE *fx = fopen(SIM_PATH, "rb");
+ assert(fx);
+
+ fseek(fx, 0, SEEK_END);
+ size_t x_size = ftell(fx) - sizeof(size_t);
+ char *in = malloc(x_size);
+ rewind(fx);
+ assert(x_size);
+ assert(in);
+
+ size_t size = 0;
+ fread(&size, sizeof(size_t), 1, fx);
+ fread(in, 1, x_size, fx);
+ fclose(fx);
+ assert(size);
+
+ char *out = malloc(size);
+ assert(out);
+
+ z_stream strm = { 0 };
+ strm.next_in = (Bytef *)in;
+ strm.avail_in = x_size;
+ strm.zalloc = NULL;
+ strm.zfree = NULL;
+ strm.opaque = NULL;
+
+ inflateInit(&strm);
+
+ strm.avail_out = size;
+ strm.next_out = (Bytef *)out;
+
+#ifdef NDEBUG
+ inflate(&strm, Z_FINISH);
+#else
+ assert(inflate(&strm, Z_FINISH));
+#endif
+
+ inflateEnd(&strm);
+
+ FILE *f = fmemopen(out, size, "rb");
+#else
FILE *f = fopen(SIM_PATH, "rb");
+#endif
assert(f);
@@ -593,6 +679,11 @@ void salis_load() {
#pragma GCC diagnostic pop
fclose(f);
+
+#ifdef COMPRESS
+ free(in);
+ free(out);
+#endif
}
#endif
diff --git a/src/ui/curses.c b/src/ui/curses.c
index 1d70ca7..d1f821d 100644
--- a/src/ui/curses.c
+++ b/src/ui/curses.c
@@ -6,6 +6,8 @@
* Implements a TUI for the Salis simulator using the ncurses library.
*/
+// GCC_EXTRA_FLAGS -lncursesw
+
#include <curses.h>
#include <locale.h>
#include <time.h>