[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH 4/9] hbitmap: store / restore
From: |
Paolo Bonzini |
Subject: |
Re: [Qemu-devel] [PATCH 4/9] hbitmap: store / restore |
Date: |
Thu, 08 Jan 2015 22:37:50 +0100 |
User-agent: |
Mozilla/5.0 (X11; Linux x86_64; rv:31.0) Gecko/20100101 Thunderbird/31.3.0 |
On 08/01/2015 22:21, John Snow wrote:
> Why are the conversions to little endian, though? Shouldn't we be
> serializing to a Big Endian format?
Because reading two 32-bit little-endian longs or a 64-bit little-endian
long gives the same value. This is not true for big-endian.
Take the following two 32-bit values:
0x04030201 0x08070605
representing offsets 0 and 32 in the bitmap. Parse them back as one
64-bit little endian value:
0x0807060504030201 = 0x04030201 + 0x08070605 * 2^32
Now parse them as as one 64-bit big endian value:
0x0403020108070605 => 0x08070605 + 0x04030201 * 2^32
so the values are swapped.
>> +void hbitmap_restore_data(HBitmap *hb, uint8_t *buf,
>> + uint64_t start, uint64_t count)
>> +{
>> + uint64_t last = start + count - 1;
>> + unsigned long *in = (unsigned long *)buf;
>> +
>> + if (count == 0) {
>> + return;
>> + }
>> +
>> + start = (start >> hb->granularity) >> BITS_PER_LEVEL;
>> + last = (last >> hb->granularity) >> BITS_PER_LEVEL;
>> + count = last - start + 1;
>> +
>> +#ifdef __BIG_ENDIAN_BITFIELD
>> + for (i = start; i <= last; ++i) {
>> + hb->levels[HBITMAP_LEVELS - 1][i] =
>> + (BITS_PER_LONG == 32 ? be32_to_cpu(in[i]) :
>> be64_to_cpu(in[i]));
>> + }
>> +#else
>> + memcpy(&hb->levels[HBITMAP_LEVELS - 1][start], in,
>> + count * sizeof(unsigned long));
>> +#endif
>> +}
>> +
>
> ...? We're storing as LE but restoring from BE? I'm confused.
>
> I'm also not clear on the __BIG_ENDIAN_BITFIELD macro. Why do we want to
> pack differently based on how C-bitfields are packed by the compiler? I
> don't think that has any impact on how longs are stored (always in the
> host native format.)
I agree.
Paolo