[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [PATCH v1 2/5] tools/ocaml/libs/xc: add binding to xc_evtchn_status


  • To: Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx>
  • From: Edwin Torok <edvin.torok@xxxxxxxxxx>
  • Date: Thu, 1 Dec 2022 14:37:33 +0000
  • Accept-language: en-GB, en-US
  • Arc-authentication-results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=citrix.com; dmarc=pass action=none header.from=citrix.com; dkim=pass header.d=citrix.com; arc=none
  • Arc-message-signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector9901; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=2a6X1odYGz18AIWN2ze9NBqfaMB0fs6Us7TSZizNaN0=; b=GsSy5qysnERGZr1okTV4d7aEwte+QOUdYFI/I+XCtiMt3/Z+Fwfw6162r4sdZAAWop0KpPl2tscv/MuuPXoy8crbX8qRpYJ9o9BgS7oVWPyT/m6QnWlyx+mlQ0zwmVUCKMx8gKuEW2JIP7LPWDpk8behvCb+NCVFUtIKeuIUAJahjBoILosZefUQc1732fxA2hVPNCA/muxvrQVArIieW6oZ0vTMtB/YQJ9M1TtH9S3kPJL9n5vpMVDyCvpMGoDdpQiWYBvX/dpU7pzxIkLwSdbhqvSA8cow9XSbSFdpmTsCA8d0iLZHe4rJT57opZEWN+yCxIciSaWEyDTDNm7lAg==
  • Arc-seal: i=1; a=rsa-sha256; s=arcselector9901; d=microsoft.com; cv=none; b=iQ+GcINoH8ENHYYLTTw3NQD6d2b6dkMAgvkVfevHPIankqbObTm0E6yrTPbDbOCYquJylRlYVpG2MeufcRx69wgM4t30FYH63nsoPAN5IShuBXjwavDN/mD4PZve6GVaWa4mRBgBsybqihc+A3Y20e05dUu7MTqsZjPqW6RVBAZiIFPGMFZIFx+pdyDY1r0TfVlajlrt7FTlNI7dc23f7mzftXKBKr+nPS6XNGVzCAHt4RYewuiU9cNlRfZlS2SjZLxF1tKwP4lmLLeyiA+OcomcryFFgo2N5HX2pWkcqCYB9DwRuuYeYMUY3laio93EqA+EtPGOTNoA1XwJIaytrA==
  • Authentication-results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=citrix.com;
  • Cc: "xen-devel@xxxxxxxxxxxxxxxxxxxx" <xen-devel@xxxxxxxxxxxxxxxxxxxx>, Christian Lindig <christian.lindig@xxxxxxxxxx>, David Scott <dave@xxxxxxxxxx>, Wei Liu <wl@xxxxxxx>, Anthony Perard <anthony.perard@xxxxxxxxxx>
  • Delivery-date: Thu, 01 Dec 2022 14:37:47 +0000
  • Ironport-data: A9a23:ilCFkK9ODQPLyyLT6NPDDrUDp3+TJUtcMsCJ2f8bNWPcYEJGY0x3m GBKD22HMquJNzT9Koxxaonn8BgD6MDcy9M2HlRu/Co8E34SpcT7XtnIdU2Y0wF+jCHgZBk+s 5hBMImowOQcFCK0SsKFa+C5xZVE/fjUAOG6UKucYHsZqTZMEE8JkQhkl/MynrlmiN24BxLlk d7pqojUNUTNNwRcawr40Ire7kIx1BjOkGlA5AZnP6gS5AW2e0Q9V/rzG4ngdxMUfaEMdgKKb 76r5K20+Grf4yAsBruN+losWhRXKlJ6FVHmZkt+A8BOsDAbzsAB+v9T2M4nQVVWk120c+VZk 72hg3ASpTABZcUgkMxFO/VR/roX0aduoNcrKlDn2SCfItGvn9IBDJyCAWlvVbD09NqbDklTq 9EoBjoVZCnTmrvv66zmSrFUiPwKeZyD0IM34hmMzBn/JNN/GdXpZfqP4tVVmjAtmspJAPDSI dIDbiZiZwjBZBsJPUoLDJU5n6GjgXyXnz9w8QrJ4/ZopTeLilUpjNABM/KMEjCObchZgEee4 H7B5WP6KhobKMae2XyO9XfEaurnzX2nCN5MROPQGvhCmXCQwGNQNiQvZWCF8cedyU6fHPRPN BlBksYphe1onKCxdfHtUhv9rHOasxo0X9tLD/Z8+AyL0rDT4QuSGi4DVDEpQNAvqsIeXzEh0 V6N2dTzClRHr7m9WX+bsLCOoluP1TM9KGYDYWoOS1QD6ty6+IUr1EuXEpBkDbK/icDzFXfo2 TeWoSMihrIVy8kWy6G8+lOBiDWpznTUcjMICszsdjrNxmtEiESNPORENXCzAS58Ebuk
  • Ironport-hdrordr: A9a23:+1tNeaBm9+3ttzjlHem755DYdb4zR+YMi2TDsHoQdfU1SKGlfq WV954mPHDP+VUssQ4b6LW90cW7LU80lqQFg7X5X43CYOCOggLBEGgI1+XfKlPbdBEW/9QtsZ tdTw==
  • List-id: Xen developer discussion <xen-devel.lists.xenproject.org>
  • Thread-index: AQHZBOHW/H7dZ4yOzkGdiH1xKACrBq5Y590AgAAh0QCAAAbXgIAACo8A
  • Thread-topic: [PATCH v1 2/5] tools/ocaml/libs/xc: add binding to xc_evtchn_status


> On 1 Dec 2022, at 13:59, Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx> wrote:
> 
> On 01/12/2022 13:35, Edwin Torok wrote:
>>> On 1 Dec 2022, at 11:34, Andrew Cooper <Andrew.Cooper3@xxxxxxxxxx> wrote:
>>> 
>>> On 30/11/2022 17:32, Edwin Török wrote:
>>>> +
>>>> +    caml_enter_blocking_section();
>>>> +    rc = xc_evtchn_status(_H(xch), &status);
>>>> +    caml_leave_blocking_section();
>>>> +
>>>> +    if ( rc < 0 )
>>>> +        failwith_xc(_H(xch));
>>>> +
>>>> +    if ( status.status == EVTCHNSTAT_closed )
>>>> +        result = Val_none;
>>>> +    else
>>>> +    {
>>> This is actually one example where using a second CAMLreturn would
>>> simply things substantially.
>>> 
>>> switch ( status.status )
>>> {
>>> case EVTCHNSTAT_closed:
>>>    CAMLreturn(Val_none);
>>> 
>>> case EVTCHNSTAT_unbound:
>>>    ...
>>> 
>>> Would remove the need for the outer if/else.
>> 
>> CAMLreturn has some macro magic to ensure it gets paired with the toplevel 
>> CAMLparam correctly (one of them opens a { scope and the other closes it, or 
>> something like that),
>> so I'd avoid putting it into the middle of other syntactic elements, it 
>> might just cause the build to fail (either now or in the future).
> 
> From the manual:
> 
> "The macros CAMLreturn, CAMLreturn0, and CAMLreturnT are used to replace
> the C keyword return. Every occurrence of return x must be replaced by ..."
> 
> It is common in C to have multiple returns, and the manual does say
> "Every occurrence" without stating any requirement for there to be a
> single occurrence.
> 
> CAMLreturn can't syntactically work splitting a scope with CAMLparam,
> because then this wouldn't compile:
> 
> CAMLprim value stub_xc_evtchn_status(value foo)
> {
>     CAMLparam1(foo);
>     int bar = 0;
> 
> retry:
>     if ( bar )
>         CAMLreturn(foo);
> 
>     bar++
>     goto retry;
> }
> 


I wouldn't expect it to, or at least I've never seen a C binding written that 
way (with CAMLreturn not as last statement),
but indeed nothing in the manual states that it wouldn't work.

> CAMLreturn does use a normal "do { ... } while (0)" construct simply for
> being a macro, and forces paring with CAMLparamX by referencing the
> caml__frame local variable by name.
> 
> 
> So I really do think that multiple CAMLreturns are fine and cannot
> reasonably be broken in the future.
> 
> But if we do really still want to keep a single return, then a "goto
> done" would be acceptable here and still better than the if/else.

I almost always used to use do/while(0) and break even in C as a replacement 
for 'goto',
especially if there are multiple nested resources that need cleaning up, 
do/while ensures you
unwind them in the correct order and don't accidentally skip one.
I think most code that is written using 'goto' can be rewritten not to use it, 
and might avoid some bugs in the process
(e.g. using goto might leave some local variables uninitialised).
I'm reluctant to introduce a goto just to decrease nesting level.

There might be another way to rewrite the code:
```
switch(status.status)
{
case EVTCHNSTAT_closed:
 stat = Val_none;
 break;
... other code that assigns to stat something other than None ...
}

if (Val_none == stat) {
   result = Val_none;
} else {
   .. code as it was before to construct a some ...
}

CAMLreturn(result);
```

This would then follow the logical order of how the values are constructed, and 
avoids the deep nesting of the switch.
(reading the code backwards from exit will show you how each piece is 
nested/constructed without jumps that alter control flow)

Val_none == is used instead of == Val_none to catch a typo where stat = 
Val_none would change stat, whereas Val_none = stat would be a compile error.

What do you think?

(might be slightly less efficient than the original version, but a reasonable C 
compiler should produce almost equal optimized code for both).

> 
>>> caml_alloc_some() is perhaps less interesting as it only appeared in
>>> Ocaml 4.12 AFAICT, but we could also have some ifdefary for that at the
>>> top of the file.
>>> 
>>> I don't know whether we have opencoded options elsewhere in the
>>> bindings, but it certainly would be reduce the amount opencoding that
>>> exists for standard patterns.
>> 
>> perhaps we can look into doing that cleanup as a separate patch.
> 
> Probably best, yes.
> 
> ~Andrew


 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.