/// <summary> /// Indicate exit from a critical section containing a write operation. /// </summary> /// <param name="criticalValueAtEnter">the opaque value (token) returned from the matching <see cref="WriterCriticalSectionEnter()"/> call.</param> /// <remarks> /// This call is wait-free on architectures that support wait free atomic increment operations, and is lock-free on architectures that do not. /// <para> /// <see cref="WriterCriticalSectionExit(long)"/> must be matched with a preceding <see cref="WriterCriticalSectionEnter"/> call, and must be provided with the matching <see cref="WriterCriticalSectionEnter"/> call's return value, in order for CriticalSectionPhaser synchronization to function properly. /// </para> /// </remarks> public void WriterCriticalSectionExit(long criticalValueAtEnter) { if (criticalValueAtEnter < 0) { WriterReaderPhaser.GetAndIncrement(ref _oddEndEpoch); } else { WriterReaderPhaser.GetAndIncrement(ref _evenEndEpoch); } }
/// <summary> /// Indicate entry to a critical section containing a write operation. /// </summary> /// <returns> /// an (opaque) value associated with the critical section entry, /// which MUST be provided to the matching <see cref="WriterCriticalSectionExit"/> call. /// </returns> /// <remarks> /// <para> /// This call is wait-free on architectures that support wait free atomic increment operations, /// and is lock-free on architectures that do not. /// </para> /// <para> /// <see cref="WriterCriticalSectionEnter"/> must be matched with a subsequent <see cref="WriterCriticalSectionExit"/> /// in order for CriticalSectionPhaser synchronization to function properly. /// </para> /// <para> /// The <seealso cref="IDisposable"/> pattern could have been used but was not due to the high allocation count it would have incurred. /// </para> /// </remarks> public long WriterCriticalSectionEnter() { return(WriterReaderPhaser.GetAndIncrement(ref _startEpoch)); }