On Fri, Feb 27, 2015 at 02:37:00PM +0100, Michal Privoznik wrote:
On 26.02.2015 15:17, Michal Privoznik wrote:
> <snip/>
>
BTW: I've done some testing locally and it helped me to find a bug in my
patches (I've just proposed the diff to be squashed in). Basically, my
test program defines 10 dummy networks, and spawns a thread over each
one of them. The thread does 1000 iterations of some network API calls,
e.g. define, undefine, start, destroy, IsActive, IsPersistent, and so
on. And the results are astonishing:
Without my patches:
$ time ./test_network_lock qemu+tcp://localhost/system
Connected. Starting workers ...
Waiting for workers to end ...
real 0m54.083s
user 0m1.317s
sys 0m1.302s
With my patches:
$ time ./test_network_lock qemu+tcp://localhost/system
Connected. Starting workers ...
Waiting for workers to end ...
real 0m42.355s
user 0m1.231s
sys 0m1.324s
So nearly 12 seconds speed up! The test program can be found at [1].
Michal
1:
http://fpaste.org/191340/
Since paste bin's expire, adding the test program content below:
--------------------------------------------------------------------
#include <stdio.h>
#include <stdlib.h>
#include <pthread.h>
#include <libvirt/libvirt.h>
#include <libvirt/virterror.h>
#define NETS 10
#define ITER 1000
static void *
workerfunc(void *opaque)
{
virNetworkPtr *netptr = opaque;
virNetworkPtr net = *netptr;
virConnectPtr conn = virNetworkGetConnect(net);
size_t i;
char *xml = NULL;
char *bridgename = NULL;
for (i = 0; i < ITER; i++) {
int isActive = virNetworkIsActive(net);
int isPersistent = virNetworkIsPersistent(net);
int autostart;
if (virNetworkGetAutostart(net, &autostart) < 0) {
fprintf(stderr, "Unable to get autostart\n");
goto cleanup;
}
if (!(xml = virNetworkGetXMLDesc(net, 0))) {
fprintf(stderr, "Unable to get net XML\n");
goto cleanup;
}
if (!(bridgename = virNetworkGetBridgeName(net))) {
fprintf(stderr, "Unable to get net bridge name\n");
goto cleanup;
}
if (virNetworkCreate(net) < 0) {
fprintf(stderr, "Unable to start network\n");
goto cleanup;
}
if (virNetworkDestroy(net) < 0) {
fprintf(stderr, "Unable to destroy network\n");
goto cleanup;
}
if (virNetworkUndefine(net) < 0) {
fprintf(stderr, "Unable to undefine network\n");
goto cleanup;
}
if (!(net = virNetworkDefineXML(conn, xml))) {
fprintf(stderr, "Unable to define network back\n");
goto cleanup;
}
free(xml);
free(bridgename);
xml = bridgename = NULL;
}
cleanup:
free(xml);
free(bridgename);
*netptr = net;
return NULL;
}
static int
defineNets(virConnectPtr conn,
virNetworkPtr **nets,
int *nnets)
{
int ret = -1;
char *defxml = NULL;
const char *xml = \
"<network>" \
" <name>testnet%d</name>" \
" <forward mode='bridge'/>" \
" <bridge name='br%d'/>" \
"</network>";
for (*nnets = 0; *nnets < NETS; (*nnets)++) {
virNetworkPtr net;
if (asprintf(&defxml, xml, *nnets, *nnets) < 0) {
fprintf(stderr, "Unable to create network XML\n");
goto cleanup;
}
if (!(*nets = realloc(*nets, (*nnets + 1) * sizeof((*nets)[0])))) {
fprintf(stderr, "Unable to allocate memory\n");
goto cleanup;
}
if (!(net = virNetworkDefineXML(conn, defxml))) {
fprintf(stderr, "Unable to define network\n");
goto cleanup;
}
(*nets)[*nnets] = net;
}
ret = 0;
cleanup:
free(defxml);
if (ret < 0) {
while (*nnets) {
(*nnets)--;
virNetworkUndefine((*nets)[*nnets]);
virNetworkFree((*nets)[*nnets]);
}
}
return ret;
}
int main(int argc, char **argv)
{
int ret = -1;
virConnectPtr conn = NULL;
virNetworkPtr *nets = NULL;
int nnets = 0;
pthread_t workers[NETS];
size_t nworkers = 0;
if (virInitialize() < 0) {
fprintf(stderr, "Failed to initialize libvirt.\n");
return -1;
}
conn = virConnectOpenAuth(argc > 1 ? argv[1] : NULL,
virConnectAuthPtrDefault, 0);
if (!conn) {
fprintf(stderr, "error opening\n");
return -1;
}
if (defineNets(conn, &nets, &nnets) < 0)
goto cleanup;
printf("Connected. Starting workers ...\n");
for (nworkers = 0; nworkers < nnets; nworkers++) {
if (pthread_create(&workers[nworkers], NULL, workerfunc, &nets[nworkers])
< 0)
goto cleanup;
}
printf("Waiting for workers to end ...\n");
while (nworkers)
pthread_join(workers[--nworkers], NULL);
ret = 0;
cleanup:
while (nnets) {
nnets--;
virNetworkDestroy(nets[nnets]);
virNetworkUndefine(nets[nnets]);
virNetworkFree(nets[nnets]);
}
free(nets);
while (nworkers)
pthread_join(workers[--nworkers], NULL);
virConnectClose(conn);
return ret;
}
--------------------------------------------------------------------
--
/kashyap