ECP-VeloC / AXL

Asynchronous Transfer Library
MIT License
2 stars 8 forks source link

Improving logic for creating unique ids for BB APIs. #142

Closed hariharan-devarajan closed 1 year ago

hariharan-devarajan commented 1 year ago

The main issue is that with current logic, we have same thread ids across threads. So we now include:

tonyhutter commented 1 year ago

You shouldn't need the TID since the counter is going to be unique between threads (due to the lock). I'm thinking now:

22 bit PID (max on Linux) + 18 bit counter + 24 bit timestamp (33 years, to mitigate PID rollover)

You'll also need to save the value of counter in the locked section.

You could try something like this (completely untested!):

diff --git a/src/axl_async_bbapi.c b/src/axl_async_bbapi.c
index 1203dcd..f18d4aa 100644
--- a/src/axl_async_bbapi.c
+++ b/src/axl_async_bbapi.c
@@ -38,9 +38,9 @@
 #define XFS_SUPER_MAGIC 0x58465342  /* "XFSB" in ASCII */
 #endif

-/* Global varibales */
+/* Global variables */

-uint16_t counter=0;
+uint64_t counter = 0;
 pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER; 

 /* We're either running on a compute node with access to the BBAPI, or
@@ -253,28 +253,24 @@ int axl_async_finalize_bbapi(void)
  * Returns 0 on success, 1 otherwise. */
 static BBTAG axl_get_unique_tag(void)
 {
+  uint64_t counter_18;

   /* This is somewhat of a hack.
    *
    * We need a 64-bit tag that will never be repeated on this node.  To do
    * that we construct an ID of:
    *
-   * 17-bit (pid) + 15-bit (tid)
-   * 16-bit counter + 16-bit (timestamp)
-   *
+   * 22 bit PID + 18 bit counter + 24 bit timestamp (33 years, to mitigate PID rollover)
    */
   /* Lock counter for shared memory access */
   pthread_mutex_lock(&lock);
-  ++counter; /* To capture call count and inter-thread calls */
+  counter_18 = counter & ((1ULL << 18) - 1); /* To capture call count and inter-thread calls */
+  counter++;
   pthread_mutex_unlock(&lock);
-  const int max_17_bit = USHRT_MAX * 2;
-  const int max_16_bit = USHRT_MAX * 2;
-  const int max_15_bit = USHRT_MAX * 2;
-  uint64_t pid_17 = getpid() % max_17_bit; /* PID is 17 bit*/
-  uint64_t tid_15 = syscall(__NR_gettid) % max_15_bit; /* TID are just hashes so 15 bit should be ok.*/
-  uint64_t timestamp = time(NULL) % max_16_bit; /* To capture restart of apps */
-
-  uint64_t tag = (pid_17 << 47) | (tid_15 << 32) | (timestamp << 16) | counter;
+  uint64_t pid_22 = getpid() &  ((1ULL << 22) - 1);
+  uint64_t timestamp_24 = time(NULL) & ((1ULL << 24) - 1);
+
+  uint64_t tag = (pid_22 << 42) | (counter_18 << 18) | timestamp_24;
   return tag;
 }