Jump to content


  • Content Count

  • Joined

  • Last visited

Community Reputation

1 Neutral

Recent Profile Visitors

The recent visitors block is disabled and is not being shown to other users.

  1. I expect that more than two threads will enter "if", but only one will reset the FWriteIndex because of the "MAX_SIZE + aOverFlow" passed to InterlockedCompareExchange. The writer I believe works ok :). About the overflow, it's one of the checks I plan to add, even though I believe the single reader will always be fast enough to consume the items. Thank you for your time!
  2. I know for sure that it doesn't work for more than one readers, my implementation is specific for single reader and I plan to add checks to make sure only one thread reads. If you see GetItem(), I intentionally used Inc() and not Interlocked version knowing that only one reader will exist. Having that in mind, Primož Gabrijelčič, do you think it's a good start? Also thank you dummzeuch for your reply, will check your implementation.
  3. Hi all, For a system I'm currently designing and developing I have the need for a queue that N threads are going to add items and a single thread is going to consume them I have created a class and tested it, it works well in my opinion and I thought to share it here for your opinion as well. Maybe I missed something and it's not actually thread safe. The basic idea is a "ring" buffer and two indexes for read and write access. Also I took as granted that reading an integer is an atomic operation. Please keep in mind the code is draft and definitely needs polishing and more checks. And here it is: unit uMWSRList; interface uses Windows, Classes, SyncObjs, SysUtils; const MAX_SIZE = 32; type TMWSRList = class(TObject) private FWriteIndex : Integer; FReadIndex : Integer; FAvailableCount : Integer; FItems : Array [0..MAX_SIZE-1] of Integer; FOnNewItemAdd : TNotifyEvent; public constructor Create; function AddItem(pItem : Integer):Integer; function GetItem():Integer; function ItemsAvailable():Boolean; property OnNewItemAdd : TNotifyEvent read FOnNewItemAdd write FOnNewItemAdd; end; implementation { TMWSRList } constructor TMWSRList.Create; begin FWriteIndex := -1; FReadIndex := -1; end; function TMWSRList.AddItem(pItem : Integer):Integer; var aOverFlow : Integer; begin Result := InterlockedIncrement(FWriteIndex); if Result >= MAX_SIZE then begin aOverFlow := Result - MAX_SIZE; { Reset FWriteIndex when it reaches MAX_SIZE } InterlockedCompareExchange(FWriteIndex, -1, MAX_SIZE + aOverFlow); Result := InterlockedIncrement(FWriteIndex); end; FItems[Result] := pItem; InterlockedIncrement(FAvailableCount); if Assigned(FOnNewItemAdd) then FOnNewItemAdd(self); end; function TMWSRList.GetItem():Integer; begin if FAvailableCount > 0 then begin Inc(FReadIndex); if FReadIndex = MAX_SIZE then FReadIndex := 0; Result := FItems[FReadIndex]; InterlockedDecrement(FAvailableCount); end else Result := -1; end; function TMWSRList.ItemsAvailable():Boolean; begin Result := FAvailableCount > 0; end; end. Regards.