Skip to content

Commit 3df0823

Browse files
committed
Avoid qname cache when possible
1 parent 99f1700 commit 3df0823

File tree

2 files changed

+56
-8
lines changed

2 files changed

+56
-8
lines changed

include/simics/dmllib.h

Lines changed: 27 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2256,36 +2256,55 @@ __qname(dml_qname_cache_t *cache, const char *fmt, ...)
22562256
return (const char *)s;
22572257
}
22582258

2259-
UNUSED static char *
2260-
_DML_get_qname_alloc(_identity_t id, const _id_info_t *id_infos,
2261-
const char *dev_name) {
2259+
UNUSED static const char *
2260+
__static_qname(_identity_t id, const _id_info_t *id_infos,
2261+
const char *dev_name)
2262+
{
22622263
_id_info_t info = id_infos[id.id - 1];
2263-
22642264
const char *logname = info.logname;
22652265

22662266
// In order to distinguish the device object from any other, its id_info
22672267
// logname is always "dev", but we want its name when it comes to qname.
22682268
if (strcmp(logname, "dev") == 0) {
2269-
return MM_STRDUP(dev_name);
2269+
return dev_name;
22702270
}
22712271

2272+
// avoid the qname cache if we can
22722273
if (info.dimensions == 0) {
2273-
return MM_STRDUP(logname);
2274+
return logname;
22742275
}
22752276

2277+
return NULL;
2278+
}
2279+
2280+
UNUSED static char *
2281+
_DML_get_qname_alloc(_identity_t id, const _id_info_t *id_infos,
2282+
const char *dev_name)
2283+
{
2284+
const char *simple = __static_qname(id, id_infos, dev_name);
2285+
if (simple != NULL) {
2286+
return MM_STRDUP(simple);
2287+
}
2288+
2289+
_id_info_t info = id_infos[id.id - 1];
22762290
uint32 indices[info.dimensions];
22772291
uint32 index = id.encoded_index;
22782292
for (int32 i = info.dimensions - 1; i >= 0; --i) {
22792293
indices[i] = index % info.dimsizes[i];
22802294
index /= info.dimsizes[i];
22812295
}
22822296

2283-
return _DML_format_indices(logname, indices, info.dimensions);
2297+
return _DML_format_indices(info.logname, indices, info.dimensions);
22842298
}
22852299

22862300
UNUSED static const char *
22872301
_DML_get_qname(_identity_t id, const _id_info_t *id_infos,
2288-
dml_qname_cache_t *cache, const char *dev_name) {
2302+
dml_qname_cache_t *cache, const char *dev_name)
2303+
{
2304+
const char *simple = __static_qname(id, id_infos, dev_name);
2305+
if (simple != NULL) {
2306+
return simple;
2307+
}
22892308
char *temp_qname = _DML_get_qname_alloc(id, id_infos, dev_name);
22902309
const char *qname = __qname(cache, "%s", temp_qname);
22912310
MM_FREE(temp_qname);

test/1.4/lib/T_qname.dml

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@ device test;
88

99
group test;
1010

11+
group arr[i < 10];
12+
1113
method init() {
1214
// _qname() is built on the identity de/serialization machinery,
1315
// which takes care to distinguish between the device object
@@ -16,4 +18,31 @@ method init() {
1618
// string it retrieves from the identity de/serialization machinery.
1719
assert strcmp(dev._qname(), "test") == 0;
1820
assert strcmp(test._qname(), "test") == 0;
21+
22+
// qname depends on a weird circular caching mechanism which gives
23+
// incorrect names if you have too many (currently >4) indexed qnames in
24+
// flux simultaneously. A couple of hacks are applied to reduce the risk
25+
// that this happens. This test checks the edges of when it breaks and when
26+
// it doesn't.
27+
local const char *s[5];
28+
for (local int i = 0; i < s.len; i++) {
29+
s[i] = arr[i].qname;
30+
}
31+
local strbuf_t sb = sb_newf(
32+
"%s %s %s %s %s",
33+
s[0], s[1], s[2], s[3], s[4]);
34+
// circular buffer overflow, arr[4] overwrites arr[0]
35+
assert strcmp(sb_str(&sb), "arr[4] arr[1] arr[2] arr[3] arr[4]") == 0;
36+
37+
// some usages of qname don't affect the cache:
38+
// constant indexed
39+
local const char *_ = arr[4].qname;
40+
// unindexed
41+
_ = test._qname();
42+
// non-constant indexed qname in a log statement causes log string rewrite
43+
local int i = 5;
44+
log info: "%s", arr[i].qname;
45+
sb_fmt(&sb, "%s %s %s %s %s", s[0], s[1], s[2], s[3], s[4]);
46+
// arr[1] is unaffected by the above qname expressions
47+
assert strcmp(sb_str(&sb), "arr[4] arr[1] arr[2] arr[3] arr[4]") == 0;
1948
}

0 commit comments

Comments
 (0)