mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-08-16 02:49:21 +02:00
rewrite SpinLock to still work without the need to accidentally disable optimizations for a large part of the classes unit
git-svn-id: trunk@27864 -
This commit is contained in:
parent
d3bb0d4a17
commit
e89669bedc
@ -83,6 +83,11 @@ var
|
|||||||
{ this list holds all instances of external threads that need to be freed at
|
{ this list holds all instances of external threads that need to be freed at
|
||||||
the end of the program }
|
the end of the program }
|
||||||
ExternalThreads: TThreadList;
|
ExternalThreads: TThreadList;
|
||||||
|
|
||||||
|
{ this must be a global var, otherwise unwanted optimizations might happen in
|
||||||
|
TThread.SpinWait() }
|
||||||
|
SpinWaitDummy: LongWord;
|
||||||
|
|
||||||
threadvar
|
threadvar
|
||||||
{ the instance of the current thread; in case of an external thread this is
|
{ the instance of the current thread; in case of an external thread this is
|
||||||
Nil until TThread.GetCurrentThread was called once (the RTLs need to ensure
|
Nil until TThread.GetCurrentThread was called once (the RTLs need to ensure
|
||||||
@ -572,15 +577,23 @@ end;
|
|||||||
|
|
||||||
|
|
||||||
class procedure TThread.SpinWait(aIterations: LongWord);
|
class procedure TThread.SpinWait(aIterations: LongWord);
|
||||||
|
var
|
||||||
|
i: LongWord;
|
||||||
begin
|
begin
|
||||||
{ yes, it's just a simple busy wait to burn some cpu cycles... and as the job
|
{ yes, it's just a simple busy wait to burn some cpu cycles... and as the job
|
||||||
of this loop is to burn CPU cycles we switch off any optimizations that
|
of this loop is to burn CPU cycles we switch off any optimizations that
|
||||||
could interfere with this (e.g. loop unrolling) }
|
could interfere with this (e.g. loop unrolling) }
|
||||||
{$PUSH}
|
{ Do *NOT* do $PUSH, $OPTIMIZATIONS OFF, <code>, $POP because optimization is
|
||||||
{$OPTIMIZATION OFF}
|
not a local switch, which means $PUSH/POP doesn't affect it, so that turns
|
||||||
while aIterations > 0 do
|
off *ALL* optimizations for code below this point. Thanks to this we shipped
|
||||||
Dec(aIterations);
|
large parts of the classes unit with optimizations off between 2012-12-27
|
||||||
{$POP}
|
and 2014-06-06.
|
||||||
|
Instead, use a global var for the spinlock, because that is always handled
|
||||||
|
as volatile, so the access won't be optimized away by the compiler. (KB) }
|
||||||
|
for i:=1 to aIterations do
|
||||||
|
begin
|
||||||
|
Inc(SpinWaitDummy); // SpinWaitDummy *MUST* be global
|
||||||
|
end;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user