Wednesday, April 25, 2018

Multithreading is (still) hard!

Multithreading is hard!

No matter how long you deal with it and how good you (think) you are, you will make a mistake. Usually, it will be a problem that will only exhibit itself in a rare circumstances, most probably on a hard-to-reach customer machine. With some (bad) luck it will only appear on Friday afternoons or during your vacation.

That is why I'm always introducing multithreading with the "Don't do it yourself!" motto. Use a standard library! (And by that I mean OmniThreadLibrary, of course. ;) ) As your code, it too will have bugs. Unlike your code, it has 1000+ users running it in very different environments which means that at least it is tested as much as possible.

There are, nevertheless, bugs that escape detection for a long time. In 2011, for example, I fixed a well-hidden problem in TOmniBlockingCollection ("Multithreading is Hard!"). As nasty as that was, it was nothing compared to the bug I found recently!

As it turned out, the implementation of a bounded (fixed-size) multiple-producer multiple-consumer lock-free queue TOmniBoundedQueue (try saying that in one breath!) was buggy since its inception! As this queue is basis to all OmniThreadLibrary communication channels it is really surprising that the bug hid from everybody for 9 (yes, nine!) long years.

Friday, March 02, 2018

Delphi High Performance

My second book was also released these days. I wrote it for Packt Publishing, a publishing house which has recently started printing Delphi titles. The first was Delphi Cookbook by Daniele Teti, a very successful title that was followed by Delphi Cookbook - Second Edition by the same author.
Last year they published Expert Delphi by Paweł Głowacki, followed this year by my book and (as I have it on a good authority) at least one more. All books are available in electronic and printed formats. They also offer Delphi video lectures.

Delphi High Performance Book CoverDelphi High Performance is, as the name says, a book about writing Delphi applications that perform well. That does not mean writing multithreaded applications - and I say this many times in the book. To write high performance applications you need to known much more. The book therefore starts with the basics - with the algorithms, how we can classify them, how they behave and how can we pull the most from the built-in Delphi data structures. Then it moves to profilers because you should never guess what the slowest part of the code is. Always measure!

Writing a book that tells you "this is how you make your algorithm faster" is, sadly, impossible. That's why we consultants are for ;) In the book I only gave few advises (with lots of examples) about working with the GUI and about caching results from calculations.

Only then do I go deep into Delphi. Writing fast applications means knowing how built-in data types behave. I look into data life-cycle, what happens when a data of some type is modified and how it is passed in function calls. The life-cycle part cannot be explained without talking about memory which brings in a discussion of memory managers in general and FastMM in specifics.

Only then does the book introduce multithreading. Whole three chapters are dedicated to it and one of them is specifically written to show you why multithreading is hard, what you should never do when writing multithreaded code and why you shouldn't approach this topic with a preconception that it will automatically speed up your code. Only then do I introduce TThread and modern concepts such as tasks, futures, parallel for and so on. Most of the time I stay with the Delphi RTL and show how modern multithreading concepts can be neatly implemented on that basis. Only at the end I introduce OmniThreadLibrary's concept of a pipeline.

At the end the book admits that sometimes you have to look around and find a prepackaged solution elsewhere. As this solution will be typically compiled for C or C++, the book shows how to link in C object files, how to write a proxy DLL which allows you to use a C++ library and at least tries to introduce you to the world of pain related to all that. Reading this book will definitely not give you enough information on the topic of linking, but at least it will give you a good starting point so that you can research further.

I really hope that you'll like this book. It was a great joy to write, but also lots of very hard work. At the end, all the hard work was immediately forgotten when Stefan Glienke (who very kindly reviewed the whole book and pointed out some glaring errors - Stefan, thanks!) said:
"This is the best Delphi book (for me personally) I've read since 'Delphi in a Nutshell'. It is 'must buy' for our department and mandatory that everyone reads it."

Wednesday, February 28, 2018

Parallel Programming with OmniThreadLibrary - the book is here!

My first book Parallel Programming with OmniThreadLibrary is finally out!

The book covers OmniThreadLibrary version 3.07.5 which was also released today.

As this book was always meant to be documentation for the OmniThreadLibrary, my job doesn't end here. I will update and enhance the e-book whenever OmniThreadLibrary is updated and modified. All owners of the e-book will get these updates for the lifetime of the book.

The printed book will also be updated, but most probably only with major updates to OmniThreadLibrary. There will not be an update for release 3.07.6 (if there will be such release), but most probably there will be a new version of printed book when OmniThreadLibrary 3.08 is released and there most definitely will be one when version 4.0 comes out.

Here are your options at the moment.

1. If you would like to own the ebook, go to LeanPub. You can buy an ebook for $29.99 and package containing ebook + three webinars about the OmniThreadLibrary for $34.99. You can also buy an organizational license which allows you to give as many copies as you want to members of your organization.

2. To buy the hardcover printed book go to Lulu. For the next month the price is reduced from $49.99 to $45.99 as an introductory offer! I'm still deciding the possibility of also releasing a paperback version but I'm not entirely sure about that as paperback binding on Lulu is reportedly not of high quality. A price of the paperback would be about $10 lower than the price of the hardcover (that is the difference in print costs) and if you think that would make a difference for you, leave me a note.

3. To buy both versions (ebook and printed), go to Lulu and buy the printed book first! You will get an email with a link for ebook at reduced price $9.99 (and combo with webinars for $14.99).

All existing owners of the electronic book should have already received an email with notification about the new release. This email also contains a link to a specially reduced printed book for mere $29.99! If you previously bought the ebook but didn't receive the email, let me know!

Before I sign out for today, let me tell you that writing this book was lots of hard work but also a great joy and I could never do it without all the great people who bought the ebook before it was even completed. Thank you!



OmniThreadLibrary 3.07.5

OmniThreadLibrary 3.07.5 has been released. You can get it at GitHub or download the ZIP.

There are only small number of changes in this release.

General improvements

  • Reduced number of times NameThreadForDebugging is called when threadpool is used.

Bug fixes

  • [VyPu] fixed race condition in TOmniCriticalSection.Release which affected code that was using TOmniCriticalSection.LockCount.
  • OtlThreadPool did not respect OTL_DontSetThreadName define.


Tuesday, February 13, 2018

Data-driven Multithreading

About a week ago, Craig Chapman posted a vlog Lockless Multi-Threading in Delphi where he programmed a lockless communication channel which transfers messages between the main thread and a worker thread (or, actually, between any two threads).

I do like Craig's implementation of a lockless queue. It is small, neat, and working. I also like that he approached multithreading from a communication viewpoint. I do, however, have several issues with how it is integrated into the application. While I whole understand the need for simple demo that viewers can understand, I feel that the Delphi world is full of such examples. That makes it hard for a newcomer to the multithreaded world to find appropriate patterns to copy.

Hence I decided to rewrite Craig's code with different objectives in mind. Instead of speed I focused on flexibility, ease of use and good multithreaded programming patterns. Before I jump into my solution, however, I must articulate the bad programming practices in the Lockless demo. (That is strictly subjective reasoning. Your mileage may vary. It is, alas, a reasoning supported by many many years of writing bad multithreaded code - and not yet enough years of writing good code.)

Saturday, February 03, 2018

Books, wonderful books!

I love reading. I loved it since the (very) young days. As far as I remember, books were my friends.

I also love - as I somewhat surprisingly discovered in my twenties - teaching and writing. I always kept to the short form - blog posts, magazine articles, and so on. Always - until few years ago I somehow decided that documenting OmniThreadLibrary would be best done in a form of a book.

Friday, December 08, 2017

Spring4D presentation slides and more

Slides and code for my Spring4D presentation are now online on the Presentations page.

And to the participants of the workshop, here's the answer I promised.

If you want to catch all calls to some function while mocking, you can pass in Arg.IsAny (or call some other function of the TArg type, defined in Spring.Mocking.Matching).

I have added an example to the Mocking project.

mockCalc.Setup.Returns(4).When.AddTwo(2);
mockCalc.Setup.Executes(
  function(const callInfo: TCallInfo): TValue
  begin
    lbLog.Items.Add('Don''t know how to handle ' + callInfo.Method.Name +
     
'(' + IntToStr(callInfo.Args[0].AsInteger) + ')');

  end).When.AddTwo(Arg.IsNotIn([2]));

Or you can pass Args.Any to the When function. In that case, the argument passed to AddTwo is ignored.

mockCalc.Setup.Returns(-1).When(Args.Any).AddTwo(0);


Monday, December 04, 2017

Advent of Code

Last few days I'm having great fun solving problems from Advent of Code 2017 page and so does my daughter (with a bit of help from her dad). I'm using Delphi and she Python so that's also a good practice to brush my multilanguage skills ;)

Go ahead, take a look at the problems. Some are simple, some not so much, but they are all quite interesting.

All my solutions are posted to my GpDelphiCode repository so you can look at and criticise my code. Most of the solutions depend on units from my GpDelphiUnits repo so you'll need that one too.


Friday, December 01, 2017

In the middle of winter, Spring comes to Ljubljana

Indeed, it is snowing for the last three days. Not much, but winter is definitely here.

To add some green to the white surroundings we'll spend the next Friday talking about spring. Or, actually Spring. For Delphi. Also known as Spring4D - definitely the best Delphi collection of programming goodies that you can find around.

If you speak Slovenian language (sorry, almost all of the world population), you're welcome to my workshop about that ingenious library. If not, you'll have to find that information somewhere else, sorry. Or you can learn Slovenian and come to Ljubljana. Where else can you listen about Delphi in a session targeted to only 2 millions of humans?

Programerji smo včasih malo leni in iščemo bližnjice. Odlične programe bi radi napisali s kar najmanj kode. Pri tem nam pomaga tudi fleksibilnost jezika Delphi in odlične programerske knjižnice.

Tokrat si bomo ogledali knjižnico Spring4D, ki prinaša množico malih pripomočkov in bljižnic za pametne programerje - od objektov, ki jih ni treba sproščati, do razredov, ki jih ni treba inicializirati in seznamov, po katerih se lahko sprehajamo, jih filtriramo, povezujemo in še in še.

Za nameček bomo podrobneje obdelali še tehniko Dependency Injection in si - bolj za zabavo, kot zares - ogledali še, kako lahko v Delphiju s tehniko odzivnega programiranja ReactiveX dogodke obravnavamo čisto drugače kakor smo navajeni.


Izkoristite priložnost in spoznajte kako lahko hitreje napišete odlične programe. Vabljeni v petek, 8. decembra, ob 9.00 uri, v predavalnico Obrtne zbornice Vič. 


Sunday, November 05, 2017

Writing a Simple DSL Compiler with Delphi [7. AST Compiler]

This article provides a description of an AST compiler used for my toy language project. If you are new to this series, I would recommend to start reading with this post. At least you should read the previous post, Intermezzo, as it explains some parts of the compiler that I won't touch here.

Please note that this article describes an initial implementation of the compiler. If you want to browse the code while reading the article, make sure that you have switched to branch dsl_v1.

In my toy compiler framework, a compiler (or codegen as it is called internally), is a piece of code that implements the ISimpleDSLCodegen interface. This interface exposes only one function, Generate, which takes an abstract syntax tree and converts it into an object implementing an ISimpleDSLProgram interface which allows you to call any function in a compiled program by name.

type
  TParameters = TArray;
  TFunctionCall = reference to function (const parameters: TParameters): integer;
  ISimpleDSLProgram = interface ['{2B93BEE7-EF20-41F4-B599-4C28131D6655}']
    function  Call(const functionName: string; const params: TParameters;       var return: integer): boolean;
   end;

  ISimpleDSLCodegen = interface ['{C359C174-E324-4709-86EF-EE61AFE3B1FD}']
    function Generate(const ast: ISimpleDSLAST;      
      var
runnable: ISimpleDSLProgram): boolean;
  end;

Thursday, October 19, 2017

OmniThreadLibrary 3.07.4 has been released

Bug fixes:

  • TOmniEnumeratorProvider and TOmniValueEnumeratorProvider support dmoPreserveOrder option. Now you can use PreserveOrder modifier on Parallel.ForEach when input is IEnumerable, IEnumerator, TEnumerator, or TEnumerable.
  • Fixed 64-bit issues in DSiWin32, GpLists, GpStringHash, and GpStuff.

New features:
  • Locked.Value is now both readable and writable property.  
  • Moved 'inline' functions around so that they will be inlined more often.
As usual, you can get OmniThreadLibrary from GitHub (3.07.4HEAD), download the zip, install it with GetIt or with Delphinus.

Tuesday, October 17, 2017

Writing a Simple DSL Compiler with Delphi [Intermezzo]

When I was preparing an article about the compiler part of my toy language project, I found out that the concept of wrapping a whole program into a bunch of anonymous functions (what the compiler does) is exceedingly hard to explain. I had therefore prepare a simplified version of the compiler, written for a very simplified language ... and then I couldn't stop and I added an AST, parser, tokenizer, interpreter and all shebang.

The result of all that is a program introduction.dpr, a self-contained console program which contains a complete (almost trivial) language together with the full documentation, written in a Literate Programming style. Simply put - you can read it from top to bottom like a story.

As an intermezzo and to simplify my explanation of the compiler, I'm posting the whole program here, reformatted as a blog post.

Saturday, October 14, 2017

Writing a Simple DSL Compiler with Delphi [6. AST Dumper]

This article provides a description of a testing tool used for my toy language project. If you are new to this series, I would recommend to start reading with this post

Please note that this article describes an initial implementation of the parser. If you want to browse the code while reading the article, make sure that you have switched to branch dsl_v1.

Now that we have a working tokenizer and parser outputting an AST, we can start working on the compiler. Still, it would be great if we can verify whether the parser output (the AST) makes any sense. In other words, we need unit tests.

Writing unit tests for a tree structure is, however, a very tedious operation. In the next post I'll show a test for a tree with only five nodes and it will already be a process one would rather skip. Luckily, we can do something more fun - we can write a code that recreate the original program from an AST.

Tuesday, October 03, 2017

Writing a Simple DSL Compiler with Delphi [5. Framework]

This article provides a description of a compiler framework used in my toy language project. If you are new to this series, I would recommend to start reading with this post.

We have now a working parser that converts a string of code into an abstract syntax tree - AST. It is, however, not yet time to write about the most interesting piece - the compiler - as we should first do some integration and testing.

Friday, September 29, 2017

Writing a Simple DSL Compiler with Delphi [4. Parser]

This article provides a description of a parser used in my toy language project. If you are new to this series, I would recommend to start reading with this post.

Please note that this article describes an initial implementation of the parser. If you want to browse the code while reading the article, make sure that you have switched to branch dsl_v1.

After a short break I'm returning to my "toy compiler" series. This time I'll describe the working of the parser - the part of the code which reads the input (usually in a tokenized form) and generates internal representation of the program (in my case an abstract syntax tree - AST).

The goal of my project was to study the compilation step and parser was just a necessary evil that I had to deal with. That's why it is written in a pretty primitive manner, without using any improvements like a Pratt parser.

Tuesday, September 19, 2017

Delphi and Linux

I'd just like to remind my Slovenian readers that on 28th this month I'll be having a presentation about RAD Studio and Linux in Ljubljana.

As the presentation will be given in Slovenian language, the rest of my post containing the description of the presentation is written in that language, too.

Vljudno vabljeni na delavnico "RAD Studio in Linux", na kateri si bomo ogledali:

  • Kako namestiti Ubuntu v virtualni računalnik.
  • Kaj storiti, ko namestitev nagaja.
  • Kako pripraviti virtualni računalnik in RAD Studio za delo.
  • Kako napisati konzolno aplikacijo za Windows in Linux, ki streže podatke z uporabo tehnologij FireDAC in DataSnap.
  • Kako napisati grafično aplikacijo za Windows, OS X, iOS, Android, ki prikazuje in spreminja podatke na aplikacijskem strežniku iz prejšnjega koraka.
  • Z nekaj sreče pa še: 
    • Kako to grafično aplikacijo pognati na Linuxu in
    • Kako konzolno aplikacijo spremeniti v pravi Linux "service".
Vstop prost, prosimo vas le, da se vnaprej registrirate, da bomo znali pripraviti zadostno količino kave in prigrizkov ;)

Wednesday, September 06, 2017

Autumn is coming ...

... and with it, a whole bunch of events.

First, I'll be going to IBC 2017 in Amsterdam where we are presenting our products in Hall 2. I'll be there from 15th to 18th, so if anybody wants to meet, contact me.

Immediately after that I'm going to Zegrze (just north of Warsaw) to speak at Zlot Programistów Delphi (Delphi programmers convention) on 21st and 22nd. Never been there before, should be great fun.

A week later (28th) I'll be leading a workshop on Delphi and Linux in Ljubljana. (Slovenian readers - you can sign on now.)

To finish it up, I'll present two all-new topics in ITDevCon in Rome on October 11th and 12th.

All that in four weeks. Should be quite an interesting time ;)

Monday, September 04, 2017

Introducing OmniThreadLibrary Core

Yesterday I wanted to use OmniThreadLibrary as a git submodule in a top secret ;) open source project I'm working on and I was a bit shocked when it turned out that newly cloned OmniThreadLibrary folder is a 83 megs in size. Given that I only need it to support my other project and that I won't do any OTL fixing/development in this submodule, that looked a bit excessive.

So I went ahead and created a core branch which contains only the barebones - the OmniThreadLibrary root folder without any subfolders. If you want to compile such submodule, you'll also need the GpDelphiUnits repo. Together they weight measly 3,5 MB, which is a big improvement over the original 80+ megs.

I'll be keeping core in sync with the latest OTL release, not with the HEAD, so it will also provide a stable platform for all depending repositories.

Friday, September 01, 2017

Writing a Simple DSL Compiler with Delphi [3. Tokenizer]

This article provides a description of a tokenizer used in my toy language project. If you are new to this series, I would recommend to start reading with this post.

Please note that this article describes an initial implementation of the tokenizer. If you want to browse the code while reading the article, make sure that you have switched to branch dsl_v1.

With this article I'm moving into the gritty part of the project - the code which reads the source code and turns it into a beautiful abstract syntax tree. In other words, I'll be talking about the parser.

I must admit that I spent as little time on the parser as I could. After all, my main goal was to convert AST into an executable code, not to parse input. Still, one cannot write a compiler without writing a parser, so ... here I am.

Monday, August 28, 2017

Writing a Simple DSL Compiler with Delphi [2. Abstract Syntax Tree]

This article provides a description of an abstract syntax tree used to represent "The Language". If you are new to this series, I would recommend to start reading with this post. 

Please note that this article describes an initial implementation of the AST. If you want to browse the code while reading the article, make sure that you have switched to branch dsl_v1.

An abstract syntax tree (AST) is, simply put, a symbolic representation of the program in a form of a tree.

While the textual representation of a program is great for us, humans, computers have hard time dealing with it. Because of that, a special part of any interpreter/compiler, called parser, reads the input and converts it into a computer-readable format - AST. This tree can then be used for multiple purposes. We can, for example, feed to into an interpreter which will then run the program for us, or we can feed it into a compiler to generate an executable program or cross-compiler to generate an equivalent program in a different programming language.

Friday, August 25, 2017

Writing a Simple DSL Compiler with Delphi [1. The Language]

Part 1: The Language

This article provides an informal definition of a simple language (a.k.a. "The Language") I am writing a compiler for. If you are new to this series, I would recommend to start reading with this post.

Let's start with a simple example which calculates an i-th Fibonacci number.

 fib(i) {
   if i < 3 {
     return 1
   } else {
     return fib(i-2) + fib(i-1)
   }
 }

The code is quite simple. First two numbers in a Fibonacci sequence are 1 and every other Fibonacci number is a sum of previous two in the sequence.

Wednesday, August 23, 2017

Writing a Simple DSL Compiler with Delphi [0. Introduction]

Part 0: Introduction

Some time ago I was listening to the Hanselminutes podcast where a guy described how he wrote a simple interpreter in Go language (YOU should write an interpreter with Thorsten Ball). I was not really interested in writing an interpreter - I did that a long time ago - but a thought crossed my mind. I asked myself whether I can do something better - write a compiler. (Or, rather, a kinda-compiler. You'll see.)

What I wanted to do is to take a small language, parse it, generate an abstract syntax tree, and then convert this into one large anonymous function calling other anonymous functions calling other anonymous functions and so on and so on. It is hard to explain, so let me try using a very simple example.

Tuesday, August 01, 2017

OmniThreadLibrary 3.07.3

TL;DR: Update OmniThreadLibrary now!

A nasty bug was found in the DSiWin32 library. It causes the DSiTimeGetTime64 function to work incorrectly when called from multiple threads at the same time. As this function is central to time measurement in the OmniThreadLibrary, it was essential to release new, fixed version.

This version also contains two small enhancements.

  • SetTimer method now accepts TProc and TProc timer methods.
  • IOmniTask implements method InvokeOnSelf which can be used to schedule anonymous function execution from a task back to self.  

As usual, you can get OmniThreadLibrary from GitHub (3.07.3HEAD), download the zip, install it with GetIt or with Delphinus.

Damn, multithreading is hard!

Thursday, July 06, 2017

OmniThreadLibrary 3.07.2

This is just a small update which adds few helpful methods. Although the change log mentions a potentially breaking change I don't think this will affect anybody. (And if you are not sure, you can enabled backward-compatible behaviour by adding one line to the code.)

I have also (finally) found some time to work on The book. It is now fully up to date (all OmniThreadLibrary features are documented on its whooping 293 pages) and is only missing one or two introductory chapters.

As usual, you can get OmniThreadLibrary from GitHub (3.07.2, HEAD), download the zip, install it with GetIt or with Delphinus.

Change log follows after the break.

Wednesday, May 24, 2017

RAD Studio 10.2 links

This post contains just a bunch of links to online resources that I mentioned on the today’s presentation.

Monday, May 22, 2017

10.2 Tokyo comes to Slovenia

In two days I’ll present RAD Studio 10.2 Tokyo in Ljubljana.

Click here for more information and to register.

Thursday, May 18, 2017

OmniThreadLibrary 3.07.1

This update brings only few small changes. The biggest of them is support for the Delphi 10.2 Tokyo.

You can get it as a zipped download, git checkout, via Delphinus, and via GetIt.

For more information on OmniThreadLibrary, go to www.omnithreadlibrary.com.

Monday, March 20, 2017

Forward record declaration

Forward declaration is not really a new concept. It was already present in the original Wirth Pascal where it allowed the programmer to do one thing and one thing only – call procedure A from procedure B and procedure B from procedure A. Remember – in ye olde times of good old Pascal we had no interfaces, no classes, no units … just procedures and functions.

Because the code tells more than thousand words, here’s an example (still perfectly valid in modern Object Pascal).

procedure ProcA; forward;

procedure ProcB;
begin
  ProcA;
end;

procedure ProcA;
begin
  ProcB;
end;

Friday, February 17, 2017

OmniThreadLibrary 3.07

New year, new release ;) You can get it as a zipped download, git checkout, via Delphinus, and via GetIt.

For more information on OmniThreadLibrary, go to www.omnithreadlibrary.com.

Tuesday, February 07, 2017

OmniThreadLibrary 3.07 beta + plans for OmniThreadLibrary 4.0

It is almost time for a new release! If you’d like to see what 3.07 will contain – or if you just want to test it before it is out – click here.

[If you are a serious OTL user - and especially if you are using pre-Seattle Delphi - please test your program(s) with the beta release. Thanks!]

I have started work on OTL 4.0 which will (fingers crossed) fully support cross-platorm work. Yup, it will work on all platforms that Delphi can compile for! Multiplatform support was implemented by Sean B. Durkin so if OTL/Mobile is something you were waiting for a long time, go to OmniThreadLibrary-For-Mobile Google+ community and express your gratitude.

Thursday, December 08, 2016

RAD Studio and Version Control + Git – links

This post contains just a bunch of links that I refered to in my two-part (live) presentation on version control management with RAD Studio and Git.

Slides for the presentation: pps, pdf

Wednesday, November 30, 2016

Embarcadero Akademija: RAD Studio and Version Control

This is an announcement for the next Slovenian “Embarcadero Academy” session. As it is intended for Slovenian Delphi programmers, the rest of this post is in the Slovenian language.

Monday, November 21, 2016

Debug Faster. Debug Smarter.

My CodeRage XI session on debugging in RAD Studio is now available on YouTube.

If you have missed the presentation or want to see it again, now is a good time :)

Additional materials (slides, code) are available on the Presentations page.

Monday, November 14, 2016

Hear me speak at CodeRage XI

This year I’ll be presenting two sessions at CodeRage XI.

On Wednesday, I’ll be exploring the topic of debugging in RAD Studio. I’ll show how advanced options in breakpoint properties work and drop some debugging tips & tricks here and there. Join me in room 1 at 7 am PST / 10 am EST / 16.00 CET.

On Thursday I’ll be demoing new enhancements in FastMM. If you are writing multithreaded code, then this session will be targeted to you! Join me in room 1 at 10 am PST / 1 pm EST / 19.00 CET.

Saturday, November 05, 2016

Recording Webinars (repost)

As I’m pretty sure many Delphi programmers will be working on their CodeRage XI videos this weekend ;) , I decided to repost a link to my year old post Recording Webinars – My Workflow. Maybe it will be of some use to you.

Monday, October 24, 2016

OmniThreadLibrary 3.06.2

Another week, another critical update …

There was a logical error – also known as “my own stupidity” – built into OTL 3.06 which prevented programs that used OtlCommon to be started on Windows XP. This is now fixed.

There’s also a tiny addition to OtlSync included in this release.

download / git

Wednesday, October 19, 2016

OmniThreadLibrary 3.06.1

There was a nasty bug in DSiWin32 unit included with the 3.06 release so I had no other option than to quickly issue a fix. If you have downloaded version 3.06 then please update to 3.06.1 as with 3.06 you could experience weird crashes during program startup. I’m really sorry for that :(

There’s also a tiny addition to TOmniValue included in this release.

download / git

Monday, October 17, 2016

OmniThreadLibrary 3.06

Hi, guys! After a looong time, a new version of OmniThreadLibrary was released! It is available as a zipped download, git checkout, via Delphinus and (really soon) via GetIt.

Following stuff was added/changed/fixed since the 3.05 release:

Monday, October 10, 2016

ITDevCon 2016

ITDevCon was - as always before - a blast! Great topics, great presenters, great organization and great food!

My presentations (slides and code) are now online at the usual place.

Friday, July 15, 2016

OmniThreadLibrary Everywhere

For the last year and some, Sean B. Durkin has been working on the mobile port of the OmniThreadLibrary. There was lots to be done, as OTL was never designed to be a portable library – after all, it was created in Delphi 2007 times.

Recently I merged his latest commits into the mobile OmniThreadLibrary branch. This version is (by his words) functionally complete (although it may be missing some very recent OTL features) but is very much untested. So Sean is asking everybody that is interested in multithreading on OS/X, iOS, and Android to help him find bugs and to make OTL even more awesome!

Please report any findings to his OmniThreadLibrary-For-Mobile-DevelopmentProject on Google+. I am currently working on other aspects of the OTL and didn’t I put much energy into checking his work.

Wednesday, June 22, 2016

When 64 cores are not enough

Just a little teaser …

Following two branches just sprung to life:
https://github.com/gabr42/OmniThreadLibrary/tree/numa
https://github.com/gabr42/FastMM4-MP/tree/numa

Plus I started planning OTL&FastMM changes:
https://docs.google.com/document/d/1dHiJyHj80TJ2oFAOtFxNtXLMrAhzm7F5SoczBl5ssxM

Feel free to comment on that Google Docs document.

Friday, June 10, 2016

OmniXML Official Repository

In case you are wondering which of the many github (and even bitbucket) omnixml repos is the official one (as www.omnixml.com is still pointing to the old googlecode storage), this is it: https://github.com/mremec/omnixml.

www.omnixml.com should be pointing to the correct repository “real soon now” ;)

Wednesday, May 25, 2016

RAD Studio Berlin 10.1 Notes and Links

In case you are already using RAD Studio Berlin 10.1 or are merely looking into it, these links and notes may help you.

YouTube videos

Thursday, May 19, 2016

RAD Studio 10.1 Berlin presentation in Ljubljana

Next week (Wednesday 25th) I’ll be presenting the new and shiny 10.1 release in Ljubljana.

For more info click here.

Tuesday, March 01, 2016

Defensive Programming and Advanced Debugging

Next Wednesday (9th) I’ll be holding a presentation in Ljubljana. Topic: defensive programming, maintaining a clean code, and debugging tips and tricks. Presentation will be applicable to both Delphi and C++Builder programmers.

As usual, I’ll be presenting in Slovenian language.

For more information and registration click here!

Sunday, February 21, 2016

Finding Memory Allocation Bottlenecks with FastMM4

Recently, I had to find bottlenecks in one of our applications that does all sorts of things related to DVB and is handling real-time reading and sending of data streams over IP with bitrates up to 80 Mb/s (in our lab; in real life maybe even more). Our customer created a configuration which essentially brought the app to the crawl and I had to fix it.

It quickly turned out that although the program was not able to handle the load, the CPU was not very busy. The busiest core was only using about 30% CPU. So I suspected the thread contention problems in FastMM, switched it for SapMM and indeed - the problem went away. CPU load went up and application could again handle the load.

Crisis averted, I took time to find the real problem - excessive get/freemem calls in this program. As far as I could tell, there existed no tool to find that so in a true DIY manner I created my own ;)

Wednesday, November 18, 2015

Connect Your Applications with REST – Links

The materials for my “Connect your applications with REST” workshop are now available online (in Slovenian language).

Below you can find all the interesting DELPHI- and REST-related links I have collected during the preparation of this workshop.

Thursday, November 12, 2015

Connect Your Applications with REST

Next Wednesday (18th) I’ll be holding a presentation about all things RESTish in Delphi. We’ll start with basics and then move to DataSnap, REST Client Library, REST Debugger, BaaS and more!
As usual, I’ll be presenting in Slovenian language.
Register here!

Sunday, October 18, 2015

Simplify Parallel Programming with Patterns

My CodeRage X session on parallel programming with patterns is now available on YouTube.

You can also download the slides (pps, pdf) and code.

Friday, October 16, 2015

Recording Webinars – My Workflow

Each time I have to record a webinar, I have trouble remembering how exactly did I do it last time, so I decided to document my workflow. Maybe this will help somebody else besides me …

If you have any ideas on how to improve my workflow or if you have a different way of solving same problems, then please post it in the comment section. Thanks!

[v 1.01: Added screenshots of CamStudio and Filmora settings and few words on Audacity settings.]
[v 1.02: Added appendix A with some time&space information.]

Updating a Progress Bar From a Parallel For Loop (Plus Two Bonuses)

During the Q&A part of my Simplify Parallel Programming with Patterns presentation on CodeRage X, I’ve promised the listeners to publish a demo for updating a progress bar from a parallel for loop.

In this article I’ll try to explain few different approaches that all solve this problem. I’ve also put together a demo project which demonstrates all techniques.

Thursday, September 24, 2015

Links for 10 Seattle Presentation in Ljubljana

Firstly, thanks to everybody who visited my RAD Studio 10 Seattle presentation! I’m sorry I had to improvise because of bad video drivers, but on the other hand RAD Studio performed great!

2015-09-24 09.16.20

Secondly, here is a bunch of links I’ve promised.

OmniThreadLibrary Spotlight now On-line

My short spotlight presentation about high-level OmniThreadLibrary patterns is now available on YouTube.

Wednesday, September 23, 2015

Conditional Compilation with Features

EDIT: Make sure you read this post to the very end!

Are you developing a code that must work in different Delphi versions? Are you sick of writing code like

{$IF CompilerVersion >= 22}
class function Mapper<T1,T2>:
IMapper<T1,T2>;
{$ENDIF}

as you a) never know when some feature was introduced into Delphi and b) constantly wonder which version of Delphi has CompilerVersion equal to 22?


Then maybe you could use this simple include file.


Wednesday, September 16, 2015

Learn All About RAD Studio 10 “Seattle” in Ljubljana

Next Thursday (24th) I’ll be presenting new RAD Studio 10 Seattle in Ljubljana. This is announcement for Slovenian readers.

Naslednji četrtek (24.) se mi pridružite v kristalni palači na predstavitvi novega RAD Studia 10 Seattle, ki je po mnenju mnogih (in tudi mojem), ena boljših različic tega programskega orodja v zadnjih letih.

Predstavil vam bom izboljšano podporo za Windows 10 (v VCL in FMX), nove vizualne gradnike, izboljšave v IDE, novo podporo za mobilna okolja (razhroščevanje iOS 64-bit programov, pisanje sistemskih storitev za Android), novosti in izboljšave v sistemskih knjižnicah RTL, pa tudi novosti v prevajalnikih za C++ in še marsikaj.

Več podatkov o dogodku najdete tu.

Monday, September 07, 2015

OmniThreadLibrary 3.05

Hear, hear, OmniThreadLibrary 3.05 has just been released!

What’s new? Not much.

  • Added Delphi 10 Seattle packages and projects. OmniThreadLibrary now supports Delphis from 2007 to 10 Seattle.
  • Setting IOmniThreadPool.MinWorkers property will start up idle worker threads if total number of threads managed by the thread pool is lower than the new value.

There were, however, many quite important bug fixes. You are strongly advised to update to this version!

Monday, August 31, 2015

OmniThreadLibrary on Delphinus

OmniThreadLibrary now supports the Delphinus package installer. If you are using Delphi XE or newer, you can install Delphinus, select OmniThreadLibrary, and click Install. Delphinus will do the same steps GetIt does: download OTL, recompile and install package, and add proper paths to the search and browsing path. Source will be installed to c:\Users\Public\Documents\Embarcadero\Studio\<release>\Comps\.

image

Friday, August 28, 2015

Spotlight on OmniThreadLibrary

If you are not using OmniThreadLibrary yet, or if you are only using its low-level parts (CreateTask and company), I’m kindly inviting you to a 20-minute presentation “Simple Parallel Programming with Patterns and OmniThreadLibrary”, which will be transmitted as a part of the Embarcadero Technology Partner Spotlights series on September 3rd.

There are three timeslots to chose from so I’m sure everybody can find a suitable time. After the first two presentations I’ll be handling Questions and Answers and Jim McKeeth has kindly offered to do the job for the third presentation as it will be around 02.25 AM here when it is finished.

If you want to see something interesting and new, register here!

[Slides, code, and video will be available on my blog after the presentation.]

Thursday, August 27, 2015

OmniThreadLibrary 3.04b on XE8

Just a quick note – OmniThreadLibrary 3.04b is now available on XE8 via GetIt.

Thursday, August 20, 2015

Book Update: Miscellaneous

I have updated the Parallel Programming with OmniThreadLibrary book with the Miscellaneous chapter. The book is now almost complete!

Changelog:

  • Documented TOmniMessageQueue.
  • Documented TOmniTwoWayChannel.
  • Documented TOmniValueContainer.
  • Documented TOmniCounter.
  • Documented TGp4AlignedInt and TGp8AlignedInt.
  • Documented TOmniRecordWrapper.
  • Documented IOmniAutoDestroyObject.
  • Documented IOmniEnvironment.
  • Documented examples.

Sunday, August 02, 2015

Setting Up a Parallel Build System

OmniThreadLibrary now supports 11 different Delphi versions (2007, 2009, 2010, XE, XE2, XE3, XE4, XE5, XE6, XE7, XE8), some with very special requirements about the supported pascal syntax (2007 and 2009 clearly standing out in that regard) so it takes quite some time to test the compilation of all demos and run unit tests on all supported editions. (And this time will only increase with the addition of support for mobile platforms and OS X. Not that I’m complaining. Sean is doing a terrific job there!)

It does not help that I don’t have all those Delphis installed on my computer. Most of them are only installed in a VM. And it takes a looooong time to start up a VM, run tests, power it down, start up next VM, and so on. And when I fix something, I have to retest it all ….

This kind of testing hurts. So in the manner of the Continuous Integration mantra, I decided to do it more often.

Wednesday, July 29, 2015

Double Bill: OmniThreadLibrary 3.04b & a Book Update

I have just updated OmniThreadLibrary to version 3.04b. This is kinda important update as I somehow messed the 3.04a release which did not include support for more than 60 concurrent tasks that was added in version 3.04. This important feature is now back and I’ve added few other small improvements.

Changelog for this release:

  • Reimplemented support for TWaitFor in the TOmniTaskControl which was removed from the code in release 3.04a by mistake.
  • Implemented TOmniSingleThreadUseChecker, a record which checks that the owner is only used from one thread.
  • TOmniCommunicationEndpoint.ReceiveWait and .SendWait are now fully thread-safe and support multiple consumers (former) and multiple producers (latter).

Version 3.04b can be downloaded here. Alternatively, you can check out this release or update to the trunk.

I have also released a new version of “the book” which is now 239 pages long! Following sections were added/updated:

  • Documented TOmniValue.
  • Documented TWaitFor.
  • Documented TOmniLockManager.
  • Documented TOmniSingleThreadUseChecker.
  • Adapted Communication Subsystem documentation.

Sunday, July 12, 2015

OmniThreadLibrary Book Update

After a (much too) long time, I have (finally) found some time to work on my book “Parallel Programming with OmniThreadLibrary”. For starters, I have updated existing content so that the current version (3.04) is properly documented. The following topics were added/updated:

  • Documented Parallel.For.
  • Documented Parallel.Map.
  • Documented TOmniBlockCollection.ToArray<T>.
  • Added longer example for Parallel.For.
  • Documented IOmniTaskConfig.SetPriority and .ThreadPool.
  • Documented Parallel.Pipeline.PipelineStage[] property.
  • Documented new demos.
  • Documented other changes and additions.
  • Updated hyperlinks.

Update is free (as it always was and as it will always be) for all owners of the book. You probably already received an email with details. If not, you should just go to LeanPub and download the new version.

You can buy the book (and with that support the OmniThreadLibrary development) here.

GpSQLBuilder Improvements

Thanks to [leledumbo], GpSQLBuilder now works with the FPC pascal and supports the INSERT statement.

You can now write statements such as:

  query := CreateGpSQLBuilder
.Insert
.Into(DB_TEST)
.&Set(COL_1, [42])
.&Set(COL_2, 'abc')
.AsString;

Which will give you:



INSERT INTO Test (Column1, Column2) VALUES (42, 'abc')


Saturday, July 04, 2015

Using OmniThreadLibrary’s Message Queue with a TThread Worker

A reader recently asked about using OmniThreadLibrary’s communication channels with a TThread-based worker thread so I prepared a simple example, now part of the OTL repository (stored in the folder examples\TThread communication).
Two separate topics are covered in this example:
  • Sending data from any thread (main or background) to a TThread-based worker.
  • Sending data from a TThread-based worker to a form.

Friday, May 15, 2015

OmniThreadLibrary – GetIt!

OmniThreadLibrary is now available on GetIt so it can be installed in XE8 with a single click!

image
Go, Embarcadero! That’s really great!

Thursday, May 14, 2015

XE8 links

In case you’d like to know more about the RAD Studio/Delphi/C++ Builder XE8, following links will give you a good starting point.

Thursday, May 07, 2015

Presenting XE8 in Slovenia

Next Thursday (14th) I’ll be presenting XE8 in Ljubljana. We’ll be doing the standard “launch” combo – official (English) slides and demos + Slovenian presentation.

Register here!

Thursday, April 30, 2015

Runtime SQL Query Builder v3

There’s a whole new SQL Query Builder available on GitHub. I have basically rebuilt it from scratch as the previous “architecture” (it does not actually deserve to be called that) was just slapping strings together and that approach had reached its limits.

Query builder is now implemented as three units – GpSQLBuilder.AST implements an abstract syntax tree for SQL queries, GpSQLBuilder.Serialize knows how to serialize this tree to a string and GpSQLBuilder creates the tree and calls the serializer when necessary. Now it will be much simpler to a) add support for new SQL keywords and b) create different serializers, for example a ‘pretty print’ version. (If anybody wants to tackle this last task, please go ahead – I’ll be happy to merge a pretty print serializer into the master branch.)

In addition to that I have added support for different Joins: .InnerJoin, .RightJoin, and .FullJoin are now supported in addition to .LeftJoin.

A .&Case method was redesigned a bit. It now returns an interface which can be sent as a parameter to a .Select, .Column, and .OrderBy methods. You can use it like this:

  query := CreateGpSQLBuilder
.Select(
CreateGpSQLBuilder
.&Case
.When([COL_2, '< 0']).&Then('0')
.When([COL_2, '> 100']).&Then('2')
.&Else('1')
.&End)
.From(DB_TEST);

and

  query := CreateGpSQLBuilder;
query
.Select.All
.From(DB_TEST)
.OrderBy(
query.&Case
.When([COL_2, '< 0']).&Then(COL_3)
.&Else(COL_4)
.&End
);

New version also supports the .Distinct select flag.

I’ve created a unit test suite (actually I did that before the redesign so that I could refactor my code in piece) which now includes 51 tests, all passing.

Wednesday, April 29, 2015

Portable OmniThreadLibrary

If you care about running OmniThreadLibrary on mobile devices and on OS X, please join the OmniThreadLibrary-For-Mobile-DevelopmentProject page on Google+ where Sean has started to document his progress on doing exactly that – breaking the chains of Windows and bringing OmniThreadLibrary to all supported platforms!

Go, Sean!

Saturday, April 25, 2015

Value Never Used – Or Is It?

Sometimes, dcc32 is just plain stupid …

I have this code in the OmniThreadLibrary:

function TOmniThreadPool.Cancel(taskID: int64): boolean;
var
res: TOmniWaitableValue;
begin
{$IF CompilerVersion >= 22}
Result := false; // not really used
{$IFEND}
res := TOmniWaitableValue.Create;
try
otpWorkerTask.Invoke(@TOTPWorker.Cancel, [taskID, res]);
res.WaitFor(INFINITE);
Result := res.Value;
finally FreeAndNil(res); end;
end
;

The IFDEF part is there because otherwise compiler complains about result being potentially undefined.


[DCC Warning] OtlThreadPool.pas(1315): W1035 Return value of function 'TOmniThreadPool.Cancel' might be undefined


I’ve first observed this with the XE and it was fixed after the XE2 (can’t repeat this with XE8, but I didn’t check every compiler inbetween.)


Friday, April 17, 2015

New Home for OmniThreadLibrary

OmniThreadLibrary has been moved from Google Code to GitHub.

I still have to move existing issues as they were not moved automatically.

Thursday, April 16, 2015

New Home for My Units

My collection of open-sourced units has been moved from Google Code to GitHub.

Wednesday, April 08, 2015

XE8 is out …

… and OmniThreadLibrary works fine with it. (That’s it. Just wanted to let you know.)

Friday, April 03, 2015

Runtime SQL Query Builder

I don’t want to use long SQL strings in the code.

Really.

Firstly, it is a pain to write long multiline strings in Object Pascal. (Embarcadero, are you listening? Can we please get multiline strings in Delphi? Please?)

Secondly, I’m very OCD when it comes to compiler watching my every step. I absolutely hate runtime errors and I want every problem to be detected during the compilation. That includes typos in database field names and changes attributed to the entropy (i.e. changes in the database structure).

On a tangent, that’s why we are creating and managing tables and databases in the code. We have all fields defined as constants, all SQL statements created in runtime and everything stored under version control.Upgrading a database to a version required by the program is therefore a very simple operation. (Downgrading is still a problem. Downgrading is hard.)

Thirdly, concatenating query strings together when you are dynamically building a query string based on the conditions in the program is a mess.

That’s why long years ago I created a simple runtime query builder. It was dormant (in the “good enough for me” state) for a long time but recently I required more functionality from it and I extended it further. It is now in a state which may be useful for somebody else but me so I’m releasing it as an open source under a BSD license.

For impatient: Get GpSQLBuilder on GitHub.