From ab173e9b6978d5befb4884a803773967d52bcfef Mon Sep 17 00:00:00 2001 From: Matteo Martincigh Date: Thu, 5 Sep 2019 12:02:04 +0100 Subject: IVGCVSW-3691 Add utility function to generate valid UIDs for profiling objects Change-Id: I59ad320bfd52c881671c5e4710fb70c5d0293aad Signed-off-by: Matteo Martincigh --- src/profiling/ProfilingUtils.cpp | 25 ++++++++++++++++++++++++- src/profiling/ProfilingUtils.hpp | 2 ++ src/profiling/test/ProfilingTests.cpp | 28 +++++++++++++++++++++++++++- 3 files changed, 53 insertions(+), 2 deletions(-) (limited to 'src') diff --git a/src/profiling/ProfilingUtils.cpp b/src/profiling/ProfilingUtils.cpp index 015a66ed93..ef67f0324c 100644 --- a/src/profiling/ProfilingUtils.cpp +++ b/src/profiling/ProfilingUtils.cpp @@ -10,6 +10,8 @@ #include #include +#include +#include namespace armnn { @@ -17,6 +19,27 @@ namespace armnn 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 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::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 @@ uint64_t ReadUint64(const unsigned char* buffer, unsigned int offset) BOOST_ASSERT(buffer); uint64_t value = 0; - value = static_cast(buffer[offset]); + value = static_cast(buffer[offset]); value |= static_cast(buffer[offset + 1]) << 8; value |= static_cast(buffer[offset + 2]) << 16; value |= static_cast(buffer[offset + 3]) << 24; diff --git a/src/profiling/ProfilingUtils.hpp b/src/profiling/ProfilingUtils.hpp index 410198a2cc..0e94e612d9 100644 --- a/src/profiling/ProfilingUtils.hpp +++ b/src/profiling/ProfilingUtils.hpp @@ -16,6 +16,8 @@ namespace armnn namespace profiling { +uint16_t GetNextUid(); + void WriteUint64(unsigned char* buffer, unsigned int offset, uint64_t value); void WriteUint32(unsigned char* buffer, unsigned int offset, uint32_t value); diff --git a/src/profiling/test/ProfilingTests.cpp b/src/profiling/test/ProfilingTests.cpp index eda45e8640..fe94092c7f 100644 --- a/src/profiling/test/ProfilingTests.cpp +++ b/src/profiling/test/ProfilingTests.cpp @@ -11,7 +11,7 @@ #include "../Packet.hpp" #include "../PacketVersionResolver.hpp" #include "../ProfilingStateMachine.hpp" - +#include "../ProfilingUtils.hpp" #include "../ProfilingService.hpp" #include @@ -502,4 +502,30 @@ BOOST_AUTO_TEST_CASE(CheckProfilingServiceEnabledRuntime) BOOST_CHECK(service.GetCurrentState() == ProfilingState::WaitingForAck); } +void GetNextUidTestImpl(uint16_t& outUid) +{ + outUid = GetNextUid(); +} + +BOOST_AUTO_TEST_CASE(GetNextUidTest) +{ + uint16_t uid0 = 0; + uint16_t uid1 = 0; + uint16_t uid2 = 0; + + std::thread thread1(GetNextUidTestImpl, std::ref(uid0)); + std::thread thread2(GetNextUidTestImpl, std::ref(uid1)); + std::thread thread3(GetNextUidTestImpl, std::ref(uid2)); + thread1.join(); + thread2.join(); + thread3.join(); + + BOOST_TEST(uid0 > 0); + BOOST_TEST(uid1 > 0); + BOOST_TEST(uid2 > 0); + BOOST_TEST(uid0 != uid1); + BOOST_TEST(uid0 != uid2); + BOOST_TEST(uid1 != uid2); +} + BOOST_AUTO_TEST_SUITE_END() -- cgit v1.2.1