OmniThreadLibrary internals - OtlContainers
![]() The time has come to bring the OtlContainers subthread to the end. In previous parts (1, 2, 3, 4) I obsessively described underlying lock-free structures but hadn't said a word about the higher-level classes that are actually used for message transfer inside the OmniThreadLibrary. Let's take a quick look at all OtlContainers classes. TOmniBaseContainer is an abstract parent of the whole container hierarchy. It's basic function is to provide memory allocation and lock-free algorithms for all descendants. Most of the code I already described in previous installments and the rest is trivial. TOmniBaseContainer = class abstract(TInterfacedObject) Then there is the base stack implementation, which only adds Push and Pop to the base container. We've seen those two already. TOmniBaseStack = class(TOmniBaseContainer) The queue is only slightly more complex. It provides Enqueue and Dequeue, which we already know, and overrides Empty and IsEmpty to take the dequeued messages chain into account. TOmniBaseQueue = class(TOmniBaseContainer) Now we come to the interesting part. Basic stack and queue operations are also described with interfaces IOmniStack and IOmniQueue - just in case you'd like to use them in your programs. OTL uses class representation of the queue directly. IOmniStack = interface ['{F4C57327-18A0-44D6-B95D-2D51A0EF32B4}'] Actual implementation of the higher-level structures is exposed with classes TOmniStack and TOmniQueue. Besides implementing IOmniStack and IOmniQueue (respectively), they both implement IOmniNotifySupport and IOmniMonitorSupport. TOmniStack = class(TOmniBaseStack, IOmniStack, IOmniNotifySupport, IOmniMonitorSupport) IOmniMonitorSupport is describing a container with monitoring support (notifies attached monitor whenever new message is sent). IOmniNotifySupport is describing a container that notifies interested parties (by setting an event) that new message has been sent. Both are used in the OTL - notification support is needed to implement IOmniCommunicationEndpoint.NewMessageEvent in the OtlComm and monitoring support is needed to support IOmniTaskControl.MonitorWith in the OtlTaskControl unit. IOmniMonitorSupport = interface ['{6D5F1191-9E4A-4DD5-99D8-694C95B0DE90}'] The following excerpt from the TOmniQueue code demonstrates the implementation of those interfaces. TOmniStack is implemented in a similar manner. The constructor takes the options parameter when you can enable monitoring and/or notification support. type Enqueue calls original enqueueing code and then signals notification (if enabled) and notifies the monitor (if enabled). Dequeue is similar, except that it only triggers notification so that the reader rechecks the input queue. Stop. Enough words have been said about the OtlContainer. Next time, I'll discuss something completely different. Labels: Delphi, multithreading, OmniThreadLibrary, open source, programming, source code, work in progress |
2 Comments:
Thank you Gabr for writing on this topic. This looks to be a very useful tool for fine grained message passing between threads.
I have a query regarding the use of ASM in the code. Does this have a significant speed advantage over using native Delphi code?
If this was used in .NET applications the ASM would need to be replaced with Object Pascal code... [Now, I haven't actually downloaded the code yet, so I may have the wrong end of the stick ;-) ]
Cheers,
Raymond.
In this case, there is a speed difference. Plus the code is simpler (at least for people that understand the Intel asm).
I don't think there is a simple way of porting this code to .NET - short of using PInvoke, of course. (But then, I know almost nothing about the .NET programming.)
Post a Comment
Links to this post:
Create a Link
<< Home