fix(sysman): fixes multithread access issue with FDCache

Related-To: NEO-9720

Signed-off-by: Kulkarni, Ashwin Kumar <ashwin.kumar.kulkarni@intel.com>
This commit is contained in:
Kulkarni, Ashwin Kumar 2023-12-07 07:40:17 +00:00 committed by Compute-Runtime-Automation
parent f395bdbdab
commit a064388ba8
6 changed files with 66 additions and 2 deletions

View File

@ -45,6 +45,7 @@ void FdCacheInterface::eraseLeastUsedEntryFromCache() {
}
int FdCacheInterface::getFd(std::string file) {
std::unique_lock<std::mutex> lock(fdMutex);
int fd = -1;
if (fdMap.find(file) == fdMap.end()) {
fd = NEO::SysCalls::open(file.c_str(), O_RDONLY);

View File

@ -13,6 +13,7 @@
#include <map>
#include <memory>
#include <mutex>
#include <vector>
namespace L0 {
@ -31,6 +32,7 @@ class FdCacheInterface {
std::map<std::string, std::pair<int, uint32_t>> fdMap = {};
private:
std::mutex fdMutex{};
void eraseLeastUsedEntryFromCache();
};

View File

@ -218,6 +218,35 @@ TEST(FdCacheTest, GivenValidFdCacheWhenCallingGetFdOnSameFileThenVerifyCacheIsUp
EXPECT_EQ(pFdCache->fdMap.end(), pFdCache->fdMap.find("mockfile9.txt"));
}
TEST(FdCacheTest, GivenValidFdCacheWhenCallingGetFdOnMultipleFilesManyTimesThenVerifyCacheIsUpdatedCorrectly) {
class MockFdCache : public FdCacheInterface {
public:
using FdCacheInterface::fdMap;
};
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
return 1;
});
std::unique_ptr<MockFdCache> pFdCache = std::make_unique<MockFdCache>();
std::string fileName = {};
for (auto i = 0; i < L0::Sysman::FdCacheInterface::maxSize; i++) {
fileName = "mockfile" + std::to_string(i) + ".txt";
int j = i + 1;
while (j--) {
EXPECT_LE(0, pFdCache->getFd(fileName));
}
}
// replace a least referred file and add new file
fileName = "mockfile100.txt";
EXPECT_LE(0, pFdCache->getFd(fileName));
// Verify cache doesn't have an element that is accessed less number of times.
EXPECT_EQ(pFdCache->fdMap.end(), pFdCache->fdMap.find("mockfile0.txt"));
}
TEST(FdCacheTest, GivenValidFdCacheWhenClearingCacheThenVerifyProperFdsAreClosedAndCacheIsUpdatedProperly) {
class MockFdCache : public FdCacheInterface {

View File

@ -46,6 +46,7 @@ void FdCache::eraseLeastUsedEntryFromCache() {
}
int FdCache::getFd(std::string file) {
std::unique_lock<std::mutex> lock(fdMutex);
int fd = -1;
if (fdMap.find(file) == fdMap.end()) {
fd = NEO::SysCalls::open(file.c_str(), O_RDONLY);

View File

@ -18,6 +18,7 @@
#include <list>
#include <map>
#include <memory>
#include <mutex>
#include <sstream>
#include <string>
#include <sys/stat.h>
@ -41,6 +42,7 @@ class FdCache {
std::map<std::string, std::pair<int, uint32_t>> fdMap = {};
private:
std::mutex fdMutex{};
void eraseLeastUsedEntryFromCache();
};

View File

@ -540,6 +540,35 @@ TEST(FdCacheTest, GivenValidFdCacheWhenClearingCacheThenVerifyProperFdsAreClosed
delete pFdCache;
}
TEST(FdCacheTest, GivenValidFdCacheWhenCallingGetFdOnMultipleFilesManyTimesThenVerifyCacheIsUpdatedCorrectly) {
class MockFdCache : public FdCache {
public:
using FdCache::fdMap;
};
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {
return 1;
});
std::unique_ptr<MockFdCache> pFdCache = std::make_unique<MockFdCache>();
std::string fileName = {};
for (auto i = 0; i < L0::FdCache::maxSize; i++) {
fileName = "mockfile" + std::to_string(i) + ".txt";
int j = i + 1;
while (j--) {
EXPECT_LE(0, pFdCache->getFd(fileName));
}
}
// replace a least referred file and add new file
fileName = "mockfile100.txt";
EXPECT_LE(0, pFdCache->getFd(fileName));
// Verify cache doesn't have an element that is accessed less number of times.
EXPECT_EQ(pFdCache->fdMap.end(), pFdCache->fdMap.find("mockfile0.txt"));
}
TEST_F(SysmanDeviceFixture, GivenSysfsAccessClassAndUnsignedIntegerWhenCallingReadThenSuccessIsReturned) {
VariableBackup<decltype(NEO::SysCalls::sysCallsOpen)> mockOpen(&NEO::SysCalls::sysCallsOpen, [](const char *pathname, int flags) -> int {