
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
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