2

This would generally be done using volatile. But in the case of a long or double that's impossible.

Perhaps just making it public is enough, and the compiler then knows that this can be used by another assembly and won't "optimize it out"? Can this be relied upon? Some other way?

To be clear, I'm not worried about concurrent reading/writing of the variable. Only one thing - that it doesn't get optimized out. (Like in https://stackoverflow.com/a/1284007/939213 .)

Community
  • 1
  • 1
ispiro
  • 26,556
  • 38
  • 136
  • 291
  • Use the Random class, it will have more predictable behavior. Or System.Threading.Volatile – Hans Passant Dec 27 '15 at 20:49
  • can you show some code that you think might be optimized away? – Batavia Dec 27 '15 at 20:49
  • How are you planing on updating this variable "from another thread"? This isnt really how managed code works. – srandppl Dec 27 '15 at 20:49
  • @HansPassant Can you give an example of what you mean? I don't understand. – ispiro Dec 27 '15 at 20:58
  • @Batavia It's linked to in the question. Did you follow the link? – ispiro Dec 27 '15 at 20:58
  • @OwlSolo From time to time one thread Invokes a method on another with a `double` parameter. But that `double` might be optimized-out in that method (by the compiler). – ispiro Dec 27 '15 at 21:05
  • Well the problem is, double and long operation are not atomic on 32bit system, so afaik you shouldnt do this at all. Use volatile int instead. However if you absolutely want to GC.KeepAlive should do the trick – srandppl Dec 27 '15 at 21:18
  • Why can't volatile be used? [what about this?](http://igoro.com/archive/volatile-keyword-in-c-memory-model-explained/) – m_a_s Dec 27 '15 at 21:21
  • @m_a_s Double and long types are 64bit wide, on 32 bit system they require more than one operation to be computated (aka not atomic), this means that thread interoperability between them is a lot more difficult as you would need proper lock management to ensure that no invalid inbetween values are being used. Therefore these two cannot carry the volatile keyword in c# in the first place – srandppl Dec 27 '15 at 21:24
  • @HansPassant Thanks. I didn't know about those new `Volatile` methods. – ispiro Dec 27 '15 at 21:47

1 Answers1

0

The best way to prevent code removal is to use the code.

if you are worries about optimizing the while loop in your example

class Test  
{
   long foo;

   static void Main()
   {
      var test = new Test();

      new Thread(delegate() { Thread.Sleep(500); test.foo = 255; }).Start();

      while (test.foo != 255) ;
      Console.WriteLine("OK");
   }
}

you still could use volatile to do this by modifying your while loop

volatile int temp;

//code skipped in this sample
while(test.foo != 255) { temp = (int)foo;}

Now assuming you are SURE you won't have any thread safety issues. you are using your long foo so it won't be optimized away. and you don't care about losing any part of your long since you are just trying to keep it alive.

Make sure you mark your code very clearly if you do something like this. possibly write a VolatileLong class that wraps your long (and your volatile int) so other people understand what you are doing

also other thread-safty tools like locks will prevent code removal. for example the compiler is smart enough not to remove the double if in the sinleton pattern like this.

if (_instance == null) {
  lock(_lock) {
       if (_instance == null) { 
          _instance = new Singleton();
        }
   }
}
return _instance;
Batavia
  • 2,497
  • 14
  • 16