Control Builder C development using Sublime Text and GCC

Recently I started a project using ABB Control Builder to program a AC500 PM573 PLC.

I need to write a collection of C functions that can be used in CoDeSys as functions & function blocks so the end user (PLC Programmer) doesn’t need to use Structured Text (ST) to write what would be complicated Pascal.

Control Builder doesn’t provide a C editor, so I chose something light as I don’t need a full IDE – Sublime Text 2. This is the first time I’ve used it.

Control Builder is also a bit dated and doesn’t seem to have keyboard shortcuts for compiling, so I created my own build system for AC500 C development. This is the sublime-build file I used, thanks to sublimetext.info:

C.sublime-build

{
    "cmd" : [
    	"C:\\GCC\\4.7.0\\bin\\powerpc-elf-eabi-gcc.exe",
    	"-I", "C:\\Program Files (x86)\\Common Files\\CAA-Targets\\ABB_AC500\\AC500_FWAPI",
    	"-mcpu=860",
    	"-fno-common",
    	"-msdata=none",
    	"-fno-jump-tables",
    	"-fno-section-anchors",
    	"-fno-merge-constants",
    	"-fno-builtin",
    	"-nostdlib",
    	"-Werror-implicit-function-declaration",
    	"-Wconversion",
    	"-std=c99",
    	"-c", "C_Code_App_Shell.c",
    	"-o", "C_Code_App.obj"
	],
    "shell" : true,
    "working_dir" : "$file_path",
    "path" : "C:\\GCC\\4.7.0\\bin"
}

You’ll notice the following things about this build definition:

  • It won’t work with the “automatic” setting as I don’t want it picking up any other C projects
  • It compiles a specific file only – C_Code_App_Shell.c – which is the same file compiled by Control Builder so your other included files should be included properly

Use at your own risk, and I recommend using Control Builder to finally build your code when ready for testing and production, but this is a handy way of using a modern editor in the meantime.

The Speed of a Delegate

A Delegate in C# is a type, but one that can be assigned from a method. Any method that matches the delegate signature can be assigned to that delegate.

I have the need to run a dynamically loaded method from a DLL so that the user can choose the DLL or method at run time, so long as it matches the signature. I also need to run it 1E06 to 3E08 times in a row, so speed is essential, as a millisecond saved will reduce the run time substantially.

In a separate project I have the following method compiled in a DLL:

public class Controller
{
    public double Control(double a, double b, double c, double d)
    {
        // variable names have been changed to protect their identity!
        double setP = Math.Max(0, b - c);
        return Math.Min(setP, d);
    }
}

In my main project (which doesn’t reference the previous project), I define a Delegate that matches the signature of the Control method:

public delegate double Controller(double a, double b, double c, double d);

Then I load the delegate from the DLL (note the Controller here is the Delegate, not the class above):

        private Delegate LoadDelegate()
        {
            Assembly assembly = Assembly.LoadFrom(@"path\to\My.dll");
            Type controllerType = assembly.GetTypes().First(t => t.IsClass && t.Name.Equals("Controller"));
            object controller = Activator.CreateInstance(controllerType);
            MethodInfo handler  = controller.GetType().GetMethod("Control", BindingFlags.Public | BindingFlags.Instance);
            return Delegate.CreateDelegate(typeof(Controller), controller, handler);
        }

Now I have an Actor() class with a Run() function that I call in a loop.

I wire this into my Run() loop through the actors constructor:

public Actor(Delegate controller)
{
    _controller = (Controller)controller;
}

and then call the delegate like so:

public void Run()
{
    ...
    double setP = _controller (a1, b1, c1, d1);
    ...
}

The loop is simply:

Actor actor = new Actor(LoadDelegate());
for (int i = 0; i < 1000000; i ++)
{
    actor.Run();
}

Now the big question: the results! Using a timer around my for loop, and much more detail in the Run() functions that shown here, the results are:

No delegate, code verbatim in the Run() function

Run 10000 iterations...
inner loop took 0.3710212s

Run 100000 iterations...
inner loop took 3.7302133s

Run 1000000 iterations...
inner loop took 39.9192832s

Identical code, moved into a delegate and called from the Run() function

Run 10000 iterations...
inner loop took 0.3810218s

Run 100000 iterations...
inner loop took 4.5762617s

Run 1000000 iterations...
inner loop took 41.1173518s

Identical code but in a private instance method in the Actor() class:

Run 10000 iterations...
inner loop took 0.3650209s

Run 100000 iterations...
inner loop took 3.7172126s

Run 1000000 iterations...
inner loop took 39.9982877s

In all cases, the time is directly proportional to the number of iterations. The slight variability is due to random computer activity, which would average out over lots of test runs.

It appears that the Delegate method of calling a function is slightly slower, but not noticeably until you call at least 1 million iterations. Even then, the variability is the same as may be caused simply by other idle processes using CPU instructions at the time.

Is IHttpHandler ProcessRequest thread safe or not?

short answer: “Yes” with an “If,” long answer: “No” — with a “But.”
— Reverend Lovejoy

I was debugging a HttpHandler and came across many examples that stated ProcessRequest() is not thread safe, unless of course you’re doing something very simple, like the following:

public void ProcessRequest(HttpContext context)
{
    context.Response.Write("hello");
}

If, however, you’re doing anything with local variables (the examples say), you probably have a problem:

public void ProcessRequest(HttpContext context)
{
    var someValue = someFunction();
    context.Response.Write(someValue);
}

However, local variables are thread safe! So the above example is perfectly ok, even if someFunction() returns a different value each call, so long as it is, in itself, thread safe.

The obviously broken example would be:

public class AttachmentHandler : IHttpHandler
{
    private static int _callCnt = 0;

    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        context.Response.Write(_callCnt++);
    }
}

because all static variables (except thread static variables) are shared amongst all threads.

To demonstrate a working example, here’s an attachment handler which imposes a 10 second wait. Call it multiple times within 10 seconds and you should get a different value in the file each time:

public class AttachmentHandler : IHttpHandler
{
    public bool IsReusable
    {
        get { return true; }
    }

    public void ProcessRequest(HttpContext context)
    {
        Random r = new Random();
        double foo = r.Next();
        Thread.Sleep(10000);

        context.Response.ContentType = "text/plain";
        context.Response.AddHeader("Content-disposition", "attachment; filename=\"foo.txt\"");
        context.Response.BinaryWrite(Encoding.ASCII.GetBytes(string.Format("hello, universe {0}!", foo)));
        context.Response.Flush();
        HttpContext.Current.ApplicationInstance.CompleteRequest();
    }
}

So yes, ProcessRequest() is thread safe unless you reference (and maybe not even then) any thread unsafe objects, such as session, static variables, etc.