unsigned char to4096; /* Our max. */
uint8_t mode;
- uint32_t quota;
- uint32_t active;
+ atomic_uint_fast32_t quota;
+ atomic_uint_fast32_t active;
double atr;
/*
e->srtt = (isc_random_uniform(0x1f)) + 1;
e->lastage = 0;
e->expires = 0;
- e->active = 0;
+ atomic_init(&e->active, 0);
e->mode = 0;
- e->quota = adb->quota;
+ atomic_init(&e->quota, adb->quota);
e->atr = 0.0;
ISC_LIST_INIT(e->lameinfo);
ISC_LINK_INIT(e, plink);
isc_netaddr_format(&netaddr, addrbuf, sizeof(addrbuf));
isc_log_write(dns_lctx, DNS_LOGCATEGORY_DATABASE, DNS_LOGMODULE_ADB,
- ISC_LOG_INFO, "adb: quota %s (%u/%u): %s",
- addrbuf, entry->active, entry->quota, msgbuf);
+ ISC_LOG_INFO,
+ "adb: quota %s (%" PRIuFAST32 "/%" PRIuFAST32 "): %s",
+ addrbuf, atomic_load_relaxed(&entry->active),
+ atomic_load_relaxed(&entry->quota), msgbuf);
}
static void
INSIST(bucket != DNS_ADB_INVALIDBUCKET);
LOCK(&adb->entrylocks[bucket]);
- if (entry->quota != 0 &&
- entry->active >= entry->quota)
- {
+ if (dns_adbentry_overquota(entry)) {
find->options |=
(DNS_ADBFIND_LAMEPRUNED|
DNS_ADBFIND_OVERQUOTA);
INSIST(bucket != DNS_ADB_INVALIDBUCKET);
LOCK(&adb->entrylocks[bucket]);
- if (entry->quota != 0 &&
- entry->active >= entry->quota)
- {
+ if (dns_adbentry_overquota(entry)) {
find->options |=
(DNS_ADBFIND_LAMEPRUNED|
DNS_ADBFIND_OVERQUOTA);
fprintf(f, " [ttl %d]", (int)(entry->expires - now));
if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) {
- fprintf(f, " [atr %0.2f] [quota %u]",
- entry->atr, entry->quota);
+ fprintf(f, " [atr %0.2f] [quota %" PRIuFAST32 "]",
+ entry->atr, atomic_load_relaxed(&entry->quota));
}
fprintf(f, "\n");
addr->entry->atr = ISC_CLAMP(addr->entry->atr, 0.0, 1.0);
if (addr->entry->atr < adb->atr_low && addr->entry->mode > 0) {
- addr->entry->quota = adb->quota *
- quota_adj[--addr->entry->mode] / 10000;
- log_quota(addr->entry, "atr %0.2f, quota increased to %u",
- addr->entry->atr, addr->entry->quota);
+ uint_fast32_t new_quota =
+ adb->quota * quota_adj[--addr->entry->mode] / 10000;
+ atomic_store_release(&addr->entry->quota,
+ ISC_MIN(1, new_quota));
+ log_quota(addr->entry, "atr %0.2f, quota increased to %"
+ PRIuFAST32,
+ addr->entry->atr,
+ new_quota);
} else if (addr->entry->atr > adb->atr_high &&
addr->entry->mode < (QUOTA_ADJ_SIZE - 1)) {
- addr->entry->quota = adb->quota *
- quota_adj[++addr->entry->mode] / 10000;
- log_quota(addr->entry, "atr %0.2f, quota decreased to %u",
- addr->entry->atr, addr->entry->quota);
+ uint_fast32_t new_quota =
+ adb->quota * quota_adj[++addr->entry->mode] / 10000;
+ atomic_store_release(&addr->entry->quota,
+ ISC_MIN(1, new_quota));
+ log_quota(addr->entry, "atr %0.2f, quota decreased to %"
+ PRIuFAST32,
+ addr->entry->atr,
+ new_quota);
}
-
- /* Ensure we don't drop to zero */
- if (addr->entry->quota == 0)
- addr->entry->quota = 1;
}
#define EDNSTOS 3U
bool
dns_adbentry_overquota(dns_adbentry_t *entry) {
REQUIRE(DNS_ADBENTRY_VALID(entry));
- return (entry->quota != 0 && entry->active >= entry->quota);
+
+ uint_fast32_t quota = atomic_load_relaxed(&entry->quota);
+ uint_fast32_t active = atomic_load_acquire(&entry->active);
+
+ return (quota != 0 && active >= quota);
}
void
dns_adb_beginudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
- int bucket;
-
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
- bucket = addr->entry->lock_bucket;
-
- LOCK(&adb->entrylocks[bucket]);
- addr->entry->active++;
- UNLOCK(&adb->entrylocks[bucket]);
+ INSIST(atomic_fetch_add_relaxed(&addr->entry->active, 1) != UINT32_MAX);
}
void
dns_adb_endudpfetch(dns_adb_t *adb, dns_adbaddrinfo_t *addr) {
- int bucket;
-
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
- bucket = addr->entry->lock_bucket;
-
- LOCK(&adb->entrylocks[bucket]);
- if (addr->entry->active > 0)
- addr->entry->active--;
- UNLOCK(&adb->entrylocks[bucket]);
+ INSIST(atomic_fetch_sub_release(&addr->entry->active, 1) != 0);
}