none
Is this thread-safe ? RRS feed

  • Question

  • The question lies in the title.

    using System;
    using System.Runtime.InteropServices;
    
    namespace GServer
    {
    	public static class Random
    	{
    		[DllImport("Rdrexp.dll")]
    		private static extern uint rdrget32();
    
    		private uint Nextu(uint maxValue)
    		{
    			uint num = maxValue - 1u;
    			uint num2 = 1u;
    			if (maxValue <= 1u)
    			{
    				return 0u;
    			}
    			while ((num & num2) != num)
    			{
    				num2 <<= 1;
    				num2 |= 1u;
    			}
    			uint num3;
    			do
    			{
    				num3 = (rdrget32() & num2);
    			}
    			while (num3 > num);
    			return num3;
    		}
    
    		public int Next()
    		{
    			return (int)(rdrget32() & 2147483647u);
    		}
    
    		public int Next(int maxValue)
    		{
    			if (maxValue < 0)
    			{
    				throw new ArgumentOutOfRangeException("max < 0");
    			}
    			return (int)Nextu((uint)maxValue);
    		}
    
    		public int Next(int minValue, int maxValue)
    		{
    			if (minValue > maxValue)
    			{
    				throw new ArgumentOutOfRangeException("min > max");
    			}
    			uint num = (uint)(maxValue - minValue);
    			if (num <= 1u)
    			{
    				return minValue;
    			}
    			return (int)(Nextu(num) + (uint)minValue);
    		}
    	}
    }

    And here's the DLL code (in C++) :

    #include <immintrin.h>
    
    extern "C" __declspec(dllexport) unsigned int rdrget32() {
    	unsigned int val = 0;
    
    	while (!_rdrand32_step(&val));
    	return val;
    }
    If I understood correctly, _rdrand32_step() is thread-safe. Moreover, everything that's shared here is immutable : all variables are method-local, hence not shared, or did I miss something ?
    • Edited by NovHak Sunday, August 12, 2018 4:52 PM
    Sunday, August 12, 2018 4:51 PM

Answers

  • When every variable you use is local and you're not using any class that can introduce side effect, yes you can declare it thread-safe.
    • Marked as answer by NovHak Monday, August 13, 2018 3:07 AM
    Monday, August 13, 2018 1:12 AM
    Answerer

All replies

  • When every variable you use is local and you're not using any class that can introduce side effect, yes you can declare it thread-safe.
    • Marked as answer by NovHak Monday, August 13, 2018 3:07 AM
    Monday, August 13, 2018 1:12 AM
    Answerer
  • Thanks for replying !

    I was needing some confirmation, since I'm not used to multithreaded programming.

    Just for the record, I'm modding a game that seems to have problems with its random generation, drawing random numbers from different threads with sometimes strange results.

    Considering it uses System.Random which is not thread-safe, I thought it would be a good idea to either modify this class and put a lock() on some critical sections, or rewrite another one using a non-deterministic, stateless RNG, hence no need for shared variables, and redirect references to System.Random to my class instead.

    Monday, August 13, 2018 3:07 AM