input: calloc minimization for xi2mask_new

There's no reason to do this as (nmasks + 2) callocs, and it's a
surprisingly hot path.  Turns out you hit this ~once per passive grab,
and you do a few bajillion passive grab changes every time you enter or
leave the overview in gnome-shell.  According to a callgrind of Xorg
with gnome-shell-perf-tool run against it:

Ir before: 721437275
Ir after:  454227086

Signed-off-by: Adam Jackson <ajax@redhat.com>
Reviewed-by: Jasper St. Pierre <jstpierre@mecheye.net>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
This commit is contained in:
Adam Jackson 2013-09-10 14:18:18 -04:00 committed by Peter Hutterer
parent 44d502c6f1
commit 5ac4bfca64

View File

@ -960,8 +960,15 @@ XI2Mask *
xi2mask_new_with_size(size_t nmasks, size_t size) xi2mask_new_with_size(size_t nmasks, size_t size)
{ {
int i; int i;
int alloc_size;
unsigned char *cursor;
XI2Mask *mask;
XI2Mask *mask = calloc(1, sizeof(*mask)); alloc_size = sizeof(struct _XI2Mask)
+ nmasks * sizeof(unsigned char *)
+ nmasks * size;
mask = calloc(1, alloc_size);
if (!mask) if (!mask)
return NULL; return NULL;
@ -969,20 +976,14 @@ xi2mask_new_with_size(size_t nmasks, size_t size)
mask->nmasks = nmasks; mask->nmasks = nmasks;
mask->mask_size = size; mask->mask_size = size;
mask->masks = calloc(mask->nmasks, sizeof(*mask->masks)); mask->masks = (unsigned char **)(mask + 1);
if (!mask->masks) cursor = (unsigned char *)(mask + 1) + nmasks * sizeof(unsigned char *);
goto unwind;
for (i = 0; i < mask->nmasks; i++) { for (i = 0; i < nmasks; i++) {
mask->masks[i] = calloc(1, mask->mask_size); mask->masks[i] = cursor;
if (!mask->masks[i]) cursor += size;
goto unwind;
} }
return mask; return mask;
unwind:
xi2mask_free(&mask);
return NULL;
} }
/** /**
@ -1003,14 +1004,9 @@ xi2mask_new(void)
void void
xi2mask_free(XI2Mask **mask) xi2mask_free(XI2Mask **mask)
{ {
int i;
if (!(*mask)) if (!(*mask))
return; return;
for (i = 0; (*mask)->masks && i < (*mask)->nmasks; i++)
free((*mask)->masks[i]);
free((*mask)->masks);
free((*mask)); free((*mask));
*mask = NULL; *mask = NULL;
} }