mirror of
https://gitlab.com/freepascal.org/fpc/source.git
synced 2025-04-09 13:08:49 +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
|
||||
the end of the program }
|
||||
ExternalThreads: TThreadList;
|
||||
|
||||
{ this must be a global var, otherwise unwanted optimizations might happen in
|
||||
TThread.SpinWait() }
|
||||
SpinWaitDummy: LongWord;
|
||||
|
||||
threadvar
|
||||
{ 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
|
||||
@ -572,15 +577,23 @@ end;
|
||||
|
||||
|
||||
class procedure TThread.SpinWait(aIterations: LongWord);
|
||||
var
|
||||
i: LongWord;
|
||||
begin
|
||||
{ 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
|
||||
could interfere with this (e.g. loop unrolling) }
|
||||
{$PUSH}
|
||||
{$OPTIMIZATION OFF}
|
||||
while aIterations > 0 do
|
||||
Dec(aIterations);
|
||||
{$POP}
|
||||
{ Do *NOT* do $PUSH, $OPTIMIZATIONS OFF, <code>, $POP because optimization is
|
||||
not a local switch, which means $PUSH/POP doesn't affect it, so that turns
|
||||
off *ALL* optimizations for code below this point. Thanks to this we shipped
|
||||
large parts of the classes unit with optimizations off between 2012-12-27
|
||||
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;
|
||||
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user