#include <isc/file.h>
#include <isc/heap.h>
#include <isc/hex.h>
+#include <isc/list.h>
#include <isc/log.h>
#include <isc/loop.h>
#include <isc/mem.h>
struct cds_list_head types_list;
struct cds_list_head *data;
- /*%
- * NOTE: The 'dirty' flag is protected by the node lock, so
- * this bitfield has to be separated from the one above.
- * We don't want it to share the same qword with bits
- * that can be accessed without the node lock.
- */
- uint8_t : 0;
- uint8_t dirty : 1;
- uint8_t : 0;
+ ISC_LIST(dns_slabheader_t) dirty;
/*%
* Used for dead nodes cleaning. This linked list is used to mark nodes
* Caller must be holding the node lock.
*/
- DNS_SLABTOP_FOREACH(top, node->data) {
+ /*
+ * We can't use ordinary loop because multiple headers to be cleaned can
+ * be stashed under a single slabtop.
+ */
+ for (dns_slabheader_t *dirty = ISC_LIST_HEAD(node->dirty);
+ dirty != NULL; dirty = ISC_LIST_HEAD(node->dirty))
+ {
+ dns_slabtop_t *top = dirty->top;
+
+ ISC_LIST_UNLINK(node->dirty, dirty, dirtylink);
+
clean_cache_headers(top);
/*
dns_slabtop_destroy(((dns_db_t *)qpdb)->mctx, &top);
}
}
-
- node->dirty = false;
}
/*
}
/* Handle easy and typical case first. */
- if (!node->dirty && !cds_list_empty(node->data)) {
+ if (ISC_LIST_EMPTY(node->dirty) && !cds_list_empty(node->data)) {
goto unref;
}
}
}
- if (node->dirty) {
+ if (!ISC_LIST_EMPTY(node->dirty)) {
clean_cache_node(qpdb, node);
}
mark_ancient(dns_slabheader_t *header) {
setttl(header, 0);
mark(header, DNS_SLABHEADERATTR_ANCIENT);
- HEADERNODE(header)->dirty = 1;
+ if (!ISC_LINK_LINKED(header, dirtylink)) {
+ ISC_LIST_APPEND(HEADERNODE(header)->dirty, header, dirtylink);
+ }
}
/*
.nspace = nspace,
.references = ISC_REFCOUNT_INITIALIZER(1),
.locknum = isc_random_uniform(qpdb->buckets_count),
+ .dirty = ISC_LIST_INITIALIZER,
};
isc_mem_attach(qpdb->common.mctx, &newdata->mctx);
dns_slabheader_t *header = data;
qpcache_t *qpdb = HEADERNODE(header)->qpdb;
+ if (ISC_LINK_LINKED(header, dirtylink)) {
+ ISC_LIST_UNLINK(HEADERNODE(header)->dirty, header, dirtylink);
+ }
+
if (header->heap != NULL && header->heap_index != 0) {
isc_heap_delete(header->heap, header->heap_index);
}
#include <isc/ascii.h>
#include <isc/atomic.h>
+#include <isc/list.h>
#include <isc/mem.h>
#include <isc/region.h>
#include <isc/result.h>
.typepair = typepair,
.trust = rdataset->trust,
.ttl = rdataset->ttl,
+ .dirtylink = ISC_LINK_INITIALIZER,
};
}
atomic_init(&h->attributes, 0);
atomic_init(&h->last_refresh_fail_ts, 0);
+ ISC_LINK_INIT(h, dirtylink);
+
STATIC_ASSERT(sizeof(h->attributes) == 2,
"The .attributes field of dns_slabheader_t needs to be "
"16-bit int type exactly.");
h = isc_mem_get(mctx, sizeof(*h));
*h = (dns_slabheader_t){
.node = node,
+ .dirtylink = ISC_LINK_INITIALIZER,
};
return h;
}