private final Object slotExchange ( Object item , boolean timed , long ns ) { Node p = participant . get ( ) ; Thread t = Thread . currentThread ( ) ; if ( t . isInterrupted ( ) ) // preserve interrupt status so caller can recheck return null ; for ( Node q ; ; ) { if ( ( q = slot ) != null ) { if ( U . compareAndSwapObject ( this , SLOT , q , null ) ) { Object v = q . item ; q . match = item ; Thread w = q . parked ; if ( w != null ) U . unpark ( w ) ; return v ; } // create arena on contention, but continue until slot null if ( NCPU > 1 && bound == 0 && U . compareAndSwapInt ( this , BOUND , 0 , SEQ ) ) arena = new Node [ ( FULL + 2 ) << ASHIFT ] ; } else if ( arena != null ) return null ; // caller must reroute to arenaExchange else { p . item = item ; if ( U . compareAndSwapObject ( this , SLOT , null , p ) ) break ; p . item = null ; } } // await release int h = p . hash ; long end = timed ? System . nanoTime ( ) + ns : 0L ; int spins = ( NCPU > 1 ) ? SPINS : 1 ; Object v ; while ( ( v = p . match ) == null ) { if ( spins > 0 ) { h ^= h << 1 ; h ^= h >>> 3 ; h ^= h << 10 ; if ( h == 0 ) h = SPINS | ( int ) t . getId ( ) ; else if ( h < 0 && ( -- spins & ( ( SPINS >>> 1 ) - 1 ) ) == 0 ) Thread . yield ( ) ; } else if ( slot != p ) spins = SPINS ; else if ( ! t . isInterrupted ( ) && arena == null && ( ! timed || ( ns = end - System . nanoTime ( ) ) > 0L ) ) { U . putObject ( t , BLOCKER , this ) ; p . parked = t ; if ( slot == p ) U . park ( false , ns ) ; p . parked = null ; U . putObject ( t , BLOCKER , null ) ; } else if ( U . compareAndSwapObject ( this , SLOT , p , null ) ) { v = timed && ns <= 0L && ! t . isInterrupted ( ) ? TIMED_OUT : null ; break ; } } U . putOrderedObject ( p , MATCH , null ) ; p . item = null ; p . hash = h ; return v ; }
Exchange function used until arenas enabled . See above for explanation .