tag:blogger.com,1999:blog-29331675.post3801175127994362659..comments2024-03-05T17:37:00.995+01:00Comments on The Delphi Geek: Implementing lock-free stackgabr42http://www.blogger.com/profile/06903558857617342477noreply@blogger.comBlogger9125tag:blogger.com,1999:blog-29331675.post-38944564770414040372019-07-09T11:46:56.420+02:002019-07-09T11:46:56.420+02:00Indeed, assembler could be removed from the implem...Indeed, assembler could be removed from the implementation without a problem.gabr42https://www.blogger.com/profile/06903558857617342477noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-45223500441487351932019-07-08T18:11:24.176+02:002019-07-08T18:11:24.176+02:00I enjoyed your writing, and have purchased 3 of yo...I enjoyed your writing, and have purchased 3 of your books.<br /><br />I first read this post 10~12 years ago. Now I read it again, and I wonder if you could directly use the Win32 API InterlockedCompareExchange, rather than those ASM code?<br />https://docs.microsoft.com/en-us/windows/win32/api/winnt/nf-winnt-interlockedcompareexchangeahwuxhttps://www.blogger.com/profile/01761244856677079567noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-66984624947580877862008-07-30T15:13:00.000+02:002008-07-30T15:13:00.000+02:00Depends on how you depend lock-free, of course. Th...Depends on how you depend lock-free, of course. This code is lock-free in the sense that it doesn't acquire a lock (and that is the prevailing definition as far as I can tell).<BR/><BR/>If you manage to write/find a less-locked stack on the Intel processor, I'll happily incorporate it into OTL. As far as I know, the current solution is the best you can do.gabr42https://www.blogger.com/profile/06903558857617342477noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-53503404464874880572008-07-30T14:56:00.000+02:002008-07-30T14:56:00.000+02:00Of course, since you're using the "lock" assembler...Of course, since you're using the "lock" assembler instruction, you can't really claim to be "lock-free". If there are multiple processors, you're taking all the overhead of synchronizing them and their caches every time you go through this code.<BR/><BR/>A true low-lock stack would avoid the "lock" instruction, and its overhead, on read. You almost certainly still need it on write, though. (I already posted a comment with a link to an MS article on low-lock programming -- won't spam you by posting the link again here.)Unknownhttps://www.blogger.com/profile/04747855792846273047noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-5795273992870156462008-07-17T18:58:00.000+02:002008-07-17T18:58:00.000+02:00@mp:a) No, Variants are reference counted, just as...@mp:<BR/><BR/>a) No, Variants are reference counted, just as interfaces. Variant message goes automatically 'out of scope' and string is destroyed when that happens. I've extended 8_RegisterComm test with a button that sends a string and checked with FastMM that everything is indeed released. Result: no leaks.<BR/><BR/>b) You're right, Initialize doesn't work when numElements = 1. Hardly a realistic case, but still worth fixing. Thanks for the catch!<BR/><BR/>Both updates are already in the repository.gabr42https://www.blogger.com/profile/06903558857617342477noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-65389780377090916522008-07-17T13:27:00.000+02:002008-07-17T13:27:00.000+02:00Maybe a "crash" innextElement := nil; //...Maybe a "crash" in<BR/><BR/>nextElement := nil; // to remove compiler warning in nextElement.Next := nil assignment below currElement := obcRecycleChain; for iElement := 0 to obcNumElements - 2 do begin nextElement := POmniLinkedData(cardinal(currElement) + bufferElementSize); currElement.Next := nextElement; currElement := nextElement; end; nextElement.Next := nil; // terminate the chain obcPublicChain := nil;<BR/><BR/>if obcNumElements = 1 <BR/>nextElement.Next := nil; -> nil.Next := nil;Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-24057554795436748572008-07-16T20:43:00.000+02:002008-07-16T20:43:00.000+02:00Sadly, the PopLink as implemented in this post, do...Sadly, the PopLink as implemented in this post, doesn't work :(<BR/><BR/>It fails very rarely and only under very stressful conditions, but it fails nevertheless :(<BR/><BR/>Our kung-fu master GJ has created better version, which passed all current tests. I'll post it here as soon as I manage to understand it.gabr42https://www.blogger.com/profile/06903558857617342477noreply@blogger.comtag:blogger.com,1999:blog-29331675.post-8401099230627741562008-07-16T19:50:00.000+02:002008-07-16T19:50:00.000+02:00I'd really like to thank you for writing on this t...I'd really like to thank you for writing on this topic, I'm learning a bunch and the timing couldn't be better since I'm now focused on learning about lock free structures.<BR/><BR/>Thanks!!!Anonymousnoreply@blogger.comtag:blogger.com,1999:blog-29331675.post-91544713429426601592008-07-16T14:21:00.000+02:002008-07-16T14:21:00.000+02:00perhaps problem with no desallocate variant (if is...perhaps problem with no desallocate variant (if is a string for exemple) in TOmniMessage = record<BR/> MsgID : word;<BR/> MsgData: TOmniValue;<BR/> end; { TOmniMessage }<BR/>The destructor in TOmniBaseContainer do just FreeMem(obcBuffer) not "desallocate" variant in record.Anonymousnoreply@blogger.com