Exemplo n.º 1
0
        /// <summary>
        /// Construct with the specified minimum concurrency level.
        /// </summary>
        /// <remarks>
        /// minConcurrencyLevel must be at least one, an exception is thrown if it is less than 1 (i.e. zero or negative).
        /// The actual concurrency level is required to be a power of two, thus the actual level is chosen to be the
        /// nearest power of two that is greater than or equal to minConcurrencyLevel/
        /// </remarks>
        public DefaultRandomSeedSource(int minConcurrencyLevel)
        {
            if (minConcurrencyLevel < 1)
            {
                throw new ArgumentException("Must be at least 1.", nameof(minConcurrencyLevel));
            }

            // The actual concurrency level is required to be a power of two, thus the actual level is chosen
            // to be the nearest power of two that is greater than or equal to minConcurrencyLevel.
            int concurrencyLevel = MathUtils.CeilingToPowerOfTwo(minConcurrencyLevel);

            _concurrencyLevel = (uint)concurrencyLevel;

            // Create high quality random bytes to init the seed PRNGs.
            byte[] buf = GetCryptoRandomBytes(concurrencyLevel * 8);

            // Init the seed PRNGs and associated sync lock objects.
            // Note. In principle we could just use each RNG object as the sync lock for itself, but that is considered bad practice.
            _seedRngArr = new Xoshiro256StarStarRandom[concurrencyLevel];
            _lockArr    = new object[concurrencyLevel];

            for (int i = 0; i < concurrencyLevel; i++)
            {
                // Init rng.
                ulong seed = BitConverter.ToUInt64(buf, i * 8);
                _seedRngArr[i] = new Xoshiro256StarStarRandom(seed);
                _lockArr[i]    = new object();
            }
        }
Exemplo n.º 2
0
        /// <summary>
        /// Construct with the specified minimum concurrency level.
        /// </summary>
        /// <remarks>
        /// minConcurrencyLevel must be at least one, an exception is thrown if it is less than 1 (i.e. zero or negative).
        /// The actual concurrency level is required to be a power of two, thus the actual level is chosen to be the
        /// nearest power of two that is greater than or equal to minConcurrencyLevel/
        /// </remarks>
        public DefaultRandomSeedSource(int minConcurrencyLevel)
        {
            if (minConcurrencyLevel < 1)
            {
                throw new ArgumentException("Must be at least 1.", nameof(minConcurrencyLevel));
            }

            // The actual concurrency level is required to be a power of two, thus the actual level is chosen
            // to be the nearest power of two that is greater than or equal to minConcurrencyLevel.
            int concurrencyLevel = MathUtils.CeilingToPowerOfTwo(minConcurrencyLevel);

            _concurrencyLevel = (uint)concurrencyLevel;

            // Create high quality random bytes to init the seed PRNGs.
            byte[] buf = GetCryptoRandomBytes(concurrencyLevel * 8);

            // Init the seed PRNGs and associated sync lock objects.
            _seedRngArr = new Xoshiro256StarStarRandom[concurrencyLevel];

            for (int i = 0; i < concurrencyLevel; i++)
            {
                // Init rng.
                ulong seed = BitConverter.ToUInt64(buf, i * 8);
                _seedRngArr[i] = new Xoshiro256StarStarRandom(seed);
            }

            // Create a semaphore that will allow N threads into a critical section, and no more.
            _semaphore = new SemaphoreSlim(minConcurrencyLevel, concurrencyLevel);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Construct with the specified minimum concurrency level.
        /// </summary>
        /// <param name="minConcurrencyLevel">Minimum concurrency level.</param>
        /// <remarks>
        /// minConcurrencyLevel must be at least one, an exception is thrown if it is less than 1 (i.e. zero or negative).
        /// The actual concurrency level is required to be a power of two, thus the actual level is chosen to be the
        /// nearest power of two that is greater than or equal to minConcurrencyLevel.
        /// </remarks>
        public DefaultRandomSeedSource(int minConcurrencyLevel)
        {
            if (minConcurrencyLevel < 1)
            {
                throw new ArgumentException("Must be at least 1.", nameof(minConcurrencyLevel));
            }

            // The actual concurrency level is required to be a power of two, thus the actual level is chosen
            // to be the nearest power of two that is greater than or equal to minConcurrencyLevel.
            int concurrencyLevel = MathUtils.CeilingToPowerOfTwo(minConcurrencyLevel);

            _concurrencyLevel = (uint)concurrencyLevel;

            // Create high quality random bytes to init the seed PRNGs.
            Span <byte> buf = stackalloc byte[concurrencyLevel << 3];

            // Note. Generating crypto random bytes can be very slow, relative to a PRNG; we may even have to wait
            // for the OS to have sufficient entropy for generating the bytes.
            using (RNGCryptoServiceProvider cryptoRng = new RNGCryptoServiceProvider()) {
                cryptoRng.GetBytes(buf);
            }

            // Init the seed PRNGs and associated sync lock objects.
            // Note. In principle we could just use each RNG object as the sync lock for itself, but that is considered bad practice.
            _seedRngArr = new Xoshiro256StarStarRandom[concurrencyLevel];
            _lockArr    = new object[concurrencyLevel];

            for (int i = 0; i < concurrencyLevel; i++)
            {
                // Init rng.
                ulong seed = BitConverter.ToUInt64(buf.Slice(i << 3, 8));
                _seedRngArr[i] = new Xoshiro256StarStarRandom(seed);
                _lockArr[i]    = new object();
            }
        }