Friday, November 7, 2008

That which is old is new again

Last week at PDC, I was able to make it to the repeat session of Anders Hejlsberg's talk on the future of C#.  A talk by Anders is always interesting and enjoyable. He showed some really interesting things; but the most intriguing thing was the new "dynamic" keyword. Anders demonstrated several interesting uses for this "newfangled" gizmo, such as interoperating with JavaScript code. Hmm... I think I demonstrated something just like that over a year ago with Delphi. In that demonstration I showed how you could get JavaScript to access Delphi components dynamically. The reverse could just as easily have been done by using a Variant along with the very old (like Delphi 3 old) notion of dynamic variant dispatching. Any variant can be treated like an object in that you can simply start calling any old method or accessing any old property without even having a declaration for what that property is. For instance for many years you've been able to do this:

procedure TForm1.Button1Click(Sender: TObject);
var
Doc, Word: Variant;
begin
Word := CreateOleObject('Word.Application');
Doc := Word.Documents.Add();
Doc.Content.InsertAfter('This is some sample Text');
Word.ActiveWindow.Visible := True;
end;

Just add ComObj to your uses list and you can now paste that code into a button click, and you're automating MS Word. The Delphi Variant type (or the more COM/OLE specific OleVariant) support this dynamically typed, dynamic invocation.


I had a chance to meet with Anders for a few moments out in the "Big Room" and I mentioned that the whole "dynamic" thing looked remarkably like the old Variant dispatching stuff. He chuckled and mentioned that the C# model allows for doing different kinds of dispatching and not just COM IDispatch... Hmm... I smiled and reminded him that Delphi does as well. I explained that since Delphi initially introduced the Variant dispatching in D3, we've added support for custom variant types. We now support all kinds kind of dynamic dispatching by creating your own custom variant type by descending from TInvokableVariantType over in the Variants unit. He paused a moment, chucked again, and explained that really none of these concepts are new, we're just all learning how to reconcile the strongly-type world with the dynamically typed world of JavaScript, Python, and Ruby. Using the above notion of a TInvokeableVariantType, you could create a custom variant type that allows you to directly call and manipulate... oh... say... some RESTful service. It would be interesting to be able to do this:

procedure TForm1.Button1Click(Sender: TObject);
var
I: Integer;
Twitter, Timeline: Variant;
begin
Twitter := OpenXMLRESTConnection('http://twitter.com/statuses');
Timeline := Twitter.public_timeline();
//for I := VarArrayLowBound(Timeline.statuses, 0) to VarArrayHighBound(Timeline.statuses, 0) do
for I := 0 to Timeline.statuses.count - 1 do // This is far better and easier to use.
begin
Memo1.Lines.Add(Format('User: %s; Message: %s', [Timeline.statuses[I].user.name, Timeline.statuses[I].text]));
Memo1.Lines.Add('');
end;
end;

The above code is purely conjecture on my part, but I can certainly envision such an easy to use, dynamic mechanism to accessing RESTful services.


So, we've appeared to have, yet again, come full circle. That which was old is now new again. Hmm... maybe some of those old codgers back in the 70s, 80s, and 90s were on to something? I just hope we're not merely repeating history, but rather building on it and recognizing that there are only a few new ideas under the sun... knowledge and ideas are not silos unto themselves, but rather built on top of that which has come before. So maybe you could go back even further? Even with the invention of the the first widely used "programable" devices (the programmable fabric loom head) by Jacquard, many of the concepts and ideas of modern computing today can be easily traced back to 1801 and the great pioneers and thinkers of the day.


You can read about the Twitter API here and see how the above code snippet could easily be mapped to it.  To see the XML response just navigate here: http://twitter.com/statuses/public_timeline.xml.

Monday, November 3, 2008

PDC - In a few bullet points

Last week I was at PDC 2008 in Los Angeles. It really felt like a huge BorCon. The "geek quotient" was very high :-). There were several high-level themes that permeated the whole conference:

  • Windows Azure - "The Cloud." Cloud computing with high-level tooling and initial support for managed code. Will eventually support native code. Meh :-/
  • Parallel Computing - "No magic bullet" - As a reminder, Moore's Law is about transistor density not clock speed, folks! Moore's Law is still going strong, only now it is about cramming more cores into the same space. Until the heat/power problem is solved, clock speeds will continue to stall. Now the focus is on doing more things an once. The "free lunch" is over. With the new interest in parallelism and multi-core, classic imperative programming models don't lend themselves to automatic parallelism. In other words, we're a long way from that magic compiler switch called, "make my program parallel and faster." Thus there is a keen interest in data immutability and functional languages (F#, Haskell, ML, Caml, OCaml, etc..) and adding functional programming constructs to existing imperative languages (LINQ, PLINQ). The former is nice for greenfield projects or for portions of an application, but the latter is most likely going to the route taken by the mainstream languages. Consider that the forthcoming C++0x is introducing Lambda expressions, C# has LINQ & PLINQ, and even Delphi is moving in that direction with Prism and Delphi native (LINQ in Prism, anon methods in native).
  • Windows 7 - Pay no attention to the Vista in the corner... Look at Windows 7! Admittedly, it does look nice. They've done a lot of homework and are working very hard to "fix" the usability issues with Vista. The Driver Model is remaining largely unchanged from Vista so all the investment in getting good Vista drivers up an going can be preserved. They seemed to hint that much of the perceived "instabilities" of Vista (aside from the usability issues) were due to the extensive reworking of a lot of the driver model, most notably the Video driver model and DX10. A lot of the hardware vendors were just not ready at launch with solid driver support. Apparently, it's getting better and by the time Win7 is released, the hardware vendors will have ironed out those problems. When will it be released? The statements made were "3 years from the general availability of Vista" which puts it into the last half of 2010. I suspect the move back to a version number from years (98, 2000) or names (XP, Vista) is a way of "starting fresh" and shedding some of the negative baggage that is Vista.
  • Multi-Touch - Windows 7 will support multi-touch out of the box. They also had a whole bunch of Surface PCs. It is interesting to note that the Surface PC is all vision based using a camera placed underneath the rear projected display, while all the Windows 7 APIs are based on the more traditional touch screen technologies (resistive, capacitive, etc...) WPF will eventually have some "unifying" APIs that will map those two APIs to a common WPF layer. This is not until .NET 4.0, which is apparently after Windows 7 since they keep talking about Windows 7 shipping with .NET 3.5 SP1. No word on native Surface APIs. Windows 7 touch support is all native at the lower level and even has some really nice intrinsic support for "manipulators" and "inertia."

Then there was the big Embarcadero/CodeGear announcement of Delphi Prism. Now that we've gone public with information about Prism and Embarcadero's relationship with RemObjects, I can certainly talk about how I was able to spend time with some of the guys from RO. They're booth was setup right next to the Embarcadero booth. I ended up staying the same hotel as the RO guys, so I spent a good amount of time getting to know them better. I met Carlo Kok, the Delphi Prism compiler engineer, for the first time. I certainly enjoyed hanging out with marc hoffman, Mike Oriss, and Carlo Kok. We will be spending a lot of time looking at ways we can not only leverage each other's work, but also work together on advancing the Delphi Object Pascal language in ways that make sense for each market and platform.

Overall, there was a lot of really good information. I didn't come away feeling like there was any kind of overall "buzz" around any particular topic. If I had to pick one "buzz-worthy" item, it would have to be the whole Azure thing and the "cloud."

One personally interesting item was that they gave out a little Freescale USB "badge" sensor board to demonstrate the both the unified sensor API coming in Windows 7, but also the new user level driver model. This little technology demonstrator has a ColdFire V1 microcontroller, which is a MC68000 derivative CPU, with lots of built-in I/O ports, timers, USB port, SCI, I2C, A/D converters and 128K flash Memory and 64K of ram. The board had a 3-axis accelerometer, ambient light sensor, 8 proximity touch switches, Lithium-Ion rechargeable coin cell and charger circuit. It came with all the drivers, on board firmware, trial versions of the C/C++ compiler for the CPU, and the Windows 7 driver code and some demo applications. They said it would only work with Windows 7. Hogwash, I say! It's just a USB HID (Human Interface Device), and well, guess what? Within the extensive JEDI-VCL library is an HID component. There was also enough documentation to describe the 64-byte data packets that the board sends out with information about the accelerometer, light sensor and 8 proximity switches that I was able to write a little Delphi application to read and interpret the raw data stream. Sure, it's using the raw data streams from the device without the nicely unified Sensor API from Windows 7. I played with it over the weekend and got it all working on my Windows XP Dell D820 laptop.

Sunday, October 26, 2008

At PDC

Just a quick little note that I'm at the PDC conference. I'll be at the multicore/concurrent programming pre-con session. If that's where you'll be as well, be sure to say hi.

Wednesday, October 15, 2008

Value Capture vs. Variable Capture

Anonymous methods (aka. Closures) capture the variables from the outer scope that are referenced within the body of the method itself. This is the intended behavior as it serves to extend the lifetime of the variable to match that of the anonymous method itself. This should not be confused with capturing the value of a variable. In my previous posts, A Sink Programming and More A Sink Kronos Programming, I demonstrated a technique for asynchronously dispatching an anonymous method from a background thread into the main UI thread. I also mentioned how there was a potential race-condition on the SR local variable. The simple, yet not very scalable, way of eliminating this race was to pause the loop by calling EndInvoke() prior to accessing SR again (in the FindNext() call). This time, I'm going to show a technique for capturing the value of the SR.Name field and not the whole SR variable. This will eliminate the race on the SR variable because the anonymous method body will no longer need to access it.

Value capturing is a little more manual, but through the use of generic methods and a corresponding generic class, we only need to create this code once. The idea is to add an overloaded BeginInvoke() method that takes an extra parameter, which will be the value we want to capture and pass along to the anonymous method. Here's the new BeginInvoke method:


TControlHelper = class helper for TControl
...
function BeginInvoke<T1>(const AProc: TProc<T1>; const Param: T1): IASyncResult; overload;
...
end;

This overload is different from the BeginInvoke<TResult> version since the AProc parameter takes a procedure reference instead of a function reference. As you can see, the procedure reference (can be an anonymous method), AProc, is defined as taking a single parameter of type T1. There is also an extra parameter which is where we'll pass in the value we want to capture. Behind the scenes we'll need to save off this value some place so when the procedure is called, that value can be passed along. For this, we'll create another descendant of the TBaseAsyncResult class, only this time it is a generic class because we need to have a field of type T1:

  TAsyncProcedureResult<T1> = class sealed (TBaseAsyncResult)
private
FAsyncProcedure: TProc<T1>;
FParam: T1;
protected
procedure AsyncDispatch; override;
constructor Create(const AAsyncProcedure: TProc<T1>; const Param: T1);
end;

As before, we override the AsyncDispatch abstract virtual method and add a constructor that takes the procedure reference and the value. The body of BeginInvoke<T1>() looks like this:

function TControlHelper.BeginInvoke<T1>(const AProc: TProc<T1>; const Param: T1): IASyncResult;
begin
Result := TAsyncProcedureResult<T1>.Create(AProc, Param).Invoke;
end;

Now let's change the background thread code to take advantage of this:

procedure TBeginInvokeTestForm.TSearchThread.Execute;
var
SR: TSearchRec;
SH: Integer;
AR: IAsyncResult;
begin
if not Terminated then
begin
AR := FForm.ListBox1.BeginInvoke<string>(TFunc<string>(function: string
begin
Result := FForm.Edit1.Text;
end));
FFolder := FForm.ListBox1.EndInvoke<string>(AR);
SH := FindFirst(IncludeTrailingPathDelimiter(FFolder) + '*.*', faAnyFile, SR);
while (SH = 0) and not Terminated do
begin
//Sleep(10); // this makes the background thread go a little slower.
AR := FForm.ListBox1.BeginInvoke<string>(TProc<string>(procedure (SRName: string)
begin
if not Terminated then
FForm.ListBox1.Items.Add(SRName);
end),
SR.Name); // Pass the value of SR.Name on through.
// FForm.ListBox1.EndInvoke(AR); { this call can be safely removed since SR isn't
touched inside the anonymous method body}
SH := FindNext(SR);
end;
end;
end;

Now the the loop in this thread will execute as quickly as it can to dispatch asynchronous calls to the main UI thread regardless of how fast they can be consumed. This same technique can be applied to the "TFunc" version by adding more BeginInvoke() overloads. It can also be extended to allow more than one extra parameter so you can capture and pass long many values. In the above case, it only specifically captured just the string that is the name of the file. It could have also captured the value of the whole SR structure.


What about exceptions? What if an exception were raised while the anonymous method were executing? It would still get caught and propagated back to the specific IAsyncResult instance but because EndInvoke() isn't being called it is lost in the ether. It is also "bad form" to forgo the call to EndInvoke() as there may be some other internal cleanup that needs to happen. A simple way to deal with this is to store the IAsyncResult instances in a local TList<IAsyncResult> list. Then once the loop is done, iterate through the list, calling EndInvoke() on each one. This may still be less than ideal because you cannot cancel subsequent invocations of the anonymous method which may just stack up a whole plethora of exceptions. In this instance, aside from the exception problem, it is ok to defer or not call EndInvoke(). In other cases this may not be true, such as using this technique for overlapped IO.

Friday, October 10, 2008

CodeRage III - PDC - Delphi Programming

  • Be sure to mark your calendar for the upcoming CodeRage virtual conference. Apparently the abstract submissions are coming in fast and furious, so if you would like to present, make sure you contact Anders Ohlsson.
  • There are several folks in the Delphi community planning on taking advantage of the whole Open Space or UnSessions thing at PDC this year. Since I'll be there this year, let me know if you're planning an UnSession and what it'll be about; I may show up. Also, if there is some kind of Delphi/C++Builder related UnSession you'd like to see, let me know too and it may happen.
  • Delphi Programming - Just doing my part.
  • I just realized that I have written nearly 450 posts in the 5 years I've been doing this whole blog thing. I hope I haven't wasted too much of your time if you've been following along.

Monday, October 6, 2008

Some newsworthy items

  • In case you've missed it, while at the SDN conference in the Netherlands, Nick Hodges has dropped some information about Delphi Prism, the next release of Delphi on the .NET platform hosted inside the Visual Studio Shell. Dr. Bob, Marco Cantu and Tim Anderson, have all commented on it. I guess this isn't an "official" announcement as that will happen later this month at the Microsoft PDC.
  • Speaking of the Microsoft PDC, I'll be there. If you're planning on going and would like to meet, let me know.
  • We've been reworking our beta-test process using a new solution from Centercode.
  • If you'd like to get in on the Delphi Prism fun and try out the new Centercode portal at the same time, you can apply to be a beta tester here.
  • The Scotts Valley High School Falcons, SCCAL co-champions, beat reigning CCS champion, the Santa Cruz High School Cardinals under the Friday night lights in both teams' league opener, October 3rd, 2008. Scotts Valley is now 1-0 in league play, 4-1 overall. Why does this matter? My son is a starting lineman for the Scotts Valley Falcons :-). Next Saturday, October 11th, Scotts Valley travels to Harbor High School to meet up with the Pirates on their home turf. Game at 2pm, PDT.

Monday, September 29, 2008

More A Sink Kronos programming

Today, we'll look at the implementation behind some of the code presented in this post. Let's start by looking at the implementation of the IAsyncResult interface. Because there are two pairs of BeginInvoke/EndInvoke, one that just calls a procedure and one that is designed to call a function, we'll start with a base implementation that will be shared between these two patterns. Here's the declaration for the TBaseAsyncResult class that forms the core of the IAsyncResult implementation:

  TBaseAsyncResult = class;

IGetAsyncResult = interface
['{E833C81B-0F16-4A67-BE7C-48E21A784B1A}']
function GetAsyncResult: TBaseAsyncResult;

property AsyncResult: TBaseAsyncResult read GetAsyncResult;
end;

TBaseAsyncResult = class(TInterfacedObject, IAsyncResult, IGetAsyncResult)
private
FCompleted: Boolean;
FSynchronous: Boolean;
FAsyncHandle: TSimpleEvent;
FInvokingThread: Cardinal;
procedure Complete;
procedure DoAsyncDispatch;
{ IGetAsyncResult }
function GetAsyncResult: TBaseAsyncResult;
{ IAsyncResult }
function GetAsyncHandleObject: THandleObject;
function GetCompletedSynchronously: Boolean;
function GetIsCompleted: Boolean;

property AsyncHandleObject: THandleObject read GetAsyncHandleObject;
protected
FInvokingException: TObject;
procedure AsyncDispatch; virtual; abstract;
function Invoke: IAsyncResult;
procedure InitDispatch;
procedure WaitForCompletion;
public
destructor Destroy; override;
end;

Let me explain the IGetAsyncResult interface. Since you cannot merely typecast an interface instance back to an object, we needed some way to get back to the actual implementation. Using this internal-only interface we can simply perform and "as" cast on an IAsyncResult variable or parameter to get access to the underlying implementation. If an exception is raised due to an invalid cast, most likely someone passed in another implementation of IAsyncResult. The the rule is that you can only use the result of BeginInvoke, with the corresponding EndInvoke. Calling the wrong EndInvoke method will cause an invalid type cast exception to be raised.


We could have done all of this by returning an object instance (say a pure abstract TAsyncResult type) and eliminated the interface altogether. However, that would have meant that the BeginInvoke caller would now be responsible for destroying the instance, it would also have actually complicated the implementation because There would now have to be two object instances because the lifetime of the instance returned by BeginInvoke() would have to specifically be independent from the actual asynchronous call. Otherwise, the destructor would have to block until the call completed. Another reason is that we'll re-use this interface in other asynchronous scenarios.


Let's cover the Invoke and WaitForCompletion methods first:

function TBaseAsyncResult.Invoke: IAsyncResult;
begin
FInvokingThread := GetCurrentThreadId;
Result := Self;
_AddRef();
TThread.Queue(nil, DoAsyncDispatch);
end;

procedure TBaseAsyncResult.WaitForCompletion;
var
LException: TObject;
begin
if not FCompleted then
ASyncHandleObject.WaitFor(INFINITE);
LException := InterlockedExchangePointer(Pointer(FInvokingException), nil);
if LException <> nil then
raise LException;
end;

The intended usage of the Invoke method is to be called immediately upon successful construction, preferably within the same expression:

  Result := TAsyncProcResult.Create(AProc).Invoke;

We don't schedule, or queue, the procedure until the Invoke call because that causes a race-condition. Because the queued procedure, DoAsyncDispatch, is a normal method pointer, it doesn't serve as an interface reference. There is a chance that the BeginInvoke caller could schedule a call, then immediately drop the IAsyncResult (or simply go out of scope) reference which would have freed the instance prematurely. We could have done some of the Invoke work in the constructor, but we'd also have to deal with the way TInterfacedObject does its construction (another topic, look in System.pas).


Invoke, first gets the invoking thread so we know which thread scheduled the call. We'll use this later to determine whether or not TThread.Queue made a direct method call because BeginInvoke was called from the main thread and is the basis for the CompletedSynchronously property on IAsyncResult. Next is assigns the Result. Here the compiler will perform a static cast of "Self" to get the interface and then call _AddRef(). The caller is guaranteed a valid reference now. Next we manually call _AddRef() because as indicated in the previous paragraph, the caller is free to drop the IAsyncResult reference at any point. By doing the _AddRef() before the call is queued, we can now guarantee that when DoAsyncDispatch is called, it is still a valid instance. Finally the call is queued and the function returns.


WaitForCompletion, serves a dual-fold purpose. The first is as the name implies, it merely blocks the caller until the queued method is completed. The other purpose is to properly propagate any exception that may have occurred during the call on the main thread. We'll see how this is handled when we look at DoAsyncDispatch() and Complete() next.

procedure TBaseAsyncResult.DoAsyncDispatch;
begin
FSynchronous := FInvokingThread = GetCurrentThreadId;
try
try
AsyncDispatch;
except
FInvokingException := AcquireExceptionObject
end;
finally
Complete;
_Release;
end;
end;

procedure TBaseAsyncResult.Complete;
begin
System.TMonitor.Enter(Self);
try
FCompleted := True;
if FAsyncHandle <> nil then
FAsyncHandle.SetEvent;
finally
System.TMonitor.Exit(Self);
end;
end;

The first thing that DoAsyncDispatch does is to determine whether or not this method was called synchronously. Again, this can happen if the TThread.Queue call above decided to directly execute the method. Then it proceeds to do the actual work of the call by calling AsyncDispatch, which is an abstract virtual method. The intent here is that only descendants should ever be instantiated and they must override AsyncDispatch. Here is also where we'll trap all exceptions. The AquireExceptionObject function is from the System unit which will find the current exception object from the raise list and return a reference to it. It will also drop that reference from the raise list which will mean it will no longer be automatically destroyed. When an except block is exited normally or another object instance is raised (raise; is a special case), the existing exception object instance is automatically freed. This prevents that instance from being freed and allows us to hang on to a reference for use in WaitForCompletion where we can raise it again.


The next call is to Complete which encapsulates the steps necessary to safely set the completed state and optionally release any callers blocked in WaitForCompletion. Here is uses the new "monitor" support available on any object instance for locking. Now back in DoAsyncDispatch, the last call is to _Release. This undoes the manual _AddRef call Invoke because we now know the TThread queue doesn't have a reference to this instance anymore. It is also entirely possible that this _Release call could cause this instance to be freed. This is safe because there is no other code following this call that accesses any instance fields. Only the local stack and exception frames are cleaned up and control is returned to the caller.


Here are the remaining methods of TBaseAsyncResult. They should be self-explanatory:

destructor TBaseAsyncResult.Destroy;
begin
FAsyncHandle.Free;
FInvokingException.Free;
inherited;
end;

function TBaseAsyncResult.GetAsyncHandleObject: THandleObject;
begin
if FAsyncHandle = nil then
begin
System.TMonitor.Enter(Self);
try
if FAsyncHandle = nil then
begin
FAsyncHandle := TSimpleEvent.Create();
if FCompleted then
FAsyncHandle.SetEvent;
end;
finally
System.TMonitor.Exit(Self);
end;
end;
Result := FAsyncHandle;
end;

function TBaseAsyncResult.GetAsyncResult: TBaseAsyncResult;
begin
Result := Self;
end;

function TBaseAsyncResult.GetCompletedSynchronously: Boolean;
begin
Result := FSynchronous and FCompleted;
end;

function TBaseAsyncResult.GetIsCompleted: Boolean;
begin
Result := FCompleted;
end;

Now that the base functionality is defined, we can create the specialized descendant classes that will provide the specific functionality for the procedure and function call cases. We'll start with the simple procedure call first:

type
TAsyncProcedureResult = class sealed (TBaseAsyncResult)
private
FAsyncProcedure: TProc;
protected
procedure AsyncDispatch; override;
constructor Create(const AAsyncProcedure: TProc);
end;

As you can imagine, this one is pretty simple now. All the "meat" of the functionality is in TBaseAsyncResult. All this class needs to do is to add an instance field for a place to store the TProc reference, and override the AsyncDispatch virtual method. There is some tricky code here :-):

constructor TAsyncProcedureResult.Create(const AAsyncProcedure: TProc);
begin
inherited Create;
FAsyncProcedure := AAsyncProcedure;
end;

procedure TAsyncProcedureResult.AsyncDispatch;
begin
FAsyncProcedure();
end;

The function call version gets a little more interesting and is made possible through the judicious application of a generic type:

  TAsyncFunctionResult<T> = class sealed (TBaseAsyncResult)
private
FAsyncFunction: TFunc<T>;
FRetVal: T;
protected
procedure AsyncDispatch; override;
function GetRetVal: T;
constructor Create(const AAsyncFunction: TFunc<T>);
end;

Here we've created a generic type from a non-generic ancestor. The reason is that we don't know what the result type will be. Like the TAsyncProcedureResult type, we need an instance field to hold on to the TFunc<T> reference. For this class, however, we also need to save off the result of the function call, thus the FRetVal: T; field. We also need to have a way to get this value, so I've added the GetRetVal: T; function. The reason for the function call rather than directly accessing the field is to ensure that the caller blocks until the actual async call is completed by calling WaitForCompletion.

constructor TAsyncFunctionResult<T>.Create(const AAsyncFunction: TFunc<T>);
begin
inherited Create;
FAsyncFunction := AAsyncFunction;
end;

procedure TAsyncFunctionResult<T>.AsyncDispatch;
begin
FRetVal := FAsyncFunction();
end;

function TAsyncFunctionResult<T>.GetRetVal: T;
begin
WaitForCompletion;
Result := FRetVal;
end;

The final step is to put all of this together. Now that the core functionality is handled, the implementation of BeginInvoke/EndInvoke becomes very simple:

function TControlHelper.BeginInvoke(const AProc: TProc): IAsyncResult;
begin
Result := TAsyncProcedureResult.Create(AProc).Invoke;
end;

function TControlHelper.BeginInvoke<T>(const AFunc: TFunc<T>): IAsyncResult;
begin
Result := TAsyncFunctionResult<T>.Create(AFunc).Invoke;
end;

procedure TControlHelper.EndInvoke(const ASyncResult: IAsyncResult);
begin
(AsyncResult as IGetAsyncResult).AsyncResult.WaitForCompletion;
end;

function TControlHelper.EndInvoke<T>(const AsyncResult: IAsyncResult): T;
begin
Result := ((AsyncResult as IGetAsyncResult).AsyncResult as TAsyncFunctionResult<T>).GetRetVal;
end;

Finally, I need to explain the little "gotcha" with the usage example from my last post. Understanding how anonymous methods "capture" the enclosing context will serve to protect you from potentially confusing runtime errors, especially when dealing with asynchronous code. When the compiler "captures" the context it does so by capturing variables, not values. This is an important and critical distinction. It essentially means that you still have to work to protect variables being accessed by multiple threads. In the example code, the SR: TSearchRec; variable is used both inside and outside the anonymous method. The outer context is looping and updating the SR structure, and the inner anonymous method context is reading the value. Because of the asynchronous nature of the whole BeginInvoke/EndInvoke thing, they are now running completely independent of one another. Because of the very thing we're trying to accomplish, this causes a race on the SR variable.  The example implicitly synchronizes access to SR by not allowing FindNext() to execute until after the FForm.EndInvoke(AR); call. In this case, it essentially "re-serializes" the code and doesn't really demonstrate truly async code. Next time I'll present a technique that allows you to capture the values instead of the variables so that we don't actually "capture" SR and can "stack" lots of asynchronous calls. We'll ignore the exception propagation thing for now.

Friday, September 26, 2008

A Sink Programming.

In this post I demonstrated how you can use an Anonymous Method to "synchronize" a background thread with the main UI thread. However there are times where you don't want to block execution of the thread but still want to have something happen in the main UI thread, asynchronously. For several releases of Delphi there has been the Queue() method on TThread. This allows you to schedule a TThreadMethod (just like Synchronize) to execute on the main UI thread. The difference is that Synchronize will block the caller until the UI thread completes the call, while Queue will return immediately. The problem with the Queue() method is that there is no simple way to know when the "queued" event is done executing. Queue() really only works in a "queue it and forget it" scenario. It is still a form of Async programming has limited usefulness. New to D2009, a new Queue() overload was added just like Synchronize() that takes "reference to procedure" type (the underlying type to which you can assign an Anonymous Method). Let's see if we can use the Queue() method as the underlying mechanism for doing some "A Sink" programming :-).

Since the point of this exercise is to create something that we can use to asynchronously run some code on the UI thread and also know when it is complete, we need something that will represent a particular scheduled event. For this we'll declare an interface:

type
IAsyncResult = interface
function GetAsyncHandleObject: THandleObject;
function GetCompletedSynchronously: Boolean;
function GetIsCompleted: Boolean;
property AsyncHandleObject: THandleObject read GetAsyncHandleObject;
property CompletedSynchronously: Boolean read GetCompletedSynchronously;
property IsCompleted: Boolean read GetIsCompleted;
end;

The next thing I'm going to do is a trick I'm going to use to "extend" the existing framework using a class helper. This allows us to syntactically add something to the framework we will eventually fold into the class itself. If you looked closely we did this for the Windows Vista extensions to VCL for D2007, then in D2009, all those added methods and properties were folded directly into the classes themselves and the helpers were removed. Any consumers of the D2007 code could remain unchanged. But, I digress...

  TControlHelper = class helper for TControl
public
function BeginInvoke(const AProc: TProc): IAsyncResult; overload;
function BeginInvoke<T>(const AFunc: TFunc<T>): IAsyncResult; overload;
procedure EndInvoke(const ASyncResult: IAsyncResult); overload;
function EndInvoke<T>(const AsyncResult: IAsyncResult): T; overload;
end;

The non-generic versions of the methods are used for normal procedure calls where you're only interested in calling some method that doesn't have a return value. The non-generic EndInvoke() method simply blocks until the method call is complete and returns. If the call is complete before calling EndInvoke, then it will return immediately. If you call BeginInvoke from the UI thread, then the Proc is executed synchronously, and CompletedSynchronously returns true. The generic versions of these methods allow you to asynchronously call a function and get the return value once it becomes available. Using the AsyncHandleObject property on IAsyncResult, you can dispatch several different async calls with BeginInvoke() and then wait for one or all of them to complete using the new class function THandlObject.WaitForMultiple() in SyncObjs.pas. Another thing is that if an exception is raised during the execution of the Proc, it will be caught, saved off and then re-raised when you call EndInvoke(). So you should always call EndInvoke() at some point.


So that's an overview of the exposed interfaces. In this example, this is the execute method of a TThread descendant that searches a disk folder for all the files and fills up a list box the results. An edit box on the form holds the path to the folder, which is read asynchronously. Yes, a regular "Synchronize" could have been used in this case, but I needed a quick little example:

procedure TBeginInvokeTestForm.TSearchThread.Execute;
var
SR: TSearchRec;
SH: Integer;
AR: IAsyncResult;
begin
if not Terminated then
begin
AR := FForm.BeginInvoke<string>(TFunc<string>(function: string
begin
Result := FForm.Edit1.Text;
end));
FFolder := FForm.EndInvoke<string>(AR);
SH := FindFirst(IncludeTrailingPathDelimiter(FFolder) + '*.*', faAnyFile, SR);
while (SH = 0) and not Terminated do
begin
//Sleep(10); // this makes the background thread go a little slower.
AR := FForm.BeginInvoke(procedure
begin
if not Terminated then
FForm.ListBox1.Items.Add(SR.Name);
end);
FForm.EndInvoke(AR);
SH := FindNext(SR);
end;
end;
end;

This shows both the usage of the generic and non-generic BeginInvoke/EndInvoke functions. In the next post we'll start to look at the implementation behind all of this. We'll also start to look at how this same pattern can be used for async IO using I/O Completion ports and a simple thread pool. There is also a little "gotcha" in the above code using this technique that I'll explain.


Yes, this this looks remarkably like what is available in .NET. Hey they co-opted a bunch of ideas from Delphi and VCL... why not return the favor :-).


NOTE: The TFunc<string>() cast in the first BeginInvoke<string>() call is to work around an overload resolution bug that is slated to be fixed in a future service pack.

Thursday, September 25, 2008

News Flash! Someone has already invented the wheel!

I'm sure most, if not all, of you have heard the phrase "Why reinvent the wheel?" Another one I'm very fond of is "Standing on the shoulders of giants." The latter was often heard coming from Distinguished Engineer, Anders Hejlsberg during his tenure at Borland. So, why reinvent the wheel when there are giant shoulders to stand on ;-)?

If you've been following along for the last year or so, I've been working on something I loosely refer to as the Delphi Parallel Library. While I've not been blogging about the DPL for a while, I have been going back to it from time to time as I gain more knowledge and more information into the fascinating subject of parallelism and task dispatching. There is a veritable wellspring of information flooding the internet on this subject, so keeping up on it has been a daunting task. One excellent source of information is Joe Duffy the lead for the Task Parallel Libary team at Microsoft. Another is an interesting project at MIT called Cilk (that's pronounced "silk"). There is a spin-off company that is set to deliver on the work started from the Cilk project, called Cilk Arts. There is the Thread Building Blocks library from Intel. Finally, there are many smaller upstart projects, open source and otherwise out there. The point is that this is a hot topic.

One of the interesting facets about all of the projects I mentioned above, is that none of these libraries are really about "threading." They're about breaking down iterative algorithms into smaller and smaller chunks of work or "tasks" and then working on ways to execute as many of these tasks in parallel on separate cores. They're about scalability and performance. They try and minimize the overhead associated with traditional threading models. As I get deeper into creating a Delphi Parallel Library, the plan is to cull together some of the key concepts from all the existing research and libraries out there and use them as a "blueprint" for the DPL. I want to take these concepts and apply them in a "Delphi-like" manner that would be familiar and intuitive to the Delphi programmer while leveraging as much of the newer Delphi language features such as Generics and Anonymous methods. Joe Duffy's series about creating a Work Stealing Queue and combining it with a thread pool in which forms the basis for the .NET TPL is an excellent source of information. This whole notion of distributed work queues and work stealing is also something that the Cilk project has also done. A lot of the current research on parallelism also relies heavily on the latest in lock-free programming and algorithms. An excellent source for various lock-free lists, stacks and queues for the Delphi & C# folks is Julian Bucknall's blog.

The best way to learn is to actually do. While playing with some of these ideas and concepts, I've found that I really need to have an easy way to do some simple performance measuring. In .NET, there is an interesting little class, System.Diagnostics.Stopwatch. As I begin to lay the foundation, some of these little utility classes will be heavily used. Why not provide a stopwatch gizmo for Delphi? While the stopwatch is just a thin wrapper around the QueryPerformanceCounter() and QueryPerformanceFrequency() APIs, it provides a neatly encapsulated way to start, stop, reset, for measuring elapsed time. When I looked at the various use-cases for the stopwatch, it became clear that implementing this thing as a Delphi class would be require more housekeeping overhead than I wanted. Instead, I opted for doing this as a record with methods. Sorry, no Generics or Anonymous Methods in this one :-). Here's a Delphi version of the declaration:

  TStopwatch = record
strict private
FElapsed: Int64;
FRunning: Boolean;
FStartTimeStamp: Int64;
function GetElapsedMilliseconds: Int64;
function GetElapsedTicks: Int64;
function GetElapsedSeconds: Double;
class procedure InitStopwatchType; static;
public
class function Create: TStopwatch; static;
class function GetTimeStamp: Int64; static;
procedure Reset;
procedure Start;
class function StartNew: TStopwatch; static;
procedure Stop;
property ElapsedMilliseconds: Int64 read GetElapsedMilliseconds;
property ElapsedTicks: Int64 read GetElapsedTicks;
property ElapsedSeconds: Double read GetElapsedSeconds;
property IsRunning: Boolean read FRunning;
public class var Frequency: Int64;
public class var IsHighResolution: Boolean;
end;

Here's a simple use case using Barry's little benchmarker class (only the actual benchmarking functions):

class function TBenchmarker.Benchmark(const Code: TProc; Iterations,
Warmups: Integer): Double;
var
SW: TStopwatch;
i: Integer;
begin
for i := 1 to Warmups do
Code;

SW := TStopwatch.StartNew;
for i := 1 to Iterations do
Code;
SW.Stop;

Result := SW.ElapsedSeconds / Iterations;
end;

function TBenchmarker.Benchmark<T>(const Name: string; const Code: TFunc<T>): T;
var
SW: TStopwatch;
i: Integer;
begin
for i := 1 to FWarmups do
Result := Code;

SW := TStopwatch.StartNew;
for i := 1 to FIterations do
Result := Code;
SW.Stop;

FReportSink(Name, SW.ElapsedSeconds / Iterations - FOverhead);
end;

It's minor, yes, but it does reduce some of the thinking about calculating the time interval and having to declare a start and stop local variable. Also, since it is a record that is allocated on the stack, there are no heap allocations and there is no need to do any cleanup. Although, I admit that it would be nice to have a type constructor in order to better handle the initialization of the IsHighResolution and Frequency class variables.


And now the implementation:

class function TStopwatch.Create: TStopwatch;
begin
InitStopwatchType;
Result.Reset;
end;

function TStopwatch.GetElapsedMilliseconds: Int64;
begin
Result := GetElapsedTicks div (Frequency div 1000);
end;

function TStopwatch.GetElapsedSeconds: Double;
begin
Result := ElapsedTicks / Frequency;
end;

function TStopwatch.GetElapsedTicks: Int64;
begin
Result := FElapsed;
if FRunning then
Result := Result + GetTimeStamp - FStartTimeStamp;
end;

class function TStopwatch.GetTimeStamp: Int64;
begin
if IsHighResolution then
QueryPerformanceCounter(Result)
else
Result := GetTickCount * 1000;
end;

class procedure TStopwatch.InitStopwatchType;
begin
if Frequency = 0 then
begin
IsHighResolution := QueryPerformanceFrequency(Frequency);
if not IsHighResolution then
Frequency := 1000;
end;
end;

procedure TStopwatch.Reset;
begin
FElapsed := 0;
FRunning := False;
FStartTimeStamp := 0;
end;

procedure TStopwatch.Start;
begin
if not FRunning then
begin
FStartTimeStamp := GetTimeStamp;
FRunning := True;
end;
end;

class function TStopwatch.StartNew: TStopwatch;
begin
InitStopwatchType;
Result.Reset;
Result.Start;
end;

procedure TStopwatch.Stop;
begin
if FRunning then
begin
FElapsed := FElapsed + GetTimeStamp - FStartTimeStamp;
FRunning := False;
end;
end;

Now here's a question I've been unable to get a definite answer to: When would QueryPerformanceCounter and QueryPerformanceFrequency ever fail on a standard Windows system? Does this only occur for things like WinCE, Embedded NT, or systems with strange HAL layers? Even though I've taken into account that, according to the documentation, it could fail, in practice when is that?

Another "MacGyver" moment

Or, "More fun with Generics and Anonymous methods".

I'll just leave it up to you whether or not these utility functions are useful, but here they are:

type
Obj = class
class procedure Lock(O: TObject; Proc: TProc); static;
class procedure Using<T: class>(O: T; Proc: TProc<T>); static;
end;

class procedure Obj.Lock(O: TObject; Proc: TProc);
begin
TMonitor.Enter(O);
try
Proc();
finally
TMonitor.Exit(O);
end;
end;

class procedure Obj.Using<T>(O: T; Proc: TProc<T>);
begin
try
Proc(O);
finally
O.Free;
end;
end;

While very contrived, here's how you could use Obj.Using():

procedure TForm1.Button1Click(Sender: TObject);
begin
Obj.Using<TStringList>(TStringList.Create, procedure (List: TStringList)
begin
List.Add('One');
List.Add('Two');
List.Add('Three');
List.Add('Four');
ListBox1.Items := List;
end);
end;

And here's how you could use Obj.Lock():

procedure TMyObject.Process;
begin
Obj.Lock(Self, procedure
begin
//code executing within critical section
end);
end;