Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / fpc-pascal / 2013-10

Getting the state of a TRTLCriticalSection

11 messages · 5 people · –

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Mark Morgan Lloyd

Is there a preferred way of reading back whether something (including the current thread) has already entered a TCriticalSection?

I'm trying to put assertions in code that, partly under non-GUI thread control via Synchronize, adds and deletes pages to a TPageControl. If I do this

property BloodyGreatLock: boolean read GetBGL write SetBGL;
..
         fBGL: TCriticalSection;
..
function GetBGL: boolean;
var     gotLock: boolean;
begin
   try
     gotLock := fBGL.TryEnter
   finally
     if gotLock then
       fBGL.Leave
   end;
   result := not gotLock
end { GetBGL } ;

then this initialisation code and test sequence

initialization
   fBGL := TCriticalSection.Create;
   Assert(BloodyGreatLock = false); (* Check lock read works properly  *)
   Assert(BloodyGreatLock = false);
   BloodyGreatLock := true;
   Assert(BloodyGreatLock = true); <===== FAILURE HERE
   Assert(BloodyGreatLock = true);

fails where indicated since the lock is owned by the current thread so TryEnter has succeeded.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Michael Van Canneyt
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote
Is there a preferred way of reading back whether something (including the current thread) has already entered a TCriticalSection?

To my knowlede this does not exist.

The Microsoft implementation of a critical section has TryEnterCriticalSection, but I do not know how portable or useful that is.

Michael.

Mark Morgan Lloyd
to Michael Van Canneyt
Michael Van Canneyt wrote 9 lines
On Sun, 6 Oct 2013, Mark Morgan Lloyd wrote: > Is there a preferred way of reading back whether something (including > the current thread) has already entered a TCriticalSection? To my knowlede this does not exist. The Microsoft implementation of a critical section has TryEnterCriticalSection, but I do not know how portable or useful that is.

I think that one's generally available, but it looks as though it does the same as TCriticalSection.TryEnter.

In the end I stuck in code to increment/decrement a counter, and looked for it to be explicitly 0 or 1.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Michael Van Canneyt
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 13 lines
Michael Van Canneyt wrote: > On Sun, 6 Oct 2013, Mark Morgan Lloyd wrote: > >> Is there a preferred way of reading back whether something (including the >> current thread) has already entered a TCriticalSection? > > To my knowlede this does not exist. > > The Microsoft implementation of a critical section has > TryEnterCriticalSection, but I do not know how portable or useful that is. I think that one's generally available, but it looks as though it does the same as TCriticalSection.TryEnter.

Yes, but it is different from EnterCriticalSection, which makes it more suitable for testing.

Anyway, glad you found an alternative.

Michael.

Benito van der Zander
to Mark Morgan Lloyd: I think that one's generally available, but it looks as though it does the same as…
In the end I stuck in code to increment/decrement a counter, and looked for it to be explicitly 0 or 1.

Do you need to put a memory barrier around that, or does the critical section take care of that?

Mark Morgan Lloyd wrote 18 lines
Michael Van Canneyt wrote: > On Sun, 6 Oct 2013, Mark Morgan Lloyd wrote: > >> Is there a preferred way of reading back whether something >> (including the current thread) has already entered a TCriticalSection? > > To my knowlede this does not exist. > > The Microsoft implementation of a critical section has > TryEnterCriticalSection, but I do not know how portable or useful > that is. I think that one's generally available, but it looks as though it does the same as TCriticalSection.TryEnter. In the end I stuck in code to increment/decrement a counter, and looked for it to be explicitly 0 or 1.
Mark Morgan Lloyd
to Benito van der Zander
Benito van der Zander wrote 6 lines
> > In the end I stuck in code to increment/decrement a counter, and > looked for it to be explicitly 0 or 1. Do you need to put a memory barrier around that, or does the critical section take care of that?

I used the interlocked increment/decrement, which- as I understand it- should handle membar itself on architectures that can benefit from it.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Jonas Maebe
to Mark Morgan Lloyd
Mark Morgan Lloyd wrote 10 lines
Benito van der Zander wrote: >> >> In the end I stuck in code to increment/decrement a counter, and >> looked for it to be explicitly 0 or 1. > Do you need to put a memory barrier around that, or does the > critical section take care of that? I used the interlocked increment/decrement, which- as I understand it- should handle membar itself on architectures that can benefit from it.

They do not include any memory barrier. The only thing those routines guarantee on all platforms, is that the value is atomically incremented/decremented.

Jonas

Marco van de Voort
to Jonas Maebe

In our previous episode, Jonas Maebe said:

Show quoted text 7 lines
> I used the interlocked increment/decrement, which- as I understand > it- should handle membar itself on architectures that can benefit > from it. They do not include any memory barrier. The only thing those routines guarantee on all platforms, is that the value is atomically incremented/decremented.

(btw that depends on which functions you mean, our own assembler versions probably.

The Windows
functions of the same name are guaranteed to have memory barriers afaik, but do require alignment. (probably to avoid crosssing cache lines) )

http://msdn.microsoft.com/en-us/library/windows/desktop/ms683614%28v=vs.85%29.aspx

Mark Morgan Lloyd
to Jonas Maebe: They do not include any memory barrier. The only thing those routines guarantee on all…
Jonas Maebe wrote 15 lines
On 07 Oct 2013, at 09:14, Mark Morgan Lloyd wrote: > Benito van der Zander wrote: >>> >>> In the end I stuck in code to increment/decrement a counter, and >>> looked for it to be explicitly 0 or 1. >> Do you need to put a memory barrier around that, or does the critical >> section take care of that? > > I used the interlocked increment/decrement, which- as I understand it- > should handle membar itself on architectures that can benefit from it. They do not include any memory barrier. The only thing those routines guarantee on all platforms, is that the value is atomically incremented/decremented.

Thanks Jonas, noted. For completeness, is there a way to force one?

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]
Jonas Maebe
to Marco van de Voort: In our previous episode, Jonas Maebe said: (btw that depends on which functions you mean,…
Marco van de Voort wrote 15 lines
In our previous episode, Jonas Maebe said: >> [interlocked increment/decrement] > They do not include any memory barrier. The only thing those routines > guarantee on all platforms, is that the value is atomically > incremented/decremented. (btw that depends on which functions you mean, our own assembler versions probably. The Windows functions of the same name are guaranteed to have memory barriers afaik, but do require alignment. (probably to avoid crosssing cache lines) )

That's why I wrote "on all platforms". They also always require a native alignment on all platforms, because those are cpu limitations for atomic instructions.

Mark Morgan Lloyd wrote
Thanks Jonas, noted. For completeness, is there a way to force one?

See http://www.freepascal.org/docs-html/rtl/system/ readwritebarrier.html and the pages linked from there.

Jonas

Mark Morgan Lloyd
to Jonas Maebe
Jonas Maebe wrote 27 lines
On 07 Oct 2013, at 11:33, Marco van de Voort wrote: > In our previous episode, Jonas Maebe said: >>> [interlocked increment/decrement] >> They do not include any memory barrier. The only thing those routines >> guarantee on all platforms, is that the value is atomically >> incremented/decremented. > > (btw that depends on which functions you mean, our own assembler versions > probably. > > The Windows > functions of the same name are guaranteed to have memory barriers afaik, > but do require alignment. (probably to avoid crosssing cache lines) > ) That's why I wrote "on all platforms". They also always require a native alignment on all platforms, because those are cpu limitations for atomic instructions. On 07 Oct 2013, at 11:40, Mark Morgan Lloyd wrote: > Thanks Jonas, noted. For completeness, is there a way to force one? See http://www.freepascal.org/docs-html/rtl/system/readwritebarrier.html and the pages linked from there.

Thanks for that, I mistakenly thought that the code generator was inserting implicit membars but I see from my notes relating to bug 23390 that it's an RTL (>2.2.2) detail.

Mark Morgan Lloyd markMLl .AT. telemetry.co .DOT. uk [Opinions above are the author's, not those of his employers or colleagues]