isc_refcount_t references;
dns_adbnamehooklist_t nhs;
- unsigned int flags;
- unsigned int srtt;
+ atomic_uint flags;
+ atomic_uint srtt;
unsigned int completed;
unsigned int timeouts;
unsigned char plain;
unsigned char *cookie;
uint16_t cookielen;
- isc_stdtime_t expires;
- isc_stdtime_t lastage;
+ _Atomic(isc_stdtime_t) expires;
+ _Atomic(isc_stdtime_t) lastage;
/*%<
* A nonzero 'expires' field indicates that the entry should
* persist until that time. This allows entries found
enum {
ENTRY_IS_DEAD = 1 << 31,
};
-#define ENTRY_DEAD(e) (((e)->flags & ENTRY_IS_DEAD) != 0)
+#define ENTRY_DEAD(e) ((atomic_load(&(e)->flags) & ENTRY_IS_DEAD) != 0)
/*
* To the name, address classes are all that really exist. If it has a
.srtt = isc_random_uniform(0x1f) + 1,
.sockaddr = *addr,
.link = ISC_LINK_INITIALIZER,
+ .quota = adb->quota,
+ .references = ISC_REFCOUNT_INITIALIZER(1),
+ .adb = dns_adb_ref(adb),
.magic = DNS_ADBENTRY_MAGIC,
};
fprintf(stderr, "dns_adbentry__init:%s:%s:%d:%p->references = 1\n",
__func__, __FILE__, __LINE__ + 1, entry);
#endif
- isc_refcount_init(&entry->references, 1);
isc_mutex_init(&entry->lock);
- atomic_init(&entry->active, 0);
- atomic_init(&entry->quota, adb->quota);
-
- dns_adb_attach(adb, &entry->adb);
-
inc_adbstats(adb, dns_adbstats_entriescnt);
return (entry);
ai = isc_mem_get(adb->mctx, sizeof(*ai));
*ai = (dns_adbaddrinfo_t){
- .srtt = entry->srtt,
- .flags = entry->flags,
+ .srtt = atomic_load(&entry->srtt),
+ .flags = atomic_load(&entry->flags),
.publink = ISC_LINK_INITIALIZER,
.sockaddr = entry->sockaddr,
.entry = dns_adbentry_ref(entry),
while (namehook != NULL) {
dns_adbaddrinfo_t *addrinfo = NULL;
entry = namehook->entry;
- LOCK(&entry->lock);
if (adbentry_overquota(entry)) {
find->options |= DNS_ADBFIND_OVERQUOTA;
*/
ISC_LIST_APPEND(find->list, addrinfo, publink);
nextv4:
- UNLOCK(&entry->lock);
namehook = ISC_LIST_NEXT(namehook, name_link);
}
}
while (namehook != NULL) {
dns_adbaddrinfo_t *addrinfo = NULL;
entry = namehook->entry;
- LOCK(&entry->lock);
if (adbentry_overquota(entry)) {
find->options |= DNS_ADBFIND_OVERQUOTA;
*/
ISC_LIST_APPEND(find->list, addrinfo, publink);
nextv6:
- UNLOCK(&entry->lock);
namehook = ISC_LIST_NEXT(namehook, name_link);
}
}
dns_adb_t *adb = adbentry->adb;
if (!ENTRY_DEAD(adbentry)) {
- adbentry->flags |= ENTRY_IS_DEAD;
+ (void)atomic_fetch_or(&adbentry->flags, ENTRY_IS_DEAD);
result = isc_hashmap_delete(
adb->entries,
return (false);
}
- if (adbentry->expires == 0 || adbentry->expires > now) {
+ if (atomic_load(&adbentry->expires) == 0 ||
+ atomic_load(&adbentry->expires) > now)
+ {
return (false);
}
fprintf(f,
";\t%s [srtt %u] [flags %08x] [edns %u/%u] "
"[plain %u/%u]",
- addrbuf, entry->srtt, entry->flags, entry->edns, entry->ednsto,
- entry->plain, entry->plainto);
+ addrbuf, atomic_load(&entry->srtt), atomic_load(&entry->flags),
+ entry->edns, entry->ednsto, entry->plain, entry->plainto);
if (entry->udpsize != 0U) {
fprintf(f, " [udpsize %u]", entry->udpsize);
}
}
fprintf(f, "]");
}
- if (entry->expires != 0) {
- fprintf(f, " [ttl %d]", (int)(entry->expires - now));
+ if (atomic_load(&entry->expires) != 0) {
+ fprintf(f, " [ttl %d]",
+ (int)(atomic_load(&entry->expires) - now));
}
if (adb != NULL && adb->quota != 0 && adb->atr_freq != 0) {
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
REQUIRE(factor <= 10);
- isc_stdtime_t now = 0;
dns_adbentry_t *entry = addr->entry;
- LOCK(&entry->lock);
- if (entry->expires == 0 || factor == DNS_ADB_RTTADJAGE) {
+ isc_stdtime_t now = 0;
+ if (atomic_load(&entry->expires) == 0 || factor == DNS_ADB_RTTADJAGE) {
now = isc_stdtime_now();
}
- adjustsrtt(addr, rtt, factor, now);
- UNLOCK(&entry->lock);
+ adjustsrtt(addr, rtt, factor, now);
}
void
REQUIRE(DNS_ADB_VALID(adb));
REQUIRE(DNS_ADBADDRINFO_VALID(addr));
- dns_adbentry_t *entry = addr->entry;
- LOCK(&entry->lock);
-
adjustsrtt(addr, 0, DNS_ADB_RTTADJAGE, now);
-
- UNLOCK(&entry->lock);
}
static void
adjustsrtt(dns_adbaddrinfo_t *addr, unsigned int rtt, unsigned int factor,
isc_stdtime_t now) {
- uint64_t new_srtt;
+ unsigned int new_srtt;
if (factor == DNS_ADB_RTTADJAGE) {
- if (addr->entry->lastage != now) {
+ if (atomic_load(&addr->entry->lastage) != now) {
new_srtt = addr->entry->srtt;
new_srtt <<= 9;
new_srtt -= addr->entry->srtt;
new_srtt >>= 9;
- addr->entry->lastage = now;
+ atomic_store(&addr->entry->lastage, now);
} else {
- new_srtt = addr->entry->srtt;
+ new_srtt = atomic_load(&addr->entry->srtt)
}
} else {
- new_srtt = ((uint64_t)addr->entry->srtt / 10 * factor) +
+ new_srtt = ((uint64_t)atomic_load(&addr->entry->srtt) / 10 *
+ factor) +
((uint64_t)rtt / 10 * (10 - factor));
}
- addr->entry->srtt = (unsigned int)new_srtt;
- addr->srtt = (unsigned int)new_srtt;
+ atomic_store(&addr->entry->srtt, new_srtt);
+ addr->srtt = new_srtt;
- if (addr->entry->expires == 0) {
- addr->entry->expires = now + ADB_ENTRY_WINDOW;
- }
+ (void)atomic_compare_exchange_strong(&addr->entry->expires,
+ &(isc_stdtime_t){ 0 },
+ now + ADB_ENTRY_WINDOW);
}
void
isc_stdtime_t now;
dns_adbentry_t *entry = addr->entry;
- LOCK(&entry->lock);
+ unsigned int flags = atomic_load(&entry->flags);
+ while (!atomic_compare_exchange_strong(&entry->flags, &flags,
+ (flags & ~mask) | (bits & mask)))
+ {
+ /* repeat */
+ }
- entry->flags = (entry->flags & ~mask) | (bits & mask);
- if (entry->expires == 0) {
+ if (atomic_load(&entry->expires) == 0) {
now = isc_stdtime_now();
- entry->expires = now + ADB_ENTRY_WINDOW;
+ atomic_store(&entry->expires, now + ADB_ENTRY_WINDOW);
}
/*
* the most recent values from addr->entry->flags.
*/
addr->flags = (addr->flags & ~mask) | (bits & mask);
-
- UNLOCK(&entry->lock);
}
/*
entry = get_attached_and_locked_entry(adb, now, sa);
INSIST(entry != NULL);
+ UNLOCK(&entry->lock);
+
port = isc_sockaddr_getport(sa);
addr = new_adbaddrinfo(adb, entry, port);
*addrp = addr;
- UNLOCK(&entry->lock);
dns_adbentry_detach(&entry);
return (result);
REQUIRE(DNS_ADBENTRY_VALID(entry));
- if (entry->expires == 0) {
- now = isc_stdtime_now();
- entry->expires = now + ADB_ENTRY_WINDOW;
- }
+ now = isc_stdtime_now();
+ (void)atomic_compare_exchange_strong(
+ &entry->expires, &(isc_stdtime_t){ 0 }, now + ADB_ENTRY_WINDOW);
free_adbaddrinfo(adb, &addr);
}