On 7/27/23 19:36, Eric Blake wrote:
> On Thu, Jul 27, 2023 at 01:23:24PM +0200, Laszlo Ersek wrote:
>> On 7/26/23 19:50, Eric Blake wrote:
>>> This reverts commit 6725fa0e129f9a60d7b89707ef8604e0aeeeaf43, although
>>> with a more modern style.
>>>
>>> Casting a C array to a Go slice just to benefit from potential
>>> optimizations in Go's copy(), is rather complex to understand,
>>> especially when we are still copying things (the main reason to treat
>>> a C array as a Go slice is when avoiding a copy has a benefit).
>>> Without a benchmark showing measurable difference in runtime speed,
>>> and considering that network transit time probably dominates the time
>>> spent on block status and its callback, it is not worth the
>>> complexity.  Furthermore, an upcoming patch wants to add a similar
>>> helper function for converting between a list of C and Go structs,
>>> where the copy() trick will not work; and having the two helpers look
>>> alike is beneficial.
>>>
>>> Suggested-by: Laszlo Ersek <ler...@redhat.com>
>>
>> I've needed to dig a bit, but indeed, bullet (8) in:
>>
>> 0e4ff751-88d6-837b-15a5-6f6c370a2f09@redhat.com">http://mid.mail-archive.com/0e4ff751-88d6-837b-15a5-6f6c370a2f09@redhat.com
>> https://listman.redhat.com/archives/libguestfs/2023-June/031736.html
>>
>>> CC: Nir Soffer <nsof...@redhat.com>
>>> Signed-off-by: Eric Blake <ebl...@redhat.com>
>>> ---
>>>  generator/GoLang.ml | 14 ++++++++------
>>>  1 file changed, 8 insertions(+), 6 deletions(-)
>>>
>>> diff --git a/generator/GoLang.ml b/generator/GoLang.ml
>>> index 0aa83bdc..77dacadb 100644
>>> --- a/generator/GoLang.ml
>>> +++ b/generator/GoLang.ml
>>> @@ -509,12 +509,14 @@ let
>>>
>>>  /* Closures. */
>>>
>>> -func copy_uint32_array (entries *C.uint32_t, count C.size_t) []uint32 {
>>> -    ret := make([]uint32, int (count))
>>> -    // See 
>>> https://github.com/golang/go/wiki/cgo#turning-c-arrays-into-go-slices
>>> -    // TODO: Use unsafe.Slice() when we require Go 1.17.
>>> -    s := (*[1<<30]uint32)(unsafe.Pointer(entries))[:count:count]
>>> -    copy(ret, s)
>>> +func copy_uint32_array(entries *C.uint32_t, count C.size_t) []uint32 {
>>> +    ret := make([]uint32, int(count))
>>> +    addr := uintptr(unsafe.Pointer(entries))
>>> +    for i := 0; i < int(count); i++ {
>>> +        ptr := (*C.uint32_t)(unsafe.Pointer(addr))
>>> +        ret[i] = uint32(*ptr)
>>> +        addr += unsafe.Sizeof(*ptr)
>>> +    }
>>>      return ret
>>>  }
>>>  ";
>>
>> This patch mixes four things:
>>
>> - whitespace changes (due to style modernization / gofmt, presumably),
>> - reverting commit 6725fa0e129f,
>> - changes proposed in my email,
>> - functional changes on top of my email.
>>
>> The "func" line matches my proposal (OK), with additional whitespace updates 
>> (OK), but has nothing to do with reverting 6725fa0e129f, so calling the 
>> patch a "revert" is misleading.
> 
> Fair enough.  It is undoing the effects of the earlier patch, but not
> in the same way as a straight revert (in part because enough else has
> changed in the meantime that a straight revert is no longer possible).
> Plus the decision on where to stage this in the series (at one point,
> I had it after 6/7 - and you already noted there how much rebase churn
> gets caused as we mix this series around).
> 
>>
>> The initialization of "ret" undergoes a whitespace update (OK), but is 
>> neither a revert (6725fa0e129f did not change the initialization of "ret"), 
>> nor does it match my proposal. In my proposal, I had removed the "int" cast 
>> (or conversion) intentionally. Casting a C size_t to a Go int seems wrong. 
>> (IIRC I had verified the widths of the Go integer types from the Go 
>> documentation.)
> 
> I completely missed that point.  You do make a valid point that a C
> size_t might be larger than a Go int (does Go even try to run on
> 32-bit platforms?) - but we DO have the additional knowledge that
> because our block status reply results cannot exceed 64M over the
> wire, any count passed to the callback function will fit in 32 bits
> regardless of the width of C's size_t.  Maybe an assertion that count
> does not lose precision when cast to Go int is sufficient?

Sure, an assertion (with explanation) would be fine.

> 
>>
>> The initialization of "addr" matches my proposal, with some whitespace 
>> updates (OK), but is not a revert of 6725fa0e129f.
>>
>> The "for" statement is a revert, but does not match my proposal. My proposal 
>> made sure that the loop variable was a Go uint64, so that it could 
>> accommodate the C size_t. The only Go syntax I found suitable for that was 
>> to replace the ":=" embedded in the "for", with a separate 
>> definition/initialization of "i" (where I could spell out the uint64 type), 
>> and then to use the "for" variant that was effectively a "while" (using C 
>> terminology):
>>
>>     var i uint64 = 0
>>     for i < uint64(count) {
>>         ...
>>         i++
>>     }
>>
>> Here we cast the C size_t to uint64, which is OK.
>>
>> A different approach to the same end, preserving the ":=" syntax in "for", 
>> could be:
>>
>>     for i := uint64(0); i < uint64(count); i++ {
> 
> I don't know enough Go syntax to quickly state if there is some other
> way to coerce a := expression into having a guaranteed 64-bit native
> type.
> 
>>         ...
>>     }
>>
>> This keeps the "count" cast safe, and it also forces -- I think? -- "i" to 
>> have type "uint64", by casting "0" to "uint64" in the ":=" operation.
>>
>> Anyway, I was super careful about those nuances when I wrote my proposal, so 
>> I'd like to stick with them. I suggest that:
>>
>> - we not call this patch a "revert", just update the code incrementally; 
>> perhaps reference commit 6725fa0e129f in the commit message
>>
>> - we stick with the exact code I proposed (unless there are specific 
>> problems with it), applying whitespace updates on top that are now required 
>> by gofmt.
> 
> Okay, I'll need to rethink how to do this patch (perhaps by
> rearranging it to occur after 7/7, by folding it into the rest of the
> 64-bit series where I add the nbd_extent list conversion code).
> 

Thanks!
Laszlo
_______________________________________________
Libguestfs mailing list
Libguestfs@redhat.com
https://listman.redhat.com/mailman/listinfo/libguestfs

Reply via email to