Pārlūkot izejas kodu

use thread local storage for the random number generator

Julius Pfrommer 9 gadi atpakaļ
vecāks
revīzija
444926c9ef
4 mainītis faili ar 44 papildinājumiem un 7 dzēšanām
  1. 11 1
      include/ua_types.h
  2. 3 0
      src/server/ua_server_worker.c
  3. 14 6
      src/ua_types.c
  4. 16 0
      src/ua_util.h

+ 11 - 1
include/ua_types.h

@@ -29,7 +29,6 @@ extern "C" {
 #include "ua_config.h"
 #include "ua_statuscodes.h"
 
-
 /** A two-state logical value (true or false). */
 typedef bool UA_Boolean;
 #define UA_TRUE true
@@ -692,6 +691,17 @@ typedef enum {
     UA_ATTRIBUTEID_USEREXECUTABLE          = 22
 } UA_AttributeId;
 
+/***************************/
+/* Random Number Generator */
+/***************************/
+
+/**
+ * If UA_MULTITHREADING is enabled, then the seed is stored in thread local storage. The seed is
+ * initialized for every thread in the server/client.
+ */
+UA_EXPORT void UA_random_seed(UA_UInt64 seed);
+UA_EXPORT UA_UInt32 UA_random(void);
+
 #ifdef __cplusplus
 } // extern "C"
 #endif

+ 3 - 0
src/server/ua_server_worker.c

@@ -120,6 +120,9 @@ struct workerStartData {
 
 /** Waits until jobs arrive in the dispatch queue and processes them. */
 static void * workerLoop(struct workerStartData *startInfo) {
+    /* Initialized the (thread local) random seed */
+    UA_random_seed((uintptr_t)startInfo);
+
    	rcu_register_thread();
     UA_UInt32 *c = UA_malloc(sizeof(UA_UInt32));
     uatomic_set(c, 0);

+ 14 - 6
src/ua_types.c

@@ -3,12 +3,8 @@
 #include "ua_statuscodes.h"
 #include "ua_types_generated.h"
 
-/*************************/
-/* External Dependencies */
-/*************************/
 #include "pcg_basic.h"
 
-
 /*****************/
 /* Helper Macros */
 /*****************/
@@ -34,6 +30,20 @@
         UA_free(p);                  \
     }
 
+/***************************/
+/* Random Number Generator */
+/***************************/
+
+static UA_THREAD_LOCAL pcg32_random_t rng = PCG32_INITIALIZER;
+
+UA_EXPORT void UA_random_seed(UA_UInt64 seed) {
+    pcg32_srandom_r(&rng, seed, UA_DateTime_now());
+}
+
+UA_EXPORT UA_UInt32 UA_random(void) {
+    return (UA_UInt32)pcg32_random_r(&rng);
+}
+
 /*****************/
 /* Builtin Types */
 /*****************/
@@ -232,8 +242,6 @@ UA_Boolean UA_Guid_equal(const UA_Guid *g1, const UA_Guid *g2) {
 }
 
 UA_Guid UA_Guid_random(UA_UInt32 *seed) {
-    pcg32_random_t rng;
-    pcg32_srandom_r(&rng, *seed, UA_DateTime_now());
     UA_Guid result;
     result.data1 = (UA_UInt32)pcg32_random_r(&rng);
     UA_UInt32 r = (UA_UInt32)pcg32_random_r(&rng);

+ 16 - 0
src/ua_util.h

@@ -74,6 +74,22 @@
 # endif
 #endif
 
+/************************/
+/* Thread Local Storage */
+/************************/
+
+#ifdef UA_MULTITHREADING
+# ifdef __GNUC__
+#  define UA_THREAD_LOCAL __thread
+# elif defined(_MSC_VER)
+#  define UA_THREAD_LOCAL __declspec(thread)
+# else
+#  error No thread local storage keyword defined for this compiler
+# endif
+#else
+# define UA_THREAD_LOCAL
+#endif
+
 /********************/
 /* System Libraries */
 /********************/