Semaphores

11 07 2011

A semaphore allows a special kind of critical region that is not mutually exclusive. Threads may perform a take or put operation on a semaphore, atomically decreasing or increasing its current count, respectively. When a thread tries to take from a semaphore that already has a count of 0, the thread blocks until the count becomes non-0. The initial count of the semaphore specifies the maximum number of threads that can be inside the region. Unlike mutexes, semaphores are never considered to be owned by a specific thread. Different threads can safely put and take from the semaphore without any problems.

To take from the semaphore a thread calls Wait() and to put a thread calls Release(). Semaphores are typically used to protect resources that are finite in capacity. A pool of database connections for example or a swimming pool with a maximum capacity. A semaphore can span processes in the same was as a Mutex if you give it a name on construction.

class SwimmingPool
{
  static SemaphoreSlim m_Sem = new SemaphoreSlim (2);

  static void Main()
  {
    for (int i = 1; i <= 5; i++) new Thread (Swim).Start (i);
  }

  static void Swim(object id)
  {
    Console.WriteLine (id + " wants to swim");
    m_Sem.Wait();
    Console.WriteLine (id + " is swimming");           // Only two swimmers
    Thread.Sleep (1000 * (int) id);                    // can be here at
    Console.WriteLine (id + " is done swimming");       // a time.
    m_Sem.Release();
  }
}




Mutexes

10 07 2011

A mutex is a synchronization primitive, similar to a monitor, but which can also be used for interprocess synchronization. When you create a mutex you can give it a name to identify it across processes. To lock a mutex you call the WaitOne method and the ReleaseMutex method to unlock.

A common use of a mutex is to ensure that only one instance of a program can run at a time. Mutexes are about 50 times slower to obtain than monitors.

class Program
{
  static void Main()
  {
    using (var mutex = new Mutex (false, "My Program"))
    {
      //try to obtain the mutex, give it some time in case another instance is exiting
      if (!mutex.WaitOne (TimeSpan.FromSeconds (3), false))
      {
        Console.WriteLine ("Another instance is running.");
        return;
      }
      else
      {
           //Launch
      }
    }
  }
}




Monitors (CLR locks)

9 07 2011

The CLR provides “monitors” as the managed code equivalent to critical regions and Win32’s critical sections. You call Monitor.Enter on an object to acquire the monitor, if another thread already holds that monitor the calling thread will block until the owning thread releases it. The owning thread releases the monitor by calling Monitor.Exit.

Don’t use ‘this’ as your object to lock on. It is better practice to explicitly manage and wall off your synchronization objects from the rest of the world. Using ‘this’ can make encapsulation difficult by exposing the implementation detail of your locking mechanism to clients of your object. In order to ensure that a thread always leaves the monitor you use a try / finally block so that the monitor is released even in the face of an exception.

Monitors are different from mutexes. A mutex works across multiple processes while monitors are for a single process. Monitors are a lot faster (~ 50 times faster) to acquire than mutexes because they are acquired in user mode, not kernel mode.

object monitorObj = new object();

Monitor.Enter(monitorObj);
try
{

}
finally
{
    Monitor.Exit(monitorObj);
}

This pattern is so common that C# provides syntactic sugar for it in the form of the lock statement.

object monitorObj = new object();

lock(monitorObj)
{
}

The same IL is emitted by the C# compiler in both of the cases above.





Using Reflection to Choose a Method at Runtime

5 07 2011

An area in our code is charged with serializing a given object to a given BinaryWriter. Most of the time the object is a primitive type that requires just figuring out what type it is, casting it and calling the appropriate Write() method on the BinaryWriter. The obvious solution is a big if statement checking the object’s type and forwarding the casted object to Write(). This approach is a bit of a pain because the method becomes big and a pain to maintain, it’s also frustrating to look at a lot of code that is basically the same repeated over and over.

I tried a different approach using the reflection classes and a little Linq. The resulting method is small and covers all the primitive types in one go. This approach is probably slower than the if-else one (I’ll profile it later) but the reduced code size and increased maintainability make it a good option.

 
static void Serialize(Object obj, BinaryWriter writer)
{
    var objRunTimeType = obj.GetType();
    var binaryWriterType = typeof(BinaryWriter);

    var writeMethod = (from m in binaryWriterType.GetMethods()
                       where m.Name == "Write" && m.GetParameters()[0].ParameterType == objRunTimeType
                       select m).First();

    writeMethod.Invoke(writer, new object[] {obj});
}




Object.GetType()

4 07 2011

Everything in C# inherits from System.Object and as a result every instance of an object has access to the GetType() method. This method returns an instance of Type that represents the exact runtime type of the instance it is called on.

This method came in very handy today as I had to keep a record in memory of the type of every object I serialized to disk in order to deserialize it correctly later. So I set up a Listand stored each type as I serialized the data (actually I did more than that, see code). I think that relying on GetType() is acceptable in those sort of situations, if you find that your code uses it heavily in many places that’s a symptom of a design that needs rethinking.

private class TypeTracker
{
    public class ColumnComparisonTypes
    {
        public Type SrcType { get; set; }
        public Type TgtType { get; set; }

        public bool Complete { get { return SrcType != null && TgtType != null; } }
    }

    private readonly List m_ColumnComparisonTypes;
    private bool Complete
    {
      get { return m_ColumnComparisonTypes.TrueForAll(c => c.Complete); }  
    } 

    public TypeTracker(ColumnComparisonSettingsCollection columnComparisonSettingsCollection)
    {
        m_ColumnComparisonTypes = new List(columnComparisonSettingsCollection.Count);
        for(int i=0; i<columnComparisonSettingsCollection.Count; ++i)
            m_ColumnComparisonTypes.Add(new ColumnComparisonTypes());
    }

    public ColumnComparisonTypes this[int i]
    {
        get { return m_ColumnComparisonTypes[i]; }
    }

    public void Track(RowComparisonResult rowComparisonResult)
    {
        if (rowComparisonResult == null) throw new ArgumentNullException("rowComparisonResult");
        if (Complete) return;

        for(int i = 0; i < rowComparisonResult.CellResults.Count; ++i)
        {
            var cellResult = rowComparisonResult.CellResults[i];

            if (cellResult.SourceValue != null && m_ColumnComparisonTypes[i].SrcType == null)
            {
                m_ColumnComparisonTypes[i].SrcType = cellResult.SourceValue.GetType();
            }
            if (cellResult.TargetValue != null && m_ColumnComparisonTypes[i].TgtType == null)
            {
                m_ColumnComparisonTypes[i].TgtType = cellResult.TargetValue.GetType();
            }
        }
    }

}




Conditional Attributes

1 07 2011

Conditional compilation can be a real pain. There are lots of situation where we want a DEBUG build to perform some operations that are not necessary in RELEASE. A good example is a method that checks an object’s pre- and post-conditions and print out some debug information.

private void CheckConditions()
{
#if DEBUG
    //check state, print out debug information etc.
#endif
}

So in DEBUG mode this method is compiled to include your checking code, in RELEASE this method is empty. That’s fine except you still pay the price of a method call whenever CheckConditions() is called elsewhere.

A better option is offered by the Conditional attribute. You apply the Conditional attribute to a method and the compiler detects that this method should be called only when in DEBUG mode. The difference is that the calls to CheckConditions() are removed from the RELEASE build while the body of the method remains the same. No empty methods being called!.

[Conditional("DEBUG")]
private void CheckConditions()
{
    //check state, print out debug information etc.
}

The difference here is that using #if #endif you ask the preprocesor to remove the source code between those directives whereas with the Conditional attribute you ask the compiler to remove calls to that method from the IL it produces.





Readonly vs. Const

29 06 2011

C# has two different versions of constant: compile-time (const) and runtime (readonly) constants. Compile-time constants are slightly faster but significantly less flexible than runtime constants.

Compile-time and runtime constants are accessed differently. Compile-time constants are replaced with the value of that constant in your object code. Runtime constants are evaluated at runtime, the IL generated references the readonly variable, not the value. Compile-time constants are limited to numbers and strings because these are the only types that can be replaced with literal values in the IL. Runtime constants can be any type, you must initialize them in a constructor or an initializer.

public const int BirthYear = 1982;

int myYear = BirthYear;
//compiles to the same IL as
int myYear = 1982;

The way in which the different constants are evaluated affects runtime compatibility across assemblies. When you reference a const in another assembly and that const changes BOTH assemblies must be recompiled to pick up the change (because the literal value is placed in the assembly IL). A change to a readonly value in another assembly does not require the referencing assembly to be recompiled, it still references to the correct value because it gets resolved at runtime.