Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Review of public Ref(external count, Thread.Yield, error return) #8

Open
dzmitry-lahoda opened this issue Jul 26, 2018 · 4 comments
Open

Comments

@dzmitry-lahoda
Copy link

dzmitry-lahoda commented Jul 26, 2018

Did some view onto, hope you find some useful.

throw new InvalidOperationException(_errorRetryCountExceeded);

Also it is public, it may deliver some caveats to possible users:

  1. Spin probably should yield for better CPU https://referencesource.microsoft.com/#mscorlib/system/threading/thread.cs,dd960cd58d3d20c1,references
  2. Default counter should in public API, not private hidden surprise in production.
  3. Consider return error(value tuple, option, or by ref return) result from Swap instead of throwing exception. Retry exceed could be normal condition on low level.
  4. Reproduce in test retry count reached via one fast and one slow getNewValue. Until getNewValue is hanged and if Thread.Yield used I guess retry could be made infinite by default.
  5. Consider make it more private-internal if possible.
  6. T is class. Consider adding know primiteves swap like Interlocked for long int etc.
    public static T Swap<T>(ref T value, Func<T, T> getNewValue) where T : class
  7. /// <summary>Compares current Referred value with <paramref name="currentValue"/> and if equal replaces current with <paramref name="newValue"/></summary>
    consider document reference equals instead of equals (to be crystal clear).
  8. CompareAndSwap or other like name may be better name
    public bool TrySwapIfStillCurrent(T currentValue, T newValue) =>
  9. Interlocked.CompareExchange(ref _value, newValue, currentValue) == currentValue;
    does compares by reference, but returns by bool depending on possible == https://docs.microsoft.com/en-us/dotnet/csharp/language-reference/operators/equality-comparison-operator. Same seems here
    if (Interlocked.CompareExchange(ref value, newValue, oldValue) == oldValue)
  10. Consider document usage scenarios, i.e. it seems not for long running operations, not ordered operations (while does not orders getNewValue delegates).
  11. Inspire https://www.cl.cam.ac.uk/techreports/UCAM-CL-TR-579.pdf :) and think of laptop Intel with 12 cores or Ryzen with 32 cores https://en.wikipedia.org/wiki/Ryzen (these are commodities now)
@dzmitry-lahoda
Copy link
Author

Found similar code in .NET source

        public static X TryEnterWriteLock(ref X value, TimeSpan timeout)
        {
         // https://github.com/dotnet/corefx/blob/3b24c535852d19274362ad3dbc75e932b7d41766/src/Common/src/CoreLib/System/Threading/ReaderWriterLockSlim.cs#L233 

   var tracker = new TimeoutTracker(timeout);

             if (tracker.IsExpired)
                {
                    throw new TimeoutException("Some other lock is hold for too long time");
                }

@dzmitry-lahoda
Copy link
Author

I guess throw via Thrower may save some performance of spin. Could check that. Example is jtmueller/Collections.Pooled#8

@dzmitry-lahoda
Copy link
Author

These people are not afraid of timeout https://github.com/scalaz/scalaz-zio/blob/master/core/shared/src/main/scala/scalaz/zio/Ref.scala#L42. And use function. May be this Ref should to.

@dzmitry-lahoda
Copy link
Author

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant