@@ -225,7 +225,7 @@ static void synth_direntry(V9fsSynthNode *node,
}
static struct dirent *synth_get_dentry(V9fsSynthNode *dir,
- struct dirent *entry, off_t off)
+ struct dirent *entry, off_t off, V9fsSynthNode **hack)
{
int i = 0;
V9fsSynthNode *node;
@@ -243,16 +243,37 @@ static struct dirent *synth_get_dentry(V9fsSynthNode *dir,
/* end of directory */
return NULL;
}
+ *hack = node;
synth_direntry(node, entry, off);
return entry;
}
static struct dirent *synth_readdir(FsContext *ctx, V9fsFidOpenState *fs)
{
- struct dirent *entry;
+ struct dirent *entry = NULL;
V9fsSynthOpenState *synth_open = fs->private;
V9fsSynthNode *node = synth_open->node;
- entry = synth_get_dentry(node, &synth_open->dent, synth_open->offset);
+
+ /*
+ * HACK: This is just intended for benchmark, to avoid severe n-square
+ * performance problem of synth driver's readdir implementation here which
+ * would otherwise unncessarily taint the benchmark results. By simply
+ * caching (globally) the previous node (of the previous synth_readdir()
+ * call) we can simply proceed to next node in chained list efficiently.
+ *
+ * not a good idea for any production code ;-)
+ */
+ static struct V9fsSynthNode *cachedNode = NULL;
+
+ if (!cachedNode) {
+ entry = synth_get_dentry(node, &synth_open->dent, synth_open->offset, &cachedNode);
+ } else {
+ cachedNode = cachedNode->sibling.le_next;
+ if (cachedNode) {
+ entry = &synth_open->dent;
+ synth_direntry(cachedNode, entry, synth_open->offset+1);
+ }
+ }
if (entry) {
synth_open->offset++;
}
This patch is just a temporary benchmark hack, not intended to be merged! synth driver's readdir() implementation has a severe n-square performance problem. This patch is a quick and dirty hack to prevent that performance problem from tainting the readdir() benchmark results. Signed-off-by: Christian Schoenebeck <qemu_oss@crudebyte.com> --- hw/9pfs/9p-synth.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)