August 07, 2005
On Sun, 7 Aug 2005 20:37:49 +1000, Derek Parnell wrote:
Is this all I have to do to make it thread safe?

void letThem( inout int becomesOne, inout int becomesTwo)
{
    int localOne;
    int localTwo;
    // Ensure the arguments reference two different integer values.
    if (RAM_Overlaps(&becomesOne, int.sizeof, &becomesTwo, int.sizeof))
    {
       throw ReferenceException( ...whatever...);
    }

    // Take a local backup of value in case the transaction fails
    localOne = becomesOne;
    localTwo = becomesTwo;

    synchronized  /// << THREAD SAFE?
    try {
        becomesOne = 1;
        becomesTwo = 2;
    }
    catch(Object e)
    {
     // Transaction failed, so restore previous values.
      becomesOne = localOne;
      becomesTwo = localTwo;
      throw e;  // Pass exception up the tree.
    }
}


-- 
Derek Parnell
Melbourne, Australia
7/08/2005 8:40:36 PM
August 07, 2005
In article <188ahyevatlas.1ufld3sj4yymc.dlg@40tude.net>, Derek Parnell says...
>
>Okay ...
>
>(G) The specification does not say what to do with the passed values of the
>arguments.
>(H) The specification does not define if setting both values is to be
>atomic; that is, either none is set or both are set, or it doesn't matter.
>(J) The specification does not define what to do when the arguments refer
>to the same memory location.
>
>[..]

In fact, there is no specification, documentation or code comments what so ever. It's impossible to know what this function is supposed to do and why.

I got the feeling this is the kind of "joke" where the replies make up the funny part, and the poster is the one to laugh :)

Nick


August 07, 2005
Manfred Nowak wrote:
> 1) Review this code:
> 
> void f( inout int i, inout int j){
>   i= 1;
>   j= 2;
> }
> 
> 
> 2) Pass or Fail?
> 
> 3) Explain.
> 
> 
> -manfred

hmmm, from the other posts I gather there is a small problem with this kind of code:
#int i = 5;
#f(i,i);
^
such calls should be illegal; that is: no variable can be passed as an "out" parameter more than once.

Is that -by any chance- what you are trying to hint to?
August 07, 2005
In article <wfhd177f2kmv.18w8hgs4gvztb$.dlg@40tude.net>, Derek Parnell says...
>
>On Sun, 7 Aug 2005 20:37:49 +1000, Derek Parnell wrote:
>Is this all I have to do to make it thread safe?
>
>void letThem( inout int becomesOne, inout int becomesTwo)
>{
>    int localOne;
>    int localTwo;
>    // Ensure the arguments reference two different integer values.
>    if (RAM_Overlaps(&becomesOne, int.sizeof, &becomesTwo, int.sizeof))
>    {
>       throw ReferenceException( ...whatever...);
>    }
>
>    // Take a local backup of value in case the transaction fails
>    localOne = becomesOne;
>    localTwo = becomesTwo;
>
>    synchronized  /// << THREAD SAFE?
>    try {
>        becomesOne = 1;
>        becomesTwo = 2;
>    }
>    catch(Object e)
>    {
>     // Transaction failed, so restore previous values.
>      becomesOne = localOne;
>      becomesTwo = localTwo;
>      throw e;  // Pass exception up the tree.
>    }
>}
>
>
>-- 
>Derek Parnell
>Melbourne, Australia
>7/08/2005 8:40:36 PM

Hmm, what if the function is passed data which is in read-only memory? Is it possible to test for this in an in-contract?

I could also be reading too much into the post, but perhaps it is a kind of zen-riddle to demonstrate the hoops you have to jump through to make a seemingly simple function robust in D. Not that you always need robustness on this scale, though...

-Nod-


August 07, 2005

Hasan Aljudy wrote:
> Manfred Nowak wrote:
> 
>> 1) Review this code:
>>
>> void f( inout int i, inout int j){
>>   i= 1;
>>   j= 2;
>> }
>>
>>
>> 2) Pass or Fail?
>>
>> 3) Explain.
>>
>>
>> -manfred
> 
> 
> hmmm, from the other posts I gather there is a small problem with this kind of code:
> #int i = 5;
> #f(i,i);
> ^
> such calls should be illegal; that is: no variable can be passed as an "out" parameter more than once.
> 
> Is that -by any chance- what you are trying to hint to?

Gee, this really ought to get into the language spec!
August 07, 2005
In article <dd3mon$2eds$1@digitaldaemon.com>, Manfred Nowak says...
>
>1) Review this code:
>
>void f( inout int i, inout int j){
>  i= 1;
>  j= 2;
>}

# void f( inout int i, inout int j ) {
# in {
#     assert( &i != &j );
# }
# body {
#     i = 1; j = 2;
# }

Without this check, passing the same variable as both arguments will result in an undefined result, as whether the value is equal to 1 or 2 after the function call depends on the calling convention (C/D, Pascal, etc).


Sean


August 07, 2005
Yeah Mr. Kelly, that is how I would write the code...

Kind regards

Dejan

-- 
...........
Dejan Lekic
  http://dejan.lekic.org

August 07, 2005
On Sun, 07 Aug 2005 19:01:18 +0200, Dejan Lekic wrote:

> Yeah Mr. Kelly, that is how I would write the code...
> 
> Kind regards
> 
> Dejan

But that doesn't check for overlapping arguments, just ones that start on the same RAM address, plus the checks disappear in '-release' editions. So this is not how I would be coding it.

This problem is not unique to D. It is also an issue with any language that passes the address of variables.

-- 
Derek Parnell
Melbourne, Australia
8/08/2005 7:01:35 AM
August 07, 2005
Sean Kelly wrote:
> In article <dd3mon$2eds$1@digitaldaemon.com>, Manfred Nowak says...
> 
>>1) Review this code:
>>
>>void f( inout int i, inout int j){
>> i= 1;
>> j= 2;
>>}
> 
> 
> # void f( inout int i, inout int j ) {
> # in {
> #     assert( &i != &j );
> # }
> # body {
> #     i = 1; j = 2;
> # }
> 
> Without this check, passing the same variable as both arguments will result in
> an undefined result, as whether the value is equal to 1 or 2 after the function
> call depends on the calling convention (C/D, Pascal, etc).

No, it's well-defined and independent of calling convention: inout/out parameters are defined as pointers.  There is absolutely nothing wrong here and changing the language would limit the flexibility of the calling convention because you don't need to write to all inout parameters.
August 08, 2005
In article <138h7vhtkvnm7$.1i39l7uetkpdf$.dlg@40tude.net>, Derek Parnell says...
>
>On Sun, 07 Aug 2005 19:01:18 +0200, Dejan Lekic wrote:
>
>> Yeah Mr. Kelly, that is how I would write the code...
>> 
>> Kind regards
>> 
>> Dejan
>
>But that doesn't check for overlapping arguments, just ones that start on the same RAM address, plus the checks disappear in '-release' editions. So this is not how I would be coding it.

But do overlapping arguments matter in this case?  The values passed are integers.  Frankly, if someone is passing oddly aligned primitives then he has more problems than the side effects of the posted function.


Sean