[libvirt] [PATCH 2/5] tests: refactor virstoragetest for less stack space

Eric Blake eblake at redhat.com
Fri Apr 4 12:35:25 UTC 2014


On 04/04/2014 02:54 AM, Peter Krempa wrote:
> On 04/04/14 06:32, Eric Blake wrote:
>> I'm about to add fields to virStorageFileMetadata, which means
>> also adding fields to the testFileData struct in virstoragetest.
>> Alas, adding even one pointer on an x86_64 machine gave me a
>> dreaded compiler error:
>>
>> virstoragetest.c:712:1: error: the frame size of 4208 bytes is larger than 4096 bytes [-Werror=frame-larger-than=]
>>
>> After some experimentation, I realized that each test was creating
>> yet another testChainData (which contains testFileData) on the stack;
>> forcing the reuse of one of these structures instead of creating a
>> fresh one each time drastically reduces the size requirements.  While
>> at it, I also got rid of a lot of intermediate structs, with some
>> macro magic that lets me directly build up the destination chains
>> inline.
> 
> Unfortunately it's not completely trivial to understand what's happening
> on the first glance.

I'll expand the commit message before pushing.  Basically,

> -#define TEST_ONE_CHAIN(id, start, format, chain, flags)              \
> +#define TEST_ONE_CHAIN(id, start, format, flags, ...)                \
>      do {                                                             \
> -        struct testChainData data = {                                \
> -            start, format, chain, ARRAY_CARDINALITY(chain), flags,   \

the old code was populating data.files = chain, where 'chain' was an
intermediate variable and files is a testFileData*

> +        size_t i;                                                    \
> +        memset(&data, 0, sizeof(data));                              \
> +        data = (struct testChainData){                               \
> +            start, format, { __VA_ARGS__ }, 0, flags,                \
>          };                                                           \

while the new code is populating data.files = { ptr, ptr, ... }, with no
intermediate chain variable, and where files is now an array of
testFileData*.

> +        for (i = 0; i < ARRAY_CARDINALITY(data.files); i++)          \
> +            if (data.files[i])                                       \
> +                data.nfiles++;                                       \

Pre-patch, counting the number of files was done by the size of the
'chain' intermediate variable.  Post-patch, it is done by counting the
number of non-NULL pointers in the 'files' array.

> 
> +        TEST_ONE_CHAIN(#id "a", relstart, format, flags1,            \
> +                       VIR_FLATTEN_1(chain1));                       \

Here, VIR_FLATTEN_1 is macro magic that takes a single macro argument in
the form '(a, b, c)' and turns it into multiple arguments 'a, b, c' to
TEST_ONE_CHAIN's use of '...'

>      /* Raw image, whether with right format or no specified format */
> -    const testFileData chain1[] = { raw };
>      TEST_CHAIN(1, "raw", absraw, VIR_STORAGE_FILE_RAW,
> -               chain1, EXP_PASS,
> -               chain1, ALLOW_PROBE | EXP_PASS,
> -               chain1, EXP_PASS,
> -               chain1, ALLOW_PROBE | EXP_PASS);
> +               (&raw), EXP_PASS,
> +               (&raw), ALLOW_PROBE | EXP_PASS,
> +               (&raw), EXP_PASS,
> +               (&raw), ALLOW_PROBE | EXP_PASS);

Then for each test, I replaced uses of 'chain1' (the intermediate
variable)' with '(contents of chain1)' as a direct argument to TEST_CHAIN.

> 
> As it's test code: ACK

Yes, we have that going for us - if it compiles and still passes the
testsuite, it was probably correct :)

-- 
Eric Blake   eblake redhat com    +1-919-301-3266
Libvirt virtualization library http://libvirt.org

-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 604 bytes
Desc: OpenPGP digital signature
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20140404/60c74f3a/attachment-0001.sig>


More information about the libvir-list mailing list