mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 18:19:42 +00:00
2320. [func] Make statistics couters thread-safe for platforms
that support certain atomic operations. [RT #17466]
This commit is contained in:
parent
fcb738fca3
commit
1c3ed2a83d
3
CHANGES
3
CHANGES
@ -1,3 +1,6 @@
|
|||||||
|
2320. [func] Make statistics couters thread-safe for platforms
|
||||||
|
that support certain atomic operations. [RT #17466]
|
||||||
|
|
||||||
2319. [bug] Silence Coverity warnings in
|
2319. [bug] Silence Coverity warnings in
|
||||||
lib/dns/rdata/in_1/apl_42.c. [RT #17469]
|
lib/dns/rdata/in_1/apl_42.c. [RT #17469]
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: server.h,v 1.91 2008/01/18 23:46:57 tbox Exp $ */
|
/* $Id: server.h,v 1.92 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
#ifndef NAMED_SERVER_H
|
#ifndef NAMED_SERVER_H
|
||||||
#define NAMED_SERVER_H 1
|
#define NAMED_SERVER_H 1
|
||||||
@ -91,7 +91,7 @@ struct ns_server {
|
|||||||
isc_boolean_t flushonshutdown;
|
isc_boolean_t flushonshutdown;
|
||||||
isc_boolean_t log_queries; /*%< For BIND 8 compatibility */
|
isc_boolean_t log_queries; /*%< For BIND 8 compatibility */
|
||||||
|
|
||||||
isc_uint64_t * querystats; /*%< Query statistics counters */
|
dns_stats_t * querystats; /*%< Query statistics counters */
|
||||||
|
|
||||||
ns_controls_t * controls; /*%< Control channels */
|
ns_controls_t * controls; /*%< Control channels */
|
||||||
unsigned int dispatchgen;
|
unsigned int dispatchgen;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: query.c,v 1.302 2008/01/18 23:46:57 tbox Exp $ */
|
/* $Id: query.c,v 1.303 2008/01/24 02:00:43 jinmei Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@ -130,12 +130,12 @@ inc_stats(ns_client_t *client, dns_statscounter_t counter) {
|
|||||||
|
|
||||||
REQUIRE(counter < DNS_STATS_NCOUNTERS);
|
REQUIRE(counter < DNS_STATS_NCOUNTERS);
|
||||||
|
|
||||||
ns_g_server->querystats[counter]++;
|
dns_stats_incrementcounter(ns_g_server->querystats, counter);
|
||||||
|
|
||||||
if (zone != NULL) {
|
if (zone != NULL) {
|
||||||
isc_uint64_t *zonestats = dns_zone_getstatscounters(zone);
|
dns_stats_t *zonestats = dns_zone_getstats(zone);
|
||||||
if (zonestats != NULL)
|
if (zonestats != NULL)
|
||||||
zonestats[counter]++;
|
dns_stats_incrementcounter(zonestats, counter);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: server.c,v 1.500 2008/01/22 00:29:03 jinmei Exp $ */
|
/* $Id: server.c,v 1.501 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@ -3800,8 +3800,8 @@ ns_server_create(isc_mem_t *mctx, ns_server_t **serverp) {
|
|||||||
server->server_usehostname = ISC_FALSE;
|
server->server_usehostname = ISC_FALSE;
|
||||||
server->server_id = NULL;
|
server->server_id = NULL;
|
||||||
|
|
||||||
CHECKFATAL(dns_stats_alloccounters(ns_g_mctx, &server->querystats),
|
CHECKFATAL(dns_stats_create(ns_g_mctx, &server->querystats),
|
||||||
"dns_stats_alloccounters");
|
"dns_stats_create");
|
||||||
|
|
||||||
server->flushonshutdown = ISC_FALSE;
|
server->flushonshutdown = ISC_FALSE;
|
||||||
server->log_queries = ISC_FALSE;
|
server->log_queries = ISC_FALSE;
|
||||||
@ -3825,7 +3825,7 @@ ns_server_destroy(ns_server_t **serverp) {
|
|||||||
|
|
||||||
ns_controls_destroy(&server->controls);
|
ns_controls_destroy(&server->controls);
|
||||||
|
|
||||||
dns_stats_freecounters(server->mctx, &server->querystats);
|
dns_stats_destroy(server->mctx, &server->querystats);
|
||||||
|
|
||||||
isc_mem_free(server->mctx, server->statsfile);
|
isc_mem_free(server->mctx, server->statsfile);
|
||||||
isc_mem_free(server->mctx, server->dumpfile);
|
isc_mem_free(server->mctx, server->dumpfile);
|
||||||
@ -4394,6 +4394,7 @@ ns_server_dumpstats(ns_server_t *server) {
|
|||||||
FILE *fp = NULL;
|
FILE *fp = NULL;
|
||||||
int i;
|
int i;
|
||||||
int ncounters;
|
int ncounters;
|
||||||
|
isc_uint64_t counters[DNS_STATS_NCOUNTERS];
|
||||||
|
|
||||||
isc_stdtime_get(&now);
|
isc_stdtime_get(&now);
|
||||||
|
|
||||||
@ -4403,22 +4404,23 @@ ns_server_dumpstats(ns_server_t *server) {
|
|||||||
ncounters = DNS_STATS_NCOUNTERS;
|
ncounters = DNS_STATS_NCOUNTERS;
|
||||||
fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
|
fprintf(fp, "+++ Statistics Dump +++ (%lu)\n", (unsigned long)now);
|
||||||
|
|
||||||
|
dns_stats_copy(server->querystats, counters);
|
||||||
for (i = 0; i < ncounters; i++)
|
for (i = 0; i < ncounters; i++)
|
||||||
fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT "u\n",
|
fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT "u\n",
|
||||||
dns_statscounter_names[i],
|
dns_statscounter_names[i], counters[i]);
|
||||||
server->querystats[i]);
|
|
||||||
|
|
||||||
zone = NULL;
|
zone = NULL;
|
||||||
for (result = dns_zone_first(server->zonemgr, &zone);
|
for (result = dns_zone_first(server->zonemgr, &zone);
|
||||||
result == ISC_R_SUCCESS;
|
result == ISC_R_SUCCESS;
|
||||||
next = NULL, result = dns_zone_next(zone, &next), zone = next)
|
next = NULL, result = dns_zone_next(zone, &next), zone = next)
|
||||||
{
|
{
|
||||||
isc_uint64_t *zonestats = dns_zone_getstatscounters(zone);
|
dns_stats_t *zonestats = dns_zone_getstats(zone);
|
||||||
if (zonestats != NULL) {
|
if (zonestats != NULL) {
|
||||||
char zonename[DNS_NAME_FORMATSIZE];
|
char zonename[DNS_NAME_FORMATSIZE];
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
char *viewname;
|
char *viewname;
|
||||||
|
|
||||||
|
dns_stats_copy(zonestats, counters);
|
||||||
dns_name_format(dns_zone_getorigin(zone),
|
dns_name_format(dns_zone_getorigin(zone),
|
||||||
zonename, sizeof(zonename));
|
zonename, sizeof(zonename));
|
||||||
view = dns_zone_getview(zone);
|
view = dns_zone_getview(zone);
|
||||||
@ -4427,7 +4429,7 @@ ns_server_dumpstats(ns_server_t *server) {
|
|||||||
fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT
|
fprintf(fp, "%s %" ISC_PRINT_QUADFORMAT
|
||||||
"u %s",
|
"u %s",
|
||||||
dns_statscounter_names[i],
|
dns_statscounter_names[i],
|
||||||
zonestats[i],
|
counters[i],
|
||||||
zonename);
|
zonename);
|
||||||
if (strcmp(viewname, "_default") != 0)
|
if (strcmp(viewname, "_default") != 0)
|
||||||
fprintf(fp, " %s", viewname);
|
fprintf(fp, " %s", viewname);
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: statschannel.c,v 1.4 2008/01/18 23:46:57 tbox Exp $ */
|
/* $Id: statschannel.c,v 1.5 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@ -71,6 +71,7 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
|
|||||||
int xmlrc;
|
int xmlrc;
|
||||||
dns_view_t *view;
|
dns_view_t *view;
|
||||||
int i;
|
int i;
|
||||||
|
isc_uint64_t counters[DNS_STATS_NCOUNTERS];
|
||||||
|
|
||||||
isc_time_now(&now);
|
isc_time_now(&now);
|
||||||
isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime);
|
isc_time_formatISO8601(&ns_g_boottime, boottime, sizeof boottime);
|
||||||
@ -117,12 +118,13 @@ generatexml(ns_server_t *server, int *buflen, xmlChar **buf) {
|
|||||||
xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr);
|
xmlTextWriterWriteString(writer, ISC_XMLCHAR nowstr);
|
||||||
xmlTextWriterEndElement(writer);
|
xmlTextWriterEndElement(writer);
|
||||||
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
TRY0(xmlTextWriterStartElement(writer, ISC_XMLCHAR "counters"));
|
||||||
|
dns_stats_copy(server->querystats, counters);
|
||||||
for (i = 0; i < DNS_STATS_NCOUNTERS; i++) {
|
for (i = 0; i < DNS_STATS_NCOUNTERS; i++) {
|
||||||
xmlTextWriterStartElement(writer,
|
xmlTextWriterStartElement(writer,
|
||||||
ISC_XMLCHAR dns_statscounter_names[i]);
|
ISC_XMLCHAR dns_statscounter_names[i]);
|
||||||
xmlTextWriterWriteFormatString(writer,
|
xmlTextWriterWriteFormatString(writer,
|
||||||
"%" ISC_PRINT_QUADFORMAT "u",
|
"%" ISC_PRINT_QUADFORMAT "u",
|
||||||
server->querystats[i]);
|
counters[i]);
|
||||||
xmlTextWriterEndElement(writer);
|
xmlTextWriterEndElement(writer);
|
||||||
}
|
}
|
||||||
xmlTextWriterEndElement(writer); /* counters */
|
xmlTextWriterEndElement(writer); /* counters */
|
||||||
|
13
configure.in
13
configure.in
@ -18,7 +18,7 @@ AC_DIVERT_PUSH(1)dnl
|
|||||||
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
|
esyscmd([sed "s/^/# /" COPYRIGHT])dnl
|
||||||
AC_DIVERT_POP()dnl
|
AC_DIVERT_POP()dnl
|
||||||
|
|
||||||
AC_REVISION($Revision: 1.436 $)
|
AC_REVISION($Revision: 1.437 $)
|
||||||
|
|
||||||
AC_INIT(lib/dns/name.c)
|
AC_INIT(lib/dns/name.c)
|
||||||
AC_PREREQ(2.59)
|
AC_PREREQ(2.59)
|
||||||
@ -2123,11 +2123,13 @@ main() {
|
|||||||
exit((sizeof(void *) == 8) ? 0 : 1);
|
exit((sizeof(void *) == 8) ? 0 : 1);
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
[arch=x86_64],
|
[arch=x86_64
|
||||||
|
have_xaddq=yes],
|
||||||
[arch=x86_32],
|
[arch=x86_32],
|
||||||
[arch=x86_32])
|
[arch=x86_32])
|
||||||
;;
|
;;
|
||||||
x86_64-*)
|
x86_64-*)
|
||||||
|
have_xaddq=yes
|
||||||
arch=x86_64
|
arch=x86_64
|
||||||
;;
|
;;
|
||||||
alpha*-*)
|
alpha*-*)
|
||||||
@ -2232,7 +2234,14 @@ else
|
|||||||
ISC_PLATFORM_HAVEATOMICSTORE="#undef ISC_PLATFORM_HAVEATOMICSTORE"
|
ISC_PLATFORM_HAVEATOMICSTORE="#undef ISC_PLATFORM_HAVEATOMICSTORE"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
if test "$have_xaddq" = "yes"; then
|
||||||
|
ISC_PLATFORM_HAVEXADDQ="#define ISC_PLATFORM_HAVEXADDQ 1"
|
||||||
|
else
|
||||||
|
ISC_PLATFORM_HAVEXADDQ="#undef ISC_PLATFORM_HAVEXADDQ"
|
||||||
|
fi
|
||||||
|
|
||||||
AC_SUBST(ISC_PLATFORM_HAVEXADD)
|
AC_SUBST(ISC_PLATFORM_HAVEXADD)
|
||||||
|
AC_SUBST(ISC_PLATFORM_HAVEXADDQ)
|
||||||
AC_SUBST(ISC_PLATFORM_HAVECMPXCHG)
|
AC_SUBST(ISC_PLATFORM_HAVECMPXCHG)
|
||||||
AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE)
|
AC_SUBST(ISC_PLATFORM_HAVEATOMICSTORE)
|
||||||
|
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: stats.h,v 1.13 2007/06/19 23:47:17 tbox Exp $ */
|
/* $Id: stats.h,v 1.14 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_STATS_H
|
#ifndef DNS_STATS_H
|
||||||
#define DNS_STATS_H 1
|
#define DNS_STATS_H 1
|
||||||
@ -42,11 +42,66 @@ typedef enum {
|
|||||||
|
|
||||||
LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[];
|
LIBDNS_EXTERNAL_DATA extern const char *dns_statscounter_names[];
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_stats_create(isc_mem_t *mctx, dns_stats_t **statsp);
|
||||||
|
/*%<
|
||||||
|
* Create a statistics counter structure.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li 'mctx' must be a valid memory context.
|
||||||
|
*
|
||||||
|
*\li 'statsp' != NULL && '*statsp' == NULL.
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_stats_destroy(isc_mem_t *mctx, dns_stats_t **statsp);
|
||||||
|
/*%<
|
||||||
|
* Destroy a statistics counter structure.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li 'mctx' must be a valid memory context.
|
||||||
|
*
|
||||||
|
*\li 'statsp' != NULL and '*statsp' be valid dns_stats_t.
|
||||||
|
*
|
||||||
|
* Ensures:
|
||||||
|
*
|
||||||
|
*\li '*statsp' == NULL
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_stats_incrementcounter(dns_stats_t *stat, dns_statscounter_t counter);
|
||||||
|
/*%<
|
||||||
|
* Increment a counter field of 'stat' specified by 'counter'.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li 'stat' be a valid dns_stats_t.
|
||||||
|
*
|
||||||
|
*\li counter < DNS_STATS_NCOUNTERS
|
||||||
|
*/
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_stats_copy(dns_stats_t *src, isc_uint64_t *dst);
|
||||||
|
/*%<
|
||||||
|
* Copy statistics counter fields of 'src' to the 'dst' array.
|
||||||
|
*
|
||||||
|
* Requires:
|
||||||
|
*
|
||||||
|
*\li 'src' be a valid dns_stats_t.
|
||||||
|
*
|
||||||
|
*\li 'dst' be sufficiently large to store DNS_STATS_NCOUNTERS 64-bit
|
||||||
|
* integers.
|
||||||
|
*/
|
||||||
|
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp);
|
dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp);
|
||||||
/*%<
|
/*%<
|
||||||
* Allocate an array of query statistics counters from the memory
|
* Allocate an array of query statistics counters from the memory
|
||||||
* context 'mctx'.
|
* context 'mctx'.
|
||||||
|
*
|
||||||
|
* This function is obsoleted. Use dns_stats_create() instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -54,6 +109,8 @@ dns_stats_freecounters(isc_mem_t *mctx, isc_uint64_t **ctrp);
|
|||||||
/*%<
|
/*%<
|
||||||
* Free an array of query statistics counters allocated from the memory
|
* Free an array of query statistics counters allocated from the memory
|
||||||
* context 'mctx'.
|
* context 'mctx'.
|
||||||
|
*
|
||||||
|
* This function is obsoleted. Use dns_stats_destroy() instead.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
ISC_LANG_ENDDECLS
|
ISC_LANG_ENDDECLS
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: types.h,v 1.126 2007/09/12 01:09:08 each Exp $ */
|
/* $Id: types.h,v 1.127 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_TYPES_H
|
#ifndef DNS_TYPES_H
|
||||||
#define DNS_TYPES_H 1
|
#define DNS_TYPES_H 1
|
||||||
@ -106,6 +106,7 @@ typedef isc_uint8_t dns_secproto_t;
|
|||||||
typedef struct dns_signature dns_signature_t;
|
typedef struct dns_signature dns_signature_t;
|
||||||
typedef struct dns_ssurule dns_ssurule_t;
|
typedef struct dns_ssurule dns_ssurule_t;
|
||||||
typedef struct dns_ssutable dns_ssutable_t;
|
typedef struct dns_ssutable dns_ssutable_t;
|
||||||
|
typedef struct dns_stats dns_stats_t;
|
||||||
typedef struct dns_tkeyctx dns_tkeyctx_t;
|
typedef struct dns_tkeyctx dns_tkeyctx_t;
|
||||||
typedef isc_uint16_t dns_trust_t;
|
typedef isc_uint16_t dns_trust_t;
|
||||||
typedef struct dns_tsig_keyring dns_tsig_keyring_t;
|
typedef struct dns_tsig_keyring dns_tsig_keyring_t;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.h,v 1.153 2007/09/18 00:22:31 marka Exp $ */
|
/* $Id: zone.h,v 1.154 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
#ifndef DNS_ZONE_H
|
#ifndef DNS_ZONE_H
|
||||||
#define DNS_ZONE_H 1
|
#define DNS_ZONE_H 1
|
||||||
@ -1488,6 +1488,12 @@ dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on);
|
|||||||
|
|
||||||
isc_uint64_t *
|
isc_uint64_t *
|
||||||
dns_zone_getstatscounters(dns_zone_t *zone);
|
dns_zone_getstatscounters(dns_zone_t *zone);
|
||||||
|
/*%<
|
||||||
|
* This function is obsoleted by dns_zone_getstats().
|
||||||
|
*/
|
||||||
|
|
||||||
|
dns_stats_t *
|
||||||
|
dns_zone_getstats(dns_zone_t *zone);
|
||||||
/*%<
|
/*%<
|
||||||
* Requires:
|
* Requires:
|
||||||
* zone be a valid zone.
|
* zone be a valid zone.
|
||||||
|
145
lib/dns/stats.c
145
lib/dns/stats.c
@ -15,13 +15,19 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: stats.c,v 1.12 2007/06/19 23:47:16 tbox Exp $ */
|
/* $Id: stats.c,v 1.13 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
#include <config.h>
|
#include <config.h>
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
#include <isc/atomic.h>
|
||||||
#include <isc/mem.h>
|
#include <isc/mem.h>
|
||||||
|
#include <isc/platform.h>
|
||||||
|
#include <isc/rwlock.h>
|
||||||
|
#include <isc/util.h>
|
||||||
|
|
||||||
#include <dns/stats.h>
|
#include <dns/stats.h>
|
||||||
|
|
||||||
@ -37,6 +43,143 @@ LIBDNS_EXTERNAL_DATA const char *dns_statscounter_names[DNS_STATS_NCOUNTERS] =
|
|||||||
"dropped"
|
"dropped"
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#ifndef DNS_STATS_USEMULTIFIELDS
|
||||||
|
#if defined(ISC_RWLOCK_USEATOMIC) && defined(ISC_PLATFORM_HAVEXADD) && !defined(ISC_PLATFORM_HAVEXADDQ)
|
||||||
|
#define DNS_STATS_USEMULTIFIELDS 1
|
||||||
|
#else
|
||||||
|
#define DNS_STATS_USEMULTIFIELDS 0
|
||||||
|
#endif
|
||||||
|
#endif /* DNS_STATS_USEMULTIFIELDS */
|
||||||
|
|
||||||
|
#if DNS_STATS_USEMULTIFIELDS
|
||||||
|
typedef struct {
|
||||||
|
isc_uint32_t hi;
|
||||||
|
isc_uint32_t lo;
|
||||||
|
} dns_stat_t;
|
||||||
|
#else
|
||||||
|
typedef isc_uint64_t dns_stat_t;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
struct dns_stats {
|
||||||
|
/* XXXJT: do we need a magic? */
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
isc_rwlock_t lock;
|
||||||
|
#endif
|
||||||
|
dns_stat_t counters[DNS_STATS_NCOUNTERS];
|
||||||
|
};
|
||||||
|
|
||||||
|
isc_result_t
|
||||||
|
dns_stats_create(isc_mem_t *mctx, dns_stats_t **statsp) {
|
||||||
|
dns_stats_t *stats;
|
||||||
|
isc_result_t result = ISC_R_SUCCESS;
|
||||||
|
|
||||||
|
REQUIRE(statsp != NULL && *statsp == NULL);
|
||||||
|
|
||||||
|
stats = isc_mem_get(mctx, sizeof(*stats));
|
||||||
|
if (stats == NULL)
|
||||||
|
return (ISC_R_NOMEMORY);
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
result = isc_rwlock_init(&stats->lock, 0, 0);
|
||||||
|
if (result != ISC_R_SUCCESS) {
|
||||||
|
isc_mem_put(mctx, stats, sizeof(*stats));
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
memset(stats->counters, 0, sizeof(dns_stat_t) * DNS_STATS_NCOUNTERS);
|
||||||
|
|
||||||
|
*statsp = stats;
|
||||||
|
|
||||||
|
return (result);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_stats_destroy(isc_mem_t *mctx, dns_stats_t **statsp) {
|
||||||
|
dns_stats_t *stats;
|
||||||
|
|
||||||
|
REQUIRE(statsp != NULL && *statsp != NULL);
|
||||||
|
|
||||||
|
stats = *statsp;
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
isc_rwlock_destroy(&stats->lock);
|
||||||
|
#endif
|
||||||
|
isc_mem_put(mctx, stats, sizeof(*stats));
|
||||||
|
|
||||||
|
*statsp = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_stats_incrementcounter(dns_stats_t *stats, dns_statscounter_t counter) {
|
||||||
|
isc_int32_t prev;
|
||||||
|
|
||||||
|
REQUIRE(counter < DNS_STATS_NCOUNTERS);
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
/*
|
||||||
|
* We use a "read" lock to prevent other threads from reading the
|
||||||
|
* counter while we "writing" a counter field. The write access itself
|
||||||
|
* is protected by the atomic operation.
|
||||||
|
*/
|
||||||
|
isc_rwlock_lock(&stats->lock, isc_rwlocktype_read);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DNS_STATS_USEMULTIFIELDS
|
||||||
|
prev = isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].lo, 1);
|
||||||
|
/*
|
||||||
|
* If the lower 32-bit field overflows, increment the higher field.
|
||||||
|
* Note that it's *theoretically* possible that the lower field
|
||||||
|
* overlaps again before the higher field is incremented. It doesn't
|
||||||
|
* matter, however, because we don't read the value until
|
||||||
|
* dns_stats_copy() is called where the whole process is protected
|
||||||
|
* by the write (exclusive) lock.
|
||||||
|
*/
|
||||||
|
if (prev == (isc_int32_t)0xffffffff)
|
||||||
|
isc_atomic_xadd((isc_int32_t *)&stats->counters[counter].hi, 1);
|
||||||
|
#elif defined(ISC_PLATFORM_HAVEXADDQ)
|
||||||
|
UNUSED(prev);
|
||||||
|
isc_atomic_xaddq((isc_int64_t *)&stats->counters[counter], 1);
|
||||||
|
#else
|
||||||
|
UNUSED(prev);
|
||||||
|
stats->counters[counter]++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
isc_rwlock_unlock(&stats->lock, isc_rwlocktype_read);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
dns_stats_copy(dns_stats_t *src, isc_uint64_t *dst) {
|
||||||
|
int i;
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
/*
|
||||||
|
* We use a "write" lock before "reading" the statistics counters as
|
||||||
|
* an exclusive lock.
|
||||||
|
*/
|
||||||
|
isc_rwlock_lock(&src->lock, isc_rwlocktype_write);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#if DNS_STATS_USEMULTIFIELDS
|
||||||
|
for (i = 0; i < DNS_STATS_NCOUNTERS; i++) {
|
||||||
|
dst[i] = ((isc_uint64_t)src->counters[i].hi) << 32 |
|
||||||
|
src->counters[i].lo;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
UNUSED(i);
|
||||||
|
memcpy(dst, src->counters, DNS_STATS_NCOUNTERS * sizeof(dst[0]));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef ISC_RWLOCK_USEATOMIC
|
||||||
|
isc_rwlock_unlock(&src->lock, isc_rwlocktype_write);
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
/***
|
||||||
|
*** Obsolete functions follow
|
||||||
|
***/
|
||||||
isc_result_t
|
isc_result_t
|
||||||
dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp) {
|
dns_stats_alloccounters(isc_mem_t *mctx, isc_uint64_t **ctrp) {
|
||||||
int i;
|
int i;
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: zone.c,v 1.470 2007/12/02 22:27:54 marka Exp $ */
|
/* $Id: zone.c,v 1.471 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
/*! \file */
|
/*! \file */
|
||||||
|
|
||||||
@ -251,7 +251,7 @@ struct dns_zone {
|
|||||||
/*%
|
/*%
|
||||||
* Optional per-zone statistics counters (NULL if not present).
|
* Optional per-zone statistics counters (NULL if not present).
|
||||||
*/
|
*/
|
||||||
isc_uint64_t *counters;
|
dns_stats_t *counters;
|
||||||
isc_uint32_t notifydelay;
|
isc_uint32_t notifydelay;
|
||||||
dns_isselffunc_t isself;
|
dns_isselffunc_t isself;
|
||||||
void *isselfarg;
|
void *isselfarg;
|
||||||
@ -736,7 +736,7 @@ zone_free(dns_zone_t *zone) {
|
|||||||
isc_mem_free(zone->mctx, zone->journal);
|
isc_mem_free(zone->mctx, zone->journal);
|
||||||
zone->journal = NULL;
|
zone->journal = NULL;
|
||||||
if (zone->counters != NULL)
|
if (zone->counters != NULL)
|
||||||
dns_stats_freecounters(zone->mctx, &zone->counters);
|
dns_stats_destroy(zone->mctx, &zone->counters);
|
||||||
if (zone->db != NULL)
|
if (zone->db != NULL)
|
||||||
zone_detachdb(zone);
|
zone_detachdb(zone);
|
||||||
if (zone->acache != NULL)
|
if (zone->acache != NULL)
|
||||||
@ -8092,11 +8092,11 @@ dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
|
|||||||
if (on) {
|
if (on) {
|
||||||
if (zone->counters != NULL)
|
if (zone->counters != NULL)
|
||||||
goto done;
|
goto done;
|
||||||
result = dns_stats_alloccounters(zone->mctx, &zone->counters);
|
result = dns_stats_create(zone->mctx, &zone->counters);
|
||||||
} else {
|
} else {
|
||||||
if (zone->counters == NULL)
|
if (zone->counters == NULL)
|
||||||
goto done;
|
goto done;
|
||||||
dns_stats_freecounters(zone->mctx, &zone->counters);
|
dns_stats_destroy(zone->mctx, &zone->counters);
|
||||||
}
|
}
|
||||||
done:
|
done:
|
||||||
UNLOCK_ZONE(zone);
|
UNLOCK_ZONE(zone);
|
||||||
@ -8105,6 +8105,15 @@ dns_zone_setstatistics(dns_zone_t *zone, isc_boolean_t on) {
|
|||||||
|
|
||||||
isc_uint64_t *
|
isc_uint64_t *
|
||||||
dns_zone_getstatscounters(dns_zone_t *zone) {
|
dns_zone_getstatscounters(dns_zone_t *zone) {
|
||||||
|
/*
|
||||||
|
* This function is obsoleted by dns_zone_getstats().
|
||||||
|
*/
|
||||||
|
UNUSED(zone);
|
||||||
|
return (NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
dns_stats_t *
|
||||||
|
dns_zone_getstats(dns_zone_t *zone) {
|
||||||
return (zone->counters);
|
return (zone->counters);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -8342,13 +8351,16 @@ dns_zone_xmlrender(dns_zone_t *zone, xmlTextWriterPtr xml, int flags)
|
|||||||
xmlTextWriterEndElement(xml);
|
xmlTextWriterEndElement(xml);
|
||||||
|
|
||||||
if (zone->counters != NULL) {
|
if (zone->counters != NULL) {
|
||||||
|
isc_uint64_t counters[DNS_STATS_NCOUNTERS];
|
||||||
|
|
||||||
xmlTextWriterStartElement(xml, ISC_XMLCHAR "counters");
|
xmlTextWriterStartElement(xml, ISC_XMLCHAR "counters");
|
||||||
|
dns_stats_copy(zone->counters, counters);
|
||||||
for (i = 0 ; i < DNS_STATS_NCOUNTERS ; i++) {
|
for (i = 0 ; i < DNS_STATS_NCOUNTERS ; i++) {
|
||||||
xmlTextWriterStartElement(xml,
|
xmlTextWriterStartElement(xml,
|
||||||
ISC_XMLCHAR dns_statscounter_names[i]);
|
ISC_XMLCHAR dns_statscounter_names[i]);
|
||||||
xmlTextWriterWriteFormatString(xml,
|
xmlTextWriterWriteFormatString(xml,
|
||||||
"%" ISC_PRINT_QUADFORMAT "u",
|
"%" ISC_PRINT_QUADFORMAT "u",
|
||||||
zone->counters[i]);
|
counters[i]);
|
||||||
xmlTextWriterEndElement(xml);
|
xmlTextWriterEndElement(xml);
|
||||||
}
|
}
|
||||||
xmlTextWriterEndElement(xml); /* counters */
|
xmlTextWriterEndElement(xml); /* counters */
|
||||||
|
@ -15,7 +15,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: platform.h.in,v 1.45 2007/09/13 04:45:18 each Exp $ */
|
/* $Id: platform.h.in,v 1.46 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
#ifndef ISC_PLATFORM_H
|
#ifndef ISC_PLATFORM_H
|
||||||
#define ISC_PLATFORM_H 1
|
#define ISC_PLATFORM_H 1
|
||||||
@ -236,6 +236,12 @@
|
|||||||
*/
|
*/
|
||||||
@ISC_PLATFORM_HAVEXADD@
|
@ISC_PLATFORM_HAVEXADD@
|
||||||
|
|
||||||
|
/*
|
||||||
|
* If the "xaddq" operation (64bit xadd) is available on this architecture,
|
||||||
|
* ISC_PLATFORM_HAVEXADDQ will be defined.
|
||||||
|
*/
|
||||||
|
@ISC_PLATFORM_HAVEXADDQ@
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the "atomic swap" operation is available on this architecture,
|
* If the "atomic swap" operation is available on this architecture,
|
||||||
* ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
|
* ISC_PLATFORM_HAVEATOMICSTORE" will be defined.
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: atomic.h,v 1.8 2007/07/27 14:22:53 explorer Exp $ */
|
/* $Id: atomic.h,v 1.9 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
#ifndef ISC_ATOMIC_H
|
#ifndef ISC_ATOMIC_H
|
||||||
#define ISC_ATOMIC_H 1
|
#define ISC_ATOMIC_H 1
|
||||||
@ -43,6 +43,24 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
|||||||
return (prev);
|
return (prev);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_HAVEXADDQ
|
||||||
|
static __inline__ isc_int64_t
|
||||||
|
isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
isc_int64_t prev = val;
|
||||||
|
|
||||||
|
__asm__ volatile(
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xaddq %0, %1"
|
||||||
|
:"=q"(prev)
|
||||||
|
:"m"(*p), "0"(prev)
|
||||||
|
:"memory", "cc");
|
||||||
|
|
||||||
|
return (prev);
|
||||||
|
}
|
||||||
|
#endif /* ISC_PLATFORM_HAVEXADDQ */
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* This routine atomically stores the value 'val' in 'p'.
|
* This routine atomically stores the value 'val' in 'p'.
|
||||||
*/
|
*/
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
* PERFORMANCE OF THIS SOFTWARE.
|
* PERFORMANCE OF THIS SOFTWARE.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/* $Id: atomic.h,v 1.4 2007/06/19 23:47:21 tbox Exp $ */
|
/* $Id: atomic.h,v 1.5 2008/01/24 02:00:44 jinmei Exp $ */
|
||||||
|
|
||||||
#ifndef ISC_ATOMIC_H
|
#ifndef ISC_ATOMIC_H
|
||||||
#define ISC_ATOMIC_H 1
|
#define ISC_ATOMIC_H 1
|
||||||
@ -49,15 +49,32 @@ isc_atomic_xadd(isc_int32_t *p, isc_int32_t val) {
|
|||||||
"lock;"
|
"lock;"
|
||||||
#endif
|
#endif
|
||||||
"xadd %eax, (%rdx)\n"
|
"xadd %eax, (%rdx)\n"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* set the return value directly in the register so that we
|
* XXX: assume %eax will be used as the return value.
|
||||||
* can avoid guessing the correct position in the stack for a
|
|
||||||
* local variable.
|
|
||||||
*/
|
*/
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef ISC_PLATFORM_HAVEXADDQ
|
||||||
|
static isc_int64_t
|
||||||
|
isc_atomic_xaddq(isc_int64_t *p, isc_int64_t val) {
|
||||||
|
UNUSED(p);
|
||||||
|
UNUSED(val);
|
||||||
|
|
||||||
|
__asm (
|
||||||
|
"movq %rdi, %rdx\n"
|
||||||
|
"movq %rsi, %rax\n"
|
||||||
|
#ifdef ISC_PLATFORM_USETHREADS
|
||||||
|
"lock;"
|
||||||
|
#endif
|
||||||
|
"xaddq %rax, (%rdx)\n"
|
||||||
|
/*
|
||||||
|
* XXX: assume %rax will be used as the return value.
|
||||||
|
*/
|
||||||
|
);
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
static void
|
static void
|
||||||
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
||||||
UNUSED(p);
|
UNUSED(p);
|
||||||
@ -70,6 +87,9 @@ isc_atomic_store(isc_int32_t *p, isc_int32_t val) {
|
|||||||
"lock;"
|
"lock;"
|
||||||
#endif
|
#endif
|
||||||
"xchgl (%rax), %edx\n"
|
"xchgl (%rax), %edx\n"
|
||||||
|
/*
|
||||||
|
* XXX: assume %rax will be used as the return value.
|
||||||
|
*/
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -89,7 +109,7 @@ isc_atomic_cmpxchg(isc_int32_t *p, isc_int32_t cmpval, isc_int32_t val) {
|
|||||||
#endif
|
#endif
|
||||||
/*
|
/*
|
||||||
* If (%rdi) == %eax then (%rdi) := %edx.
|
* If (%rdi) == %eax then (%rdi) := %edx.
|
||||||
% %eax is set to old (%ecx), which will be the return value.
|
* %eax is set to old (%ecx), which will be the return value.
|
||||||
*/
|
*/
|
||||||
"cmpxchgl %ecx, (%rdx)"
|
"cmpxchgl %ecx, (%rdx)"
|
||||||
);
|
);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user