@State

(

Scope

.

Thread

)

public

class

VolatileBarrierBench

{

volatile

int

sink

;

Integer

src

;

private

int

c

;

@Param

(

"0"

)

private

int

backoff

;

/*

The benchmark below is rather fragile:

- we pass the object to non-inlinable method, and at least on Linux x86_64

calling convention the argument gets to %(rsp+0), which is important for this test;

- looping() is non-inlinable to prevent loop unrolling effects;

- consumeCPU allows for tunable backoffs;

- unboxing value before entering the consumeCPU allows to split the *load* from %(rsp),

and the subsequent barrier;

Use with great care, and mostly for producing profiled assemblies.

*/

@Setup

public

void

setup

()

throws

NoSuchFieldException

{

src

=

42

;

}

@Benchmark

public

void

testVolatile

()

{

testWith_Volatile

(

src

);

}

@CompilerControl

(

CompilerControl

.

Mode

.

DONT_INLINE

)

public

void

testWith_Volatile

(

Integer

v1

)

{

c

=

0

;

do

{

int

v

=

v1

;

Blackhole

.

consumeCPU

(

backoff

);

sink

=

v

;

}

while

(

looping

());

}

@CompilerControl

(

CompilerControl

.

Mode

.

DONT_INLINE

)

private

boolean

looping

()

{

return

c

++

<

100

;

}

}