IVGCVSW-3691 Add utility function to generate valid UIDs for profiling objects

Change-Id: I59ad320bfd52c881671c5e4710fb70c5d0293aad
Signed-off-by: Matteo Martincigh <matteo.martincigh@arm.com>
diff --git a/src/profiling/ProfilingUtils.cpp b/src/profiling/ProfilingUtils.cpp
index 015a66e..ef67f03 100644
--- a/src/profiling/ProfilingUtils.cpp
+++ b/src/profiling/ProfilingUtils.cpp
@@ -10,6 +10,8 @@
 #include <boost/assert.hpp>
 
 #include <fstream>
+#include <limits>
+#include <mutex>
 
 namespace armnn
 {
@@ -17,6 +19,27 @@
 namespace profiling
 {
 
+uint16_t GetNextUid()
+{
+    // Static mutex for reading and modifying the global UID a single thread at the time
+    static std::mutex mutex;
+    std::unique_lock<std::mutex> lock(mutex);
+
+    // The UID used for profiling objects and events. The first valid UID is 1, as 0 is a reserved value
+    // (it is used to indicate that a record is not associated with any device)
+    static uint16_t uid{ 0 };
+
+    // Check that it is possible to generate the next UID without causing an overflow
+    if (uid == std::numeric_limits<uint16_t>::max())
+    {
+        throw RuntimeException("Generating the next UID for profiling would result in an overflow");
+    }
+
+    // Thread safe increment, the value that is incremented is the value checked for overflow,
+    // as this whole function is mutexed
+    return ++uid;
+}
+
 void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value)
 {
     BOOST_ASSERT(buffer);
@@ -54,7 +77,7 @@
     BOOST_ASSERT(buffer);
 
     uint64_t value = 0;
-    value = static_cast<uint64_t>(buffer[offset]);
+    value  = static_cast<uint64_t>(buffer[offset]);
     value |= static_cast<uint64_t>(buffer[offset + 1]) << 8;
     value |= static_cast<uint64_t>(buffer[offset + 2]) << 16;
     value |= static_cast<uint64_t>(buffer[offset + 3]) << 24;