G
Guest
Certainly it is clear when not using locking constructs if you don't use a
volatile keyword for variable access and you loop on the variable and check
it's value, you may be looking at the register value and not the actual value
so it may never change. The question is, is it possible even with locking
constructs this is an issue.
ALso, what locking constructs will force a memory barrier to prevent
enregistration of a variable? Any of them such as lock, Monitor enter/exit,
WaitOne, Set on events etc?
Will the JIT possibly possibly register the variable so that we would not
see it’s value change in some circumstances? Even in cases where locking IS
used?
If for example you had something like the code below. Imagine each of these
methods was started on a separate thread.
Public class Myclass()
{
private Int my_value=0;
Public void Mythread1Func()
{
While (true)
{
Monitor.Enter(this);
my_value++; //I presume that writes will always happen even
if this did get put into a register?
Monitor.Exit(this);
}
}
Public void MyThread2Func()
{
Monitor.Enter(this);
While(my_value<500000) // Would the JIT have possibly
put my_value in a register so we never see it change?
{
Monitor.Exit(this);
Monitor.Enter(this);
}
Monitor.Exit(this);
}
//This example would make it harder for the compiler and JIT to
determine what is going on, would this be a problem
Public void MyThread3Func()
{
While (true)
{
Utils.Lock(this);
Int value=my_value; // could my_value be put in a register here
and then when we access it later it has actually not been updated?
Utils.Unlock(this);
Utils.Lock(this);
If (my_value>500000) // Would the JIT have possibly
put my_value in a register so we never see it change?
{
Utils.Unlock(this);
break;
}
Utils.Unlock(this);
}
}
}
Public class Utils
{
Public static void Lock(object obj)
{
Monitor.Enter(obj);
}
Public static void Unlock(object obj)
{
Monitor.Exit(obj);
}
}
volatile keyword for variable access and you loop on the variable and check
it's value, you may be looking at the register value and not the actual value
so it may never change. The question is, is it possible even with locking
constructs this is an issue.
ALso, what locking constructs will force a memory barrier to prevent
enregistration of a variable? Any of them such as lock, Monitor enter/exit,
WaitOne, Set on events etc?
Will the JIT possibly possibly register the variable so that we would not
see it’s value change in some circumstances? Even in cases where locking IS
used?
If for example you had something like the code below. Imagine each of these
methods was started on a separate thread.
Public class Myclass()
{
private Int my_value=0;
Public void Mythread1Func()
{
While (true)
{
Monitor.Enter(this);
my_value++; //I presume that writes will always happen even
if this did get put into a register?
Monitor.Exit(this);
}
}
Public void MyThread2Func()
{
Monitor.Enter(this);
While(my_value<500000) // Would the JIT have possibly
put my_value in a register so we never see it change?
{
Monitor.Exit(this);
Monitor.Enter(this);
}
Monitor.Exit(this);
}
//This example would make it harder for the compiler and JIT to
determine what is going on, would this be a problem
Public void MyThread3Func()
{
While (true)
{
Utils.Lock(this);
Int value=my_value; // could my_value be put in a register here
and then when we access it later it has actually not been updated?
Utils.Unlock(this);
Utils.Lock(this);
If (my_value>500000) // Would the JIT have possibly
put my_value in a register so we never see it change?
{
Utils.Unlock(this);
break;
}
Utils.Unlock(this);
}
}
}
Public class Utils
{
Public static void Lock(object obj)
{
Monitor.Enter(obj);
}
Public static void Unlock(object obj)
{
Monitor.Exit(obj);
}
}