final boolean addReference ( final JNIReference ref ) { /* Implementation note: This method is extremely * hot, and so I've unrolled the lock and unlock * methods from above. Take care if you change * them to change the unrolled versions here. * */ // First try to grab the non blocking lock boolean gotNonblockingLock = false ; gotNonblockingLock = mSpinLock . compareAndSet ( false , true ) ; if ( gotNonblockingLock ) { final int slot = mNextAvailableReferenceSlot ++ ; if ( slot < mMaxValidReference ) { mValidReferences [ slot ] = ref ; // unlock the non-blocking lock, and progress to a full lock. final boolean result = mSpinLock . compareAndSet ( true , false ) ; assert result : "Should never be unlocked here" ; return true ; } // try the big lock without blocking if ( ! mLock . tryLock ( ) ) { // we couldn't get the big lock, so release the spin lock // and try getting the bit lock while blocking gotNonblockingLock = false ; mSpinLock . compareAndSet ( true , false ) ; } } // The above code needs to make sure that we never // have gotNonblockingLock set, unless we have both // the spin lock and the big lock. if ( ! gotNonblockingLock ) { mLock . lock ( ) ; while ( ! mSpinLock . compareAndSet ( false , true ) ) ; // grab the spin lock } try { int slot = mNextAvailableReferenceSlot ++ ; if ( slot >= mMaxValidReference ) { sweepAndCollect ( ) ; slot = mNextAvailableReferenceSlot ++ ; } mValidReferences [ slot ] = ref ; } finally { final boolean result = mSpinLock . compareAndSet ( true , false ) ; assert result : "Should never ever be unlocked here" ; mLock . unlock ( ) ; } return true ; }
Add a reference to the set of references we ll collect .