158
171
struct isc_mempool {
159
172
/* always unlocked */
160
unsigned int magic; /* magic number */
161
isc_mutex_t *lock; /* optional lock */
162
isc_mem_t *mctx; /* our memory context */
163
/* locked via the memory context's lock */
164
ISC_LINK(isc_mempool_t) link; /* next pool in this mem context */
165
/* optionally locked from here down */
166
element *items; /* low water item list */
167
size_t size; /* size of each item on this pool */
168
unsigned int maxalloc; /* max number of items allowed */
169
unsigned int allocated; /* # of items currently given out */
170
unsigned int freecount; /* # of items on reserved list */
171
unsigned int freemax; /* # of items allowed on free list */
172
unsigned int fillcount; /* # of items to fetch on each fill */
174
unsigned int gets; /* # of requests to this pool */
175
/* Debugging only. */
173
unsigned int magic; /*%< magic number */
174
isc_mutex_t *lock; /*%< optional lock */
175
isc_mem_t *mctx; /*%< our memory context */
176
/*%< locked via the memory context's lock */
177
ISC_LINK(isc_mempool_t) link; /*%< next pool in this mem context */
178
/*%< optionally locked from here down */
179
element *items; /*%< low water item list */
180
size_t size; /*%< size of each item on this pool */
181
unsigned int maxalloc; /*%< max number of items allowed */
182
unsigned int allocated; /*%< # of items currently given out */
183
unsigned int freecount; /*%< # of items on reserved list */
184
unsigned int freemax; /*%< # of items allowed on free list */
185
unsigned int fillcount; /*%< # of items to fetch on each fill */
187
unsigned int gets; /*%< # of requests to this pool */
188
/*%< Debugging only. */
176
189
#if ISC_MEMPOOL_NAMES
177
char name[16]; /* printed name in stats reports */
190
char name[16]; /*%< printed name in stats reports */
749
775
ctx->checkfree = ISC_TRUE;
750
776
#if ISC_MEM_TRACKLINES
751
777
ctx->debuglist = NULL;
778
ctx->debuglistcnt = 0;
753
780
ISC_LIST_INIT(ctx->pools);
755
#if ISC_MEM_USE_INTERNAL_MALLOC
756
782
ctx->freelists = NULL;
757
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
759
ctx->stats = (memalloc)(arg,
760
(ctx->max_size+1) * sizeof(struct stats));
761
if (ctx->stats == NULL) {
762
result = ISC_R_NOMEMORY;
765
memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof(struct stats));
767
#if ISC_MEM_USE_INTERNAL_MALLOC
768
if (target_size == 0)
769
ctx->mem_target = DEF_MEM_TARGET;
771
ctx->mem_target = target_size;
772
ctx->freelists = (memalloc)(arg, ctx->max_size * sizeof(element *));
773
if (ctx->freelists == NULL) {
774
result = ISC_R_NOMEMORY;
777
memset(ctx->freelists, 0,
778
ctx->max_size * sizeof(element *));
779
783
ctx->basic_blocks = NULL;
780
784
ctx->basic_table = NULL;
781
785
ctx->basic_table_count = 0;
782
786
ctx->basic_table_size = 0;
783
787
ctx->lowest = NULL;
784
788
ctx->highest = NULL;
785
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
790
ctx->stats = (memalloc)(arg,
791
(ctx->max_size+1) * sizeof(struct stats));
792
if (ctx->stats == NULL) {
793
result = ISC_R_NOMEMORY;
796
memset(ctx->stats, 0, (ctx->max_size + 1) * sizeof(struct stats));
798
if ((flags & ISC_MEMFLAG_INTERNAL) != 0) {
799
if (target_size == 0U)
800
ctx->mem_target = DEF_MEM_TARGET;
802
ctx->mem_target = target_size;
803
ctx->freelists = (memalloc)(arg, ctx->max_size *
805
if (ctx->freelists == NULL) {
806
result = ISC_R_NOMEMORY;
809
memset(ctx->freelists, 0,
810
ctx->max_size * sizeof(element *));
787
813
#if ISC_MEM_TRACKLINES
788
814
if ((isc_mem_debugging & ISC_MEM_DEBUGRECORD) != 0) {
958
#if ISC_MEM_USE_INTERNAL_MALLOC
960
mem_putunlocked(ctx, ptr, size);
961
#else /* ISC_MEM_USE_INTERNAL_MALLOC */
962
mem_put(ctx, ptr, size);
964
mem_putstats(ctx, ptr, size);
965
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
1003
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) {
1004
if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
1005
si = &(((size_info *)ptr)[-1]);
1006
oldsize = si->u.size - ALIGNMENT_SIZE;
1007
if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)
1008
oldsize -= ALIGNMENT_SIZE;
1009
INSIST(oldsize == size);
1011
isc__mem_free(ctx, ptr FLARG_PASS);
1013
MCTXLOCK(ctx, &ctx->lock);
1015
if (ctx->references == 0)
1016
want_destroy = ISC_TRUE;
1017
MCTXUNLOCK(ctx, &ctx->lock);
1024
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
1025
MCTXLOCK(ctx, &ctx->lock);
1026
mem_putunlocked(ctx, ptr, size);
1028
mem_put(ctx, ptr, size);
1029
MCTXLOCK(ctx, &ctx->lock);
1030
mem_putstats(ctx, ptr, size);
967
1033
DELETE_TRACE(ctx, ptr, size, file, line);
968
1034
INSIST(ctx->references > 0);
1057
1125
isc__mem_put(isc_mem_t *ctx, void *ptr, size_t size FLARG)
1059
1127
isc_boolean_t call_water = ISC_FALSE;
1061
1131
REQUIRE(VALID_CONTEXT(ctx));
1062
1132
REQUIRE(ptr != NULL);
1064
#if ISC_MEM_USE_INTERNAL_MALLOC
1066
mem_putunlocked(ctx, ptr, size);
1067
#else /* ISC_MEM_USE_INTERNAL_MALLOC */
1068
mem_put(ctx, ptr, size);
1070
mem_putstats(ctx, ptr, size);
1071
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
1134
if ((isc_mem_debugging & (ISC_MEM_DEBUGSIZE|ISC_MEM_DEBUGCTX)) != 0) {
1135
if ((isc_mem_debugging & ISC_MEM_DEBUGSIZE) != 0) {
1136
si = &(((size_info *)ptr)[-1]);
1137
oldsize = si->u.size - ALIGNMENT_SIZE;
1138
if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0)
1139
oldsize -= ALIGNMENT_SIZE;
1140
INSIST(oldsize == size);
1142
isc__mem_free(ctx, ptr FLARG_PASS);
1146
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
1147
MCTXLOCK(ctx, &ctx->lock);
1148
mem_putunlocked(ctx, ptr, size);
1150
mem_put(ctx, ptr, size);
1151
MCTXLOCK(ctx, &ctx->lock);
1152
mem_putstats(ctx, ptr, size);
1073
1155
DELETE_TRACE(ctx, ptr, size, file, line);
1231
1329
isc__mem_allocate(isc_mem_t *ctx, size_t size FLARG) {
1331
isc_boolean_t call_water = ISC_FALSE;
1234
1333
REQUIRE(VALID_CONTEXT(ctx));
1236
#if ISC_MEM_USE_INTERNAL_MALLOC
1238
si = isc__mem_allocateunlocked(ctx, size);
1239
#else /* ISC_MEM_USE_INTERNAL_MALLOC */
1240
si = isc__mem_allocateunlocked(ctx, size);
1243
mem_getstats(ctx, si[-1].u.size);
1244
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
1335
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
1336
MCTXLOCK(ctx, &ctx->lock);
1337
si = isc__mem_allocateunlocked(ctx, size);
1339
si = isc__mem_allocateunlocked(ctx, size);
1340
MCTXLOCK(ctx, &ctx->lock);
1342
mem_getstats(ctx, si[-1].u.size);
1246
1345
#if ISC_MEM_TRACKLINES
1247
1346
ADD_TRACE(ctx, si, si[-1].u.size, file, line);
1348
if (ctx->hi_water != 0U && !ctx->hi_called &&
1349
ctx->inuse > ctx->hi_water) {
1350
ctx->hi_called = ISC_TRUE;
1351
call_water = ISC_TRUE;
1353
if (ctx->inuse > ctx->maxinuse) {
1354
ctx->maxinuse = ctx->inuse;
1355
if (ctx->hi_water != 0U && ctx->inuse > ctx->hi_water &&
1356
(isc_mem_debugging & ISC_MEM_DEBUGUSAGE) != 0)
1357
fprintf(stderr, "maxinuse = %lu\n",
1358
(unsigned long)ctx->inuse);
1360
MCTXUNLOCK(ctx, &ctx->lock);
1363
(ctx->water)(ctx->water_arg, ISC_MEM_HIWATER);
1256
1369
isc__mem_free(isc_mem_t *ctx, void *ptr FLARG) {
1372
isc_boolean_t call_water= ISC_FALSE;
1260
1374
REQUIRE(VALID_CONTEXT(ctx));
1261
1375
REQUIRE(ptr != NULL);
1263
si = &(((size_info *)ptr)[-1]);
1377
if ((isc_mem_debugging & ISC_MEM_DEBUGCTX) != 0) {
1378
si = &(((size_info *)ptr)[-2]);
1379
REQUIRE(si->u.ctx == ctx);
1380
size = si[1].u.size;
1382
si = &(((size_info *)ptr)[-1]);
1266
#if ISC_MEM_USE_INTERNAL_MALLOC
1268
mem_putunlocked(ctx, si, size);
1269
#else /* ISC_MEM_USE_INTERNAL_MALLOC */
1270
mem_put(ctx, si, size);
1272
mem_putstats(ctx, si, size);
1273
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
1386
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
1387
MCTXLOCK(ctx, &ctx->lock);
1388
mem_putunlocked(ctx, si, size);
1390
mem_put(ctx, si, size);
1391
MCTXLOCK(ctx, &ctx->lock);
1392
mem_putstats(ctx, si, size);
1275
1395
DELETE_TRACE(ctx, ptr, size, file, line);
1398
* The check against ctx->lo_water == 0 is for the condition
1399
* when the context was pushed over hi_water but then had
1400
* isc_mem_setwater() called with 0 for hi_water and lo_water.
1402
if (ctx->hi_called &&
1403
(ctx->inuse < ctx->lo_water || ctx->lo_water == 0U)) {
1404
ctx->hi_called = ISC_FALSE;
1406
if (ctx->water != NULL)
1407
call_water = ISC_TRUE;
1409
MCTXUNLOCK(ctx, &ctx->lock);
1412
(ctx->water)(ctx->water_arg, ISC_MEM_LOWATER);
1345
1480
REQUIRE(VALID_CONTEXT(ctx));
1481
MCTXLOCK(ctx, &ctx->lock);
1348
1483
inuse = ctx->inuse;
1485
MCTXUNLOCK(ctx, &ctx->lock);
1352
1487
return (inuse);
1356
1491
isc_mem_setwater(isc_mem_t *ctx, isc_mem_water_t water, void *water_arg,
1357
size_t hiwater, size_t lowater)
1492
size_t hiwater, size_t lowater)
1494
isc_boolean_t callwater = ISC_FALSE;
1495
isc_mem_water_t oldwater;
1359
1498
REQUIRE(VALID_CONTEXT(ctx));
1360
1499
REQUIRE(hiwater >= lowater);
1501
MCTXLOCK(ctx, &ctx->lock);
1502
oldwater = ctx->water;
1503
oldwater_arg = ctx->water_arg;
1363
1504
if (water == NULL) {
1505
callwater = ctx->hi_called;
1364
1506
ctx->water = NULL;
1365
1507
ctx->water_arg = NULL;
1366
1508
ctx->hi_water = 0;
1367
1509
ctx->lo_water = 0;
1368
1510
ctx->hi_called = ISC_FALSE;
1512
if (ctx->hi_called &&
1513
(ctx->water != water || ctx->water_arg != water_arg ||
1514
ctx->inuse < lowater || lowater == 0U))
1515
callwater = ISC_TRUE;
1370
1516
ctx->water = water;
1371
1517
ctx->water_arg = water_arg;
1372
1518
ctx->hi_water = hiwater;
1373
1519
ctx->lo_water = lowater;
1374
1520
ctx->hi_called = ISC_FALSE;
1522
MCTXUNLOCK(ctx, &ctx->lock);
1524
if (callwater && oldwater != NULL)
1525
(oldwater)(oldwater_arg, ISC_MEM_LOWATER);
1529
isc_mem_setname(isc_mem_t *ctx, const char *name, void *tag) {
1530
REQUIRE(VALID_CONTEXT(ctx));
1533
memset(ctx->name, 0, sizeof(ctx->name));
1534
strncpy(ctx->name, name, sizeof(ctx->name) - 1);
1376
1536
UNLOCK(&ctx->lock);
1540
isc_mem_getname(isc_mem_t *ctx) {
1541
REQUIRE(VALID_CONTEXT(ctx));
1547
isc_mem_gettag(isc_mem_t *ctx) {
1548
REQUIRE(VALID_CONTEXT(ctx));
1380
1554
* Memory pool stuff
1469
1644
* Return any items on the free list
1646
MCTXLOCK(mctx, &mctx->lock);
1472
1647
while (mpctx->items != NULL) {
1473
1648
INSIST(mpctx->freecount > 0);
1474
1649
mpctx->freecount--;
1475
1650
item = mpctx->items;
1476
1651
mpctx->items = item->next;
1478
#if ISC_MEM_USE_INTERNAL_MALLOC
1479
mem_putunlocked(mctx, item, mpctx->size);
1480
#else /* ISC_MEM_USE_INTERNAL_MALLOC */
1481
mem_put(mctx, item, mpctx->size);
1482
mem_putstats(mctx, item, mpctx->size);
1483
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
1653
if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
1654
mem_putunlocked(mctx, item, mpctx->size);
1656
mem_put(mctx, item, mpctx->size);
1657
mem_putstats(mctx, item, mpctx->size);
1485
UNLOCK(&mctx->lock);
1660
MCTXUNLOCK(mctx, &mctx->lock);
1488
1663
* Remove our linked list entry from the memory context.
1665
MCTXLOCK(mctx, &mctx->lock);
1491
1666
ISC_LIST_UNLINK(mctx->pools, mpctx, link);
1492
UNLOCK(&mctx->lock);
1668
MCTXUNLOCK(mctx, &mctx->lock);
1494
1670
mpctx->magic = 0;
1609
1785
mpctx->allocated--;
1611
1787
#if ISC_MEM_TRACKLINES
1788
MCTXLOCK(mctx, &mctx->lock);
1613
1789
DELETE_TRACE(mctx, mem, mpctx->size, file, line);
1614
UNLOCK(&mctx->lock);
1790
MCTXUNLOCK(mctx, &mctx->lock);
1615
1791
#endif /* ISC_MEM_TRACKLINES */
1618
1794
* If our free list is full, return this to the mctx directly.
1620
1796
if (mpctx->freecount >= mpctx->freemax) {
1621
#if ISC_MEM_USE_INTERNAL_MALLOC
1623
mem_putunlocked(mctx, mem, mpctx->size);
1624
UNLOCK(&mctx->lock);
1625
#else /* ISC_MEM_USE_INTERNAL_MALLOC */
1626
mem_put(mctx, mem, mpctx->size);
1628
mem_putstats(mctx, mem, mpctx->size);
1629
UNLOCK(&mctx->lock);
1630
#endif /* ISC_MEM_USE_INTERNAL_MALLOC */
1797
if ((mctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
1798
MCTXLOCK(mctx, &mctx->lock);
1799
mem_putunlocked(mctx, mem, mpctx->size);
1800
MCTXUNLOCK(mctx, &mctx->lock);
1802
mem_put(mctx, mem, mpctx->size);
1803
MCTXLOCK(mctx, &mctx->lock);
1804
mem_putstats(mctx, mem, mpctx->size);
1805
MCTXUNLOCK(mctx, &mctx->lock);
1631
1807
if (mpctx->lock != NULL)
1632
1808
UNLOCK(mpctx->lock);
1776
1952
return (fillcount);
1956
isc_mem_printactive(isc_mem_t *ctx, FILE *file) {
1958
REQUIRE(VALID_CONTEXT(ctx));
1959
REQUIRE(file != NULL);
1961
#if !ISC_MEM_TRACKLINES
1965
print_active(ctx, file);
1970
isc_mem_printallactive(FILE *file) {
1971
#if !ISC_MEM_TRACKLINES
1976
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
1979
for (ctx = ISC_LIST_HEAD(contexts);
1981
ctx = ISC_LIST_NEXT(ctx, link)) {
1982
fprintf(file, "context: %p\n", ctx);
1983
print_active(ctx, file);
1990
isc_mem_checkdestroyed(FILE *file) {
1992
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
1995
if (!ISC_LIST_EMPTY(contexts)) {
1996
#if ISC_MEM_TRACKLINES
1999
for (ctx = ISC_LIST_HEAD(contexts);
2001
ctx = ISC_LIST_NEXT(ctx, link)) {
2002
fprintf(file, "context: %p\n", ctx);
2003
print_active(ctx, file);
2014
typedef struct summarystat {
2017
isc_uint64_t blocksize;
2018
isc_uint64_t contextsize;
2022
renderctx(isc_mem_t *ctx, summarystat_t *summary, xmlTextWriterPtr writer) {
2023
REQUIRE(VALID_CONTEXT(ctx));
2025
xmlTextWriterStartElement(writer, ISC_XMLCHAR "context");
2027
xmlTextWriterStartElement(writer, ISC_XMLCHAR "id");
2028
xmlTextWriterWriteFormatString(writer, "%p", ctx);
2029
xmlTextWriterEndElement(writer); /* id */
2031
if (ctx->name[0] != 0) {
2032
xmlTextWriterStartElement(writer, ISC_XMLCHAR "name");
2033
xmlTextWriterWriteFormatString(writer, "%s", ctx->name);
2034
xmlTextWriterEndElement(writer); /* name */
2037
REQUIRE(VALID_CONTEXT(ctx));
2038
MCTXLOCK(ctx, &ctx->lock);
2040
summary->contextsize += sizeof(*ctx) +
2041
(ctx->max_size + 1) * sizeof(struct stats) +
2042
ctx->max_size * sizeof(element *) +
2043
ctx->basic_table_count * sizeof(char *);
2044
#if ISC_MEM_TRACKLINES
2045
if (ctx->debuglist != NULL) {
2046
summary->contextsize +=
2047
(ctx->max_size + 1) * sizeof(debuglist_t) +
2048
ctx->debuglistcnt * sizeof(debuglink_t);
2051
xmlTextWriterStartElement(writer, ISC_XMLCHAR "references");
2052
xmlTextWriterWriteFormatString(writer, "%d", ctx->references);
2053
xmlTextWriterEndElement(writer); /* references */
2055
summary->total += ctx->total;
2056
xmlTextWriterStartElement(writer, ISC_XMLCHAR "total");
2057
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2058
(isc_uint64_t)ctx->total);
2059
xmlTextWriterEndElement(writer); /* total */
2061
summary->inuse += ctx->inuse;
2062
xmlTextWriterStartElement(writer, ISC_XMLCHAR "inuse");
2063
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2064
(isc_uint64_t)ctx->inuse);
2065
xmlTextWriterEndElement(writer); /* inuse */
2067
xmlTextWriterStartElement(writer, ISC_XMLCHAR "maxinuse");
2068
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2069
(isc_uint64_t)ctx->maxinuse);
2070
xmlTextWriterEndElement(writer); /* maxinuse */
2072
xmlTextWriterStartElement(writer, ISC_XMLCHAR "blocksize");
2073
if ((ctx->flags & ISC_MEMFLAG_INTERNAL) != 0) {
2074
summary->blocksize += ctx->basic_table_count *
2075
NUM_BASIC_BLOCKS * ctx->mem_target;
2076
xmlTextWriterWriteFormatString(writer,
2077
"%" ISC_PRINT_QUADFORMAT "u",
2079
ctx->basic_table_count *
2083
xmlTextWriterWriteFormatString(writer, "%s", "-");
2084
xmlTextWriterEndElement(writer); /* blocksize */
2086
xmlTextWriterStartElement(writer, ISC_XMLCHAR "pools");
2087
xmlTextWriterWriteFormatString(writer, "%u", ctx->poolcnt);
2088
xmlTextWriterEndElement(writer); /* pools */
2089
summary->contextsize += ctx->poolcnt * sizeof(isc_mempool_t);
2091
xmlTextWriterStartElement(writer, ISC_XMLCHAR "hiwater");
2092
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2093
(isc_uint64_t)ctx->hi_water);
2094
xmlTextWriterEndElement(writer); /* hiwater */
2096
xmlTextWriterStartElement(writer, ISC_XMLCHAR "lowater");
2097
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2098
(isc_uint64_t)ctx->lo_water);
2099
xmlTextWriterEndElement(writer); /* lowater */
2101
MCTXUNLOCK(ctx, &ctx->lock);
2103
xmlTextWriterEndElement(writer); /* context */
2107
isc_mem_renderxml(xmlTextWriterPtr writer) {
2109
summarystat_t summary;
2112
memset(&summary, 0, sizeof(summary));
2114
xmlTextWriterStartElement(writer, ISC_XMLCHAR "contexts");
2116
RUNTIME_CHECK(isc_once_do(&once, initialize_action) == ISC_R_SUCCESS);
2120
for (ctx = ISC_LIST_HEAD(contexts);
2122
ctx = ISC_LIST_NEXT(ctx, link)) {
2123
renderctx(ctx, &summary, writer);
2127
xmlTextWriterEndElement(writer); /* contexts */
2129
xmlTextWriterStartElement(writer, ISC_XMLCHAR "summary");
2131
xmlTextWriterStartElement(writer, ISC_XMLCHAR "TotalUse");
2132
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2134
xmlTextWriterEndElement(writer); /* TotalUse */
2136
xmlTextWriterStartElement(writer, ISC_XMLCHAR "InUse");
2137
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2139
xmlTextWriterEndElement(writer); /* InUse */
2141
xmlTextWriterStartElement(writer, ISC_XMLCHAR "BlockSize");
2142
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2144
xmlTextWriterEndElement(writer); /* BlockSize */
2146
xmlTextWriterStartElement(writer, ISC_XMLCHAR "ContextSize");
2147
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2148
summary.contextsize);
2149
xmlTextWriterEndElement(writer); /* ContextSize */
2151
xmlTextWriterStartElement(writer, ISC_XMLCHAR "Lost");
2152
xmlTextWriterWriteFormatString(writer, "%" ISC_PRINT_QUADFORMAT "u",
2154
xmlTextWriterEndElement(writer); /* Lost */
2156
xmlTextWriterEndElement(writer); /* summary */
2159
#endif /* HAVE_LIBXML2 */