https://bugzilla.redhat.com/show_bug.cgi?id=1264008 The existing algorithm assumed that someone was making small, incremental changes; however, it is possible to change iothreads from 0 (or relatively small number) to some really large number and the algorithm would possibly spin its wheels doing unnecessary searches. So, optimize the algorithm using a bitmap to find available iothread_id's starting at 1 that aren't already defined by a "<thread id='#'>" and filling in the iothreadids array with those iothread_id values. Signed-off-by: John Ferlan <jferlan@xxxxxxxxxx> --- src/conf/domain_conf.c | 39 +++++++++++++++++++++++++++++++-------- 1 file changed, 31 insertions(+), 8 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index 70b2afc..3e15dcc 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2332,8 +2332,11 @@ virDomainIOThreadIDDefArrayFree(virDomainIOThreadIDDefPtr *def, static int virDomainIOThreadIDDefArrayInit(virDomainDefPtr def) { - unsigned int iothread_id = 1; int retval = -1; + size_t i; + ssize_t nxt = -1; + virDomainIOThreadIDDefPtr iothrid = NULL; + virBitmapPtr thrmap = NULL; /* Same value (either 0 or some number), then we have none to fill in or * the iothreadid array was filled from the XML @@ -2341,19 +2344,39 @@ virDomainIOThreadIDDefArrayInit(virDomainDefPtr def) if (def->iothreads == def->niothreadids) return 0; - while (def->niothreadids != def->iothreads) { - if (!virDomainIOThreadIDFind(def, iothread_id)) { - virDomainIOThreadIDDefPtr iothrid; + /* iothread's are numbered starting at 1, account for that */ + thrmap = virBitmapNew(def->iothreads + 1); + virBitmapSetAll(thrmap); - if (!(iothrid = virDomainIOThreadIDAdd(def, iothread_id))) - goto error; - iothrid->autofill = true; + /* Clear 0 since we don't use it, then mark those which are + * already provided by the user */ + ignore_value(virBitmapClearBit(thrmap, 0)); + for (i = 0; i < def->niothreadids; i++) + ignore_value(virBitmapClearBit(thrmap, + def->iothreadids[i]->iothread_id)); + + /* resize array */ + if (VIR_REALLOC_N(def->iothreadids, def->iothreads) < 0) + goto error; + + /* Populate iothreadids[] using the set bit number from thrmap */ + while (def->niothreadids < def->iothreads) { + if ((nxt = virBitmapNextSetBit(thrmap, nxt)) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("failed to populate iothreadids")); + goto error; } - iothread_id++; + if (VIR_ALLOC(iothrid) < 0) + goto error; + iothrid->iothread_id = nxt; + iothrid->autofill = true; + def->iothreadids[def->niothreadids++] = iothrid; } + retval = 0; error: + virBitmapFree(thrmap); return retval; } -- 2.1.0 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list