ref: 8fad4df88ae048a8317f1633cdc47fbaf17d896b
parent: 3d5ff2d9beb0bdf1aef5ab7afca578ebe4f55795
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Oct 12 18:18:37 EDT 2023
gefs: put tree roots on the deferred reclamation list too
--- a/blk.c
+++ b/blk.c
@@ -950,7 +950,8 @@
}
if((f = malloc(sizeof(Bfree))) == nil)
- return;
+ abort();
+ f->op = DFblk;
f->bp = bp;
if(b != nil)
f->b = holdblk(b);
@@ -996,22 +997,30 @@
return;
}
p = asetp(&fs->limbo[(ge+1)%3], nil);
- asetl(&fs->epoch, (ge+1) % 3);
+ asetl(&fs->epoch, (ge+1)%3);
- while(p != nil){
+ for(; p != nil; p = n){
n = p->next;
- a = getarena(p->bp.addr);
- qe.op = Qfree;
- qe.bp = p->bp;
- qe.b = nil;
- qe.qgen = agetv(&fs->qgen);
- qput(a->sync, qe);
- if(p->b != nil){
- setflag(p->b, Bfreed);
- dropblk(p->b);
+ switch(p->op){
+ case DFtree:
+ free(p->t);
+ break;
+ case DFblk:
+ a = getarena(p->bp.addr);
+ qe.op = Qfree;
+ qe.bp = p->bp;
+ qe.b = nil;
+ qe.qgen = agetv(&fs->qgen);
+ qput(a->sync, qe);
+ if(p->b != nil){
+ setflag(p->b, Bfreed);
+ dropblk(p->b);
+ }
+ break;
+ default:
+ abort();
}
free(p);
- p = n;
}
}
--- a/dat.h
+++ b/dat.h
@@ -406,8 +406,15 @@
char buf[Bufspc];
};
+enum {
+ DFblk,
+ DFtree,
+};
+
struct Bfree {
Bfree *next;
+ int op;
+ Tree *t;
Blk *b;
Bptr bp;
};
--- a/snap.c
+++ b/snap.c
@@ -468,7 +468,7 @@
abort();
if(unpacktree(t, kv.v, kv.nv) == nil)
abort();
- ainc(&t->memref);
+ t->memref = 1;
return t;
Error:
free(t);
@@ -482,10 +482,18 @@
void
closesnap(Tree *t)
{
+ Bfree *f;
+ ulong ge;
+
if(t == nil || adec(&t->memref) != 0)
return;
- assert(!t->dirty);
- free(t);
+ if((f = malloc(sizeof(Bfree))) == nil)
+ abort();
+ f->op = DFtree;
+ f->t = t;
+ ge = agetl(&fs->epoch);
+ f->next = fs->limbo[ge];
+ fs->limbo[ge] = f;
}
char*