Thursday, May 10, 2012

SmartMS Demos

The Smart Mobile Studio is nearing its release date (no, can’t tell you when, but it will be soon, really soon) and it’s time to revisit my demos. You test them all from my website (just click on the images) and access the source code. If you don’t (yet) have Smart, you can browse OPP file with my primitive OPP Browser.

Accelerometer

image

Accelerometer-handling demo (iOS only). Move the square by tilting the device.

article, source

Game of Life

image

Conway’s Game of Life. Works on desktop and on tablets. Click in the gray rectangle on the left to open a library of building blocks then drag and drop a block on the game surface.

source

Gesture

image

Gesture-handling demo (iOS only). Handles move, zoom and rotate.

source

Mandelbrot Explorer

image

Mandelbrot explorer. Works on device (at least on iPad) and on desktop.

article, article, source

Multi Finger Paint

image

Paint with multiple fingers (iOS only; single finger may work on Android). Also handles mouse on desktop.

article, source

SmartTTT

image

Tic-tac-toe game.

source

TSmiley

image

No IDE is mature until it has a TSmiley component. Supports desktop and mobile. Click/touch to change TSmiley’s mood.

article, source

Tuesday, May 08, 2012

Delphi-Tage 2012

Incidentally, I’ll be in Germany just when the Delphi-Tage 2012 will be going on and I'll be staying fairly close (in Nürnberg). Is there any interest amongst my German readers in me presenting a session on multithreading there?

Sunday, May 06, 2012

Embarcadero Akademija: Multithreading

This is an announcement for the next “Embarcadero Academy” session. This time I will be talking about my favourite topic – multithreading. As the previous two sessions (Unicode, FireMonkey), this one is intended for the Slovenian Delphi programmers. The rest of my post is directed to potential participants and is therefore written in the Slovenian language.

Monday, April 23, 2012

GpDelphiUnits update

As always, all units are available on Google Code.

DSiWin32 1.66

  • Implemented DSiSetFileTime and DSiSetFileTimes.
  • Implemented DSiDateTimeToFileTime.
  • TDSiRegistry.ReadBinary, WriteBinary now use RawByteString for data buffer.

GpHugeF 6.05

  • Added logging to TGpHugeFile[Stream].

GpStreams 1.39

  • Added function CopyStreamEx accepting a TStreamProgressEvent.

GpStringHash 1.11

  • TGpStringObjectHash.Find returns 'nil' in 'value' parameter if key is not found.

GpTextStream 1.10

  • Implemented TGpTextMemoryStream, a TGpTextStream wrapped around a TMemoryStream.

Saturday, April 21, 2012

OmniThreadLibrary 3.01 released

This is mainly bugfix release with only few additions to the codebase. If you are using version 3.0 and not following the SVN trunk, update is very much recommended.
Get it now: ZIP, SVN.

Friday, April 20, 2012

OmniThreadLibrary Documentation: Join

A long chapter on Parallel.Join has been added to the wiki.

All book material is now also available in the Markdown format in the SVN.

I have started putting together “the book”. The plan is to release early – most probably when all high-level stuff is covered – and then to regularly publish updates. Updates will always be free for all customers. At the moment you can’t preorder the book but you can express your interest at the link above.

Sunday, March 25, 2012

How do you build FireMonkey iOS applications on Lion?

Delphi uses FPC 2.6.0 to do the iOS compilation.

image

I have Xcode 4.3.1 installed (no idea why the version is not displayed in the list).

image

FPC 2.6.0 doesn’t recognize it. Apparently it only works with Xcode up to 4.2.

image

Apple only offers XCode 4.3.1 for Lion.

image

So I’m asking you – can I really use Lion to compile FireMonkey iOS applications? Doesn’t seem so.

Sad smile

Friday, March 23, 2012

Running FireMonkey applications on OS X 10.7.3

I have big problems with FireMonkey applications not running on my new Mac Mini. Does anybody have any information about any possible incompatibilities between XE 2 Update 4 and OS X 10.7.3?

Full problem description is on StackOverflow.


This problem is connected to the Thread Status window. If you have this window visible in the Debug desktop, Delphi will lock when you try to run an OS X application in the debugger. Removing Thread Status window from the Debug desktop solves the problem.

Interestingly, some installations of XE2 Update 4 are working just fine even when Thread Status window is visible.

Wednesday, March 14, 2012

Embarcadero Akademija: FireMonkey

This is an announcement for the second “Embarcadero Academy” session. As the previous one, it is intended for the Slovenian Delphi programmers. The rest of my post is directed to potential participants and is therefore written in the Slovenian language.

Thursday, March 08, 2012

Unicode in modern Delphi applications

The first “Embarcadero Academy” session was a huge success. More than 40 people were present (we had to cap the participants as the venue don’t allow for larger audience) and as far as I could tell from all the direct and indirect feedback they were very satisfied with the three-hour Unicode presentation.

The topic of the next workshop will be FireMonkey. See you on March the 29th!

Sunday, February 26, 2012

Embarcadero Academy

In 2012, Embarcadero with the help of Slovenian distributor Marand is preparing a series of presentations, focused on different aspects of Delphi programming – Unicode, FireMonkey, multiplatform development, Object Pascal as a modern programming language, debugging, multithreading and more. Presentations will be given in Slovenian language by yours truly. The rest of my post is directed to potential participants and is therefore written in the Slovenian language.

Friday, February 24, 2012

Exceptions in Async

Pop quiz time! What would the user see if this code is executed in your application?

Parallel.Async(
procedure
begin
raise Exception.Create('Exception in Async'); end);

The answer may surprise you: Nothing! At least if you’re not using the latest SVN version.

Wednesday, February 22, 2012

Introduction to Debugging

Blaise Pascal Magazine #21 is out with with my introductory article on debugging. Two more advanced articles on the same topic are scheduled to follow.

Tuesday, February 21, 2012

Accelerometer Revisited

I wrote about handling accelerometer in iOS from the browser before (Detecting Device Movement, Accelerometer Demo) but I wasn’t happy enough with my code and I promised to return with the third part. Today I returned to the topic with advanced features – handling data smoothing and calibration.

Monday, February 20, 2012

Sunday, February 19, 2012

Blaise Pascal Magazine Rerun #9: High Level Multithreading

This article was originally written for the Blaise Pascal Magazine and was published in Issue #18.
Relevant Delphi code is available at
http://17slon.com/blogs/gabr/BPM/HighLevel.zip.

Saturday, February 18, 2012

Friday, February 17, 2012

OmniThreadLibrary Documentation: Future

I have just finished a pretty long chapter on futures.

Any comments, corrections, ideas etc are welcome.

8 Simple Rules for Modifying Production Database

  1. Make sure you have a backup!
  2. And by that I mean a fresh backup, made just now, not an idea that there may exist a person who knows where a backup is stored!
  3. Make sure you can restore from the backup!
  4. And by that I mean that you have tested the restore procedure. On the backup that you have just created. And that you have tried accessing restored backup with the program that usually operates on it!
  5. Don’t type any SQL commands. Use only scripts/programs that were previously tested on a development/test database.
  6. And by that I mean tested by yourself, not by a fictitious somebody who may have tested a script three years before on a database used by a completely different program!
  7. Don’t modify production database!
  8. And by that I mean DON’T MODIFY PRODUCTION DATABASE!

Thursday, February 16, 2012

Tuesday, February 14, 2012

Monday, February 13, 2012

Blaise Pascal Magazine Rerun #5: Four Ways to Create a Thread

This article was originally written for the Blaise Pascal Magazine and was published in Issue #10.
Relevant Delphi code is available at http://17slon.com/blogs/gabr/BPM/FourWaysToCreateAThread.zip.

Blaise Pascal Magazine Rerun #4: Introduction to Multithreading

This article was originally written for the Blaise Pascal Magazine and was published in Issue #9.

Friday, February 10, 2012

Accelerometer Demo

My accelerometer blog ended rather abruptly, without a demo program so today I’m returning to the topic.

To test the accelerometer control I wrote a very simple program in which you can move a rectangle around the screen by tilting your iOS device. You can test it here.

This program builds heavily upon the source code I found on Alberto Sarullo’s blog. Thanks!

Wednesday, February 08, 2012

OmniThreadLibrary Documentation: Async

First small part of the forthcoming documentation is available in the wiki, Any comments, corrections, ideas etc are welcome.

Tuesday, February 07, 2012

Detecting Device Movement

For my next quest I decided to find out how accelerometer works in web applications. IOW, I wanted to control an object on my HTML page just by moving my iPad around.

I limited my quest to iOS because that’s my favorite toy. don’t know yet how to do it in Android – this StackOverflow post hinted that access from bare JavaScript may not be possible. PhoneGap somehow does that, but it’s quite possibly that they implement Java wrapper that exposes native accelerometer data to your JavaScript. But that’s just guessing.

Thursday, February 02, 2012

Wiki Editing

Is there a Windows application that simplifies editing of Wiki-formatted documents? I would settle for a very basic one - all formatting can be displayed in wiki format on screen but I would like some helpful shortcuts and logic that would simplify multilevel list editing, basic formatting, cross-document linking etc.

Do you have any recommendation? I'm sick of using Notepad2 for these purposes.

In case there's no such tool available - is there a young programmer that needs a pet project? Put together a TSynEdit (to bring in highlighting and printing) and a toolbar/ribbon and you'll be half done...

Tuesday, January 31, 2012

OmniThreadLibrary Documentation–an Outline

That’s how it’s going to look. If you feel I have left something out, now is the time to raise your voice.

Saturday, January 28, 2012

A Sign of Maturity

No IDE is mature until it has a TSmiley component.
                                            
--Anonymous

This week I got a sudden urge to write TSmiley component for Smart Mobile Studio IDE. After all, what is a development environment without a smiley?

My TSmiley is not an enterprise-y solution like latest Nick’s revisit of the old theme ;), oh no, it is a lean and mean component without any special bells and whistles. You can select the smiley’s emotion and it will change the look. And that’s it.

I thought that a story about TSmiley for Smart would be instructive for you, dear reader, as this is almost the simplest component one can write. Read on to see how writing a component for Smart is very similar to writing a component for Delphi and how it is also utterly different.

GpDelphiUnits update

Although I’m regularly pushing updates into Google Code repository, updates to my web pages and, incidentally, to my blog are dragging behind. Here is the last year worth of changes:

Friday, January 20, 2012

Handling Touch Events

I mainly started playing with the Smart Mobile Studio because I wanted to write some stuff for my iPad. OK, there’s a small issue of possibly producing client applications for my job and maybe for some freeware/shareware stuff I’m thinking about, but this is not on the horizon yet. Therefore, iPad. (And I don’t have iPhone and I don’t care about writing stuff for my wife’s Android, so – iPad.) And writing for iPad means supporting touch gestures.

[Yes, I know I could use Objective-C but – bleuch, really? – and I could use FireMonkey but I don’t have a Mac and don’t want to buy one just for playing around and I can’t make Platform Assistant run in a Hackintosh, Therefore, Smart.]

Touch is natively supported in Smart. Gestures are not (but that may change before the release). What’s the difference, you ask? Touch subsystem will give you information about separate fingers like – finger has touched – another finger has touched – first finger was moved – both fingers were moved – while gesture subsystem will give you a simple – zoom gesture in progress. But hey, let’s start with touch. Lots and lots of stuff can be written with just the information about the fingers touching the screen.

Tuesday, January 17, 2012

Improved Painting

When I wrote about my first Smart Mobile Studio program I mentioned that it failed on iPad (and would probably fail on iPhone too but I couldn’t test that) because the Paint code took too long and the iOS simply aborted it. As far as I know there are two ways to fix this in JavaScript – you can either move the calculation to a background thread using a Web worker mechanism or split the Paint into multiple parts where each part only calculates and paints small part of the screen and then returns control to the browser. For the time being I went with the latter solution but that will not prevent me from testing the Web worker approach at some time.

OmniThreadLibrary in Practice [2a]–Backround Worker and List Partitioning

Today I’m revisiting example from November 2011. This time I’ll solve it using the new Parallel.BackgroundWorker abstraction.

Part of the Zarko’s requirements (see the original post for full text) was a cancellation support.

At any time the "master" thread could be signaled to terminate (from the app's main thread) all child threads (and itself).

When I was originally implementing this using the Parallel.Pipeline abstraction I had to put some work into the cancellation support. The main reason for this was inappropriate abstraction – Parallel.Pipeline is designed around the data flow processing and supports only a basic cancellation of the “stop everything” type. To be fair, that would comply with the Zarko’s requirements, but I wanted nicer solution where you can stop processing and then continue with a new work item without rebuilding the background thread mechanism. [Pipeline solution inherently supports cancellation but you cannot recover from it – to continue processing one would have to destroy the pipeline and build a new one.]

Tuesday, January 10, 2012

Background Worker

When I wrote OmniThreadLibrary in Practice [2]–Background Worker and List Partitioning in November, I noticed that OmniThreadLibrary needed another high-level abstraction, a background worker. I published some ideas on how the background worker interface could look. Those ideas were later developed in a full-fledged high-level solution.

Background worker is designed around the concept of a work unit. You create a worker, which spawns one or more background threads, and then schedule work units to it. When they are processed, background worker notifies you so you can process the result. Work items are queued so you can schedule many work items at once and background thread will then process them one by one. [Actually, Parallel.Pipeline is used as a base for the implementation.]

Handling Mouse Events in Smart Mobile Studio

After I finished my very first Smart program, I wanted to enhance it with some interactivity. I wanted the user to be able to navigate through the Mandelbrot set by using mouse and touch. For now, I have only implemented the mouse part, touch events will be handled later (soon, I hope).

I wanted to achieve few different ways of navigation:

  • Click & drag with the left mouse button shows a rectangle on the screen. When the mouse button is released, program zooms in to display the selected rectangle.
  • Double-clicking zooms in around the point of click.
  • Right-clicking zooms out around the center of the image.
  • Right-click & drag shows a line on the screen. When the mouse button is released, program moves the current view (point of first click is moved to the point of release).
  • If a drag operation is in progress, user can click and release the other mouse button (left if right-drag is in progress, right if left-drag is in progress) to cancel the drag operation.

You can see the navigation in action in this (very low quality, sorry) YouTube video.

Saturday, January 07, 2012

My First Smart Program

Last week I wrote about my first impressions about the OP4JS/Smart Mobile Studio project. This week I’ll show you my first program.

Wednesday, January 04, 2012

First Steps with Smart Mobile Studio

“JavaScript is Assembly Language for the Web” 
[original author unknown]
I learned about that idea from the omnipresent Hanselmann and I fully agree with it. JavaScript has its good moments, but they are completely outweighed by the total mess and confusion that is the JavaScript language and by some awful decisions made by the original designer.
If you don’t believe me, try answering the following question. “What does JavaScript expression ++[[]][+[]]+[+[]] evaluate to?” I’m not kidding you – this mix of plus signs and square brackets is a legit JavaScript expression and its result is ‘10’. [For proof, see Stackoverflow question Can you explain why ++[[]][+[]]+[+[]] = 10.]
As you may have guessed, I don’t like programming in JavaScript. I can read it on a good day but I never managed to write more than few lines of JavaScript code. On the other hand, I would like to write a browser application from time to time, as that would allow me to run such an app on different platforms (and by that I mean a PC, Mac, iOS, and Android).
When I learned about the OP4JS project, which promised a cross-compiler from Delphi-like language to a JavaScript and an integrated development editor, I was almost ecstatic with joy. Truly, such a tool would be a great addition to my toolset – if the authors managed to pull it through. It looked like a tough project for just two people. But … as the Lennart (one of the authors) likes to say – one good Delphi developer is worth hundred mouse-pushers (or something to that effect). They struggled and they succeeded. Just before the end of 2011, select few people received the alpha version of the IDE so that we could play with it over the holiday season.
I’ve got the permission from the authors to write about it so in the next weeks you can expect posts that will follow my road to Delphi-generated HTML+JavaScript applications.

Friday, December 30, 2011

OmniThreadLibrary 3.0

As promised, I’m releasing OmniThreadLibrary with 64-bit support today!

Get it now: ZIP, SVN, UML diagrams (provided by Rich Shealer).

If you’ll be using it in production, wait until Tuesday as I won’t be fixing any bugs over the weekend and on the Monday there is a public holiday here in Slovenia.

Wednesday, December 28, 2011

OmniThreadLibrary 3.0 beta

OmniThreadLibrary 3.0 beta is available for download. Please test and report any problems.

Version 3.0 will be officially released on Friday.

How to Find a Missing _Release

For quite some time, thread pool in OmniThreadLibrary had a weird problem – if you scheduled more than 80 tasks in one go, FastMM would report memory leaks when application was terminated. It bothered me, of course, but I could never find the real reason behind the problem. And so I left the code “as is” and said to myself that nobody would encounter it in practice, anyway.

And then Žarko came and wrote about me on his blog :( In case you are living in a dark cave and didn’t hear of him – Žarko runs immensely popular Delphi site at About.com. His testing (and most of all his highly reproducible test case) gave me a new energy to pursue the problem.

The reason for the memory leak was a reference count leak in TOmniInterfaceDictionary, which is now fixed in the SVN. I also found some very tricky race conditions in TOmniTask.Execute and TOmniTask.Terminate and a cause for weird "A call to an OS function failed" error in DispatchEvent. All in all, I had two very productive bug-hunting nights. But that’s not why I started writing this article. I wanted to tell you a debugging story titled “How to find a missing Release.”

Wednesday, December 21, 2011

… 62, 63, 64!

It is my pleasure to announce the availability of OmniThreadLibrary 3.0 beta. The main focus of this release is on the 64-bit support. Every part of OmniThreadLibrary is now compatible with the Windows 64-bit platform!

The current status of the code is “It works on my machine”. That is not pretty encouraging and I would really like to see some external testing. If you are using OTL, please get the fresh copy from the SVN and check if your applications are still working. 64-bit bugs are not a big problem right now – they will be squashed before any 64-bit OTL code goes into production – but I’d really like not to break existing code. Thanks!

image

Tuesday, December 20, 2011

… 54, 55, 56 …

Thread pool is working, other tests are passing nicely and it looks like you’ll be able to get your hands on the alpha version tomorrow.

image

Monday, December 19, 2011

… 47, 48, 49 …

Second milestone reached – dynamic lock-free queue works in 64 bits as does blocking collection. The latter is basis for most high-level threading abstractions in the OmniThreadLibrary so this is quite an important milestone.

image

Thread pool was not tested yet so the code is still in “look but don’t touch state”.

Sunday, December 18, 2011

… 39, 40, 41 …

First milestone reached!

“Bounded” containers (fixed-size stack and queue) are now working fine both in 32- and 64- bits!

image

This is quite an important step because those containers are used to transfer data between OTL controllers and threads (i.e. they are used inside the Comm mechanism). They also contained quite some assembly code.

image

Great thanks to GJ who did all hard work to make x64 OTL possible!

Friday, December 16, 2011

32, 33, 34 …

Initial work has been committed on the x64 development branch: http://omnithreadlibrary.googlecode.com/svn/branches/x64

Current status is “Look but don’t use”. Many parts are still broken.

Thursday, December 15, 2011

Creating an Object from an Unconstrained Generic Class

As you know if you follow my blog, OmniThreadLibrary now offers a simple way to do optimistic and pessimistic atomic initialization which works for interfaces, objects and (in the case of the pessimistic initialization), anything else. [In case you missed those articles - I also discussed a comparison of both methods and wrote a short post about the third approach to initialization.]

A typical usage of both types of initialization would be:

var
  sl: TStringList;
  ol: Locked<TObjectList>;

Atomic<TStringList>.Initialize(sl,
  function: TStringList
  begin
    Result := TStringList.Create;
  end);

ol.Initialize(
  function: TObjectList
  begin
    Result := TObjectList.Create;
  end);

As you can see, this is pretty long-winded. If you are initializing an interface, then you’ll usually have written a factory method already and the code would be much simpler (example below this paragraph) but in the case of objects this is not very typical.

Atomic<IGpIntegerList>.Initialize(list, TGpIntegerList.CreateInterface);

So I thought – both Atomic and Locked already know what entity type they wrap around so calling a constructor from inside Initialize would be trivial, eh? I could then write a simplified version

Atomic<TStringList>.Initialize(sl);
ol.Initialize;

and use the longer version only when needed, for example to initialize interfaces or to call a non-default object constructor. What could possibly go wrong?

Sunday, December 04, 2011

Busy-Wait Initialization

In response to my recent article on various kinds of initialization, GJ proposed another algorithm, which I will call here busy-wait initialization. This is the first time I’ve encountered this approach and I have no idea whether it is wide-known and has an “official” name.
The algorithm itself is very simple:
class function BusyWait<T>.Initialize(var storage: T; factory: TFactory): T;
begin
  if storage = nil then begin
    if InterlockedCompareExchangePointer(
         PPointer(@storage)^, PPointer(@factory)^, nil) = nil 
    then
      storage := factory()
  end;
  while PPointer(@storage)^ = PPointer(@factory)^ do
    Sleep(0);
end;
[This is not exactly the algorithm GJ proposed but my modified version, changed to work in a generic class.]

Friday, December 02, 2011

On Optimistic and Pessimistic Initialization

When you want to initialize a shared resource in a multithreaded application, you have two possibilities to choose from – optimistic and pessimistic. The difference between them is visible from the pseudocode.

var
Shared: T;

procedure OptimisticInitializer;
var
temp: T;
begin
if not assigned(Shared) then begin
temp := T.Create;
if not AtomicallyTestAndStore(Shared, nil, temp) then
temp.Free;
end;
end;

procedure PessimisticInitializer;
begin
if not assigned(Shared) then begin
Lock;
try
if not assigned(Shared) then
Shared := T.Create;
finally Unlock; end;
end;
end;

Thursday, December 01, 2011

Fibonacci Numbers the Weird Way

Yanniel recently posted two ways to generate Fibonacci numbers, here are two more.

Generating Fibonacci numbers with an enumerator

for i in Fibonacci(10) do
    Writeln(i);
Of course you need a Fibonacci-implementing enumerator. I wrote one on 2007 and it uses the iterative approach. Read more in my old article Fun with enumerators, part 6 – generators.

Generating Fibonacci numbers with anonymous methods

This one was prepared for ITDevCon 2011 as an example of tricky (but pretty much useless) example of what can be done using anonymous methods.

Tuesday, November 29, 2011

Per-object locking

I was always holding the opinion that locks should be as granular as possible. Putting many small locks around many unrelated pieces of code is better then using one giant lock for everything.

To make this simpler, OmniThreadLibrary includes a very useful record called TOmniCS which allows you to do locking without doing any upfront initialization. Just declare it and you’re ready to go. [You can read more about it in my previous blog post.]

Monday, November 28, 2011

Atomic interface initialization

OmniThreadLibrary includes (in the OtlSync unit) a neat record called TOmniCS which wraps IOmniCriticalSection interface (which in itself is just a wrapper around the TCriticalSection) and allows you to use it without an explicit initialization. You just declare a variable of the TOmniCS type in your code and then call Acquire and Release methods of this variable and everything is handled for you.

type
  TOmniCS = record
  strict private
    ocsSync: IOmniCriticalSection;
    function  GetSyncObj: TSynchroObject;
  public
    procedure Initialize;
    procedure Acquire; inline;
    procedure Release; inline;
    property SyncObj: TSynchroObject read GetSyncObj;
  end;
As records don’t provide automatic initialization via parameterless constructor, the code is slightly tricky. The record contains a field (ocsSync) that contains the interface reference used to do real work. This interface is initialized in the Initialize method, which is in turn called from the Acquire and Release.

procedure TOmniCS.Acquire;
begin
  Initialize;
  ocsSync.Acquire;
end;

Tuesday, November 15, 2011

OmniThreadLibrary needs more unit tests

Eh. How true. :( Care to step in?

It’s really simple. Take a sample application (for example 37_ParallelJoin), check what it’s doing and convert it into a unit test. [In this example, first button should cause a wait of about 3 sec and second button should cause a wait of about 5 sec. That’s all.] If the application you have chosen seems too complicated to be converted to a unit test, just ignore it and select another.

Why? Because I’ll be converting OmniThreadLibrary to support 64-bit and FireMonkey in the next week and I really could use a safety net which would ensure at least that I don’t break everything at once.

Why you? Because I’ll be converting OmniThreadLibrary to … but I already said that. If you can spend some time on that, then I don’t have to and everything will be finished quicker.

For really curious people – why 37_ParallelJoin? Because it is broken in the current SVN version. Parallel.Join.NumProc is not working correctly and I only noticed it by chance. [Fixing the bug right now …]

If you like OmniThreadLibrary but don’t feel competent enough to help developing it, this is your chance to step in and help the development effort!

Wednesday, November 09, 2011

TOmniValue handles arrays, hashes and records

Arrays

For quite some time, TOmniValue record has the ability to store arrays. You would use

TOmniValue.Create([1, 2, OTL, TButton.Create(nil)]) 
and some magic would store this array inside TOmniValue.
The problem, though, was that this magic was quite lame. The array was converted to a ‘variant array’ and you could only access its elements as Variant type. This, besides other things, meant that it was not simple to store pointers, interfaces and objects in TOmniValue array. Or, better said, it was simple to store them but not simple to retrieve them. You needed some ugly casting like

o := TButton(NativeUInt(ov[1]));
Since today, TOmniValue supports native arrays, that is, each item in the array is again of the TOmniValue type.

Thursday, November 03, 2011

OmniThreadLibrary in Practice [2]–Background Worker and List Partitioning

Today’s question was asked by Žarko Gajić, the excellent maintainer of About.com’s Delphi section.
Here's my (simplified) task I would like to solve using OTL (Delphi XE) - my real-world task is somehow more complicated but can be described as:
input: a string. output: a TStringList containing characters (one per entry) of the input string.
Example: input: "delphi"
A background thread ("master") grabs the input string and splits it into several pieces (let's say 2): "del" and "phi". For each of the split strings a new thread ("child") is created that fills in the TStringList (output) with characters from the section of the string it receives.
At any time the "master" thread could be signaled to terminate (from the app's main thread) all child threads (and itself).
When everything is done the app's main thread processes the string list.
Preferably, the order of the characters should (when all ends) be 'd', 'e', 'l', 'p', 'h', 'i' (note that characters are actually items in the resulting string list).

Saturday, October 29, 2011

ITDevCon 2011–recap

ITDevCon 2011 has closed its doors and I’m back at home, completely washed out. It was tiresome but it was also fun!

All the sessions I’ve visited were interesting and I always managed to learn something new. If I would have to expose three most important products I didn’t knew before, I would mention (in the order I learned about them) CopyCat, a great database replication engine which you can compile into your application; Delphi Relax, an extension to Delphi’s WebBroker and DataSnap REST architecture; and DORM, a new ORM for Delphi.

Thursday, October 27, 2011

ITDevCon 2011

Just few photos from the opening session …

P1070456P1070458P1070462P1070463P1070464P1070465P1070470

Wednesday, October 26, 2011

Nasty COM regression in XE2

David Heffernan found a nasty RTL bug in XE2 COM implementation.

Is COM broken in XE2, and how might I work around it?

I’ve found a workaround (see the link above), but it is ugly and this should really be fixed in the next XE2 update so please – vote on the QC #100414!

Update: XE2 Update 2 fixes the bug described above. Great response time from Embarcadero!

Saturday, October 22, 2011

Multithreading Made Simple–additional material

Thank you for listening to my CodeRage 6 presentation! I’m very sorry that there were some issues with the sound that were caused by network problems :( If you want to look at the presentation again (or for the first time), please go to the Embarcadero CodeCentral or download the presentation from my Dropbox.

To help you understanding the complicated world of multithreading I’ve repacked the complete presentation in a longish PDF with slides and a transcript of my talk. (Actually, it was done vice versa – first I wrote that script and only then I prepared the presentation based on the script.) You can also download the code that was used for the presentation.

If you have any questions or if you asked me something after the presentation and I didn’t understand your question and answered something completely unrelated or even if my answer was too short and you want to learn more - feel free to leave a comment here or open a new topic in the forum.

Friday, October 21, 2011

Multithreading Made Simple

Keep in mind – my session on high-level OmniThreadLibrary stuff goes on air at 06:00 AM PDT / 15:00 CET.

Thursday, October 20, 2011

OmniThreadLibrary in Practice [1]–Web Download and Database Storage

From time to time I get a question on the OmniThreadLibrary forum that could be of interest to other OmniThreadLibrary users. As I believe that many of you don’t follow that forum I have decided to repost such questions on the blog (and provide answers, of course).

The first question in this series was asked by GoustiFruit:

I need to download a list of web pages, extract data on them and then store these data in a SQLite database. The downloading/extracting part will happen in multiple threads (I'm using Synapse), but querying the database needs to be done asynchronously as I can only have one concurrent access to it.
So I'd like to know how (conceptually) I could implement that ? My first idea is to run one single thread for querying the DB, run several threads for each Url to download/analyse and then exchange messages between these threads and the querying thread, with the extracted data as a parameter: does it make sense or am I totally wrong? I also read things about the connection pool concept but I'm not sure if it applies when only one connection is allowed at one time?

Sunday, October 16, 2011

CodeRage 6 is Starting!

Tomorrow starts the CodeRage week!

My presentation is scheduled for Friday, 21st, at 06:00 PDT / 15:00 CET, which is early for the West coast folks but great for East cost and us Europeans. See you there!

Tuesday, October 11, 2011

OmniThreadLibrary 2.2

Only three months since 2.1 and a new release is already here? What’s going on?

I had to change some things to make OTL work in XE2 and although I could simply release new files as a patch I noticed that I’ve also done quite some work on exception handling and that I could equally well wrap everything in a new release.

Here it is: ZIP, SVN, UML diagrams (provided by Rich Shealer; Rich, thanks!).

Friday, October 07, 2011

Hear Me at CodeRage

CodeRage 6 will start in ten days! Will you be there? I’ll be joining it for the sixth time as a listener and for the first time as presenter!
The exact date and time of the presentation was not determined yet (if you look at the session list you’ll see some empty spots – I’m one of them). I’ll let you know when the timeslot is fixed. In the meantime, go and register for the conference!
The topic of my talk you can probably guess – multithreading with the OmniThreadLibrary. Due to a limited session time and to attract as wide an audience as possible, I’ve decided to focus on high-level OTL functionality. The title of the talk is Multithreading made simple and it will deal with Async, Future, ForEach, Pipeline, ForkJoin, Join, and ParallelTask.

Wednesday, September 28, 2011

NeverSleepOnThreadContention–NOT!

FastMM is a wonderful memory manager, but it can slow down quite a lot when used in multithreading environment. While Pierre has implemented some conditional defines that could help the multithreaded code, namely NeverSleepOnThreadContention and SwitchToThread, I’m now making a point that you shouldn’t ever use them! Just see for yourself.

Friday, September 16, 2011

Meet Me in Verona

SpeakerButtonI know that XE2 on Win64, OS/X and iOS is all the rage but some of us (or is it most of us?) still have to make living in the Win32 world. That’s why my ITDevCon 2011 talks are not focused into specific technologies but into techniques and tools that will make your life easier. (At least your life as a programmer, that is.)

If you have time and you live close enough, come to Verona at the end of October and meet many interesting people. Lots of speakers, three separate tracks, free lunch and wifi – what do you want more? David I is rumored to be there, Marco Cantù will lead sessions all the time and you’ll have a chance to talk to me. I’ll be giving four sessions, some targeted at beginners, some at experienced programmers. (All between those extremes are also invited, of course.)

Monday, September 12, 2011

Life after 2.1: Parallel data production [Introducing Parallel.Task]

An interesting problem appeared on StackOverflow shortly ago – how to generate large quantities of data as fast as possible and store it in a file. (As one could expect) I wrote a parallel solution using OmniThreadLibrary, more specifically the Parallel.ForEach high-level primitive. I’m not posting the complete solution here, just the important part – a method that accepts two parameters, requested file size and output stream, and generates the data. Actual initialization of data buffers is delegated to the FillBuffer method which you can see in the StackOverflow post.

Tuesday, September 06, 2011

Life after 2.1: Pimp My Pipeline

While the biggest focus on the Pipeline improvement was on the exception handling, there were also some changes in the basic functionality.

The most important (and code breaking!) change happened to the Input function, which was renamed to From. If you now want to pass a input queue to a pipeline, use pipeline.From(queue).

Second code breaking change happened to the Run function which now returns IOmniPipeline (i.e. the pipeline interface) itself, not the output blocking collection. Luckily, both changes will be caught by the compiler which would not want to compile the old code any more.

Thursday, August 25, 2011

Multithreading is Hard!

I have known for a long time that there’s a potential race condition between two writers in TOmniBlockingCollection but I thought that it doesn’t present and clear and present danger. Boy was I wrong!

Friday, July 29, 2011

Life after 2.1: Parallel.Join’s new clothes

Parallel.Join has started its life as a very simple construct.
class procedure Join(const task1, task2: TProc); overload;
class procedure Join(const task1, task2: TOmniTaskDelegate); overload;
class procedure Join(const tasks: array of TProc); overload;
class procedure Join(const tasks: array of TOmniTaskDelegate); overload;
Later it got an optional parameter of the IOmnITaskConfig type, but that didn’t change its simplicity. You called Join, it executed some code in parallel, and only when all code blocks completed its execution, your main thread would proceed by executing the statement following the Join call.
Then I started to think about handling exceptions (just as I did for the Parallel.Future) and somehow this simplicity didn’t feel right to me anymore. At the same time I got involved in a prolonged discussion with Антон Алисов (Anton Alisov) and together we defined new features that new Join would have to have.

Thursday, July 28, 2011

OmniThreadLibrary 2.1 hotfix

All users of the 2.1 release, please download this very important hotfix.

There was a nasty bug in OtlEventMonitor where FreeAndNil was called on a variable containing garbage from the stack. >:-(

Great thanks to [Антон Алисов] for finding the problem.

Thursday, July 21, 2011

Life after 2.1: Exceptions in Parallel.Future

The main focus in the next OmniThreadLibrary release is on exception handling in high-level constructs (i.e. the OtlParallel unit). The first one to get this support is Parallel.Future. Why? Simple reason – it has a well-defined point of interaction with the owner (the Value function) and only one background task, which makes exception handling easy to implement.
IOmniFuture<T> was extended with three functions.
  IOmniFuture<T> = interface
    procedure Cancel;
    function  DetachException: Exception;
    function  FatalException: Exception;
    function  IsCancelled: boolean;
    function  IsDone: boolean;
    function  TryValue(timeout_ms: cardinal; var value: T): boolean;
    function  Value: T;
    function  WaitFor(timeout_ms: cardinal): boolean;
  end; { IOmniFuture<T> }
Any exception thrown in the background task and not caught in the future-calculating code will be caught by the IOmniFuture<T> implementation. When a Value is accessed, this exception will be raised in the owner thread.

Wednesday, July 20, 2011

Life after 2.1: Async redux

OtlParallel unit defines four overloaded Async methods in OTL v2.1:

class procedure Async(task: TProc; taskConfig: IOmniTaskConfig = nil); overload;
class procedure Async(task: TOmniTaskDelegate;
taskConfig: IOmniTaskConfig = nil); overload;
class procedure Async(task: TProc; onTermination: TProc;
taskConfig: IOmniTaskConfig = nil); overload;
class procedure Async(task: TOmniTaskDelegate; onTermination: TProc;
taskConfig: IOmniTaskConfig = nil); overload;

As it turned out, two of them are not necessary anymore. Since the introduction of the taskConfig parameter, termination procedure can also be specified by setting taskConfig.OnTerminated.

Tuesday, July 19, 2011

OmniThreadLibrary 2.1

Yes, it is ready. Get the ZIP or check it from SVN.

If you’re following the trunk, do the update. You’ll actually get more than 2.1 as I’ve already merged in development branch with support for exception handling in Parallel.Future and Parallel.Join. Warning – those changes may break the code as two version of Parallel.Async were removed. Check the history.txt and documentation in OtlParallel.pas for more info.

This time you can also download full UML diagrams for OmniThreadLibrary, courtesy of Rich Shealer.

2.1 release should be mostly non-breaking, except for changes in OtlHook exception filtering mechanism and removed EXIT_EXCEPTION exit code (see below for more info).

I’d like to thank dottor_jeckill, Rico Krasowski, vcldeveloper and TOndrej, who helped make this release even more awesomer.

Saturday, July 16, 2011

Getting ready for OmniThreadLibrary 2.1

After a long long wait (sorry folks, due to events out of my control this release took many months longer that I expected) OmniThreadLibrary 2.1 is finally ready!

I’m just putting together change log, testing demos to see if everything is working as it should and so on … A day or two and it will be packed and ready to go. If you’re impatient, just go ahead and check out the current version from the SVN – all the code is already in there.

I have a small favor to ask, though. If you’re using OmniThreadLibrary in D2009 or D2010 – can you please make sure that all tests are included in the appropriate Tests.<version>.groupproj file (and create missing <project name>.<version>.dproj files in the process)? And send the changes to me, of course – my email address is in OTL source files. It would be best if you can leave a comment here if you choose to help me so that the work won’t be duplicated by other programmers.

Thanks in advance, that will really help me getting OTL out quickly. (Otherwise I have to set up a virtual machine and install D2009 and D2010 as I’m not using them for everyday work anymore.)

EDIT: D2010 projects and updated test group are now in the repository, thanks to [vcldeveloper].

EDIT: D2009 projects and updated test group are now in the repository, thanks to [TOndrej].

Saturday, June 25, 2011

Sleep Sort in OTL

I found Sleep Sort so ingenious (in the mad genius way) that I just had to implement it using the OmniThreadLibrary framework.

The code is now shorter than Serg’s original implementation and it’s … wait for it, wait for it … even faster! Twice as fast as the original, actually! Now that I call an improvement!

The code below carries not copyright nor copyleft and can be used in any occasion as long as you don’t blame me for getting fired or any other problems in your personal or professional life it may cause.

Friday, June 10, 2011

Lock-free vs. Locking: Rematch!

My article on lock-free vs. locking data queues was well-received but there were also some comments and complaints. To answer the critics (your comments were all very appreciated!) and to fix some issues with the previous test I’ve decided to stage a rematch.

New contestants

Both Iztok and Chris have provided me with new versions of their queue implementations. Iztok’s code was tuned a little and changed to use TOmniValue instead of TAnyValue for better comparison with TOmniQueue. Chris has created three different variants of his code.

Thursday, June 02, 2011

OmniThreadLibrary Needs YOU!

That is, if you are a C++Builder programmer and want to help an open source project.

image

The problem with OmniThreadLibrary and C++Builder is very simple – I’m not using it. (The C++Builder part, obviously.) Therefore I’m not checking for compatibility with C++Builder and I cannot fix the stuff if it doesn’t work. (In C++Builder.)

And now a user reported that the OTL doesn’t compile. In C++Builder. And I don’t know how to help him. With his problems. In C++Builder.

[BCC32 Error] DSiWin32.hpp(36): E2257 , expected

[BCC32 Error] DSiWin32.hpp(346): E2040 Declaration terminated incorrectly

[BCC32 Error] OtlCommon.hpp(305): E2238 Multiple declaration for 'TOmniValueContainer::Item'

[BCC32 Error] OtlCommon.hpp(304): E2344 Earlier declaration of 'TOmniValueContainer::Item'

[BCC32 Error] OtlSync.hpp(33): E2113 Virtual function '_fastcall IOmniCriticalSection::Release()' conflicts with base class 'IUnknown'

[BCC32 Error] OtlSync.hpp(74): E2113 Virtual function '_fastcall IOmniResourceCount::Release()' conflicts with base class 'IUnknown'

Is there a nice soul out there that can tell me how to fix the problem? (Or even better, who can make sure that the OmniThreadLibrary compiles with C++ Builder.) Your fixed will be gratefully imported into the main development branch and you’ll earn an eternal fame.

Thursday, May 26, 2011

Lock-free vs. locking

For the past few days I was running tests on three different queue implementations – one lock-free, one based on Delphi’s TQueue<T> and TMonitor and one implemented using critical section and linked list. For a good measure I’ve also thrown a blocking wrapper around the lock-free queue into the mix. [Mostly because I’m using it a lot (it has useful features for multithreading work) and I wondered how much time penalty it adds to my applications.]
During that time I’ve discovered a showstopper bug in TMonitor which practically made TSimpleThreadedQueue useless when using more than one reader. Still, I’m including partial results for that implementation too, as they provide a good comparison.

Tuesday, May 24, 2011

TMonitor bug?

When Chris Rolliston implemented a simple threaded queue class using TMonitor, I was quite ecstatic. Finally I will be able to compare my lock-free queue with a threaded implementation! (That’s something I wanted to do for a long time but I never found a willpower to write a locking queue.)
My elation continued while I was coding my test app and while I tested my own queue. And then I plugged in Chris’ queue and … everything went downhill :( Immediately, my test app started crashing. At first it looked like the bug was in Chris’ code, but when I enabled debug DCUs, debugger pointed to a very unlikely location – TMonitor. Unlikely because of two reason – because I know that Delphi people take quality to the heart and test the code and because I know Allen is an experienced guy who writes excellent code.

Sunday, May 15, 2011

TDM Rerun #17: Put It In A Tree

Hierarchical data appears everywhere and most of the time it must be rebuilt from simple non-hierarchical storage. Think about mail, news, CVS repositories and databases, not to mention groupware and chat forums. Trees are everywhere.

- Put It In A Tree, The Delphi Magazine 118, June 2005

This article dealt with thread sorting, an algorithm that takes a number of items connected with parent-child relationship and puts them into a tree so that they can be displayed in a nice structured way. The ideas and implementation are still perfectly valid.

Links: article (PDF, 82 KB), source code (ZIP, 241 KB).

Divide and Conquer (in parallel)

One of the latest additions to the high-level OtlParallel constructs, Fork/Join, was implemented just before ADUG 2011 and presented there for the first time. Shortly after the ADUG I improved the Fork/Join a little but then forgot to blog about it as I was busy implementing Parallel.Async and Parallel.TaskConfig. Sorry :(
Fork/Join helps you solve just one class of problems, but it is an important one – the problems that can be solved by so-called Divide and Conquer algorithm.
For deeper discussion of D&C, read the Wikipedia article linked above. What interests us is that D&C works by subdividing the problem. Instead of trying to solve the big problem, we divide it into many smaller problems and then we try to solve them. Those subproblems may again be too big and have to be subdivided even further. The process continues until the subproblems are small enough that they can be solved easily.
Of particular interest to us are D&C algorithms where subproblems can be solved in parallel.

Tuesday, April 26, 2011

Configuring background OtlParallel tasks

High-level OmniThreadLibrary parallelism (i.e. the OtlParallel unit) is great when you are running mostly independent parts of code but what can you do when you want to communicate with the main thread from a task?
A few weeks ago my answer would be along the lines of setting communication channel manually or dropping down to low-level parallelism (i.e. the CreateTask) but both are very complicated solutions. There was certainly a room for better solution.
Since the release 910, released on April 17th, OtlParallel contains much simpler way to configure tasks and to set them up for communication with the owner.

Sunday, April 17, 2011

Simple background tasks with OtlParallel

While there’s a simple way to execute one-shot background threads with the low-level OTL API (by calling CreateTask), there is no such high-level function in OtlParallel. At least, there wasn’t one until release 899 was committed to the SVN. (Incidentally, that happened 11 days ago but I was silent about it because I was working on another feature – TaskConfig – which will be completed “really soon now”.)
In short, Parallel.Async accepts an anonymous method, normal method or procedure (all of them must be without parameters) and executes it in a background thread. That’s all.

Thursday, March 31, 2011

ADUG 2011 Slides

My presentation from ADUG 2011 is now online at http://www.thedelphigeek.com/p/presentations.html.

Check out the handouts document as it contains lots of my previous writing on OmniThreadLibrary (high-level stuff) neatly collected and organized into one document.

ADUG 2011 - presenters

Thursday, March 24, 2011

Delphi Down Under

This year’s Australia Delphi User Group symposium is a two day event with sessions in Melbourne and Sydney. The first of those – the Melbourne session – happened today. We met in the John Scott Meeting House at the La Trobe university.

image
Turnout was quite big – nearly 80 very attentive listeners.
listeners

Saturday, March 19, 2011

GpProfile on Google code

You may know that lifetime ago I developed fairly successful Delphi profiler called GpProfile.

You may also know that it kinda slipped into oblivion and that it can’t correctly profile modern Delphi code (it is a source instrumenting profile, i.e. it changes your source code so it can be profiled).

You may know all that but I’m fairly sure that you don’t know that GpProfile now works for all Delphis up to XE! How can I be so sure? Because I only learned this a short time ago!

Антон Алисов (Anton Alisov) was brave enough to step in, update the code and create the Google code archive. Go Anton!

In case you’re still using GpProfile (or just want to find out why it was one of most popular Delphi profilers), visit gpprofile2011 project on Google code.

Wednesday, March 16, 2011

Synchronize comes to OmniThreadLibrary

This just came in:

  • IOmniTaskControl.Invoke(procedure begin … end)
  • IOmniTaskControl.Invoke(procedure (const task: IOmniTask) begin … end)
  • IOmniTask.Invoke(procedure begin … end)

Still missing:

  • IOmniTask.Invoke(procedure (const task: IOmniTaskControl) begin … end)