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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list